TLS می‌تواند در Nginx میزبان یا در frontend کانتینری خاتمه یابد. امشب هر دو مسیر را روشن می‌کنیم و دسترسی کلید خصوصی را به فرایند لازم محدود می‌کنیم.

این جلسه بخشی از دورهٔ انجین‌اکس در ۵۰ شب است. قرارداد آزمایشگاه، مسیرها و روال اعمال تغییر در راهنمای دوره آمده است.

محیط: Compose شب ۴۰، گواهی آزمایشگاهی و frontend با UID/GID ثبت‌شده. تغییر را در clone و با در دسترس بودن config قبلی انجام بده.

TLS داخل کانتینر#

در پوشهٔ tls آزمایشگاه، فقط leaf key و certificate را قرار بده؛ CA private key همان‌جا روی کلاینت ۲۰ می‌ماند. فایل کلید روی میزبان root-owned، group با GID عددی frontend و mode 640 باشد؛ پوشه root-owned همان گروه و mode 750. عضو جدید به این گروه نده و key را در image یا Git نگذار.

برای frontend یک mount readonly اختصاصی ./tls:/etc/nginx/tls:ro,Z و port محلی 127.0.0.1:18443:8443 به Compose اضافه کن. در nginx.conf، server TLS کامل را با همان location پراکسی بساز:

listen 8443 ssl;
server_name app.nginx.test;
ssl_certificate /etc/nginx/tls/web.crt;
ssl_certificate_key /etc/nginx/tls/web.key;
ssl_protocols TLSv1.2 TLSv1.3;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=300" always;

این directiveها داخل server قرار می‌گیرند، نه در main. HTTP/2 را طبق نسخهٔ داخل image و شب ۱۴ اضافه کن. port داخلی 8443 به capability ویژه نیاز ندارد. default server ناشناس را هم با policy TLS شب ۱۲ روی همین address/port طراحی کن.

docker compose -p nginx-lab config --quiet
docker compose -p nginx-lab up -d --force-recreate frontend
docker compose -p nginx-lab exec frontend nginx -t
curl --cacert /etc/nginx/tls/ca.crt \
  --resolve app.nginx.test:18443:127.0.0.1 https://app.nginx.test:18443/

این درخواست از میزبان آزمایشگاه است. اگر CA عمومی آنجا نیست، مسیر فایل عمومی را اصلاح کن؛ با -k خطای اعتماد را پنهان نکن. port محلی را تنها پس از طراحی firewall و ACL به IP شبکه bind کن. در Docker، ترافیک منتشرشده می‌تواند مسیر فیلتر متفاوت از سرویس میزبان داشته باشد؛ نتیجه را از کلاینت ۲۱ آزمایش کن، به خروجی UFW اکتفا نکن.

TLS روی میزبان و upstream کانتینر#

اگر Nginx میزبان edge است، می‌تواند به http://127.0.0.1:18081 proxy کند؛ port کانتینر همچنان localhost-only می‌ماند. هدرها در edge بازنویسی شوند. frontend کانتینری peer شبکهٔ Docker را می‌بیند؛ آن peer الزاماً 127.0.0.1 نیست. با log مقدار واقعی را ثبت کن و اگر realip لازم است تنها منبع کنترل‌شدهٔ edge را trust کن، نه تمام subnet مشترک برنامه‌ها.

یک owner برای هدرهای امنیتی تعیین کن. اگر میزبان policy را می‌سازد، هدرهای هم‌نام backend را با proxy_hide_header حذف کن تا HSTS/CSP تکراری و ناسازگار ساخته نشود. HTTPS تشخیص‌داده‌شده در edge را فقط با همتای قابل اعتماد به برنامه منتقل کن؛ قواعد شب ۳۳ همین‌جا هم برقرارند.

آزمون و بازگشت: TLS معتبر، نام اشتباه، نبودن key، فایل readonly و هدر جعلی را جدا آزمایش کن. در خطای permission، UID/GID و label mount را اصلاح کن. mount کلید با mode 777 راه حل نیست. config/Compose قبلی و digest ثبت‌شده را برگردان و frontend را recreate کن.

منبع: bind mount و SELinux ، TLS در Nginx ، فیلتر شبکهٔ Docker .