Tarkibga o'tish

Let's Encrypt

Let's Encrypt — bepul, avtomatlashtirilgan va ochiq sertifikat markazi (CA). U 2015-yildan beri ishlaydi va bugungi kunda internetdagi HTTPS saytlarning katta qismi uning sertifikatlaridan foydalanadi.

Ilgari sertifikat olish pullik va qo‘lda bajariladigan jarayon edi: so‘rov yaratish, CA saytiga yuklash, emailni tasdiqlash, sertifikatni yuklab olib, serverga o‘rnatish. Har yili yoki ikki yilda bu jarayon takrorlanardi va ko‘pincha unutilardi. Natijada sertifikat muddati o‘tib, sayt birdan ishlamay qolardi.

Let's Encrypt bu jarayonni to‘liq avtomatlashtirdi. Sertifikat bir necha soniyada olinadi va muddati tugashidan oldin avtomatik yangilanadi.

ACME protokoli

Let's Encrypt ACME (Automatic Certificate Management Environment) protokoli orqali ishlaydi. Uning asosiy g‘oyasi: CA sertifikat berishdan oldin so‘rovchi haqiqatan ham domenni boshqarayotganini tekshiradi.

1. Server → CA:   "api.example.uz uchun sertifikat kerak"
2. CA → Server:   "Isbotlang: mana bu tokenni ko‘rsating"
3. CA → api.example.uz:  tokenni tekshiradi (HTTP-01 yoki TLS-ALPN-01)
4. CA → Server:   "Tasdiqlandi, mana sertifikat"

Domenni boshqarishni isbotlashning asosiy usullari (challenges):

Usul Qanday ishlaydi Talab
HTTP-01 CA http://domen/.well-known/acme-challenge/<token> manzilini ochadi 80-port internetdan ochiq
TLS-ALPN-01 CA 443-portga maxsus TLS handshake bilan ulanadi 443-port internetdan ochiq
DNS-01 CA domenning DNS’idagi TXT yozuvni tekshiradi DNS provayderining API’si

DNS-01 bitta afzallikka ega: faqat shu usul bilan *.example.uz kabi wildcard sertifikat olish mumkin. Qolgan ikki usul oddiyroq, chunki ular uchun faqat ochiq port kerak.

Sertifikat muddati

Let's Encrypt sertifikatlari qisqa muddatli. Hozirgi standart muddat 90 kun. Let's Encrypt bu muddatni bosqichma-bosqich yanada qisqartirishni rejalashtirgan.

Qisqa muddat ataylab tanlangan. Kalit sizib chiqsa ham, zarar vaqt bilan cheklanadi. Bundan tashqari, bu yondashuv avtomatlashtirishni majburiy qiladi. Qo‘lda yangilash qiyin bo‘lgani uchun "unutib qo‘yish" xavfi ham yo‘qoladi.

Joriy muddatlar va cheklovlarni Let's Encrypt’ning rasmiy hujjatlaridan tekshiring. Ular vaqt o‘tishi bilan o‘zgaradi.

Go’da: autocert paketi

Go jamoasi qo‘llab-quvvatlaydigan golang.org/x/crypto/acme/autocert paketi ACME protokolini to‘liq amalga oshiradi. U sertifikatni birinchi so‘rovda oladi, diskda saqlaydi va muddati tugashidan oldin o‘zi yangilaydi.

go get golang.org/x/crypto/acme/autocert

Asosiy qism

