تعزيز أمن الخدمات الصغيرة باستخدام Istio

مرحبا! اسمي إيليا ، أعمل كمهندس DevOps في فريق التطوير. نحن نستخدم نهج الخدمة الدقيقة بنشاط ، وبسبب تفاصيل عملنا ، فإن أمن التفاعل بين الخدمات مهم بالنسبة لنا. في هذه المقالة ، أريد أن أصف كيفية عمل Istio وإظهار كيفية استخدام بعض ميزات الأمان الخاصة به باستخدام مثال. آمل أن يكون هذا مفيدًا لحل مشاكلك. استمتع بالقراءة!







ما هي شبكة الخدمة؟



تعد شبكة الخدمة ، في هذه الحالة Istio ، ملزمة لكل ما هو مطلوب لإدارة وتكوين الاتصال بين الخدمات: التوجيه والمصادقة والتفويض والتتبع والتحكم في الوصول والمزيد. وعلى الرغم من وجود العديد من المكتبات مفتوحة المصدر لتنفيذ هذه الوظائف مباشرة في رمز الخدمة ، مع Istio يمكنك الحصول على كل نفس دون إضافة أي شيء إلى الخدمة نفسها.



مكونات 



مقال مكتوب في istio 1.6


حول التغييرات
Istio , . , , - , , . , , Istio 1.4   v1beta1 , Istio RBAC. 1.5 , Pilot, Galley Citadel istiod. - . .



ينقسم Istio منطقيًا إلى مستوى بيانات ومستوى تحكم.

مستوى البيانات عبارة عن مجموعة من الخوادم الوكيلة (Envoy) المضافة إلى الجراب كسيارات جانبية. توفر هذه الوكلاء وتتحكم في جميع اتصالات الشبكة بين الخدمات الصغيرة ويتم تكوينها من مستوى التحكم.



يوفر مستوى الإدارة (istiod) اكتشاف الخدمة والتكوين وإدارة الشهادة. يحول كائنات Istio إلى تكوينات صديقة للمبعوثين ويوزعها في مستوى البيانات.







مكونات شبكة خدمة Istio



يمكنك إضافة مبعوث إلى لوحة التطبيق إما يدويًا أو عن طريق إعداد الإضافة التلقائية باستخدام الرد التلقائي على الويب Mutating Admission ، الذي يضيفه Istio أثناء تثبيته. للقيام بذلك ، ضع التسمية istio-injection = ممكّنة على مساحة الاسم الضرورية.



بالإضافة إلى السيارة الوكيل مع المبعوث ، ستضيف Istio حاوية التهيئة الخاصة إلى الجراب ، والتي ستعيد توجيه حركة القتال إلى الحاوية مع المبعوث. ولكن كيف يتحقق ذلك؟ في هذه الحالة ، لا يوجد سحر ، ويتم تنفيذ ذلك عن طريق تعيين قواعد iptables إضافية في مساحة اسم شبكة pod.



حول استهلاك الموارد
, 100 Istio ~2-3 , envoy 40 , CPU 5%-7% pod.



دعونا نرى عمليا كيف تلتقط السيارة الجانبية حركة المرور الواردة والصادرة من الحاوية. للقيام بذلك ، ألق نظرة على مساحة الشبكة من جراب مع إضافة Istio sidecar بمزيد من التفاصيل. 



موقف تجريبي
Kubernetes Istio. 

Kubernetes minikube:



Linux:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/

minikube start --driver=<driver_name> // --driver=none        .




MacOS:
brew install minikube
minikube start --driver=<driver_name>






Istio demo :



curl -L https://istio.io/downloadIstio | sh -
cd istio-1.6.3
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo


: productpage details. Istio .



kubectl label namespace default istio-injection=enabled
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml








دعنا نرى قائمة بالحاويات لتطبيق صفحة المنتج:



kubectl -n default get pods productpage-v1-7df7cb7f86-ntwzz -o jsonpath="{.spec['containers','initContainers'][*].name}"
productpage 
istio-proxy 
istio-init


بالإضافة إلى صفحة المنتج نفسها ، فإن sidecar istio-proxy (المبعوث نفسه) وحاوية init تعمل istio-init في الكبسولة.



يمكنك إلقاء نظرة على قواعد iptables التي تم تكوينها في مساحة pod باستخدام الأداة المساعدة nsenter. للقيام بذلك ، نحتاج إلى معرفة pid لعملية الحاوية:



docker inspect k8s_productpage --format '{{ .State.Pid }}'
16286


يمكننا الآن رؤية قواعد iptables المحددة في هذه الحاوية.







يمكن ملاحظة أن جميع حركة المرور الواردة والصادرة تقريبًا يتم اعتراضها وإعادة توجيهها إلى الموانئ التي ينتظرها المبعوث بالفعل. 



تمكين تشفير حركة المرور المتبادلة



تمت إزالة كائنات Policy و MeshPolicy من الإصدار 1.6. بدلاً من ذلك ، يُقترح استخدام كائن PeerAuthentication


