Self-Signed & Internal CA #
Tidak semua lingkungan penyebaran (deployment) memiliki akses langsung ke internet global atau nama domain publik yang dapat diverifikasi oleh Let’s Encrypt atau ZeroSSL. Server pengembangan lokal (localhost), lingkungan pengujian internal (staging), intranet perusahaan, serta server di dalam jaringan privat tetap membutuhkan keamanan transmisi data melalui HTTPS, namun mereka tidak dapat menyelesaikan tantangan ACME publik. Untuk mengatasi kebutuhan ini, Caddy menyediakan solusi bawaan berupa Internal Certificate Authority (CA) yang mampu menerbitkan dan mengelola sertifikat TLS secara otomatis untuk domain lokal tanpa ketergantungan pada internet.
Selain menggunakan internal CA bawaan Caddy, kita juga dapat mengonfigurasi Caddy untuk menggunakan sertifikat manual yang kita sediakan sendiri (baik yang dibuat menggunakan OpenSSL maupun yang diterbitkan oleh CA komersial pihak ketiga). Memahami perbedaan arsitektur antara penggunaan internal CA Caddy, sertifikat manual, dan integrasi dengan sistem PKI perusahaan (seperti HashiCorp Vault) akan membekali kita dengan kemampuan merancang arsitektur keamanan TLS yang tepat untuk berbagai skenario non-publik.
Dua Pendekatan untuk HTTPS Tanpa ACME Publik #
Ketika kita tidak bisa atau tidak ingin menggunakan CA publik, ada dua pendekatan utama yang didukung oleh Caddy:
Pendekatan 1: Menggunakan Internal CA Bawaan Caddy (Sangat Direkomendasikan)
Caddy secara otomatis bertindak sebagai Certificate Authority lokal.
- Membuat Root CA mandiri (Root Certificate & Private Key).
- Membuat Intermediate CA yang ditandatangani oleh Root CA.
- Menerbitkan dan memperbarui sertifikat berdurasi pendek untuk domain lokal secara otomatis.
Keunggulan: Siklus hidup sertifikat dikelola penuh oleh Caddy; browser tidak akan menampilkan
warning setelah kita menginstal Root CA sekali saja ke dalam sistem.
Pendekatan 2: Menggunakan Sertifikat Manual (Custom Certificates)
Kita menyediakan file sertifikat (.crt) dan kunci privat (.key) sendiri ke Caddy.
- Kunci privat dan sertifikat dibuat menggunakan perkakas luar (seperti OpenSSL).
- Caddy hanya bertindak sebagai pengguna sertifikat tersebut untuk negosiasi TLS.
Keunggulan: Sangat fleksibel; bisa digunakan untuk alamat IP mentah atau domain internal
yang sertifikatnya dibeli dari CA komersial tertentu.
Arsitektur PKI Internal Caddy #
Ketika fitur internal CA diaktifkan, Caddy secara otomatis menginisiasi infrastruktur kunci publik (Public Key Infrastructure atau PKI) mini di dalam server kita. Pemahaman mengenai parameter waktu masa berlaku (lifetime) komponen PKI Caddy sangat penting untuk menjaga keandalan sistem:
flowchart TD
Root["Root CA Caddy<br>(Berlaku 10 Tahun / 3650 Hari)"] -->|"Menandatangani"| Intermediate["Intermediate CA Caddy<br>(Berlaku 30 Hari, diperbarui otomatis setiap 7 hari)"]
Intermediate -->|"Menandatangani"| Leaf["Leaf Certificate (Berlaku 7 Hari)<br>(Diperbarui otomatis sebelum kedaluwarsa)"]
style Root stroke:#0288d1,stroke-width:2px
style Leaf stroke:#43a047,stroke-width:2px
Mekanisme internal ini dirancang agar sangat aman:
- Leaf Certificate yang Berdurasi Pendek: Karena sertifikat akhir hanya berlaku selama 7 hari, risiko penyalahgunaan sertifikat jika kunci privat domain bocor menjadi sangat minim. Caddy akan memperbaruinya di latar belakang tanpa disadari oleh pengguna.
- Pembaruan Otomatis Intermediate CA: Kunci perantara (Intermediate Key) diperbarui secara proaktif oleh Caddy setiap minggu sebelum masa aktif 30 hari habis, menggunakan Root Key yang tersimpan aman pada disk server.
Cara Mengaktifkan Internal CA Caddy #
Ada tiga cara umum untuk memberitahu Caddy agar menggunakan internal CA bawaannya, tergantung pada cakupan domain yang kita layani:
1. Menggunakan Kata Kunci ’localhost’ (Otomatis) #
Caddy secara cerdas mengasumsikan bahwa nama host localhost atau alamat IP lokal 127.0.0.1 adalah lingkungan lokal dan akan langsung mengaktifkan internal CA tanpa konfigurasi tambahan:
# Menggunakan localhost - otomatis memicu internal CA
localhost {
reverse_proxy localhost:3000
}
2. Menggunakan Opsi Global ’local_certs' #
Jika kita memiliki banyak blok situs dengan nama domain lokal (seperti .local atau .internal) dan ingin semuanya menggunakan internal CA, kita dapat menetapkannya secara global:
{
# Memaksa semua site menggunakan internal CA
local_certs
}
app.internal {
reverse_proxy localhost:3000
}
api.local {
file_server
}
3. Menggunakan Direktif ’tls internal’ Per-Site #
Kita juga dapat menentukan penggunaan internal CA secara spesifik pada blok situs tertentu saja menggunakan direktif tls internal:
# Hanya site ini yang menggunakan internal CA
dev.example.com {
tls internal
reverse_proxy localhost:4000
}
Menginstal Root CA ke Sistem dan Browser #
Sertifikat yang diterbitkan oleh internal CA Caddy tidak akan langsung dipercayai oleh sistem operasi maupun browser web kita karena Caddy bukan CA publik yang terdaftar secara global. Kita harus menginstal Root CA Caddy ke trust store sistem kita.
1. Menggunakan Perintah Otomatis ‘caddy trust’ #
Jika Caddy dijalankan pada komputer lokal kita (komputer pengembangan), kita dapat menggunakan perintah baris bawaan Caddy untuk menginstal Root CA secara otomatis ke sistem operasi dan browser kita:
# Menginstal Root CA Caddy ke sistem trust store (Memerlukan hak akses sudo/admin)
caddy trust
# Menghapus kembali Root CA Caddy jika tidak lagi digunakan
caddy untrust
2. Lokasi File Root CA Caddy #
Jika Caddy berjalan di server lain di jaringan lokal kita, kita harus menyalin file Root CA dari server tersebut dan menginstalnya secara manual di komputer klien kita. Lokasi file Root CA (root.crt) tergantung pada instalasi Caddy:
- Linux (Systemd):
/var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt - macOS:
~/Library/Application Support/Caddy/pki/authorities/local/root.crt - Windows:
%APPDATA%\Caddy\pki\authorities\local\root.crt
3. Panduan Instalasi Manual pada Berbagai Sistem Operasi #
Pada macOS (Keychain Access) #
# Menginstal dan mempercayai root.crt via terminal macOS
security add-trusted-cert -d -r trustRoot -k ~/Library/Keychains/login.keychain-db root.crt
Pada Linux (Ubuntu/Debian) #
# Salin file ke direktori sertifikat sistem
sudo cp root.crt /usr/local/share/ca-certificates/caddy-root.crt
# Perbarui database sertifikat tepercaya sistem
sudo update-ca-certificates
Pada Windows (PowerShell/CMD) #
# Jalankan PowerShell sebagai Administrator, lalu jalankan:
certutil -addstore -f "ROOT" root.crt
Konfigurasi Internal CA pada Docker Compose #
Saat menjalankan Caddy di dalam kontainer Docker untuk keperluan pengembangan lokal, kita perlu memetakan (mount) folder data Caddy agar file Root CA dapat diakses dari komputer induk (host).
version: "3.7"
services:
caddy:
image: caddy:2.8.4
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
# Mount folder PKI agar bisa kita akses untuk di-trust di host
- ./caddy-pki:/data/caddy/pki
volumes:
caddy_data:
caddy_config:
Setelah kontainer pertama kali dijalankan, folder ./caddy-pki/ akan terisi dengan sertifikat. Kita tinggal mengambil file ./caddy-pki/authorities/local/root.crt tersebut dan menginstalnya pada sistem operasi komputer host kita menggunakan metode instalasi manual yang dijelaskan sebelumnya.
Caddy sebagai Server ACME Lokal (Local ACME Server) #
Fitur luar biasa dari Caddy yang jarang didokumentasikan dengan baik adalah kemampuannya untuk berfungsi sebagai server ACME lokal. Ini sangat berguna di lingkungan enterprise: satu instansi Caddy utama bertindak sebagai pusat CA internal yang melayani permohonan sertifikat dari banyak instansi server web lain di dalam jaringan internal kita via protokol ACME standar.
flowchart TD
subgraph Jaringan Privat Perusahaan
A["Server Web Klien (Caddy 2)"]
B["Layanan Backend Klien (Nginx/Certbot)"]
C["Instansi Caddy Utama (Master CA)"]
end
A -->|1. Permintaan ACME /newOrder| C
B -->|2. Permintaan ACME /newOrder| C
C -->|3. Kirim Challenge Lokal| A
C -->|4. Kirim Challenge Lokal| B
A -->|5. Selesaikan Challenge| C
B -->|6. Selesaikan Challenge| C
C -->|7. Terbitkan Sertifikat Internal| A
C -->|8. Terbitkan Sertifikat Internal| B
Konfigurasi Caddy Master CA (Pemberi Layanan ACME) #
Di Caddy utama yang akan bertindak sebagai CA, kita harus mendefinisikan otoritas PKI lokal dan mengaktifkan endpoint ACME internal pada Caddyfile:
# Caddyfile pada server Master CA (IP: 192.168.1.10)
{
# Menetapkan nama otoritas PKI lokal
pki {
ca local {
name "Kantor Utama CA"
}
}
}
# Menyediakan endpoint ACME untuk mesin-mesin internal lain
# Kita mendengarkan di domain khusus acme.internal
acme.internal {
# Mengaktifkan ACME server bawaan Caddy
acme_server
# Tetap gunakan internal CA untuk mengamankan komunikasi acme.internal sendiri
tls internal
}
Konfigurasi Caddy Klien (Pemohon Sertifikat) #
Pada server-server web klien di jaringan internal kita, kita mengonfigurasi Caddyfile mereka untuk mengarahkan penerbitan sertifikat ke server Master CA kita:
# Caddyfile pada Server Klien
{
cert_issuer acme {
# Mengarahkan CA ke server Master CA kita
ca https://acme.internal/acme/local/directory
# Beritahu Caddy klien untuk memercayai sertifikat Root CA milik Master
# agar komunikasi ACME awal tidak gagal karena SSL warning
trusted_roots /etc/ssl/certs/master-ca-root.crt
}
}
# Domain internal ini akan mendapatkan sertifikat dari Master CA
layanan.internal {
reverse_proxy localhost:8080
}
Konfigurasi Sertifikat Manual #
Jika kita telah memiliki file sertifikat dan kunci privat sendiri yang dibuat dari luar Caddy, kita dapat menuliskannya secara langsung pada blok situs kita menggunakan direktif tls:
# Menggunakan sertifikat eksternal yang sudah ada
example.internal {
# Format: tls [file_sertifikat] [file_kunci_privat]
tls /etc/ssl/certs/example.internal.crt /etc/ssl/private/example.internal.key
reverse_proxy localhost:5000
}
Aturan Hak Akses Berkas (File Permissions) #
Caddy harus dapat membaca berkas sertifikat dan kunci privat tersebut. Kegagalan membaca berkas ini adalah salah satu penyebab Caddy tidak bisa dijalankan saat proses restart.
- Linux (User ‘caddy’): Jika Caddy berjalan sebagai layanan systemd, ia menggunakan akun
caddy. Berikan kepemilikan file ke pengguna tersebut:
# Mengatur kepemilikan file sertifikat dan kunci privat ke caddy
sudo chown -R caddy:caddy /etc/ssl/private/
# Mengatur izin akses yang ketat (hanya caddy yang boleh membaca kunci privat)
sudo chmod 600 /etc/ssl/private/example.internal.key
sudo chmod 644 /etc/ssl/certs/example.internal.crt
Membuat Sertifikat Manual dengan OpenSSL (SAN yang Benar) #
Banyak pengembang mengalami masalah saat menggunakan sertifikat yang dibuat dengan OpenSSL karena browser modern (seperti Chrome versi baru) menolak sertifikat tersebut dengan error ERR_CERT_COMMON_NAME_INVALID. Hal ini terjadi karena browser modern mewajibkan adanya ekstensi Subject Alternative Name (SAN); mencantumkan domain hanya pada Common Name (CN) tidak lagi dianggap cukup.
Berikut adalah panduan membuat berkas konfigurasi OpenSSL (openssl.cnf) yang benar untuk menyertakan SAN:
# Simpan berkas ini dengan nama openssl.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = v3_req
[dn]
C = ID
O = Perusahaan Kita
CN = server.internal
[v3_req]
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = server.internal
DNS.2 = *.server.internal
IP.1 = 192.168.1.100
IP.2 = 127.0.0.1
Jalankan perintah OpenSSL berikut untuk membuat sertifikat self-signed berdurasi 10 tahun menggunakan konfigurasi di atas:
# Membuat private key dan sertifikat bersertifikasi SAN
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout server.internal.key \
-out server.internal.crt \
-config openssl.cnf -extensions v3_req
Hasil pembuatan berupa file server.internal.crt dan server.internal.key kini dapat dipasang di Caddyfile dan akan dipercayai oleh browser setelah kita menginstal file .crt tersebut ke trust store komputer klien.
Pemecahan Masalah (Troubleshooting) Internal CA #
1. Browser Menampilkan Peringatan SSL Setelah ‘caddy trust’ #
- Penyebab: Beberapa browser (seperti Mozilla Firefox) tidak menggunakan trust store bawaan sistem operasi. Firefox menggunakan database sertifikat internal mereka sendiri.
- Solusi: Buka Firefox → Settings → Privacy & Security → View Certificates → Authorities → klik Import → pilih berkas
root.crtCaddy, lalu centang opsi “Trust this CA to identify websites”.
2. Perkakas ‘curl’ Menolak Sertifikat Internal Caddy #
- Gejala: Kita bisa mengakses situs di browser tanpa warning, namun perintah
curl https://localhostmembalas dengan errorSSL certificate problem: unable to get local issuer certificate. - Penyebab:
curlmenggunakan trust store sistem operasi yang berbeda atau tidak membaca perubahan trust store sebelum terminal di-restart. - Solusi: Jalankan pembaruan database sertifikat sistem kita (
sudo update-ca-certificatesdi Linux), restart sesi terminal kita, atau gunakan parameter--cacertpada perintah curl untuk menunjuk file root CA Caddy secara eksplisit:
# Melakukan kueri curl dengan menunjuk Root CA Caddy secara manual
curl --cacert ~/.local/share/caddy/pki/authorities/local/root.crt https://localhost/api/health
Ringkasan #
- Internal CA — Fitur bawaan Caddy untuk menerbitkan sertifikat TLS otomatis pada domain lokal tanpa membutuhkan koneksi internet atau nama domain publik.
- Siklus Hidup Aman — Sertifikat akhir (leaf) yang diterbitkan hanya berlaku selama 7 hari, diperbarui secara berkala oleh Caddy menggunakan kunci perantara (intermediate CA).
- Aktivasi Sederhana –> Caddy mengaktifkan internal CA otomatis untuk kata kunci
localhostatau lewat konfigurasitls internalper-site di Caddyfile.- Instalasi Root CA — Agar sertifikat di-trust browser, jalankan
caddy trustdi localhost, atau salin berkasroot.crtCaddy untuk di-import manual ke browser/klien lain.- Local ACME Server — Caddy dapat bertindak sebagai penyedia layanan ACME internal (
acme_server) untuk melayani permohonan sertifikat terenkripsi dari server internal lainnya.- Sertifikat OpenSSL — Saat membuat sertifikat manual dengan OpenSSL, wajib menggunakan ekstensi Subject Alternative Name (SAN) agar tidak ditolak oleh browser modern.