m := &autocert.Manager{
    Prompt:     autocert.AcceptTOS,
    HostPolicy: autocert.HostWhitelist("api.example.uz"),
    Cache:      autocert.DirCache("/var/lib/books-api/certs"),
    Email:      "[email protected]",
}
  • Prompt: autocert.AcceptTOS — Let's Encrypt foydalanish shartlarini qabul qilish. Bu shartsiz sertifikat berilmaydi. Shartlarni oldindan o‘qib chiqing.
  • HostPolicy — qaysi domenlar uchun sertifikat so‘rash mumkinligi. Majburiy. U bo‘lmasa, istalgan odam serveringizga soxta Host sarlavhasi bilan so‘rov yuborib, sizning nomingizdan istalgan domen uchun sertifikat so‘rashga urinishi mumkin. Bu Let's Encrypt cheklovlarini tezda tugatib yuboradi.
  • Cache — sertifikat va hisob kalitlari saqlanadigan joy. Busiz har bir qayta ishga tushirishda yangi sertifikat so‘raladi va cheklovlarga tez yetib boriladi.
  • Email — muhim xabarlar uchun aloqa manzili. Ixtiyoriy, lekin ko‘rsatish tavsiya etiladi.

To‘liq server

main.go
package main

import (
    "crypto/tls"
    "fmt"
    "log"
    "net/http"
    "time"

    "golang.org/x/crypto/acme/autocert"
)

func main() {
    m := &autocert.Manager{
        Prompt:     autocert.AcceptTOS,
        HostPolicy: autocert.HostWhitelist("api.example.uz", "www.api.example.uz"),
        Cache:      autocert.DirCache("certs"),
        Email:      "[email protected]",
    }

    mux := http.NewServeMux()
    mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Salom! %s orqali ulandingiz\n", tls.VersionName(r.TLS.Version))
    })

    // 80-port: HTTP-01 tekshiruvi va qolgan so‘rovlarni HTTPS'ga yo‘naltirish
    go func() {
        srv := &http.Server{
            Addr:              ":80",
            Handler:           m.HTTPHandler(nil),
            ReadHeaderTimeout: 5 * time.Second,
        }
        log.Fatal(srv.ListenAndServe())
    }()

    // 443-port: asosiy HTTPS server
    tlsCfg := m.TLSConfig()
    tlsCfg.MinVersion = tls.VersionTLS12

    srv := &http.Server{
        Addr:              ":443",
        Handler:           mux,
        TLSConfig:         tlsCfg,
        ReadHeaderTimeout: 5 * time.Second,
        ReadTimeout:       10 * time.Second,
        WriteTimeout:      15 * time.Second,
        IdleTimeout:       60 * time.Second,
    }

    log.Println("Server: https://api.example.uz")
    log.Fatal(srv.ListenAndServeTLS("", ""))
}

Kod qanday ishlaydi:

  • m.TLSConfig() — tayyor tls.Config qaytaradi. Uning GetCertificate funksiyasi har bir ulanishda kerakli sertifikatni beradi. Sertifikat keshda bo‘lmasa, uni Let's Encrypt’dan oladi. Konfiguratsiyada TLS-ALPN-01 tekshiruvi uchun acme-tls/1 protokoli ham yoqilgan.
  • m.HTTPHandler(nil) — 80-port uchun handler. U /.well-known/acme-challenge/ so‘rovlariga javob beradi. nil berilganda qolgan GET va HEAD so‘rovlarini 302 bilan HTTPS’ga yo‘naltiradi, boshqa metodlarga esa 400 qaytaradi. nil o‘rniga o‘z handleringizni ham berish mumkin. Masalan, keyingi darsdagi doimiy yo‘naltirish handlerini.
  • ListenAndServeTLS("", "") — fayl nomlari bo‘sh, chunki sertifikatlar TLSConfig orqali olinadi.
  • Sertifikat birinchi HTTPS so‘rov kelganda olinadi. Shuning uchun birinchi so‘rov bir necha soniya davom etishi mumkin. Keyingi so‘rovlar keshdagi sertifikatdan foydalanadi.

autocert sertifikatni muddati tugashidan oldin avtomatik yangilaydi. Standart holatda bu 30 kun yoki sertifikat umrining uchdan biri qolganda, ya’ni ikkalasidan qaysi biri kichik bo‘lsa, shu paytda bajariladi. Buning uchun hech narsa qilish shart emas.

