18-bo‘lim

TLS va HTTPS

Sertifikat nima isbotlaydi, Let's Encrypt bilan avtomatlashtirish, Nginx da TLS sozlash va muddat tugashining oldini olish.

🕑 22 daqiqa o‘qish 📄 1 445 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Sertifikat nima isbotlaydi
  2. Sinov sertifikati
  3. Sertifikat ichida nima bor
  4. HTTPS ni ishga tushiramiz
  5. HTTP dan HTTPS ga yo'naltirish
  6. HSTS
  7. TLS versiyalari
  8. Let's Encrypt
  9. Muddat tugashini kuzatish
  10. Xavfsizlik sarlavhalari
  11. Xulosa

HTTPS ikki narsani beradi: shifrlash (yo'ldagi hech kim o'qiy olmaydi) va shaxsni tasdiqlash (siz haqiqatan ham o'sha serverga ulanganingiz). Ikkinchisi ko'pincha unutiladi, lekin u muhimroq.

Sertifikat nima isbotlaydi #

Ishonch zanjiri - brauzer nimaga ishonadi Ildiz sertifikat markazi Brauzerga oldindan o'rnatilgan imzolaydi Oraliq sertifikat Let's Encrypt R11 va shunga o'xshash imzolaydi Sizning sertifikatingiz CN / SAN: softromeda.uz Sertifikat NIMANI isbotlamaydi Sayt xavfsiz ekanini emas. Egasi halol ekanini emas. Kod toza ekanini emas. U faqat: "bu domenning kaliti aynan shu serverda" deydi - boshqa hech nima.
Yashil qulf - shifrlash va domen egaligi belgisi, ishonch belgisi emas
Sertifikat turiNima tekshiriladiNarxi
DV (Domain Validation)Domenni boshqarasizmiBepul (Let's Encrypt)
OV (Organization)Tashkilot mavjudmiPullik
EV (Extended)Tashkilot batafsil tekshiriladiQimmat
EV sertifikatlar bugun ma'nosini yo'qotdi

Ilgari brauzerlar EV sertifikat uchun manzil satrida tashkilot nomini yashil rangda ko'rsatardi. 2019-yildan boshlab Chrome va Firefox bundan voz kechdi - tadqiqotlar foydalanuvchilar bu farqni sezmasligini ko'rsatdi.

Bugun amaliy farq deyarli yo'q: DV ham, EV ham bir xil shifrlash beradi va brauzerda bir xil ko'rinadi.

Veb-sayt uchun Let's Encrypt (DV) yetarli va u bepul. OV/EV faqat ba'zi tartibga solinadigan sohalarda talab qilinadi.

Sinov sertifikati #

Haqiqiy sertifikat olish uchun domen va ochiq server kerak. Mexanizmni tushunish uchun esa o'zimiz imzolagan sertifikat ham yetarli.

Terminal
[ -f logs/nginx.pid ] && kill -QUIT "$(cat logs/nginx.pid)" 2>/dev/null
sleep 0.3
mkdir -p conf/tls logs html temp
echo "<h1>HTTPS ishlayapti</h1>" > html/index.html

openssl req -x509 -newkey rsa:2048 \
    -keyout conf/tls/kalit.pem -out conf/tls/sert.pem \
    -days 365 -nodes -subj "/CN=sinov.local" >/dev/null 2>&1
chmod 600 conf/tls/kalit.pem

cat > conf/nginx.conf <<'EOF'
worker_processes 1;
error_log logs/error.log warn;
pid logs/nginx.pid;
events { worker_connections 64; }
http {
    access_log logs/access.log;
    client_body_temp_path temp;
    proxy_temp_path temp/proxy;
    fastcgi_temp_path temp/fastcgi;
    uwsgi_temp_path temp/uwsgi;
    scgi_temp_path temp/scgi;
    default_type text/html;

    server {
        listen 127.0.0.1:8080;
        server_name sinov.local;
        return 301 https://$host:8443$request_uri;
    }

    server {
        listen 127.0.0.1:8443 ssl;
        server_name sinov.local;

        ssl_certificate     tls/sert.pem;
        ssl_certificate_key tls/kalit.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_session_cache   shared:SSL:10m;
        ssl_session_timeout 1d;

        add_header Strict-Transport-Security "max-age=31536000" always;

        root html;
    }
}
EOF
Yo'llar sozlama fayliga nisbatan

Yuqoridagi sozlamada ssl_certificate tls/sert.pem - nisbiy yo'l, va u sozlama fayli joylashgan katalogga nisbatan hisoblanadi.

Haqiqiy serverda esa doim mutlaq yo'l yoziladi:

Natija
ssl_certificate     /etc/letsencrypt/live/softromeda.uz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/softromeda.uz/privkey.pem;

Bu 2-bo'limdagi qoidaning davomi: interaktiv ishda nisbiy yo'l qulay, sozlama fayllarida esa faqat mutlaq yo'l.

Sertifikat ichida nima bor #

Terminal
openssl x509 -in conf/tls/sert.pem -noout -subject -issuer
Natija
subject=CN=sinov.local
issuer=CN=sinov.local

subject va issuer bir xil - demak sertifikatni o'zi imzolagan (self-signed). Haqiqiy sertifikatda issuer sertifikat markazi bo'ladi.

Terminal
openssl x509 -in conf/tls/sert.pem -noout -checkend 86400 \
    && echo "kamida bir kun amal qiladi"
Natija
Certificate will not expire
kamida bir kun amal qiladi
BuyruqVazifa
openssl x509 -in f -noout -textTo'liq mazmun
-subject -issuerKim uchun, kim imzolagan
-datesAmal qilish muddati
-checkend NN soniyadan keyin tugaydimi
-fingerprint -sha256Barmoq izi
openssl s_client -connect ...Ishlab turgan serverdan olish

Kalit sertifikatga mos kelishini tekshirish:

Terminal
a=$(openssl x509 -noout -modulus -in conf/tls/sert.pem | openssl sha256)
b=$(openssl rsa -noout -modulus -in conf/tls/kalit.pem 2>/dev/null | openssl sha256)
[ "$a" = "$b" ] && echo "kalit sertifikatga mos"
Natija
kalit sertifikatga mos
Bu tekshiruv ssl_certificate_key xatosini tez topadi

Nginx key values mismatch degan xato bersa, sabab odatda shu: sertifikat yangilangan, kalit esa eski qolgan (yoki teskarisi).

Yuqoridagi ikki qatorli tekshiruv aynan shuni aniqlaydi - va u serverni qayta ishga tushirmasdan ishlaydi.

Kalit fayl ruxsati ham muhim: 600 va egasi root. Yopiq kalit oshkor bo'lsa, sertifikat butunlay ma'nosini yo'qotadi.

HTTPS ni ishga tushiramiz #

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -sk https://127.0.0.1:8443/
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
Natija
<h1>HTTPS ishlayapti</h1>

-k bayrog'i - "sertifikatni tekshirma". Usiz nima bo'ladi:

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -s -o /dev/null -w '%{http_code}' --max-time 3 https://127.0.0.1:8443/
echo " kod=$?"
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
Natija
000 kod=60
curl kodi 60 - "sertifikatga ishonib bo'lmadi"

15-bo'limdagi jadvalni to'ldiramiz:

KodMa'noSabab
6DNS yechilmadiDomen yo'q
7Ulanib bo'lmadiPort yopiq
28TaymautPaket yutilmoqda
35TLS qo'l siqishi buzildiProtokol yoki shifr mos kelmadi
51Sertifikatdagi nom mos kelmadiCN/SAN boshqa domen
60Sertifikatga ishonib bo'lmadiO'zi imzolagan yoki zanjir to'liq emas

60 ni ko'rganda birinchi shubha - oraliq sertifikat yetishmayapti.

Let's Encrypt ikkita fayl beradi:

FaylIchida nima
cert.pemFaqat sizning sertifikatingiz
fullchain.pemSizniki + oraliq sertifikat

Nginx da doim fullchain.pem ni ko'rsating. cert.pem ni yozsangiz, brauzerlarning bir qismida ishlaydi (ular oraliqni keshdan topadi), boshqalarida esa yo'q - va bu "menda ishlayapti" turidagi eng chalkash xatolardan biri.

HTTP dan HTTPS ga yo'naltirish #

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://127.0.0.1:8080/sahifa
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
Natija
301 https://127.0.0.1:8443/sahifa

$request_uri tufayli yo'l saqlanib qoldi - foydalanuvchi bosh sahifaga emas, o'zi so'ragan sahifaga tushadi.

rewrite emas, return 301 ishlating

Ko'p eski qo'llanmalarda shunday yoziladi:

Natija
rewrite ^(.*)$ https://$host$1 permanent;

Bu ishlaydi, lekin return tezroq va aniqroq:

Natija
return 301 https://$host$request_uri;

rewrite muntazam ifodani har so'rovda hisoblaydi, return esa shunchaki javob beradi.

Yana bir xato - yo'naltirishni location ichida yozish va .well-known yo'lini unutish. Let's Encrypt sertifikatni yangilash uchun http://sayt.uz/.well-known/acme-challenge/ ga murojaat qiladi. Agar u ham HTTPS ga yo'naltirilsa, yangilash buzilishi mumkin.

To'g'ri shakl:

Natija
server {
    listen 80;
    server_name softromeda.uz;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

HSTS #

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -skI https://127.0.0.1:8443/ | grep -i 'strict-transport'
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
Natija
Strict-Transport-Security: max-age=31536000

Bu sarlavha brauzerga aytadi: "keyingi bir yil davomida bu domenga faqat HTTPS orqali murojaat qil".

HSTS ni orqaga qaytarib bo'lmaydi

max-age=31536000 - bir yil. Brauzer buni eslab qoladi va sizning saytingizga HTTP orqali umuman ulanmaydi.

Agar sertifikatingiz muddati tugasa yoki HTTPS buzilsa, foydalanuvchilar saytga umuman kira olmaydi - HTTP ga qaytish imkoni yo'q.

Xavfsiz tartib:

Qadammax-age
1. Sinov300 (5 daqiqa)
2. Ishonch hosil qilgach86400 (1 kun)
3. Barqaror ishlagach31536000 (1 yil)

includeSubDomains va preload ni esa juda ehtiyotkorlik bilan qo'shing: preload ro'yxatiga tushgan domenni qaytarib olish oylar oladi va u brauzerlarga o'rnatilgan holda keladi.

Barcha subdomenlar HTTPS da ishlashiga to'liq ishonchingiz bo'lmasa, includeSubDomains yozmang.

TLS versiyalari #

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -sk --tls-max 1.1 -o /dev/null -w '%{http_code}' --max-time 3 https://127.0.0.1:8443/
echo " kod=$?"
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
Natija
000 kod=35

ssl_protocols TLSv1.2 TLSv1.3; tufayli eski protokol rad etildi - curl kodi 35, ya'ni qo'l siqishi buzildi.

Server qaysi versiyani tanlaganini ko'ramiz:

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
echo | openssl s_client -connect 127.0.0.1:8443 -brief 2>&1 \
    | grep -E '^Protocol version|^Ciphersuite'
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
Natija
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
VersiyaHolati
SSLv2, SSLv3Buzilgan - hech qachon
TLS 1.0, 1.1Eskirgan, 2021-yildan rasman bekor qilingan
TLS 1.2Hozircha kerak - eski mijozlar uchun
TLS 1.3Tavsiya etiladi - tezroq va soddaroq
Sozlamani o'zingiz yozmang

TLS shifrlar ro'yxatini qo'lda tanlash - xato qilishning oson yo'li. Mozilla buning uchun generator yuritadi:

ProfilKimga
ModernFaqat TLS 1.3, eng qat'iy
IntermediateTLS 1.2 + 1.3 - ko'pchilik uchun to'g'ri tanlov
OldJuda eski mijozlar kerak bo'lsa

ssl_ciphers ni internetdan ko'chirib olishdan ko'ra, generatordan olingan Intermediate profilini ishlating va uni yiliga bir marta yangilang.

Natijani tekshirish uchun ssllabs.com/ssltest yoki testssl.sh vositasidan foydalaning.

Let's Encrypt #

Terminal
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d softromeda.uz -d www.softromeda.uz

certbot uch ishni bajaradi: domen sizniki ekanini isbotlaydi, sertifikat oladi va Nginx sozlamasini o'zi tahrirlaydi.

FaylNima
/etc/letsencrypt/live/domen/fullchain.pemSertifikat + oraliq
/etc/letsencrypt/live/domen/privkey.pemYopiq kalit
/etc/letsencrypt/live/domen/cert.pemFaqat sertifikat - ishlatmang
Sertifikat 90 kun amal qiladi - avtomatik yangilanish shart

Let's Encrypt sertifikatlari atigi 90 kun yashaydi. Bu ataylab: qisqa muddat avtomatlashtirishni majburiy qiladi.

certbot o'rnatilganda systemd taymerini ham qo'shadi:

Terminal
systemctl list-timers certbot.timer

Uni tekshiring. Eng ko'p uchraydigan nosozlik ssenariysi:

  1. Sertifikat qo'lda olingan;
  2. Taymer o'chirilgan yoki --nginx o'rniga --standalone ishlatilgan;
  3. 90 kundan keyin sayt to'satdan ishlamay qoladi;
  4. HSTS tufayli foydalanuvchilar HTTP ga ham tusha olmaydi.

Yangilanishni sinash:

Terminal
sudo certbot renew --dry-run

Bu haqiqiy yangilashni bajarmaydi, lekin butun jarayonni sinab ko'radi. Uni o'rnatgandan keyin darhol bajaring.

Muddat tugashini kuzatish #

Terminal
openssl x509 -in conf/tls/sert.pem -noout -checkend 2592000 \
    && echo "30 kundan ortiq qoldi" || echo "30 kundan kam qoldi"
Natija
Certificate will not expire
30 kundan ortiq qoldi

Bu tekshiruvni skriptga aylantirish oson:

Terminal
if ! openssl x509 -in /etc/letsencrypt/live/softromeda.uz/fullchain.pem \
        -noout -checkend 1209600 >/dev/null; then
    logger -t tls-nazorat -p user.warning \
        "sertifikat 14 kundan kam qoldi"
fi

19-bo'limda buni systemd taymeri bilan har kuni ishga tushiramiz.

Ishlab turgan saytdan sertifikatni tekshirish

Fayl emas, haqiqiy ulanish orqali tekshirish ishonchliroq - u Nginx qaysi sertifikatni haqiqatan ham berayotganini ko'rsatadi:

Terminal
echo | openssl s_client -connect softromeda.uz:443 \
        -servername softromeda.uz 2>/dev/null \
    | openssl x509 -noout -dates -subject

-servername muhim: bitta IP da bir necha sayt bo'lsa, usiz siz noto'g'ri sertifikatni olasiz (SNI).

Bu Nginx sozlamasidagi eski yo'l qolib ketgan holatni ham aniqlaydi: faylda yangi sertifikat, serverda esa eski.

Xavfsizlik sarlavhalari #

SarlavhaNimadan himoya qiladi
Strict-Transport-SecurityHTTP ga tushib qolish
X-Content-Type-Options: nosniffBrauzer fayl turini taxmin qilishi
X-Frame-Options: DENYSaytni iframe ga solish (clickjacking)
Content-Security-PolicyXSS - eng kuchli, lekin murakkab
Referrer-PolicyManzilning boshqa saytga oshkor bo'lishi
add_header va always
Natija
add_header X-Frame-Options DENY always;

always bo'lmasa, sarlavha faqat muvaffaqiyatli javoblarga qo'shiladi. Xato sahifalarida (404, 500) u yo'qoladi.

Yana bir tuzoq: location blokida bitta add_header yozsangiz, server darajasidagi barcha add_header lar o'sha blokda bekor bo'ladi.

Shuning uchun sarlavhalarni bitta joyda - odatda server blokida - saqlang va location ichida add_header yozishdan qoching.

Amaliy topshiriq
  1. openssl req -x509 bilan o'zi imzolagan sertifikat yarating.
  2. subject va issuer ni ko'ring - nega bir xil?
  3. Kalit sertifikatga mosligini modulus orqali tekshiring.
  4. Nginx da HTTPS ni yoqing va curl -k bilan sinang.
  5. -k siz sinab, 60 kodini oling.
  6. return 301 bilan HTTP dan HTTPS ga yo'naltiring.
  7. HSTS sarlavhasini qo'shing va curl -I bilan tasdiqlang.
  8. --tls-max 1.1 bilan eski protokolni sinang - 35 kodi.
  9. s_client -brief bilan tanlangan protokolni ko'ring.
  10. -checkend bilan muddat tekshiruvini yozing.

Xulosa #

  • Sertifikat domen egaligini isbotlaydi, saytning halolligini emas.
  • Veb-sayt uchun bepul DV (Let's Encrypt) yetarli.
  • Nginx da doim fullchain.pem, cert.pem emas.
  • curl kodi 35 - TLS qo'l siqishi, 51 - nom mos emas, 60 - ishonch zanjiri.
  • rewrite emas, return 301 https://$host$request_uri.
  • .well-known/acme-challenge/ ni yo'naltirishdan chiqarib qoldiring.
  • HSTS ni qisqa max-age bilan boshlang - uni orqaga qaytarib bo'lmaydi.
  • ssl_protocols TLSv1.2 TLSv1.3 - eskilari rad etilsin.
  • Shifrlarni qo'lda tanlamang - Mozilla Intermediate profilini oling.
  • Let's Encrypt 90 kun - certbot renew --dry-run ni darhol sinang.

Keyingi bo'limda zaxira nusxa, rejalashtirilgan vazifalar va fail2ban ni ko'ramiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.