TLS والأمان في Envoy Gateway: اضبط HTTPS وتوقف عن تشغيل الـ API لديك مكشوفًا
تشغيل HTTP ليس إلا الإحماء. ما لم تكن خدمتك تعيش في العصر الحجري، فالإنتاج يحتاج شبه مؤكد إلى HTTPS. هذه المقالة تغطي أساسيات TLS في Envoy Gateway حتى تتوقف APIs لديك عن العمل بشكل مكشوف.
كيف يعمل TLS داخل Gateway
الأسلوب الأكثر شيوعًا هو: إنهاء TLS عند Gateway listener.
ومعناه:
- يتصل العميل عبر HTTPS
- يتولى الـ Gateway المصافحة والشهادة
- ثم يتم تمرير المرور داخليًا إلى الـ Service من دون تشفير
Listener HTTPS أساسي يبدو هكذا:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: eg
spec:
gatewayClassName: eg
listeners:
- name: http
protocol: HTTP
port: 80
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
group: ""
name: example-certهناك أمران مهمان هنا:
protocol: HTTPStls.mode: Terminate
وهذا يعني أن TLS ينتهي هنا، وأن الـ Gateway هو من يدير الشهادة.
HTTPS + HTTPRoute مقابل TLSRoute: ما الفرق
هذه نقطة مهمة، لأن كثيرًا من الناس يرون TLSRoute ويسألون فورًا:
"أليس HTTPS listener كافيًا أصلًا؟ لماذا نحتاج إلى TLSRoute منفصل؟"
الفرق هو هل يقوم الـ Gateway بإنهاء TLS أم لا:
| السيناريو | التركيبة الشائعة | الوصف |
|---|---|---|
| الـ Gateway ينهي TLS ثم يطبق قواعد HTTP | HTTPS listener + HTTPRoute |
أكثر سيناريوهات المواقع والـ APIs شيوعًا |
| الـ Gateway لا يفك التشفير، بل يوجّه المرور المشفّر بالاعتماد على SNI فقط | TLS listener + TLSRoute |
سيناريو TLS passthrough |
بمعنى آخر:
- إذا كنت تريد فحص
pathأوheaderأوmethodعند الـ Gateway، فعليك إنهاء TLS أولًا ثم استخدامHTTPRoute - إذا كنت تريد الحفاظ على التشفير من الطرف إلى الطرف وعدم فكّه عند الـ Gateway، فـ
TLSRouteهو المسار الصحيح
ولا يوجد هنا خيار "أكثر تقدمًا" من الآخر، المهم أن تعرف ما الذي تريده: "إنهاء TLS وتنفيذ توجيه L7" أم "الحفاظ على التشفير سليمًا وتنفيذ توجيه مبني على SNI."
جهّز Secret الخاص بالشهادة
في بيئات الاختبار، تكفي شهادة self-signed. والأمثلة الرسمية تستخدم ذلك بالضبط:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
-subj '/O=example Inc./CN=example.com' \
-keyout example.com.key \
-out example.com.crt
openssl req -out www.example.com.csr -newkey rsa:2048 -nodes \
-keyout www.example.com.key \
-subj "/CN=www.example.com/O=example organization"
openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key \
-set_serial 0 -in www.example.com.csr -out www.example.com.crtخزّن المفتاح/الشهادة كـ Kubernetes Secret:
kubectl create secret tls example-cert \
--key=www.example.com.key \
--cert=www.example.com.crtبعدها يستطيع Gateway الإشارة إلى هذا الـ Secret عبر certificateRefs.
⚠️ شهادات self-signed مخصصة للاختبار فقط. في الإنتاج استخدم cert-manager أو آلية إدارة الشهادات الموجودة لديك. لا تنقل إعدادات الـ demo إلى الإنتاج مباشرة، فهذا يشبه العيش على النودلز الفورية: مقبول أحيانًا، لكنه ليس نمط حياة مستدامًا.
أضف HTTPS Listener إلى Gateway موجود
إذا كان لديك بالفعل eg Gateway من المقالة السابقة، فيمكنك ترقيعه مباشرة:
kubectl patch gateway eg --type=json --patch '
- op: add
path: /spec/listeners/-
value:
name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
group: ""
name: example-cert
'تحقّق من الحالة:
kubectl get gateway/eg -o yamlإذا بدا الـ listener سليمًا، فاختبر HTTPS:
curl -v -HHost:www.example.com \
--resolve "www.example.com:443:${GATEWAY_HOST}" \
--cacert example.com.crt \
https://www.example.com/getهذا الأمر ممتاز للتحقق المحلي، خصوصًا عندما لا يكون DNS موصولًا بعد.
Gateway واحد، وعدة Domains على HTTPS
إذا كان لديك عدة domains، فأضف عدة HTTPS listeners إلى نفس الـ Gateway.
مثلًا، لإضافة foo.example.com:
listeners:
- name: https-main
protocol: HTTPS
port: 443
hostname: www.example.com
tls:
mode: Terminate
certificateRefs:
- name: example-cert
- name: https-foo
protocol: HTTPS
port: 443
hostname: foo.example.com
tls:
mode: Terminate
certificateRefs:
- name: foo-certولا تنس تحديث HTTPRoute المقابل بالـ hostname الصحيح، وإلا فقد يكون الـ listener يستمع فعلًا بينما الـ route لا يعرف إلى أين يوجّه المرور.
النموذج الذهني لـ TLSRoute
بالنسبة إلى TLS passthrough، فكر في TLSRoute بهذه الطريقة:
💡 قد يختلف
apiVersionالخاص بـTLSRouteبحسب نسخة Gateway API CRDs المثبتة لديك. المثال التالي لغرض الفهم فقط، لذا تحقّق من النسخة الموجودة في الـ cluster قبل التطبيق.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: eg-tls
spec:
gatewayClassName: eg
listeners:
- name: tls
protocol: TLS
port: 443
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: passthrough-route
spec:
parentRefs:
- name: eg-tls
hostnames:
- "db.example.com"
rules:
- backendRefs:
- name: db-service
port: 5432الحالات الشائعة لهذا النمط:
- التوجيه اعتمادًا فقط على SNI hostname
- الحفاظ على التشفير حتى الـ backend
- عدم تنفيذ تحليل path/header الخاص بـ HTTP عند الـ Gateway
ولهذا فإن الفرق الأكبر بين TLSRoute و HTTPRoute ليس الاسم فقط، بل إنهما يعملان على طبقات مختلفة تمامًا من المرور.
الإشارات إلى الشهادات عبر Namespaces مختلفة
تشير الوثائق الرسمية إلى قدرة مفيدة:
يمكن لـ Gateway الإشارة إلى Secrets الخاصة بالشهادات في namespaces أخرى، لكن ذلك يتطلب ReferenceGrant.
على سبيل المثال، إذا كان فريق المنصة يخزّن الشهادات مركزيًا داخل envoy-gateway-system، بينما Gateway الخاص بالتطبيق موجود في default، فلا يمكنك ببساطة الإشارة عبر حدود الـ namespace من دون تصريح صريح.
مثال:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-default-to-read-cert
namespace: envoy-gateway-system
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: default
to:
- group: ""
kind: Secretومعناه:
- يوجد
Gatewayفي namespace اسمهdefault - وهو مخوّل للإشارة إلى موارد
Secretالموجودة فيenvoy-gateway-system
ومن دون ReferenceGrant، تُعامل هذه الإشارة عبر namespaces على أنها غير صالحة. هذه آلية حماية، وليست لأن Gateway API يحب التعقيد بلا داعٍ.
الخلاصة في سطر واحد
TLS في Envoy Gateway ليس غامضًا كما يبدو: جهّز Secret الخاص بالشهادة، واضبط HTTPS listener، وتأكد من توافق route و hostname، وهذا هو الأساس كله تقريبًا.
💡 أكثر خطأ شائع عند المبتدئين ليس أن TLS صعب، بل أن ثلاثة أشياء لا تكون مصطفّة معًا:
hostnameوcertificateRefsوHTTPRoute hostnames. وإذا اختل واحد منها فقط، يبدأ المرور في التصرف بشكل سيئ.
الخطوة التالية
الآن وبعد أن غطيت التثبيت والمفاهيم والتوجيه و TLS، تجمع المقالة التالية ذلك كله في مجموعة ممارسات تقل معها احتمالات الانفجار في الإنتاج: 👉 أفضل الممارسات