پرش به محتویات

۱۶. وب‌سرور، DNS و TLS

بیشتر «سایت باز نمی‌شود»ها یکی از این‌هاست: DNS، گواهی، پورت/فایروال، تنظیم وب‌سرور یا backend. جدا کردن این لایه‌ها با چند فرمان ممکن است.

راهنمای سریع

فرمان کاربرد ریسک
curl -I / curl -v / curl -w تست HTTP و زمان‌بندی بدون تغییر
dig / getent hosts DNS بدون تغییر
openssl s_client / openssl x509 گواهی بدون تغییر
nginx -t / nginx -T / apachectl configtest اعتبارسنجی پیکربندی بدون تغییر
systemctl reload nginx اعمال تنظیمات تغییر
certbot renew تمدید گواهی تغییر
curl -k به‌عنوان راه‌حل غیرفعال‌کردن اعتبارسنجی TLS مخرب (فقط تشخیص)

Nginx

sudo nginx -t
sudo nginx -T | less                 # پیکربندی نهایی (همهٔ include ها)
sudo systemctl status nginx
sudo systemctl reload nginx
sudo journalctl -u nginx --since today
sudo tail -F /var/log/nginx/error.log
sudo ss -lntp | grep -E ':(80|443)\b'

همیشه پیش از reload/restart، nginx -t را اجرا کنید. مسیر لاگ ممکن است با پیکربندی تغییر کرده باشد (nginx -T | grep -E 'access_log|error_log'). Apache: sudo apachectl configtest ، apache2ctl -S (vhost ها).

کد خطای وب‌سرور ← علت

کد معنی علت‌های رایج
502 Bad Gateway پاسخ نامعتبر / backend در دسترس نیست backend پایین، پورت/سوکت اشتباه، SELinux (httpd_can_network_connect)
503 سرویس در دسترس نیست overload، maintenance، همهٔ upstream ها down
504 Gateway Timeout backend دیر جواب داد backend کند، proxy_read_timeout کم
499 (nginx) کلاینت قبل از پاسخ قطع کرد کندی backend، timeout سمت کلاینت
403 ممنوع مجوز فایل/پوشه، allow/deny، SELinux، index نبودن
404 پیدا نشد root/alias اشتباه، try_files
413 بدنهٔ درخواست بزرگ client_max_body_size
حلقهٔ redirect HTTP↔HTTPS یا www هدر X-Forwarded-Proto، قوانین return 301 تکراری

برای 502/504: همان ثانیه لاگ error وب‌سرور و لاگ backend را با هم بخوانید.

HTTP و پورت

curl -I https://example.com
curl -v --max-time 10 https://example.com/
curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' https://example.com/
curl -sS -o /dev/null -w 'dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' https://example.com/
curl -I --resolve example.com:443:192.0.2.10 https://example.com/     # تست یک سرور مشخص بدون عوض‌کردن DNS
curl -I -H 'Host: example.com' http://192.0.2.10/                     # تست vhost روی IP
curl -IL http://example.com/                                           # دنبال کردن redirect ها
nc -vz 127.0.0.1 8080

کد HTTP به‌تنهایی علت خطا را نشان نمی‌دهد؛ لاگ reverse proxy و backend را با timestamp یکسان مقایسه کنید. خروجی -w نشان می‌دهد زمان کجا رفته: time_namelookup زیاد = DNS؛ time_connect زیاد = شبکه/فایروال؛ time_appconnect − time_connect زیاد = TLS؛ ttfb زیاد = backend.

DNS

dig example.com A +short
dig example.com MX
dig example.com TXT
dig example.com NS +short
dig -x 192.0.2.10
dig +trace example.com                       # مسیر کامل از root تا پاسخ نهایی
dig @8.8.8.8 example.com A +short            # مقایسه با resolver دیگر
dig @ns1.example.com example.com SOA +short  # پرسش مستقیم از nameserver معتبر (serial)
getent hosts example.com                     # آنچه برنامه‌ها واقعاً می‌بینند (شامل /etc/hosts)
  • اگر dig @8.8.8.8 و dig @resolver-داخلی پاسخ متفاوت می‌دهند: تغییر هنوز منتشر نشده (TTL) یا split-horizon.
  • پس از تغییر رکورد، کش‌ها تا انقضای TTL قدیمی پاسخ قدیمی می‌دهند؛ قبل از تغییرات بزرگ TTL را کم کنید.
  • /etc/hosts بر DNS مقدم است؛ مرتب فراموش می‌شود.

