Skip to content

فصل ۱۰ — محافظت از Kafka

این فصل شامل

  • مبانی امنیت و اصطلاحات مرتبط
  • SSL بین کلاستر و کلاینت‌ها
  • فهرست‌های کنترل دسترسی (ACL)
  • سهمیه پهنای باند شبکه و نرخ درخواست برای محدود کردن تقاضا از منابع

این فصل بر حفظ امنیت داده‌هایمان تمرکز دارد تا فقط کسانی که نیاز دارند بتوانند از آن بخوانند یا در آن بنویسند. چون امنیت حوزه‌ای بسیار گسترده است، در این فصل درباره چند مفهوم پایه صحبت می‌کنیم تا پیش‌زمینه‌ای کلی از گزینه‌های موجود در Kafka داشته باشید. هدف این فصل راه‌اندازی امنیت نیست، بلکه آشنایی با گزینه‌های مختلفی است که می‌توانید با تیم امنیت خود درباره‌شان بحث کنید و مفاهیم را بشناسید. این راهنمای کامل امنیت به‌طور کلی نخواهد بود، اما پایه‌ای برای شما فراهم می‌کند. اقدامات عملی که می‌توانید در محیط خود انجام دهید را بررسی می‌کنیم و تأثیر بر کلاینت‌ها، بروکرها و ZooKeeper را می‌بینیم تا کلاستر امن‌تر شود.

شاید داده‌های شما به حفاظت‌هایی که بحث می‌کنیم نیاز نداشته باشند، اما شناخت داده‌هایتان کلید تصمیم‌گیری درباره نیاز به مدیریت دسترسی و trade-offهای آن است. اگر با اطلاعات شخصی یا مالی — مثل تاریخ تولد یا شماره کارت اعتباری — سر و کار دارید، احتمالاً باید بیشتر گزینه‌های امنیتی این فصل را بررسی کنید. اما اگر فقط اطلاعات عمومی مثل کمپین‌های بازاریابی را پردازش می‌کنید یا چیز حساسی ردیابی نمی‌کنید، شاید به این حفاظت نیاز نداشته باشید. در این صورت کلاستر شما لازم نیست ویژگی‌هایی مثل SSL را معرفی کند. با مثالی از داده‌های فرضی که می‌خواهیم محافظت کنیم شروع می‌کنیم.

فرض کنید هدفمان یافتن محل یک جایزه با شرکت در یک گنج‌یابی است. به‌عنوان تمرین سراسری مسابقه، دو تیم داریم و نمی‌خواهیم تیم دیگر به کار تیم خودمان دسترسی داشته باشد. در ابتدا هر تیم نام topic خود را انتخاب می‌کند و فقط با اعضای تیم به اشتراک می‌گذارد. (بدون دانستن نام topic برای نوشتن و خواندن، داده‌هایتان از دید تیم دیگر پنهان است.) هر تیم با ارسال سرنخ‌ها به topic خصوصی فرضی خود شروع می‌کند. با گذشت زمان، اعضای تیم‌ها ممکن است به پیشرفت تیم مقابل و سرنخ‌هایی که طرف دیگر ندارد فکر کنند. اینجاست که دردسر شروع می‌شود. شکل ۱۰.۱ تنظیم topic برای Team Clueful و Team Clueless را نشان می‌دهد.

در این نقطه، جز رفتار تیم‌ها چیزی مانع خواندن هر topic توسط هر تیم نیست. هر تیم می‌تواند در هر topic بخواند و بنویسد.

                                                    Topics
                            Writes

         Team Clueful                      kinaction_clueful_secrets    Kafka cluster
                            Reads

                            Writes

        Team Clueless                      kinaction_clueless_secrets

                            Reads

شکل ۱۰.۱ topicهای گنج‌یابی

یک رقیب فنی‌آگاه که تصادفاً قبلاً از Kafka استفاده کرده، به ابزارهای خط فرمان می‌رسد تا topicها را پیدا کند (topic تیم دیگر و topic خودش). پس از گرفتن فهرست topicها، رقیب topic طرف مقابل را می‌شناسد. بگوییم عضوی از Team Clueless به topic تیم Clueful — --topic kinaction_clueful_secrets — نگاه می‌کند. با خوشحالی زیاد، فقط یک دستور consumer console کافی بود تا همه داده‌هایی که Team Clueful تا اینجا روی آن کار کرده فهرست شود! اما بازیگر بد همین‌جا متوقف نمی‌شود.

برای گمراه کردن Team Clueful، بازیگر اطلاعات نادرست هم در کانال می‌نویسد. حالا Team Clueful داده بد در topic خود دارد و پیشرفت حل سرنخ‌ها کند شده! چون مطمئن نیستند چه کسی واقعاً پیام‌ها را نوشته، باید مشخص کنند کدام‌ها جعلی‌اند و در این کار زمان ارزشمندی را از دست می‌دهند که می‌توانستند برای یافتن محل جایزه بزرگ صرف کنند.

چطور می‌توان از وضعیتی که Team Clueful در آن گرفتار شده جلوگیری کرد؟ آیا راهی هست که فقط کلاینت‌های دارای مجوز بتوانند از topicهای ما بخوانند یا در آن بنویسد؟ راه‌حل دو بخش دارد. بخش اول رمزنگاری داده است. بخش بعدی این است که در سیستم بدانیم فرد کیست؛ نه فقط اینکه claim می‌کند کیست، بلکه هویت ادعایی تأیید شود. پس از تأیید کاربر، باید بدانیم در سیستم چه کاری مجاز است. با بررسی چند راه‌حل Kafka عمیق‌تر می‌شویم.

۱۰.۱ مبانی امنیت

در امنیت برنامه‌های رایانه‌ای، احتمالاً با encryption، authentication و authorization روبه‌رو می‌شوید. نگاه دقیق‌تری به این اصطلاحات بیندازیم (برای جزئیات بیشتر به http://mng.bz/o802 مراجعه کنید).

Encryption به این معنا نیست که دیگران پیام‌های شما را نبینند، بلکه اگر ببینند نتوانند محتوای اصلی محافظت‌شده را استخراج کنند. بسیاری به استفاده از سایت امن (HTTPS) برای خرید آنلاین روی Wi-Fi® فکر می‌کنند. بعداً SSL (Secure Sockets Layer) را برای ارتباط — نه بین وب‌سایت و رایانه، بلکه بین کلاینت‌ها و بروکرها — فعال می‌کنیم. به‌طور کلی، در این فصل برچسب «SSL» نام propertyای است که در مثال‌ها می‌بینید، هرچند TLS نسخه جدیدتر پروتکل است [۱].

درباره authentication: برای تأیید هویت کاربر یا برنامه، باید راهی برای authenticate کردن داشته باشیم؛ authentication فرایند اثبات این است که کاربر یا برنامه واقعاً همان کسی است که claim می‌کند. مثلاً برای کارت کتابخانه، آیا کتابخانه بدون اطمینان از هویت به هر کسی کارت می‌دهد؟ در بیشتر موارد، نام و آدرس با مدرک دولتی و قبض آب و برق تأیید می‌شود تا کسی به‌راحتی هویت دیگری را claim نکند. اگر کسی به نام شما کتاب قرض بگیرد و برنگرداند و جریمه به شما برسد، عیب عدم تأیید claim کاربر را می‌بینید.

Authorization در مقابل، روی آنچه کاربر می‌تواند انجام دهد تمرکز دارد. در مثال کتابخانه، کارت صادرشده به بزرگسال ممکن است مجوزهای متفاوتی از کارت کودک داشته باشد. دسترسی به نشریات آنلاین ممکن است فقط از ترمینال‌های داخل کتابخانه برای هر دارنده کارت محدود شود.

۱۰.۱.۱ رمزنگاری با SSL

تا اینجا همه بروکرهای این کتاب plaintext [۱] را پشتیبانی کرده‌اند؛ عملاً authentication یا رمزنگاری روی شبکه نبوده. با این دانش، شاید مرور یکی از مقادیر پیکربندی سرور بروکر منطقی باشد. در هر server.properties فعلی (برای محل فایل config/server0.properties به پیوست A مراجعه کنید) ورودی‌ای مثل listeners = PLAINTEXT:localhost//:9092 می‌بینید. آن listener در عمل نگاشت پروتکل به پورت مشخص روی بروکر است. چون بروکرها چند پورت پشتیبانی می‌کنند، این ورودی اجازه می‌دهد پورت PLAINTEXT فعال بماند تا SSL یا پروتکل‌های دیگر را روی پورت دیگر تست کنیم. دو پورت گذار از plaintext را نرم‌تر می‌کند [۲]. شکل ۱۰.۲ plaintext در برابر SSL را نشان می‌دهد.

          Third party can see
          your traffic content.

                                                             The data in topic
                                                         kinaction_clueful_secrets
                                                             did not use SSL.

              Client
                                                              Kafka cluster

                                Plaintext message
                                "secret is plaintext"


                                   Not readable

              Client
             with SSL




                                      ?
                                           ?
                                             ?
          Third party can see
          but not understand
          your traffic.

شکل ۱۰.۲ Plaintext در برابر SSL

در این نقطه با کلاستری بدون امنیت داخلی شروع می‌کنیم. (خوشبختانه می‌توانیم با سخت‌تر کردن در برابر تیم‌های دیگر، قطعات مختلف را اضافه کنیم.) راه‌اندازی SSL بین بروکرهای کلاستر و کلاینت‌ها یکی از نقاط شروع است [۱]. سرور یا دایرکتوری اضافی لازم نیست. تغییر کد کلاینت هم لازم نیست؛ تغییرات configuration-driven هستند.

نمی‌دانیم کاربران دیگر در sniff کردن ترافیک روی همان Wi-Fi با ابزار امنیتی چقدر پیشرفته‌اند، پس می‌دانیم شاید نخواهیم plaintext از بروکر به کلاینت بفرستیم. اگرچه راه‌اندازی بخش بعد برای امنیت Kafka لازم است، کسانی که قبلاً SSL یا HTTPS (به‌ویژه با Java) راه انداخته‌اند، این رویکرد را شبیه ترتیب اعتماد client/server دیگر می‌یابند.

۱۰.۱.۲ SSL بین بروکرها و کلاینت‌ها

در مثال‌های قبلی نوشتن کلاینت و اتصال به Kafka از SSL استفاده نکردیم. حالا آن را برای ارتباط کلاینت و کلاستر روشن می‌کنیم تا ترافیک شبکه با SSL رمز شود. فرایند را گام‌به‌گام می‌بینیم و آنچه برای به‌روزرسانی کلاستر لازم است.

NOTE دستورات این فصل خاص هستند و بدون تغییر روی همه سیستم‌عامل‌ها (یا حتی نام دامنه‌های مختلف بروکر) یکسان کار نمی‌کنند. مهم دنبال کردن مفاهیم کلی است. ابزارهای دیگر (مثل OpenSSL®) هم قابل تعویض‌اند. پس از فهم مفاهیم، به سایت Confluent در http://mng.bz/nrza برای منابع بیشتر بروید. اسناد Confluent که جهت مثال‌ها را داده‌اند در سراسر فصل ارجاع شده‌اند.

WARNING برای راه‌اندازی صحیح محیط خود با متخصص امنیت مشورت کنید. دستورات ما برای آشنایی و یادگیری است، نه سطح production. راهنمای کامل نیست. با مسئولیت خود استفاده کنید!

یکی از اولین گام‌ها ساخت key و certificate برای بروکرهاست [۳]. چون Java روی ماشین دارید، یک گزینه utility keytool بخشی از نصب Java است. keytool keystore کلیدها و certificateهای مورد اعتماد را مدیریت می‌کند [۴]. نکته مهم storage است. در این فصل اصطلاح broker0 در بعضی نام فایل‌ها برای شناسایی یک بروکر خاص است، نه همه بروکرها. keystore را می‌توان پایگاه‌داده‌ای دانست که برنامه‌های JVM برای فرایندها در صورت نیاز اطلاعات را از آن می‌خوانند [۴]. در این نقطه key برای بروکرها تولید می‌کنیم، مثل listing 10.1 [۳]. توجه: manning.com در listingها مثال است و برای دنبال کردن کتاب نیست.

Listing 10.1 تولید کلید SSL برای بروکر

bash
keytool -genkey -noprompt \
  -alias localhost \
  -dname "CN=ka.manning.com,OU=TEST,O=TREASURE,L=Bend,S=Or,C=US" \
  -keystore kafka.broker0.keystore.jks \
  -keyalg RSA \
  -storepass changeTreasure \
  -keypass changeTreasure \
  -validity 999

پس از اجرا، key جدید در فایل keystore kafka.broker0.keystore.jks ذخیره شده. چون key (به‌نوعی) بروکر را شناسایی می‌کند، به چیزی نیاز داریم که نشان دهد certificate تصادفی از کاربر random نیست. یکی از راه‌ها امضای certificate با CA (certificate authority) است. CAهایی مثل Let's Encrypt® (https://letsencrypt.org/) یا GoDaddy® (https://www.godaddy.com/) را شنیده‌اید. نقش CA مرجع مورد اعتمادی است که مالکیت و هویت public key را گواهی می‌کند [۳]. در مثال‌ها خودمان CA می‌سازیم تا نیاز به تأیید هویت توسط شخص ثالث نباشد. گام بعد ساخت CA خودمان است، مثل listing 10.2 [۳].

Listing 10.2 ساخت certificate authority خودمان

bash
openssl req -new -x509 \
  -keyout cakey.crt -out ca.crt \
  -days 999 \
  -subj '/CN=localhost/OU=TEST/O=TREASURE/L=Bend/S=Or/C=US' \
  -passin pass:changeTreasure -passout pass:changeTreasure

این CA تولیدشده چیزی است که می‌خواهیم کلاینت‌ها بدانند باید به آن اعتماد کنند. مشابه keystore، از truststore برای نگه‌داری این اطلاعات استفاده می‌کنیم [۳].

چون CA را در listing 10.2 ساختیم، می‌توانیم certificate بروکرهای ساخته‌شده را sign کنیم: certificate تولیدشده در listing 10.1 را از keystore export، با CA جدید sign، و CA certificate و certificate امضاشده را به keystore import کنیم [۳]. Confluent اسکریپت shell برای خودکارسازی مشابه دارد (http://mng.bz/v497) [۳]. بقیه دستورات در source code کتاب در بخش این فصل است.

NOTE هنگام اجرای دستورات listingها، سیستم‌عامل یا نسخه ابزار ممکن است prompt متفاوتی داشته باشد. احتمالاً prompt کاربر بعد از اجرا ظاهر می‌شود. مثال‌ها سعی می‌کنند از prompt اجتناب کنند.

بخشی از تغییرات، به‌روزرسانی server.properties روی هر بروکر است، مثل listing 10.3 [۳]. فقط broker0 و بخشی از فایل نشان داده شده.

Listing 10.3 تغییرات server properties بروکر

...
listeners=PLAINTEXT://localhost:9092,SSL://localhost:9093
ssl.truststore.location=/opt/kafkainaction/private/kafka.broker0.truststore.jks
ssl.truststore.password=changeTreasure
ssl.keystore.location=/opt/kafkainaction/kafka.broker0.keystore.jks
ssl.keystore.password=changeTreasure
ssl.key.password=changeTreasure
...

تغییرات برای کلاینت‌ها هم لازم است. مثلاً security.protocol=SSL و محل و رمز truststore در فایل custom-ssl.properties تنظیم می‌شود. این پروتکل SSL و اشاره به truststore را مشخص می‌کند [۳].

در تست، می‌توانیم چند listener برای بروکر داشته باشیم. این به migration تدریجی کلاینت‌ها کمک می‌کند؛ هر دو پورت قبل از حذف PLAINTEXT ترافیک سرو می‌دهند [۳]. فایل kinaction-ssl.properties اطلاع لازم برای تعامل با بروکر امن‌شده را به کلاینت می‌دهد!

Listing 10.4 استفاده از پیکربندی SSL برای کلاینت‌های خط فرمان

bash
bin/kafka-console-producer.sh --bootstrap-server localhost:9093 \
  --topic kinaction_test_ssl \
  --producer.config kinaction-ssl.properties
bin/kafka-console-consumer.sh --bootstrap-server localhost:9093 \
  --topic kinaction_test_ssl \
  --consumer.config kinaction-ssl.properties

یکی از بهترین ویژگی‌ها استفاده از همان پیکربندی برای producer و consumer است. در محتوای فایل پیکربندی، استفاده از رمز در فایل‌ها ممکن است به ذهن برسد. ساده‌ترین گزینه آگاهی از permissionهای فایل است. محدود کردن خواندن و مالکیت فایل قبل از قرار دادن روی filesystem مهم است. همیشه با متخصصان امنیت برای گزینه‌های بهتر مشورت کنید.

۱۰.۱.۳ SSL بین بروکرها

چون بروکرها با هم هم صحبت می‌کنند، باید بررسی کنید آیا برای آن تعاملات SSL لازم است. می‌توانید security.inter.broker.protocol = SSL در server properties بگذارید اگر نمی‌خواهید plaintext بین بروکرها بماند و تغییر پورت را هم در نظر بگیرید. جزئیات بیشتر: http://mng.bz/4KBw [۵].

۱۰.۲ Kerberos و Simple Authentication and Security Layer (SASL)

اگر تیم امنیت سرور Kerberos دارد، احتمالاً متخصصانی برای کمک دارید. وقتی اول با Kafka کار کردیم، بخشی از مجموعه ابزار big data بود که بیشتر Kerberos داشت. Kerberos اغلب در سازمان‌ها برای SSO امن یافت می‌شود.

اگر سرور Kerberos دارید، با کاربری که به آن محیط دسترسی دارد principal برای هر بروکر و هر کاربر (یا application ID) که به کلاستر دسترسی می‌گیرد بسازید. چون راه‌اندازی برای تست محلی ممکن است پیچیده باشد، با بحث فرمت فایل‌های JAAS (Java Authentication and Authorization Service) — نوع رایج برای بروکر و کلاینت — همراه شوید. منابع عالی: http://mng.bz/QqxG [۶].

فایل‌های JAAS با اطلاعات keytab به Kafka principal و credential می‌دهند. keytab احتمالاً فایل جداگانه‌ای با principal و کلیدهای رمزشده است. با این فایل بدون رمز می‌توان به بروکرهای Kafka authenticate کرد [۷]. keytab را با همان دقت credentialها محافظت کنید.

برای راه‌اندازی بروکرها، تغییرات server property و مثال پیکربندی JAAS لازم است. هر بروکر keytab خود را می‌خواهد. فایل JAAS محل keytab و principal را اعلام می‌کند [۷]. listing 10.5 مثال JAAS بروکر در startup است.

Listing 10.5 فایل SASL JAAS بروکر

KafkaServer {
...
    keyTab="/opt/kafkainaction/kafka_server0.keytab"
    principal="kafka/kafka0.ka.manning.com@MANNING.COM";
};

قبل از حذف پورت‌های قدیمی، پورت دیگری برای تست SASL_SSL اضافه می‌کنیم [۷]. listing 10.6 این تغییر را نشان می‌دهد. بسته به پورت اتصال، پروتکل PLAINTEXT، SSL یا SASL_SSL است.

Listing 10.6 تغییر SASL properties بروکر

listeners=PLAINTEXT://localhost:9092,SSL://localhost:9093,SASL_SSL://localhost:9094

راه‌اندازی کلاینت مشابه است [۷]. فایل JAAS لازم است، مثل listing 10.7.

Listing 10.7 فایل SASL JAAS کلاینت

KafkaClient {
...
    keyTab="/opt/kafkainaction/kafkaclient.keytab"
    principal="kafkaclient@MANNING.COM";
};

پیکربندی کلاینت برای مقادیر SASL هم به‌روز می‌شود [۳]. فایل کلاینت شبیه kinaction-ssl.properties است اما پروتکل SASL_SSL را تعریف می‌کند. پس از تست روی پورت 9092 یا 9093، با پیکربندی جدید و پروتکل SASL_SSL همان نتیجه قبلی را validate می‌کنیم.

۱۰.۳ Authorization در Kafka

پس از authentication، نحوه استفاده از آن اطلاعات برای دسترسی کاربر را می‌بینیم. با access control list شروع می‌کنیم.

۱۰.۳.۱ Access control lists (ACLs)

مرور سریع: authorization فرایندی است که کنترل می‌کند کاربر چه کاری می‌تواند انجام دهد. یکی از راه‌های authorization، ACL است. کاربران Linux با permission فایل و chmod (read، write، execute) آشنا‌اند، اما گاهی انعطاف کافی نیست. ACL برای چند فرد و گروه و انواع permission بیشتر است و وقتی سطح دسترسی متفاوت برای پوشه مشترک لازم است رایج است [۸]. مثلاً ویرایش بدون حذف (delete permission جداست). شکل ۱۰.۳ دسترسی Franz به منابع تیم فرضی گنج‌یابی را نشان می‌دهد.

                                           Principal is allowed or denied operation on resources.

                                        Franz
       User Franz is allowed                       Produce
       read/write on
       resource topic                                                  Topic: kinaction_clueful_secrets
       kinaction_clueful_secrets.                  Consume
                                        Franz

                                                   Produce

                                                                         Topic: kinaction_not_franzs

                                                   Consume

شکل ۱۰.۳ Access control lists (ACLs)

Kafka authorizer را pluggable طراحی کرده تا منطق سفارشی ممکن باشد [۸]. کلاس SimpleAclAuthorizer را در مثال استفاده می‌کنیم.

listing 10.8 افزودن authorizer class و superuser Franz به server.properties برای ACL را نشان می‌دهد. پس از پیکربندی authorizer باید ACL تنظیم شود، وگرنه فقط superuserها به منابع دسترسی دارند [۸].

Listing 10.8 ACL authorizer و superuserها

authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
super.users=User:Franz

دسترسی Team Clueful را می‌بینیم تا فقط آن تیم از topic خود kinaction_clueful_secrets produce و consume کند. برای اختصار دو کاربر Franz و Hemingway داریم. keytab کاربران ساخته شده، پس principal را می‌دانیم. در listing 10.9 عملیات Read به consumer اجازه خواندن از topic می‌دهد [۸]. Write به همان principalها اجازه produce می‌دهد.

Listing 10.9 ACLهای Kafka برای read و write روی topic

bash
bin/kafka-acls.sh --authorizer-properties \
  --bootstrap-server localhost:9094 --add \
  --allow-principal User:Franz \
  --allow-principal User:Hemingway \
  --operation Read --operation Write \
  --topic kinaction_clueful_secrets

ابزار CLI kafka-acls.sh با سایر اسکریپت‌های Kafka برای add، delete یا list ACLها [۸] است.

۱۰.۳.۲ Role-based access control (RBAC)

RBAC گزینه‌ای است که Confluent Platform پشتیبانی می‌کند؛ کنترل دسترسی بر اساس نقش [۹]. کاربران بر اساس نیاز (مثلاً وظیفه شغلی) به نقش assign می‌شوند. به‌جای grant مستقیم به هر کاربر، privilegeهای نقش‌های از پیش تعریف‌شده مدیریت می‌شود [۹]. شکل ۱۰.۴ افزودن کاربر به نقش و assignment مجوز جدید را نشان می‌دهد.

           Users                           Roles                         Permissions

           Franz

                   User assignment

                                                          Permission
                                          Role:           assignment
                                     kinaction_clueful
            Jay
                                         _secrets
                   User assignment

شکل ۱۰.۴ Role-based access control (RBAC)

برای تیم‌های گنج‌یابی، نقش per team منطقی است — شبیه تیم marketing در برابر accounting. اگر کاربر department عوض کند، نقش reassign می‌شود نه permission فردی. گزینه جدیدتر و geared به Confluent Platform است؛ برای آگاهی ذکر شد و عمیق‌تر نمی‌رویم.

۱۰.۴ ZooKeeper

بخشی از امن‌سازی Kafka، امن‌سازی همه اجزای کلاستر از جمله ZooKeeper است. اگر بروکرها محافظت شوند اما سیستم نگه‌دارنده داده امنیتی نه، با دانش کافی می‌توان مقادیر امنیتی را بدون تلاش زیاد تغییر داد. برای محافظت metadata، zookeeper.set.acl=true per broker لازم است [۱۰].

Listing 10.10 ACLهای ZooKeeper

zookeeper.set.acl=true

۱۰.۴.۱ راه‌اندازی Kerberos

اطمینان از کار Kerberos با ZooKeeper تغییرات پیکربندی متنوعی می‌خواهد. در zookeeper.properties مقادیری که SASL برای کلاینت‌ها و provider را اعلام می‌کند اضافه کنید. http://mng.bz/Xr0v [۱۰]. در حالی که گزینه‌های دیگر را بررسی کردیم، بعضی کاربران سیستم گنج‌یابی هنوز mischief می‌کردند. به quotas می‌پردازیم.

۱۰.۵ Quotas

برخی کاربران وب‌اپلیکیشن مکرراً داده درخواست می‌کنند. برای end user خوب است، اما کلاستر ممکن است به محافظت در برابر سوءاستفاده نیاز داشته باشد. در مثال، چون دسترسی فقط اعضای تیم بود، تیم مقابل راه جدیدی برای مانع شدن از موفقیت تیم ما یافت: حمله distributed denial-of-service (DDoS) [۱۱]!

حمله هدفمند بروکرها و زیرساخت اطراف را غرق می‌کند. تیم مقابل read مکرر از topicهای ما از ابتدا هر بار درخواست می‌کند. با quotas از این رفتار جلوگیری می‌کنیم. quotas per broker تعریف می‌شوند [۱۱]؛ کلاستر مجموع بین بروکرها را محاسبه نمی‌کند. شکل ۱۰.۵ مثال quota درصد درخواست را نشان می‌دهد.

             Clients all with Client IDs from
             kinaction_clueless_secrets would get
             delays after too many fetches.

                                                                         Kafka cluster
                             Constant polling

             Client                                     Broker 0            Broker 1          Broker 2
                            Broker delays reply

                                                     Quota client ID     Quota client ID   Quota client ID
       fetching.wait.ms=0
                                                        request             request           request
                                                      percentage          percentage        percentage
                             Constant polling
                                                         200%                200%              200%
             Client         Broker delays reply

       fetching.wait.ms=0
...
                                      Each broker's quotas are treated
                                      separate from other brokers.

شکل ۱۰.۵ Quotas

برای quota سفارشی باید بدانیم چه کسی محدود شود و limit چیست. وجود امنیت گزینه‌های تعریف محدودشونده را تغییر می‌دهد. بدون امنیت، client.id قابل استفاده است. با امنیت، user و ترکیب user و client.id هم [۱۱]. دو نوع quota: پهنای باند شبکه و نرخ درخواست. ابتدا پهنای باند.

۱۰.۵.۱ Quota پهنای باند شبکه

پهنای باند با بایت در ثانیه اندازه‌گیری می‌شود [۱۲]. می‌خواهیم هر کلاینت به شبکه احترام بگذارد و flood نکند. هر کاربر در مسابقه client ID مخصوص تیم برای producer/consumer دارد. در listing 10.11 کلاینت‌های با client ID kinaction_clueful را با producer_byte_rate و consumer_byte_rate محدود می‌کنیم [۱۳].

Listing 10.11 ساخت quota پهنای باند برای client kinaction_clueful

bash
bin/kafka-configs.sh --bootstrap-server localhost:9094 --alter \
  --add-config 'producer_byte_rate=1048576,consumer_byte_rate=5242880' \
  --entity-type clients --entity-name kinaction_clueful

add-config نرخ producer و consumer را تنظیم می‌کند (producer 1 MB/s، consumer 5 MB/s). entity-name rule را به client.id kinaction_clueful اعمال می‌کند.

گاه باید quotaهای فعلی را list یا delete کنیم. با آرگومان‌های مختلف به kafka-configs.sh [۱۳]:

Listing 10.12 List و delete quota برای client kinaction_clueful

bash
bin/kafka-configs.sh --bootstrap-server localhost:9094 \
  --describe \
  --entity-type clients --entity-name kinaction_clueful
bin/kafka-configs.sh --bootstrap-server localhost:9094 --alter \
  --delete-config 'producer_byte_rate,consumer_byte_rate' \
  --entity-type clients --entity-name kinaction_clueful

--describe پیکربندی فعلی را نشان می‌دهد. با delete-config حذف می‌کنیم.

با افزودن quota ممکن است بیش از یک quota روی کلاینت اعمال شود. ترتیب precedence مهم است. همیشه restrictiveترین (کمترین بایت) اول نیست. ترتیب اعمال (بالاترین precedence بالا) [۱۴]:

  • Quotaهای user و client.id
  • Quotaهای user
  • Quotaهای client.id

مثلاً اگر Franz quota کاربر 10 MB و client.id 1 MB داشته باشد، consumer او 10 MB/s مجاز است چون user quota اولویت بالاتر دارد.

۱۰.۵.۲ Quota نرخ درخواست

quota دوم نرخ درخواست است. DDoS اغلب مسئله شبکه تلقی می‌شود، اما اتصالات زیاد با درخواست‌های CPU-intensive هم بروکر را غرق می‌کند. consumerهایی که با fetch.max.wait.ms=0 مداوم poll می‌کنند نگرانی‌اند و با request rate quota (شکل ۱۰.۵) [۱۵] قابل برخورد.

همان entity type و add-config؛ تفاوت در request_percentage. فرمول با تعداد I/O thread و network thread: http://mng.bz/J6Yz [۱۶]. listing 10.13 درصد 100 برای مثال [۱۳].

Listing 10.13 ساخت quota نرخ درخواست برای client kinaction_clueful

bash
bin/kafka-configs.sh --bootstrap-server localhost:9094 --alter \
  --add-config 'request_percentage=100' \
  --entity-type clients --entity-name kinaction_clueful

Quotas راه خوبی برای محافظت از کلاستر است و به واکنش سریع به کلاینت‌هایی که ناگهان فشار می‌آورند کمک می‌کند.

۱۰.۶ داده در حالت سکون (Data at rest)

بررسی کنید آیا داده‌ای که Kafka روی دیسک می‌نویsd باید رمز شود. به‌طور پیش‌فرض Kafka رویدادهای log را رمز نمی‌کند. چند KIP (Kafka Improvement Proposal) این ویژگی را بررسی کرده‌اند، اما در زمان انتشار هنوز باید استراتژی متناسب با نیاز داشته باشید. بسته به نیاز کسب‌وکار، شاید فقط topicهای خاص یا topic با کلیدهای منحصربه‌فرد رمز شوند.

۱۰.۶.۱ گزینه‌های managed

با گزینه managed کلاستر، ویژگی‌های سرویس را ببینید. Amazon Managed Streaming for Apache Kafka (https://aws.amazon.com/msk/) مثالی از cloud provider است که بخش بزرگی از مدیریت کلاستر از جمله امنیت را handle می‌کند. patch سخت‌افزار و upgrade خودکار یک روش مهم برای دور نگه داشتن مشکلات است. مزیت دیگر این است که developer بیشتری به کلاستر دسترسی نمی‌دهید. Amazon MSK رمزنگاری داده و TLS بین اجزای Kafka [۱۷] را هم دارد.

مدیریت دیگری که در این فصل دیدیم: SSL بین کلاینت و کلاستر و ACL. Confluent Cloud (https://www.confluent.io/confluent-cloud/) روی cloudهای عمومی مختلف deploy می‌شود. رمزنگاری at rest و in motion و ACL از گزینه‌هایی است که هنگام match کردن نیاز امنیتی با provider باید بدانید.

در stack Confluent، Confluent Platform 5.3 ویژگی تجاری secret protection (http://mng.bz/yJYB) دارد. در فایل‌های SSL قبلی رمز plaintext ذخیره کردیم؛ secret protection secretها را در فایل رمز و مقادیر exposed را از فایل خارج می‌کند [۱۸]. چون commercial است عمیق نمی‌رویم، اما بدانید گزینه وجود دارد.

خلاصه

  • Plaintext برای prototype مناسب است، اما قبل از production ارزیابی شود.
  • SSL (Secure Sockets Layer) داده بین کلاینت و بروکر و حتی بین بروکرها را محافظت می‌کند.
  • Kerberos identity principal می‌دهد و محیط‌های Kerberos موجود در زیرساخت را usable می‌کند.
  • ACL مشخص می‌کند کدام کاربران چه عملیاتی دارند. RBAC گزینه Confluent Platform بر اساس نقش است.
  • Quota با limit پهنای باند شبکه و نرخ درخواست منابع کلاستر را محافظت می‌کند. quotaها قابل تغییر و fine-tune برای workload عادی و peak هستند.

منابع

  1. «Encryption and Authentication with SSL.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/kafka/authentication_ssl.html (accessed June 10, 2020).
  2. «Adding security to a running cluster.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/kafka/incremental-security-upgrade.html#adding-security-to-a-running-cluster (accessed August 20, 2021).
  3. «Security Tutorial.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/security/security_tutorial.html (accessed June 10, 2020).
  4. keytool. Oracle Java documentation (n.d.). https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html (accessed August 20, 2021).
  5. «Documentation: Incorporating Security Features in a Running Cluster.» Apache Software Foundation (n.d.). http://kafka.apache.org/24/documentation.html#security_rolling_upgrade (accessed June 1, 2020).
  6. V. A. Brennen. «An Overview of a Kerberos Infrastructure.» Kerberos Infrastructure HOWTO. https://tldp.org/HOWTO/Kerberos-Infrastructure-HOWTO/overview.html (accessed July, 22, 2021).
  7. «Configuring GSSAP.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_gssapi.html (accessed June 10, 2020).
  8. «Authorization using ACLs.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/kafka/authorization.html (accessed June 10, 2020).
  9. «Authorization using Role-Based Access.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/security/rbac/index.html (accessed June 10, 2020).
  10. «ZooKeeper Security.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/security/zk-security.html (accessed June 10, 2020).
  11. «Quotas.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/kafka/design.html#quotas (accessed August 21, 2021).
  12. «Network Bandwidth Quotas.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/kafka/design.html#network-bandwidth-quotas (accessed August 21, 2021).
  13. «Setting quotas.» Apache Software Foundation (n.d.). https://kafka.apache.org/documentation/#quotas (accessed June 15, 2020).
  14. «Quota Configuration.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/kafka/design.html#quota-configuration (accessed August 21, 2021).
  15. KIP-124 «Request rate quotas.» Wiki for Apache Kafka. Apache Software Foundation (March 30, 2017). https://cwiki.apache.org/confluence/display/KAFKA/KIP-124+-+Request+rate+quotas (accessed June 1, 2020).
  16. «Request Rate Quotas.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/kafka/design.html#request-rate-quotas (accessed August 21, 2021).
  17. «Amazon MSK features.» Amazon Managed Streaming for Apache Kafka (n.d). https://aws.amazon.com/msk/features/ (accessed July 23, 2021).
  18. «Secrets Management.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/security/secrets.html (accessed August 21, 2021).