Belajar Chi - HTTPS, Reverse Proxy & Advanced Networking
Series/Belajar Chi/Episode 15
Episode 15 of 23

Belajar Chi - HTTPS, Reverse Proxy & Advanced Networking

Episode ini mengamankan transportasi: HTTPS manual dengan http.Server, sertifikat otomatis Let's Encrypt lewat autocert dan ACME, serta HTTP/2. Kalian juga memasang reverse proxy dengan httputil.ReverseProxy di subrouter dan mengintegrasikan aplikasi dengan nginx dan Caddy.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Aplikasi production hampir selalu berada di balik HTTPS dan proxy. Episode 15 memastikan kalian paham keduanya dari sisi Go: bagaimana mengaktifkan TLS langsung di http.Server, mendapatkan sertifikat otomatis dari Let's Encrypt, memakai HTTP/2, dan menempatkan router chi di balik reverse proxy atau bahkan bertindak sebagai reverse proxy itu sendiri.

Memahami lapisan ini penting untuk debugging nyata: sertifikat kedaluwarsa, proxy yang mengubah header, dan HTTP/2 yang tidak aktif adalah masalah umum yang sering salah diagnosa.

HTTPS Manual

Sertifikat dan Kunci

Mode paling sederhana: berikan sertifikat dan kunci privat:

Generate sertifikat lokal
openssl req -x509 -newkey rsa:2048 -keyout key.pem \
  -out cert.pem -days 365 -nodes -subj "/CN=localhost"

openssl req -x509 -newkey rsa:2048 membuat sertifikat self-signed untuk development. Di production, sertifikat harus diterbitkan CA tepercaya.

Server dengan TLS

http.Server dengan TLS
srv := &http.Server{
    Addr:      ":443",
    Handler:   Routes(deps),
    TLSConfig: &tls.Config{MinVersion: tls.VersionTLS12},
}
 
srv.ListenAndServeTLS("cert.pem", "key.pem")

ListenAndServeTLS("cert.pem", "key.pem") mengaktifkan HTTPS dengan sertifikat yang diberikan. TLSConfig.MinVersion membatasi ke TLS 1.2 ke atas, menolak protokol lama yang tidak aman.

Let's Encrypt dan autocert

Sertifikat Otomatis via ACME

autocert dari ekosistem Go menangani ACME secara penuh:

HTTPS otomatis dengan autocert
m := &autocert.Manager{
    Prompt:     autocert.AcceptTOS,
    HostPolicy: autocert.HostWhitelist("api.example.com"),
    Cache:      autocert.DirCache("certs"),
}
 
srv := &http.Server{
    Addr:      ":https",
    TLSConfig: m.TLSConfig(),
    Handler:   Routes(deps),
}
 
go func() {
    http.ListenAndServe(":http", m.HTTPHandler(nil))
}()
 
srv.ListenAndServeTLS("", "")

autocert.Manager{Prompt: autocert.AcceptTOS, HostPolicy: ...} menerbitkan dan memperbarui sertifikat Let's Encrypt secara otomatis. m.HTTPHandler(nil) melayani challenge ACME di port 80 untuk verifikasi domain.

Persyaratan Autocert

  • Domain harus mengarah ke server (HostPolicy memfilter).
  • Port 80 wajib terbuka untuk challenge ACME.
  • DirCache menyimpan sertifikat agar tidak meminta ulang terus-menerus.
  • Autocert hanya untuk domain publik, bukan IP atau localhost.

HTTP/2

Aktif Otomatis

Kabar baik: http.Server mengaktifkan HTTP/2 otomatis saat TLS dipakai. Kalian tidak perlu konfigurasi tambahan.

Cek dukungan HTTP/2
curl --http2 -I https://api.example.com

curl --http2 -I https://api.example.com menampilkan HTTP/2 200 pada respons bila server dan proxy sudah mendukungnya. HTTP/2 multiplexing membuat banyak request paralel tidak lagi antri pada koneksi tunggal.

Saat di Balik Proxy

Jika di belakang nginx atau Caddy, HTTP/2 biasanya dihentikan di proxy — aplikasi Go berbicara HTTP/1.1 dengan proxy, proxy berbicara HTTP/2 dengan klien. Ini normal dan bukan masalah.

Reverse Proxy di Subrouter

Menjalankan Sebagai Proxy

chi bisa menjadi gateway: mount reverse proxy pada path tertentu:

Reverse proxy di subrouter
backend := httputil.NewSingleHostReverseProxy(
    &url.URL{Scheme: "http", Host: "localhost:9000"})
 
r.Mount("/internal", backend)

httputil.NewSingleHostReverseProxy(...) meneruskan request /internal/* ke service localhost:9000. Ini pola dasar microservices: satu entrypoint, banyak backend.

Rewrite Path

Untuk mengubah path saat diteruskan:

Rewrite path proxy
proxy := httputil.NewReverseProxy(&httputil.Director{
    Dir: func(req *http.Request) {
        req.URL.Scheme = "http"
        req.URL.Host = "backend:9000"
        req.URL.Path = strings.TrimPrefix(req.URL.Path, "/internal")
    },
})

strings.TrimPrefix(req.URL.Path, "/internal") melepas prefix sebelum diteruskan — klien melihat /internal/health, backend menerima /health.

Integrasi dengan nginx dan Caddy

nginx sebagai Front

Konfigurasi nginx klasik di depan aplikasi:

Reverse proxy nginx
server {
    listen 80;
    server_name api.example.com;
 
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for menambahkan IP asli klien. Ingat: dengan header ini, middleware RealIP di episode 14 menjadi wajib.

Caddy dengan Auto-TLS

Caddy menangani TLS otomatis tanpa konfigurasi sertifikat:

Caddyfile sederhana
api.example.com {
    reverse_proxy 127.0.0.1:8080
}

reverse_proxy 127.0.0.1:8080 meneruskan traffic dan Caddy otomatis meminta serta memperbarui sertifikat dari Let's Encrypt.

Penutup

Inti yang harus dibawa pulang:

  • TLS manual: ListenAndServeTLS dengan cert dan key.
  • autocert menangani ACME, renew otomatis, dan challenge port 80.
  • HTTP/2 aktif otomatis saat TLS dipakai.
  • httputil.NewSingleHostReverseProxy menjadikan chi sebagai gateway.
  • nginx dan Caddy menangani front; pasang middleware.RealIP.
  • Header X-Forwarded-Proto harus dijaga untuk membedakan HTTP dan HTTPS.

Di episode 16 selanjutnya kita melampaui REST: WebSocket, gRPC-Gateway, dan lainnya — realtime dengan gorilla/websocket, Server-Sent Events, mounting handler non-REST seperti gRPC-gateway dan GraphQL, serta membangun service campuran dalam satu http.Server.

Belajar Chi - HTTPS, Reverse Proxy & Advanced Networking | Belajar Chi