TLS konfiguratsiyasi
Self-signed sertifikat darsida server ListenAndServeTLS("cert.pem", "key.pem") bilan ishga tushirildi. Bu holatda barcha TLS sozlamalari standart qiymatlarda qoladi.
Go’ning standart sozlamalari xavfsiz va ko‘p hollarda yetarli. Lekin ba’zan ularni o‘zgartirishga to‘g‘ri keladi: xavfsizlik siyosati faqat TLS 1.3 ni talab qiladi, sertifikatni server to‘xtatilmasdan yangilash kerak yoki klient sertifikatini tekshirish lozim. Bu sozlamalar tls.Config struct’i orqali beriladi.
Standart holatda Go nima qiladi?
Go’ning yangi versiyalarida server tomonidagi TLS sozlamalari quyidagicha:
| Sozlama | Standart qiymat |
|---|---|
| Minimal versiya | TLS 1.2 |
| Maksimal versiya | TLS 1.3 |
| TLS 1.3 shifrlari | Barcha zamonaviy shifrlar. Ularni sozlab bo‘lmaydi |
| TLS 1.2 shifrlari | Xavfsiz ro‘yxat. RSA kalit almashish va 3DES olib tashlangan |
| Kalit almashish | X25519, NIST egri chiziqlari va post-kvant gibrid variantlari |
| HTTP/2 | HTTPS’da avtomatik yoqilgan |
Bu qiymatlar Go versiyasi bilan birga yangilanadi. Masalan, Go 1.22 da serverning minimal versiyasi TLS 1.0 dan 1.2 ga ko‘tarildi. Go 1.24 da esa post-kvant gibrid kalit almashish (X25519MLKEM768) standart ro‘yxatga qo‘shildi. Go’ni yangilab turish TLS sozlamalarini ham avtomatik zamonaviy holatda saqlaydi.
Tip
Aniq sababsiz standart sozlamalarni o‘zgartirmang. Qo‘lda yozilgan shifrlar ro‘yxati vaqt o‘tishi bilan eskiradi, standart qiymatlar esa Go bilan birga yangilanib boradi.
tls.Config bilan server
cfg := &tls.Config{
MinVersion: tls.VersionTLS12,
}
srv := &http.Server{
Addr: ":8443",
Handler: mux,
TLSConfig: cfg,
}
srv.ListenAndServeTLS("cert.pem", "key.pem")
TLSConfig maydoniga berilgan sozlamalar ListenAndServeTLS ichida ishlatiladi.
Minimal versiya
Faqat TLS 1.3 ga ruxsat berish xavfsizroq. Lekin juda eski klientlar, masalan Android 10 dan oldingi qurilmalar yoki eski Java ilovalari, ulana olmay qolishi mumkin. Ommaviy API uchun TLS 1.2 minimal versiya sifatida hali ham keng qo‘llanadi. Ichki servislar orasidagi aloqa uchun esa TLS 1.3 yaxshi tanlov.
Tanlovni API’ga ulanadigan klientlar ro‘yxatiga qarab qiling.
Shifrlar
cfg := &tls.Config{
MinVersion: tls.VersionTLS12,
CipherSuites: []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
},
}
Bu yerda bir nechta muhim jihat bor:
CipherSuitesfaqat TLS 1.0–1.2 uchun ishlaydi. TLS 1.3 shifrlarini Go’da sozlab bo‘lmaydi, ularning hammasi xavfsiz hisoblanadi.- Ro‘yxatdagi tartib e’tiborga olinmaydi. Go shifrni o‘zining ichki mantiqi asosida tanlaydi: u protsessorda AES’ni tezlashtiruvchi apparat qo‘llab-quvvatlashi bor-yo‘qligini ham hisobga oladi.
PreferServerCipherSuitesmaydoni eskirgan va hech qanday ta’sir qilmaydi.
Ro‘yxatni faqat xavfsizlik siyosati aniq talab qilsa yozing. Masalan, auditorlar aniq bir ro‘yxatni talab qilgan bo‘lsa.
Go qo‘llab-quvvatlaydigan va xavfsiz deb hisoblaydigan shifrlar ro‘yxatini dastur ichidan ham olish mumkin:
tls.InsecureCipherSuites() esa xavfsiz emas deb topilgan shifrlarni qaytaradi.
Kalit almashish
cfg := &tls.Config{
CurvePreferences: []tls.CurveID{tls.X25519MLKEM768, tls.X25519, tls.CurveP256},
}
CurvePreferences kalit almashish mexanizmlarini belgilaydi. Bo‘sh qoldirilsa, Go standart ro‘yxatni ishlatadi. U post-kvant gibrid variantlarni ham o‘z ichiga oladi. Bu variantlar kelajakda kvant kompyuterlar paydo bo‘lganda bugun yozib olingan trafikni ochish xavfidan himoya qiladi.
Odatda bu maydonni o‘zgartirish kerak emas.
Sertifikatni fayldan emas, kod orqali yuklash
ListenAndServeTLS fayllarni dastur ishga tushganda bir marta o‘qiydi. Sertifikatni boshqa manbadan olish kerak bo‘lsa, masalan muhit o‘zgaruvchisidan yoki secret manager’dan, u tls.Config.Certificates maydoniga beriladi:
cert, err := tls.X509KeyPair(certPEM, keyPEM) // []byte ko‘rinishidagi PEM ma’lumotlar
if err != nil {
log.Fatal(err)
}
srv := &http.Server{
Addr: ":8443",
Handler: mux,
TLSConfig: &tls.Config{Certificates: []tls.Certificate{cert}},
}
srv.ListenAndServeTLS("", "") // fayl nomlari bo‘sh: sertifikat TLSConfig'da
Fayl nomlari bo‘sh satr sifatida berilganda, Go sertifikatni TLSConfig ichidan oladi.
Sertifikatni server to‘xtatilmasdan yangilash
Sertifikatlarning muddati cheklangan. Let's Encrypt sertifikatlari odatda 90 kun amal qiladi. Sertifikat fayli yangilanganda serverni qayta ishga tushirmaslik uchun GetCertificate funksiyasi ishlatiladi. U har bir yangi TLS ulanishida chaqiriladi:
Sinab ko‘ramiz:
curl --cacert cert.pem https://localhost:8443
curl --cacert cert.pem --tlsv1.2 --tls-max 1.2 https://localhost:8443
TLS: TLS 1.3, shifr: TLS_AES_128_GCM_SHA256, SNI: "localhost", ALPN: "h2"
TLS: TLS 1.2, shifr: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SNI: "localhost", ALPN: "h2"
- Birinchi so‘rovda klient va server TLS 1.3 bo‘yicha kelishdi.
- Ikkinchisida
curlTLS 1.2 dan yuqori versiyani ishlatmadi va server ham shu versiyaga moslashdi. ALPN: "h2"— ulanish HTTP/2 orqali ishlayapti. ALPN (Application-Layer Protocol Negotiation) handshake paytida HTTP versiyasini tanlash imkonini beradi.
Minimal versiyani tekshiramiz. Zamonaviy curl TLS 1.1 ni o‘zi ham ishlatmaydi, shuning uchun eski klientni kichik Go dasturi bilan taqlid qilamiz:
Server TLS 1.1 ulanishni rad etdi. Server logida esa quyidagi yozuv paydo bo‘ladi:
http: TLS handshake error from 127.0.0.1:40908: tls: client offered only unsupported versions: [302 301]
Sertifikat faylini yangilagandan keyin serverga signal yuboriladi:
Mavjud ulanishlar uzilmaydi. Keyingi yangi ulanishlar esa yangi sertifikatni oladi. Yangi fayl noto‘g‘ri bo‘lsa, eski sertifikat ishlashda davom etadi.
Bir nechta domen: SNI
Bitta server bir nechta domen uchun turli sertifikatlardan foydalanishi mumkin. Certificates maydoniga bir nechta sertifikat berilsa, Go klient SNI orqali so‘ragan domenga mos sertifikatni o‘zi tanlaydi:
Murakkabroq mantiq kerak bo‘lsa, GetCertificate ichida hello.ServerName qiymatiga qarab tanlash mumkin. Let's Encrypt darsidagi autocert aynan shu usulda ishlaydi.
Klient sertifikatini tekshirish (mTLS)
Odatda faqat klient serverni tekshiradi. mTLS (mutual TLS) da server ham klientdan sertifikat so‘raydi. Bu usul mikroservislar orasidagi aloqada yoki bank API’larida ishlatiladi:
caPEM, _ := os.ReadFile("clients-ca.pem")
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(caPEM)
cfg := &tls.Config{
ClientCAs: pool,
ClientAuth: tls.RequireAndVerifyClientCert,
}
Handler ichida klient sertifikati r.TLS.PeerCertificates[0] orqali olinadi. Undagi Subject.CommonName yoki SAN qiymati klientni aniqlash uchun ishlatiladi.
Sozlamalarni tekshirish
Server TLS sozlamalarini tashqaridan tekshirish uchun vositalar bor:
testssl.sh— buyruq qatori vositasi. Lokal va ichki serverlarni ham tekshira oladi;- SSL Labs Server Test — ommaviy domenlar uchun onlayn tekshiruv.
Ular qo‘llab-quvvatlanadigan versiyalar, shifrlar va sertifikat zanjiridagi muammolarni ko‘rsatadi.
Xulosa
- Go’ning standart TLS sozlamalari xavfsiz va har yangi versiyada yangilanadi. Ularni aniq sababsiz o‘zgartirmang.
tls.Confighttp.ServerningTLSConfigmaydoni orqali beriladi.MinVersionbilan eski versiyalar o‘chiriladi. TLS 1.3 shifrlarini sozlab bo‘lmaydi, TLS 1.2 shifrlar tartibi esa e’tiborga olinmaydi.GetCertificatesertifikatni server to‘xtatilmasdan yangilash imkonini beradi.- Bir nechta domen SNI orqali, klientni tekshirish esa mTLS orqali tashkil qilinadi.
Keyingi darsda Let's Encrypt’dan bepul sertifikatni avtomatik olish va yangilashni ko‘ramiz.