TLS و گواهی

openssl s_client -connect example.com:443 -servername example.com </dev/null
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null | head -80
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -subject -issuer -dates
openssl x509 -in certificate.crt -noout -subject -issuer -dates
openssl x509 -in certificate.crt -noout -ext subjectAltName
openssl x509 -in certificate.crt -noout -fingerprint -sha256
openssl verify -CAfile chain.pem certificate.crt

برای اعتبارسنجی زنجیره، SNI، تاریخ انقضا و نام دامنه (SAN) را بررسی کنید. -k در curl اعتبارسنجی گواهی را غیرفعال می‌کند و نباید راه‌حل دائمی خطای TLS باشد.

آیا کلید و گواهی جفت هستند؟ (هش هر دو باید یکسان باشد):

openssl x509 -in cert.pem -noout -pubkey | openssl sha256
openssl pkey -in key.pem -pubout | openssl sha256

علل رایج خطای گواهی:

پیام علت
certificate has expired انقضا / ساعت سیستم اشتباه
unable to get local issuer certificate زنجیره ناقص (از fullchain.pem استفاده کنید نه cert.pem تنها)
certificate verify failed: Hostname mismatch نام در SAN نیست / SNI اشتباه
self-signed certificate CA داخلی؛ CA را روی کلاینت نصب کنید
فقط بعضی کلاینت‌ها خطا می‌دهند زنجیرهٔ ناقص، یا کلاینت قدیمی با CA قدیمی

پیدا کردن گواهی منقضی‌شونده

openssl x509 -checkend 2592000 -noout -in certificate.crt

کد خروج موفق یعنی گواهی حداقل به مدت 30 روز دیگر منقضی نمی‌شود؛ مسیر و فایل باید با گواهی واقعی سرویس جایگزین شود. گواهی را از روی سرویس واقعی هم بررسی کنید (نه فقط فایل روی دیسک): فایل ممکن است تمدید شده ولی nginx reload نشده باشد.

# مانیتورینگ ساده: انقضای گواهی یک سایت در کمتر از ۲۱ روز؟
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -checkend $((21*86400)) || echo "گواهی کمتر از ۲۱ روز اعتبار دارد!"

Let's Encrypt / certbot

sudo certbot certificates
sudo certbot renew --dry-run
systemctl list-timers | grep -i certbot
sudo journalctl -u certbot --since '-7 days'

تمدید معمولاً به این دلایل شکست می‌خورد: پورت 80 بسته/redirect اشتباه برای challenge، DNS اشاره به سرور دیگر، ساعت سیستم، یا hook ریستارت وب‌سرور نیست (--deploy-hook 'systemctl reload nginx').

نکات امنیتی

  • فقط TLS 1.2+؛ پروتکل‌ها و cipher ها را با ابزار تأییدشده بررسی کنید (testssl.sh، sslscan — فقط روی سیستم مجاز).
  • server_tokens off; (نسخهٔ nginx را فاش نکنید) و هدرهای امنیتی (HSTS را با احتیاط؛ برگشت‌پذیر نیست).
  • کلید خصوصی 600 و فقط root؛ بعد از نشت، گواهی را revoke و با کلید جدید صادر کنید.
  • SELinux: برای proxy به backend: sudo setsebool -P httpd_can_network_connect on.

خطاهای رایج

نشانه علت احتمالی روش بررسی
سایت باز نمی‌شود، IP مستقیم باز می‌شود DNS dig ، getent hosts
ERR_CERT_DATE_INVALID گواهی/ساعت openssl x509 -dates ، timedatectl
connection refused روی 443 وب‌سرور پایین / bind ss -lntp ، nginx -t
تغییر تنظیم اثر ندارد reload نشده / فایل دیگری nginx -T ، systemctl reload
بعد از تمدید هنوز گواهی قدیمی reload نشده openssl s_client روی سرویس واقعی
فقط HTTPS کند TLS handshake / OCSP / DNS curl -w ، time_appconnect

خلاصهٔ اجرایی

  1. ترتیب: DNS → TCP/پورت → TLS → وب‌سرور → backend؛ curl -w زمان هر مرحله را می‌دهد.
  2. nginx -t قبل از reload؛ گواهی را از روی سرویس واقعی بررسی کنید.
  3. زنجیره = fullchain؛ هشدار انقضا ≥ ۲۱ روز قبل.
  4. curl -k فقط تشخیصی، هرگز راه‌حل.