Maqolalar 6 daqiqa 174 ko‘rish
Let's Encrypt bilan HTTPS: o'n daqiqalik ish va bitta muhim timer
Sertifikat sotib olish shart emas — Let's Encrypt bepul beradi, certbot esa nginx'ni o'zi sozlab qo'yadi. Sertifikat olamiz, avtomatik yangilanishini timer bilan kafolatlaymiz va Django'ni HTTPS'ga to'g'ri o'tkazamiz.
Mundarija
Avvalgi qismda sayt 80-portda ochildi, lekin trafik hali ochiq matnda yurmoqda: orada turgan har kim so'rovlarni o'qiy oladi, brauzerlar esa "Not secure" deb turadi. TLS qanday ishlashini nazariy tomondan alohida maqolada yozganman — bugun esa faqat amaliyot: o'n daqiqada sertifikat olamiz va u o'z-o'zidan yangilanib turishini kafolatlaymiz. Aynan shu jarayonni shu saytning o'zida ham o'tkazganman.
certbot: o'rnatish va sertifikat olish#
Let's Encrypt sertifikatlari bilan ishlashning standart tool'i — certbot. Ubuntu'da uni snap orqali o'rnatish tavsiya qilinadi, chunki apt'dagi versiya ancha orqada yuradi:
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Sertifikat olishdan oldin ikki narsa tayyor bo'lishi shart: domen A-yozuvi serverga qaragan bo'lishi va 80-port ochiq bo'lishi (Let's Encrypt shu port orqali "bu domen haqiqatan sizning qo'lingizdami" deb tekshiradi — 1-qismdagi ufw sozlamalarida 80 ochiq edi). Endi bitta buyruq:
sudo certbot --nginx -d mysite.uz -d www.mysite.uz
Birinchi ishga tushirishda certbot bir necha savol beradi: email manzil
(sertifikat bilan bog'liq muhim xabarlar uchun), Let's Encrypt shartlariga
roziligingiz (Y) va emailni EFF bilan bo'lishish (ixtiyoriy, N desangiz
ham bo'ladi). Keyin --nginx rejimida certbot hammasini o'zi qiladi: domen
egaligini tekshiradi, sertifikat oladi, nginx konfiguratsiyasiga SSL
qatorlarini yozadi va HTTP'dan HTTPS'ga redirect'ni ham qo'shadi — hozirgi
versiyalari buni so'ramasdan, standart holatda qiladi. Ish tugagach
konfiguratsiyaga qarasangiz, o'sha faylingizda yangi qatorlar paydo bo'lganini
ko'rasiz:
# certbot qo'shgan qatorlar (qo'lda yozish shart emas edi):
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mysite.uz/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mysite.uz/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
E'tibor bering: 3-qismdagi server blokingiz endi 443-portni tinglaydi, fayl
oxirida esa certbot yozgan yangi server bloki paydo bo'ladi — u 80-portga
kelganlarni 301 bilan HTTPS'ga yuboradi. # managed by Certbot belgili
qatorlarni qo'lda o'zgartirmang.
Brauzerda tekshiramiz — qulf paydo bo'ldi. Lekin ish hali tugagani yo'q, eng muhim qismi oldinda.
Yangilanish: 90 kunlik sertifikat va uni unutmaslik san'ati#
Let's Encrypt sertifikati atigi 90 kun yashaydi. Bu ataylab qilingan: qisqa muddat o'g'irlangan sertifikatning zararini cheklaydi va hammani avtomatlashtirishga majbur qiladi. Muddat bundan ham qisqaradi: Let's Encrypt 2027-yil fevralidan boshlab 64 kunlik, 2028-yildan esa 45 kunlik sertifikatlarga o'tishini e'lon qilgan. Qo'lda yangilash odati bilan bunday jadvalga ulgurib bo'lmaydi — avtomatik yangilanish shart. Yaxshiyamki, certbot o'rnatilganda o'zi bilan systemd timer olib keladi:
systemctl list-timers | grep certbot
# snap.certbot.renew.timer — kuniga ikki marta uyg'onib, muddati yaqin sertifikatlarni yangilaydi
Timer nomi o'rnatish usuliga bog'liq: snap'da snap.certbot.renew.timer,
apt paketida esa certbot.timer. grep certbot ikkalasini ham topadi.
Timer bor-yo'qligini ko'rish yetarli emas — yangilanish haqiqatan o'tishini sinab ko'ring:
sudo certbot renew --dry-run
Bu buyruq to'liq yangilanish jarayonini "quruq" o'tkazadi: Let's Encrypt'ning
sinov (staging) serveriga murojaat qiladi, domen tekshiruvidan o'tadi va
sinov sertifikatini oladi, lekin uni diskka yozmaydi — haqiqiy sertifikatingiz
joyida qoladi. Oxirida Congratulations, all simulated renewals succeeded
chiqsa, 90 kundan keyin ham hech narsani eslab o'tirmaysiz.
80-portni yopib qo'ymang
HTTPS ishlagach "80 endi keraksiz" degan xayol keladi — va uni firewall'da yopgan odam uch oydan keyin sertifikati yangilanmay qolganini ko'radi, chunki Let's Encrypt tekshiruvi 80-port orqali keladi. Redirect uchun ham, yangilanish uchun ham 80 ochiq qolishi kerak.
Django tomonini HTTPS'ga moslash#
Nginx endi HTTPS'ni ko'taryapti, lekin Django hali eski dunyoda yashayapti. Uchta sozlama qo'shamiz:
# config/settings.py (production)
# nginx X-Forwarded-Proto yuborayotgan edi (3-qism) — endi undan foydalanamiz:
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
# cookie'lar faqat HTTPS orqali yursin
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
# Django 4+ da boshqa manbadan kelgan POST'lar uchun ishonchli ro'yxat.
# Sayt o'z formalariga yuborayotgan POST Host va X-Forwarded-Proto to'g'ri
# bo'lsa usiz ham o'tadi; mysite.uz <-> www.mysite.uz o'rtasidagi POST esa
# aynan shu ro'yxatni talab qiladi
CSRF_TRUSTED_ORIGINS = ["https://mysite.uz", "https://www.mysite.uz"]
Redirect'ni nginx qilayotgani uchun SECURE_SSL_REDIRECT shart emas —
so'rov Django'ga yetib kelguncha allaqachon HTTPS bo'ladi.
HSTS: brauzerga "faqat HTTPS" deyish#
Hammasi ishlayotganiga bir-ikki kun ishonch hosil qilgach, yana bir qadam
tashlash mumkin — HSTS. Bu header brauzerga "bu sayt bilan bundan keyin
faqat HTTPS'da gaplash" deydi. Brauzer bu header'ni bir marta olgach,
keyingi tashriflarda http:// ni o'zi https:// ga almashtiradi — HTTP
so'rov tarmoqqa umuman chiqmaydi:
# server (443) blokiga, location'lardan tashqariga:
add_header Strict-Transport-Security "max-age=31536000" always;
Bitta nginx nozikligi: location ichida o'zining add_header i bo'lsa, u
server darajasidagi add_header larni meros olmaydi. 3-qismdagi
location /static/ da Cache-Control bor — shuning uchun statika
javoblarida HSTS chiqmaydi. Brauzer HSTS'ni sahifa javobidan o'rganib oladi,
shuning uchun bu kritik emas; lekin har bir javobda bo'lishini xohlasangiz,
shu qatorni location /static/ ichiga ham qo'shing.
HSTS — shoshilmasdan yoqiladigan narsa
max-age bir yil degani: brauzer shu muddat davomida saytga HTTP orqali
kirishga umuman urinmaydi. Agar HTTPS'da biror muammo chiqib qolsa,
"vaqtincha HTTP'ga qaytib turamiz" degan yo'l yopiq bo'ladi. Shuning
uchun avval kichik max-age bilan (masalan 3600) bir hafta sinab, keyin
yillik qiymatga o'ting.
Yakuniy tekshiruv#
# HTTP redirect ishlayaptimi?
curl -I http://mysite.uz/ # 301, Location: https://...
# HTTPS to'g'ri javob beryaptimi?
curl -I https://mysite.uz/ # 200, strict-transport-security ko'rinadi
# sertifikat muddati va kimga berilgani:
echo | openssl s_client -connect mysite.uz:443 2>/dev/null | openssl x509 -noout -dates -subject
Chuqurroq baho kerak bo'lsa, SSL Labs testidan o'tkazing (ssllabs.com) — yuqoridagi sozlamalar bilan A baho odatiy natija.
Sayt endi to'liq zanjirda: firewall, systemd, nginx va TLS. Keyingi qismda serverni o'z-o'ziga xizmat qildirishni boshlaymiz: systemd timerlar bilan muntazam vazifalar va bazani avtomatik backup qilish.