۱۶. وبسرور، 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 قدیمی |
پیدا کردن گواهی منقضیشونده¶
کد خروج موفق یعنی گواهی حداقل به مدت 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 |
خلاصهٔ اجرایی¶
- ترتیب: DNS → TCP/پورت → TLS → وبسرور → backend؛
curl -wزمان هر مرحله را میدهد. nginx -tقبل از reload؛ گواهی را از روی سرویس واقعی بررسی کنید.- زنجیره =
fullchain؛ هشدار انقضا ≥ ۲۱ روز قبل. curl -kفقط تشخیصی، هرگز راهحل.