14-bo‘lim
TLS qanday ishlaydi
Oldingi o'n uch bo'lim TLS da birlashadi - qo'l siqish, versiyalar va sozlashdagi xatolar.
Ushbu bo‘lim mundarijasi
TLS (Transport Layer Security) - internetdagi eng
ko'p ishlatiladigan kriptografik protokol. https://
ning s harfi aynan shu.
Uning qiziq tomoni shundaki, u yangi hech narsa o'ylab topmaydi. U oldingi bo'limlarda ko'rgan qismlarni birlashtiradi.
TLS nimalardan yig'ilgan #
| Qism | Qaysi bo'limda ko'rdik |
|---|---|
| Kalit almashinuvi (ECDHE) | 12 |
| Server autentifikatsiyasi (sertifikat + imzo) | 11, 13 |
| Kalit ajratish (HKDF) | 6 |
| Ma'lumot shifrlash (AES-GCM / ChaCha20) | 8 |
| Nonce boshqaruvi | 9 |
| Butunlik (AEAD tegi) | 8 |
TLS - bu yig'ma protokol. Shuning uchun uni tushunish uchun oldingi bo'limlarni bilish yetarli.
Sinov serverini ishga tushiramiz #
export LC_ALL=C TZ=UTC
# 13-bo'limdagidek sinov sertifikat markazi va server sertifikati
openssl ecparam -name prime256v1 -genkey -noout -out ca.key 2>/dev/null
openssl req -x509 -new -key ca.key -sha256 -days 3650 \
-subj "/C=UZ/O=Namuna Lab CA/CN=Namuna Ildiz CA" -out ca.crt 2>/dev/null
openssl ecparam -name prime256v1 -genkey -noout -out srv.key 2>/dev/null
openssl req -new -key srv.key \
-subj "/C=UZ/O=Namuna/CN=xizmat.namuna.uz" -out srv.csr 2>/dev/null
cat > srv.ext <<'EXT'
subjectAltName=DNS:xizmat.namuna.uz
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
extendedKeyUsage=serverAuth
EXT
openssl x509 -req -in srv.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 90 -sha256 -extfile srv.ext -out srv.crt 2>/dev/null
# Mahalliy TLS serverini ishga tushiruvchi yordamchi
server() {
openssl s_server -accept "$1" -cert srv.crt -key srv.key \
${2:-} -quiet -naccept 1 >/dev/null 2>&1 &
sleep 0.7
}
server 14501
echo | openssl s_client -connect 127.0.0.1:14501 \
-CAfile ca.crt -servername xizmat.namuna.uz \
-verify_hostname xizmat.namuna.uz 2>/dev/null \
| grep -E "^(Protocol|Verify return code)"
wait 2>/dev/null; true
Protocol: TLSv1.3
Verify return code: 0 (ok)
Bir necha millisekundda quyidagilar bajarildi:
| Qadam | Ma'nosi |
|---|---|
1. ClientHello | Mijoz qo'llab-quvvatlaydigan versiya, shifrlar va o'z ECDHE ochiq kaliti |
2. ServerHello | Server tanlagan shifr va o'z ECDHE ochiq kaliti |
| 3. Sertifikat | Server o'z sertifikatini yuboradi |
4. CertificateVerify | Server maxfiy kaliti bilan imzolaydi |
5. Finished | Ikkala tomon kalitlarni hisoblaydi va tasdiqlaydi |
Diqqat qiling: 4-qadam hal qiluvchi. Server nafaqat sertifikat ko'rsatadi, balki o'sha sertifikatdagi ochiq kalitga mos maxfiy kalitga egaligini isbotlaydi.
Bu bo'lmasa, hujumchi boshqa saytning sertifikatini nusxa qilib ko'rsatishi mumkin bo'lardi (sertifikat ochiq ma'lumot).
Tekshiruvsiz ulanish #
server 14502
# CAfile ko'rsatilmagan - mijoz zanjirni qura olmaydi
echo | openssl s_client -connect 127.0.0.1:14502 2>/dev/null \
| grep -E "^Verify return code"
wait 2>/dev/null; true
Verify return code: 21 (unable to verify the first certificate)
server 14503
# Sertifikat boshqa domen uchun
echo | openssl s_client -connect 127.0.0.1:14503 \
-CAfile ca.crt -verify_hostname boshqa.namuna.uz 2>/dev/null \
| grep -E "^Verify return code"
wait 2>/dev/null; true
Verify return code: 62 (hostname mismatch)
Ikkala holatda ham openssl s_client xatoni ko'rsatdi,
lekin ulanishni uzmadi.
Bu juda muhim nuqta: TLS qo'l siqish muvaffaqiyatli bo'lishi mumkin, sertifikat esa yaroqsiz bo'lishi mumkin.
Tekshiruv - mijozning vazifasi:
| Mijoz | Standart xulq |
|---|---|
| Brauzer | Tekshiradi, xato bo'lsa to'xtatadi |
curl | Tekshiradi, xato bo'lsa to'xtatadi |
openssl s_client | Tekshiradi, lekin davom etadi (bu vosita) |
PHP file_get_contents | Tekshiradi (PHP 5.6+) |
| Ba'zi eski kutubxonalar | Tekshirmaydi |
Oxirgi qatorga ehtiyot bo'ling. Kodingizda ishlatayotgan HTTP mijozi sertifikatni tekshirayotganiga ishonch hosil qiling.
verify_peer va verify_peer_name ni false qilish -
shifrlashni saqlab, autentifikatsiyani o'chirish
demakdir. Bu esa 12-bo'limdagi o'rtadagi odam hujumiga
to'liq ochiq qoldiradi.
Protokol versiyalari #
server 14504
echo "--- standart (eng yangi):"
echo | openssl s_client -connect 127.0.0.1:14504 -CAfile ca.crt 2>/dev/null \
| grep -E "^(Protocol|Cipher)"
wait 2>/dev/null; true
--- standart (eng yangi):
Protocol: TLSv1.3
server 14505
echo "--- TLS 1.2 majburiy:"
echo | openssl s_client -connect 127.0.0.1:14505 -CAfile ca.crt -tls1_2 \
2>/dev/null | grep -E " (Protocol|Cipher) *:"
wait 2>/dev/null; true
--- TLS 1.2 majburiy:
Protocol : TLSv1.2
Cipher : ECDHE-ECDSA-AES256-GCM-SHA384
TLS 1.2 dagi nom to'rt qismdan iborat:
ECDHE-ECDSA-AES256-GCM-SHA384
| | | | |
| | | | +-- xesh
| | | +------- rejim (AEAD)
| | +------------ shifr
| +------------------- imzo turi
+------------------------- kalit almashinuvi
TLS 1.3 da esa nom qisqargan:
TLS_AES_256_GCM_SHA384
Kalit almashinuvi va imzo turi nomda yo'q, chunki TLS 1.3 da ular alohida kelishiladi va tanlov cheklangan:
| TLS 1.2 | TLS 1.3 |
|---|---|
| 300 dan ortiq to'plam | 5 ta |
| RSA kalit almashinuvi mumkin | Faqat ECDHE/DHE |
| CBC rejimi mumkin | Faqat AEAD |
| Oldinga maxfiylik ixtiyoriy | Majburiy |
| Qayta kelishuv (renegotiation) | Olib tashlangan |
Tanlovni qisqartirish - TLS 1.3 ning asosiy g'oyasi. Xavfli variantlar shunchaki olib tashlangan.
Eski versiyalarni rad etish #
# Server 1.2 dan past versiyani qabul qilmaydi
openssl s_server -accept 14506 -cert srv.crt -key srv.key \
-min_protocol TLSv1.2 -quiet -naccept 2 >/dev/null 2>&1 &
sleep 0.7
echo "--- TLS 1.0 bilan urinish:"
echo | openssl s_client -connect 127.0.0.1:14506 -CAfile ca.crt -tls1 2>&1 \
| grep -oE "alert protocol version" | head -1
echo "--- standart bilan urinish:"
echo | openssl s_client -connect 127.0.0.1:14506 -CAfile ca.crt 2>/dev/null \
| grep -E "^Protocol"
wait 2>/dev/null; true
--- TLS 1.0 bilan urinish:
alert protocol version
--- standart bilan urinish:
Protocol: TLSv1.3
| Versiya | Chiqqan yili | Holati |
|---|---|---|
| SSL 2.0, 3.0 | 1995, 1996 | Buzilgan, o'chirilsin |
| TLS 1.0 | 1999 | Eskirgan (2021 da rasman) |
| TLS 1.1 | 2006 | Eskirgan |
| TLS 1.2 | 2008 | Ishonchli, minimal daraja |
| TLS 1.3 | 2018 | Tavsiya etiladi |
nginx uchun:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
Ikkinchi qator qarama-qarshi tuyulishi mumkin, lekin TLS 1.3 da mijozning tanlovi afzal: u o'z uskunasi uchun qaysi shifr tezroq ekanini yaxshiroq biladi (masalan mobil qurilmada ChaCha20).
TLS 1.0 va 1.1 ni o'chirishda ehtiyot bo'ling: juda eski mijozlar (Android 4.x, Windows XP) ulana olmay qoladi. Amalda bu deyarli muammo emas.
SNI - bitta IP, ko'p domen #
server 14507
echo "--- SNI bilan:"
echo | openssl s_client -connect 127.0.0.1:14507 -CAfile ca.crt \
-servername xizmat.namuna.uz 2>/dev/null \
| grep -E "^(Protocol|Verify return code)"
wait 2>/dev/null; true
--- SNI bilan:
Protocol: TLSv1.3
Verify return code: 0 (ok)
SNI (Server Name Indication) - mijoz qaysi domenga ulanmoqchi ekanini qo'l siqishning eng boshida aytadi.
Bu zarur: bitta IP manzilda yuzlab sayt bo'lishi mumkin va server qaysi sertifikatni yuborishni bilishi kerak.
Muammo shundaki, SNI ochiq matnda ketadi:
| Nima yashiringan | Nima ochiq |
|---|---|
So'ralgan sahifa (/hisob/1234) | Domen nomi |
| So'rov va javob tanasi | IP manzil |
| Kukilar, sarlavhalar | Ulanish vaqti va hajmi |
Ya'ni tarmoqni kuzatayotgan tomon qaysi saytga kirganingizni ko'radi, lekin nima qilganingizni ko'rmaydi.
Buni yashirish uchun ECH (Encrypted Client Hello) ishlab chiqilmoqda, lekin u hali hamma joyda qo'llab-quvvatlanmaydi.
PHP dan TLS bilan ishlash #
cat > mijoz.php <<'PHP'
<?php
declare(strict_types=1);
// TO'G'RI sozlama - ikkala tekshiruv ham yoqilgan
$togri = [
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => 'ca.crt',
'peer_name' => 'xizmat.namuna.uz',
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
| STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT,
],
];
// XATO sozlama - hech qachon shunday yozmang
$xato = [
'ssl' => ['verify_peer' => false, 'verify_peer_name' => false],
];
foreach (['togri' => $togri, 'xato' => $xato] as $nom => $sozlama) {
$s = $sozlama['ssl'];
printf("%-6s verify_peer=%-5s verify_peer_name=%-5s cafile=%s\n",
$nom,
var_export($s['verify_peer'], true),
var_export($s['verify_peer_name'], true),
$s['cafile'] ?? '(yoq)');
}
echo "\nPHP 5.6 dan boshlab verify_peer standart holda TRUE\n";
echo "Uni false qilish - autentifikatsiyani butunlay ochirish\n";
PHP
php mijoz.php
togri verify_peer=true verify_peer_name=true cafile=ca.crt
xato verify_peer=false verify_peer_name=false cafile=(yoq)
PHP 5.6 dan boshlab verify_peer standart holda TRUE
Uni false qilish - autentifikatsiyani butunlay ochirish
HTTPS ga majburlash #
cat <<'CONF'
# nginx: barcha HTTP so'rovlarni HTTPS ga yo'naltirish
server {
listen 80;
server_name xizmat.namuna.uz;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name xizmat.namuna.uz;
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/srv.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# HSTS - brauzerga "bu saytga faqat HTTPS bilan kel" deydi
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
CONF
# nginx: barcha HTTP so'rovlarni HTTPS ga yo'naltirish
server {
listen 80;
server_name xizmat.namuna.uz;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name xizmat.namuna.uz;
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/srv.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# HSTS - brauzerga "bu saytga faqat HTTPS bilan kel" deydi
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
Foydalanuvchi manzil qatoriga xizmat.namuna.uz deb yozsa,
brauzer avval HTTP ga boradi. Aynan o'sha birinchi
so'rov himoyasiz.
Yo'lda turgan hujumchi shu paytda yo'naltirishni to'sib, foydalanuvchini o'z soxta saytiga olib ketishi mumkin (SSL stripping).
HSTS shu bo'shliqni yopadi: brauzer sarlavhani bir marta ko'rgach, keyingi safar HTTP ga umuman bormaydi - u to'g'ridan-to'g'ri HTTPS ga o'tadi.
| Parametr | Ma'nosi |
|---|---|
max-age=31536000 | Bir yil davomida eslab qol |
includeSubDomains | Barcha subdomenlar uchun ham |
preload | Brauzerlar ro'yxatiga kiritish uchun |
Birinchi tashrif muammosi preload bilan hal qilinadi:
domen brauzerlarga oldindan o'rnatilgan ro'yxatga
kiritiladi.
Ehtiyot bo'ling: HSTS ni bekor qilish qiyin. max-age
tugagunicha brauzer HTTPS talab qiladi. Sertifikat muddati
o'tib qolsa, sayt umuman ochilmaydi.
Shuning uchun kichik max-age (masalan 300) bilan
boshlang, hammasi barqaror ishlagach oshiring.
Sozlashdagi eng ko'p uchraydigan xatolar #
printf "%-32s %s\n" "XATO" "OQIBATI"
printf "%-32s %s\n" "--------------------------------" "------------------------"
printf "%-32s %s\n" "fullchain emas, faqat sayt serti" "ba'zi mijozlarda xato"
printf "%-32s %s\n" "TLS 1.0/1.1 yoqilgan" "eskirgan shifrlar"
printf "%-32s %s\n" "HSTS yo'q" "SSL stripping mumkin"
printf "%-32s %s\n" "sertifikat qo'lda yangilanadi" "kutilmaganda muddati otadi"
printf "%-32s %s\n" "maxfiy kalit git da" "kalit sizib chiqadi"
printf "%-32s %s\n" "verify_peer => false" "MITM ga toliq ochiq"
printf "%-32s %s\n" "kalit huquqlari 644" "har kim oqiy oladi"
XATO OQIBATI
-------------------------------- ------------------------
fullchain emas, faqat sayt serti ba'zi mijozlarda xato
TLS 1.0/1.1 yoqilgan eskirgan shifrlar
HSTS yo'q SSL stripping mumkin
sertifikat qo'lda yangilanadi kutilmaganda muddati otadi
maxfiy kalit git da kalit sizib chiqadi
verify_peer => false MITM ga toliq ochiq
kalit huquqlari 644 har kim oqiy oladi
- Sinov sertifikati bilan mahalliy TLS serverini ishga tushiring.
openssl s_clientbilan ulaning va protokol hamda tekshiruv kodini yozing.-CAfilesiz ulaning - tekshiruv kodi qanday o'zgardi?- Noto'g'ri domen ko'rsatib ulaning.
-tls1_2bilan ulanib, shifr to'plami nomini qismlarga ajrating.- Serverga
-min_protocol TLSv1.2qo'shing va TLS 1.0 bilan ulanishga urinib ko'ring. - TLS 1.2 va 1.3 dagi shifr to'plami nomlarini solishtiring.
- SNI nima uchun ochiq ketishini tushuntiring.
- PHP da
verify_peervaverify_peer_namefarqini yozing. - HSTS ni kichik
max-agebilan boshlash nima uchun tavsiya etilishini yozing.
Xulosa #
- TLS yangi kriptografiya o'ylab topmaydi - u oldingi bo'limlardagi qismlarni birlashtiradi.
- TLS 1.3 qo'l siqishi bitta borib-kelishda tugaydi.
- Server sertifikat ko'rsatibgina qolmay, maxfiy kalitga egaligini imzo bilan isbotlaydi.
- Qo'l siqish muvaffaqiyatli bo'lishi, sertifikat esa yaroqsiz bo'lishi mumkin.
- Sertifikatni tekshirish - mijozning vazifasi;
verify_peerni o'chirmang. - TLS 1.3 da shifr to'plamlari 300 dan 5 taga qisqargan va oldinga maxfiylik majburiy.
- Minimal versiya sifatida TLS 1.2 ni qo'ying, 1.0 va 1.1 ni o'chiring.
- SNI ochiq matnda ketadi: kuzatuvchi qaysi domenga kirganingizni ko'radi.
- Server to'liq zanjirni (
fullchain) yuborishi shart. - HSTS birinchi HTTP so'rovidagi bo'shliqni yopadi, lekin uni bekor qilish qiyin.
Keyingi bo'limda kriptografiyaning poydevori - xavfsiz tasodifiylik haqida gaplashamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.