Konfigurasi Dasar
server {
listen 443 ssl;
http2 on; # Nginx 1.25+, sebelumnya: listen 443 ssl http2
server_name contoh.id;
ssl_certificate /etc/letsencrypt/live/contoh.id/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/contoh.id/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
}
Kesalahan yang sangat sering terjadi dan sulit dikenali. Dengan cert.pem, peramban desktop tetap bekerja karena sudah menyimpan sertifikat perantara dari kunjungan sebelumnya — sementara klien API, aplikasi seluler, dan curl gagal dengan unable to verify the first certificate. Situs tampak "baik-baik saja" di layar, tetapi rusak bagi separuh klien.
openssl s_client -connect contoh.id:443 -servername contoh.id < /dev/null # Periksa bagian "Certificate chain" — harus memuat lebih dari satu sertifikat
Pengalihan HTTP ke HTTPS
server {
listen 80;
server_name contoh.id www.contoh.id;
location /.well-known/acme-challenge/ {
root /var/www/certbot; # biarkan validasi ACME lewat
}
location / {
return 301 https://$host$request_uri;
}
}
Validasi HTTP-01 dari Let's Encrypt harus dapat menjangkau /.well-known/acme-challenge/ melalui HTTP biasa. Bila seluruh port 80 dialihkan tanpa pengecualian, perpanjangan sertifikat gagal secara diam-diam — dan baru ketahuan sembilan puluh hari kemudian ketika sertifikat kedaluwarsa.
HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Setelah peramban menerima header ini, ia menolak terhubung melalui HTTP ke domain tersebut selama max-age — bahkan bila Nginx sudah diperbaiki. Dengan includeSubDomains, aturan itu berlaku pula untuk semua subdomain, termasuk yang belum punya sertifikat. Mulailah dengan max-age=300, pastikan seluruh subdomain siap, baru naikkan ke setahun.
server_name Bawaan dan SNI
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/nginx/ssl/bawaan.pem;
ssl_certificate_key /etc/nginx/ssl/bawaan.key;
return 444; # tutup koneksi tanpa balasan
}
Tanpa default_server, blok server pertama yang mendengarkan di port itu menjadi bawaan. Permintaan ke IP langsung atau ke domain asing yang diarahkan ke server ini akan mendapat sertifikat dan konten situs pertama — sering kali bukan yang diinginkan. Kode 444 khusus Nginx menutup koneksi tanpa mengirim apa pun.
OCSP Stapling
ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/contoh.id/chain.pem; resolver 1.1.1.1 8.8.8.8 valid=300s;
Tanpa stapling, peramban menghubungi penerbit sertifikat sendiri untuk memeriksa status pencabutan — menambah satu perjalanan jaringan pada setiap kunjungan pertama. Dengan stapling, Nginx mengambil bukti itu berkala dan menyertakannya langsung dalam jabat tangan.
Nginx harus dapat menyelesaikan nama host penanggap OCSP. Bila direktif resolver tidak ada, stapling gagal diam-diam dan hanya tercatat sebagai peringatan di log kesalahan.