يسمح لك Istio بتشفير جميع حركة المرور بين الحاويات ، ولن تعرف التطبيقات نفسها حتى أنها تتواصل عبر tls. يتم ذلك عن طريق Istio نفسه خارج الصندوق ببيان واحد فقط ، حيث تم تثبيت شهادات العميل بالفعل في وكلاء جانبي. 



الخوارزمية هي على النحو التالي: 



  1. يقوم وكلاء المبعوثين من جانب العميل والخادم بالمصادقة على بعضهم البعض قبل إرسال الطلبات ؛

  2. إذا نجح الفحص ، يقوم وكيل العميل بتشفير حركة المرور وإرسالها إلى وكيل الخادم ؛

  3. يقوم جانب الخادم الوكيل بفك تشفير حركة المرور وإعادة توجيهها محليًا إلى خدمة الوجهة الفعلية.



يمكنك تمكين mTLS على مستويات مختلفة:



  • على مستوى الشبكة بالكامل ؛

  • على مستوى مساحة الاسم ؛

  • على مستوى جراب معين. 



أوضاع التشغيل:



  • السماح: يسمح لكل من حركة النص المشفر والعادي ؛

  • STRICT: مسموح فقط بـ TLS ؛

  • تعطيل: يسمح فقط النص العادي.



دعنا نصل إلى خدمة التفاصيل من جراب صفحة المنتج باستخدام curl بدون تمكين TLS ونرى ما يجلبه tcpdump إلى التفاصيل:



الطلب:







تفريغ حركة المرور:







يمكن قراءة جميع النصوص والرؤوس بشكل مثالي في النص العادي.



قم بتشغيل TLS. للقيام بذلك ، قم بإنشاء كائن من نوع PeerAuthentication في مساحة الاسم باستخدام قروننا.



apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: default
spec:
  mtls:
    mode: STRICT


لنقم بتشغيل الطلب من صفحة المنتج للحصول على التفاصيل مرة أخرى ومعرفة ما نحصل عليه:







تم تشفير حركة المرور



تفويض



تمت إزالة كائنات ClusterRbacConfig و ServiceRole و ServiceRoleBinding مع تطبيق سياسة المصادقة الجديدة. يقترح استخدام كائن AuthorizationPolicy بدلاً من ذلك.


يستخدم Istio سياسات التفويض لتكوين الوصول من تطبيق إلى آخر. علاوة على ذلك ، على عكس سياسات شبكة Kubernetes الخالصة ، يعمل هذا على مستوى L7. على سبيل المثال ، بالنسبة لحركة مرور http ، يمكنك ضبط طرق الطلب ومساراته.



كما رأينا في المثال السابق ، بشكل افتراضي ، يكون الوصول مفتوحًا لجميع الكبسولات في المجموعة بأكملها.



الآن سنحظر جميع الأنشطة في مساحة الاسم الافتراضية باستخدام ملف yaml هذا:



apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: default
spec:
  {}


ودعنا نحاول الوصول إلى خدمة التفاصيل:



curl details:9080
RBAC: access denied


عظيم ، الآن فشل طلبنا.



والآن دعنا نهيئ الوصول حتى يمر طلب GET وفقط على طول المسار / التفاصيل ، ويتم رفض جميع الطلبات الأخرى. هناك عدة خيارات لذلك:



  • يمكن تكوين لتمرير الطلبات مع رؤوس محددة ؛

  • عن طريق حساب الخدمة للتطبيق.

  • عن طريق عنوان IP الصادر ؛

  • بواسطة مساحة الاسم الصادرة ؛

  • حسب الادعاءات في الرمز المميز JWT.



أسهل طريقة للاحتفاظ بها هي تكوين الوصول إلى حساب الخدمة الخاص بالتطبيق ، نظرًا لعدم الحاجة إلى تهيئة مسبقة لهذا ، نظرًا لأن تطبيق العرض التوضيحي bookinfo يأتي بالفعل مع حساب الخدمة الذي تم إنشاؤه وتحميله.



لاستخدام سياسات المصادقة المستندة إلى حسابات الخدمة ، يجب تمكين المصادقة المتبادلة لـ TLS.


قم بإعداد سياسة وصول جديدة:



apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "details-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: details
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
        paths: ["/details/*"]


ونحاول التواصل مرة أخرى:



root@productpage-v1-6b64c44d7c-2fpkc:/# curl details:9080/details/0
{"id":0,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"}


كل شيء يعمل. دعنا نجرب الطرق والطرق الأخرى:



root@productpage-v1-6b64c44d7c-2fpkc:/# curl -XPOST details:9080/details/0
RBAC: access denied
root@productpage-v1-6b64c44d7c-2fpkc:/# 
root@productpage-v1-6b64c44d7c-2fpkc:/# curl -XGET details:9080/ping
RBAC: access denied


خاتمة



في الختام ، ألاحظ أن الميزات التي تم النظر فيها ليست سوى جزء صغير من ما يمكن لـ Istio القيام به. من خارج الصندوق ، تلقينا وتكويننا تشفيرًا وتفويضًا لحركة المرور بين الخدمات ، ومع ذلك ، على حساب إضافة مكونات إضافية ، وبالتالي استهلاك موارد إضافي. 



شكرا للجميع!



All Articles