Ishga tushirish uchun shartlar

  1. Domen DNS’da serveringiz IP manziliga yo‘naltirilgan bo‘lishi kerak: A yoki AAAA yozuv.
  2. 80 va 443 portlar internetdan ochiq bo‘lishi kerak. Firewall va bulut xavfsizlik guruhlarini tekshiring.
  3. 1024 dan past portlarni Linux’da tinglash uchun maxsus huquq kerak. Dasturni root sifatida ishga tushirish o‘rniga, faqat shu huquqni bering:
sudo setcap 'cap_net_bind_service=+ep' ./books-api

Bu buyruq dastur fayliga faqat past portlarni ochish huquqini beradi. Dastur qayta build qilinganda huquq yo‘qoladi, shuning uchun buyruqni har deploy’da takrorlash kerak. systemd servisida esa buning o‘rniga AmbientCapabilities=CAP_NET_BIND_SERVICE sozlamasi ishlatiladi.

  1. Kesh katalogi faqat dastur foydalanuvchisi o‘qiy oladigan bo‘lishi kerak. Unda yopiq kalitlar saqlanadi.

Staging muhitida sinash

Let's Encrypt’da sertifikatlar soni bo‘yicha cheklovlar (rate limits) bor. Sozlashda xato qilib, qayta-qayta urinsangiz, bir necha soatga yoki kunga bloklanib qolishingiz mumkin.

Sinov uchun staging muhitidan foydalaning. U haqiqiy muhit bilan bir xil ishlaydi, cheklovlari ancha yumshoq. Faqat u bergan sertifikatlarga brauzerlar ishonmaydi:

m := &autocert.Manager{
    // ...
    Client: &acme.Client{
        DirectoryURL: "https://acme-staging-v02.api.letsencrypt.org/directory",
    },
}

Hammasi ishlagach, Client maydonini olib tashlang va kesh katalogini tozalang. Aks holda staging sertifikati keshda qolib ketadi.

Muqobil yo‘l: proxy orqali

HTTPS va TLS bo‘limining kirish qismida aytilganidek, TLS’ni proxy’da tugatish ham keng tarqalgan. Masalan, Caddy Let's Encrypt sertifikatlarini standart holatda avtomatik boshqaradi:

Caddyfile
api.example.uz {
    reverse_proxy localhost:8080
}

Bu holatda Go ilovasi oddiy HTTP’da localhost:8080da ishlaydi. Caddy esa HTTPS, sertifikatlar va HTTP’dan yo‘naltirishni o‘z zimmasiga oladi. nginx va certbot jufti ham xuddi shu vazifani bajaradi.

Proxy ortida ishlaganda ilova haqiqiy klient IP manzili va protokolni X-Forwarded-For hamda X-Forwarded-Proto sarlavhalaridan oladi. Bu sarlavhalarga faqat o‘z proxy’ingizdan kelganda ishonish kerak. Batafsil Gin: Performance va HTTP → HTTPS majburlash darslarida.

Qaysi yo‘lni tanlash kerak?

Holat Tavsiya
Bitta server, bitta Go ilova autocert — qo‘shimcha dastursiz
Bir serverda bir nechta ilova yoki domen Caddy yoki nginx
Bulut load balancer ishlatiladi Sertifikatni bulut boshqaradi, ilova HTTP’da ishlaydi
Kubernetes cert-manager va ingress controller

Xulosa

  • Let's Encrypt — bepul va avtomatlashtirilgan CA. U ACME protokoli orqali domenni boshqarishingizni tekshiradi.
  • Sertifikatlar qisqa muddatli, shuning uchun yangilash avtomatik bo‘lishi shart.
  • autocert.Manager sertifikatni oladi, keshlaydi va yangilaydi. HostPolicy va Cache majburiy.
  • 80-portda m.HTTPHandler, 443-portda m.TLSConfig() ishlatiladi.
  • Sozlashni avval staging muhitida sinang.
  • Muqobil yo‘l — TLS’ni Caddy, nginx yoki bulut load balancer’ida tugatish.

Keyingi darsda HTTP so‘rovlarini HTTPS’ga majburan yo‘naltirish va HSTS sarlavhasini o‘rganamiz.