Self-Signed Certificate

Self-Signed Certificate #

Self-signed certificate adalah sertifikat yang kamu buat dan tandatangani sendiri — tanpa Certificate Authority. Browser akan menampilkan peringatan keamanan, tapi koneksi tetap terenkripsi. Ini cocok untuk development lokal, testing, atau koneksi internal antar service di mana kamu mengendalikan kedua sisi koneksi.

Membuat Self-Signed Certificate dengan OpenSSL #

# Buat direktori untuk menyimpan sertifikat
sudo mkdir -p /etc/nginx/ssl

# Buat private key (RSA 2048-bit) dan sertifikat sekaligus
# Valid selama 365 hari, untuk domain localhost
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/nginx/ssl/self-signed.key \
    -out /etc/nginx/ssl/self-signed.crt \
    -subj "/C=ID/ST=Jakarta/L=Jakarta/O=Dev/CN=localhost"

# Atur permission yang tepat
sudo chmod 600 /etc/nginx/ssl/self-signed.key
sudo chmod 644 /etc/nginx/ssl/self-signed.crt

Penjelasan flag:

  • -x509 — buat self-signed certificate (bukan certificate signing request)
  • -nodes — jangan enkripsi private key dengan passphrase (nginx butuh key tanpa passphrase)
  • -days 365 — masa berlaku sertifikat
  • -newkey rsa:2048 — buat private key RSA 2048-bit baru bersamaan
  • -subj — isi field sertifikat langsung tanpa prompt interaktif

Membuat untuk Domain Tertentu dengan SAN #

Sertifikat modern sebaiknya menggunakan Subject Alternative Names (SAN) daripada hanya Common Name, karena browser modern mengabaikan CN dan hanya memeriksa SAN:

# Buat file konfigurasi untuk SAN
cat > /tmp/san.conf << 'EOF'
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
x509_extensions = v3_req

[dn]
C=ID
ST=Jakarta
L=Jakarta
O=Development
CN=myapp.local

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = myapp.local
DNS.2 = *.myapp.local
IP.1 = 127.0.0.1
IP.2 = 192.168.1.100
EOF

# Buat sertifikat dengan SAN
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/nginx/ssl/myapp.key \
    -out /etc/nginx/ssl/myapp.crt \
    -config /tmp/san.conf

Konfigurasi Nginx #

server {
    listen 443 ssl;
    server_name localhost myapp.local;

    ssl_certificate     /etc/nginx/ssl/self-signed.crt;
    ssl_certificate_key /etc/nginx/ssl/self-signed.key;

    # Parameter SSL yang disarankan (bahkan untuk self-signed)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    location / {
        proxy_pass http://localhost:3000;
    }
}

server {
    listen 80;
    server_name localhost myapp.local;
    return 301 https://$host$request_uri;
}

Mengatasi Peringatan Browser #

Saat mengakses site dengan self-signed certificate, browser menampilkan halaman peringatan. Untuk development, kamu bisa melewatinya:

Chrome/Edge: Klik “Advanced” → “Proceed to [domain] (unsafe)”

Firefox: Klik “Advanced” → “Accept the Risk and Continue”

curl: Gunakan flag -k atau --insecure untuk melewati verifikasi sertifikat:

curl -k https://localhost/api/health

Untuk menghilangkan peringatan sepenuhnya di development: Import sertifikat ke system trust store. Dengan cara ini browser akan mempercayainya seperti sertifikat dari CA resmi.

# Ubuntu/Debian: tambahkan ke system trust store
sudo cp /etc/nginx/ssl/self-signed.crt /usr/local/share/ca-certificates/myapp.crt
sudo update-ca-certificates

# macOS: tambahkan ke Keychain
sudo security add-trusted-cert -d -r trustRoot \
    -k /Library/Keychains/System.keychain /path/to/self-signed.crt

Alternatif: mkcert untuk Development #

mkcert adalah tool yang membuat local CA di mesin development dan menggunakannya untuk menandatangani sertifikat. Hasilnya: sertifikat yang dipercaya browser tanpa peringatan, tapi hanya di mesin yang sama.

# Install mkcert (Ubuntu)
sudo apt install mkcert
mkcert -install   # Install local CA ke trust store browser

# Buat sertifikat untuk domain lokal
mkcert localhost 127.0.0.1 myapp.local "*.myapp.local"
# Menghasilkan: localhost+3.pem dan localhost+3-key.pem

# Pindahkan ke direktori nginx
sudo cp localhost+3.pem /etc/nginx/ssl/mkcert.crt
sudo cp localhost+3-key.pem /etc/nginx/ssl/mkcert.key

Dengan mkcert, development bisa dilakukan dengan HTTPS yang benar-benar bersih di browser tanpa peringatan apapun — sangat berguna untuk testing fitur yang hanya berjalan di HTTPS (Service Workers, WebAuthn, dsb.).


Ringkasan #

  • Self-signed certificate cocok untuk development dan testing — koneksi terenkripsi tapi browser menampilkan peringatan.
  • Gunakan flag -nodes saat membuat key dengan OpenSSL agar Nginx bisa membaca key tanpa passphrase.
  • Tambahkan SAN (subjectAltName) agar sertifikat dikenali dengan benar oleh browser modern.
  • mkcert adalah cara terbaik untuk development lokal — tidak ada peringatan browser karena menggunakan local CA yang terpercaya.
  • Untuk production, gunakan Let’s Encrypt (dibahas di artikel berikutnya) — gratis dan dipercaya semua browser.

← Sebelumnya: Konsep SSL/TLS   Berikutnya: Let’s Encrypt →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact