Asosiy kontentga o‘tish

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.

security devops

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:

Terminal
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:

Terminal
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:

nginx
# 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:

Terminal
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:

Terminal
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:

Python
# 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:

nginx
# 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#

Terminal
# 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.

6 daqiqa 174 marta o‘qildi