Mengamankan Apache dengan mTLS: Autentikasi Klien Menggunakan Sertifikat SSL
Apa Itu mTLS?
Pada koneksi HTTPS biasa, server menunjukkan sertifikatnya agar klien dapat memverifikasi identitas server. Namun, server tidak mewajibkan klien menunjukkan sertifikat.
Mutual TLS atau mTLS menambahkan verifikasi dari arah sebaliknya: klien juga harus menunjukkan sertifikat yang dipercaya oleh server.
Pendekatan ini dapat digunakan untuk mengamankan API internal, komunikasi antarservice, atau portal dengan akses terbatas. Pada Apache, autentikasi sertifikat klien dapat diaktifkan melalui direktif SSLVerifyClient require. :chatgpt-content-reference{index="0"}
Dalam tutorial ini, kita akan membuat CA sendiri untuk menandatangani sertifikat server dan klien.
1. Persiapan
Contoh utama menggunakan AlmaLinux atau Rocky Linux, Apache HTTP Server 2.4, dan OpenSSL.
Domain contoh:
secure.example.com
Ganti domain tersebut dengan domain yang Anda gunakan. Pastikan domain mengarah ke alamat IP server dan port HTTPS tersedia.
Instalasi pada AlmaLinux atau Rocky Linux
sudo dnf install -y httpd mod_ssl openssl
sudo systemctl enable --now httpd
Jika menggunakan firewalld:
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Alternatif instalasi pada Ubuntu atau Debian
sudo apt update
sudo apt install -y apache2 openssl
sudo a2enmod ssl
sudo systemctl enable --now apache2
Perbedaan lokasi konfigurasi dan perintah layanan untuk Ubuntu dijelaskan pada bagian konfigurasi Apache.
2. Siapkan Direktori Kerja
Jalankan proses pembuatan sertifikat menggunakan akun administrator yang bertanggung jawab atas CA.
mkdir -p ~/nirantara-mtls
chmod 700 ~/nirantara-mtls
cd ~/nirantara-mtls
umask 077
Perintah umask 077 membuat file baru hanya dapat diakses oleh pemiliknya.
Untuk latihan, seluruh sertifikat dibuat dalam satu direktori. Pada sistem produksi, proses penandatanganan sebaiknya dilakukan pada mesin CA terpisah.
Private key CA tidak perlu disalin ke server Apache maupun perangkat klien.
3. Buat Certificate Authority
CA digunakan untuk menandatangani sertifikat server dan klien.
Buat private key CA
openssl genrsa -aes256 -out ca.key 4096
Masukkan passphrase ketika diminta. Simpan passphrase tersebut dengan aman karena diperlukan saat menerbitkan sertifikat.
Buat sertifikat CA
openssl req -x509 -new -sha256 \
-key ca.key \
-out ca.crt \
-days 3650 \
-subj "/C=ID/O=Nirantara/CN=Nirantara Demo Root CA" \
-addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-addext "subjectKeyIdentifier=hash"
Hasilnya:
| File | Fungsi |
|---|---|
ca.key | Private key CA untuk menandatangani sertifikat |
ca.crt | Sertifikat CA untuk memverifikasi sertifikat yang diterbitkan |
Konfigurasi pathlen:0 berarti CA ini digunakan untuk menerbitkan sertifikat akhir secara langsung, tanpa intermediate CA.
4. Buat Sertifikat Server
Sertifikat server digunakan Apache untuk melayani koneksi HTTPS.
Buat private key server
openssl genrsa -out server.key 2048
Private key server pada contoh ini tidak memakai passphrase agar Apache dapat berjalan otomatis. Perlindungannya bergantung pada izin file dan keamanan server.
Buat CSR server
CSR merupakan permintaan sertifikat yang akan ditandatangani CA.
openssl req -new \
-key server.key \
-out server.csr \
-subj "/C=ID/O=Nirantara/CN=secure.example.com"
Buat konfigurasi ekstensi server
cat > server.ext <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:secure.example.com
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EOF
subjectAltName atau SAN berisi nama domain server. Jika server diakses melalui alamat IP, tambahkan SAN bertipe IP, misalnya:
subjectAltName=DNS:secure.example.com,IP:192.168.1.10
extendedKeyUsage=serverAuth menunjukkan bahwa sertifikat digunakan untuk autentikasi server TLS. OpenSSL menyediakan ekstensi terpisah untuk penggunaan server, klien, dan identitas alternatif tersebut. :chatgpt-content-reference{index="1"}
Tandatangani sertifikat server
openssl x509 -req \
-in server.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out server.crt \
-days 365 \
-sha256 \
-extfile server.ext
Masukkan passphrase CA ketika diminta.
Verifikasi sertifikat server
openssl verify \
-CAfile ca.crt \
-purpose sslserver \
-verify_hostname secure.example.com \
server.crt
Hasil yang diharapkan:
server.crt: OK
5. Buat Sertifikat Klien
Sertifikat klien menjadi identitas yang ditunjukkan browser atau aplikasi ketika mengakses Apache.
Gunakan sertifikat berbeda untuk setiap pengguna, perangkat, atau service agar identitas dan siklus pengelolaannya dapat dibedakan.
Buat private key klien
openssl genrsa -out client.key 2048
Buat CSR klien
openssl req -new \
-key client.key \
-out client.csr \
-subj "/C=ID/O=Nirantara/CN=client-demo"
Buat konfigurasi ekstensi klien
cat > client.ext <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
extendedKeyUsage=clientAuth
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EOF
clientAuth menyatakan bahwa sertifikat digunakan untuk autentikasi klien TLS. :chatgpt-content-reference{index="2"}
Tandatangani sertifikat klien
openssl x509 -req \
-in client.csr \
-CA ca.crt \
-CAkey ca.key \
-CAserial ca.srl \
-out client.crt \
-days 365 \
-sha256 \
-extfile client.ext
File ca.srl dibuat saat sertifikat server diterbitkan pada langkah sebelumnya.
Verifikasi sertifikat klien
openssl verify \
-CAfile ca.crt \
-purpose sslclient \
client.crt
Hasil yang diharapkan:
client.crt: OK
Ekspor ke PKCS#12 untuk browser
openssl pkcs12 -export \
-out client.p12 \
-inkey client.key \
-in client.crt \
-certfile ca.crt \
-name "Nirantara Client Demo"
Masukkan password ekspor ketika diminta.
File client.p12 berisi private key klien. Perlakukan file ini sebagai kredensial akses dan distribusikan melalui kanal yang aman.
6. Pasang Sertifikat pada Apache
Dari direktori kerja, salin file yang diperlukan Apache:
sudo install -d -m 700 /etc/httpd/ssl
sudo install -m 600 server.key /etc/httpd/ssl/server.key
sudo install -m 644 server.crt /etc/httpd/ssl/server.crt
sudo install -m 644 ca.crt /etc/httpd/ssl/ca.crt
Pada AlmaLinux atau Rocky Linux dengan SELinux:
sudo restorecon -Rv /etc/httpd/ssl
Apache hanya membutuhkan private key server, sertifikat server, dan sertifikat CA. Private key CA serta private key klien tetap berada pada pihak masing-masing.
7. Konfigurasi VirtualHost HTTPS
Buat file:
sudo vi /etc/httpd/conf.d/mtls.conf
Isi dengan konfigurasi berikut:
<VirtualHost *:443>
ServerName secure.example.com
DocumentRoot /var/www/mtls-demo
SSLEngine on
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCertificateFile /etc/httpd/ssl/server.crt
SSLCertificateKeyFile /etc/httpd/ssl/server.key
SSLCACertificateFile /etc/httpd/ssl/ca.crt
SSLVerifyClient require
SSLVerifyDepth 1
<Directory /var/www/mtls-demo>
Options -Indexes
AllowOverride None
Require all granted
</Directory>
ErrorLog /var/log/httpd/mtls_error.log
CustomLog /var/log/httpd/mtls_access.log combined
</VirtualHost>
Pastikan Apache sudah memiliki direktif Listen 443. Pada instalasi mod_ssl, direktif ini biasanya tersedia dalam konfigurasi SSL bawaan; jangan menambahkannya dua kali.
Arti konfigurasi utama
| Direktif | Fungsi |
|---|---|
SSLEngine on | Mengaktifkan TLS pada VirtualHost |
SSLCertificateFile | Menentukan sertifikat server |
SSLCertificateKeyFile | Menentukan private key server |
SSLCACertificateFile | Menentukan CA yang dipercaya untuk memverifikasi klien |
SSLVerifyClient require | Mewajibkan sertifikat klien yang valid |
SSLVerifyDepth 1 | Membatasi kedalaman verifikasi untuk sertifikat yang ditandatangani langsung oleh CA terpercaya |
Apache mendokumentasikan penggunaan SSLVerifyClient require bersama SSLCACertificateFile untuk mewajibkan autentikasi sertifikat klien. :chatgpt-content-reference{index="3"}
Konfigurasi ini menerima sertifikat klien valid yang dipercaya melalui CA tersebut. Pembatasan hak akses per pengguna atau service tetap perlu ditambahkan sesuai kebutuhan aplikasi.
Buat halaman pengujian
sudo mkdir -p /var/www/mtls-demo
echo 'Akses berhasil: autentikasi mTLS aktif.' \
| sudo tee /var/www/mtls-demo/index.html
Pada sistem dengan SELinux:
sudo restorecon -Rv /var/www/mtls-demo
Periksa dan terapkan konfigurasi
sudo apachectl configtest
Jika muncul Syntax OK:
sudo systemctl restart httpd
Penyesuaian untuk Ubuntu atau Debian
Gunakan direktori sertifikat /etc/apache2/ssl dan simpan VirtualHost pada:
/etc/apache2/sites-available/mtls.conf
Sesuaikan seluruh path sertifikat serta log pada konfigurasi. Kemudian jalankan:
sudo a2ensite mtls.conf
sudo apache2ctl configtest
sudo systemctl restart apache2
8. Uji Menggunakan curl
Jalankan pengujian dari perangkat yang memiliki file CA dan kredensial klien.
Pengujian tanpa sertifikat klien
curl --cacert ca.crt https://secure.example.com/
Akses seharusnya ditolak karena klien tidak memberikan sertifikat. Pesan kesalahan dapat berbeda sesuai versi TLS dan curl.
Pengujian dengan sertifikat klien
curl \
--cacert ca.crt \
--cert client.crt \
--key client.key \
https://secure.example.com/
Hasil yang diharapkan:
Akses berhasil: autentikasi mTLS aktif.
Pada pengujian ini:
--cacertdigunakan curl untuk memverifikasi server.--certmemberikan sertifikat klien.--keymemberikan private key yang sesuai dengan sertifikat klien.
Jika DNS belum diarahkan
Gunakan --resolve agar nama domain tetap sesuai dengan SAN sertifikat:
curl \
--resolve secure.example.com:443:192.168.1.10 \
--cacert ca.crt \
--cert client.crt \
--key client.key \
https://secure.example.com/
Ganti 192.168.1.10 dengan alamat IP server.
9. Uji Menggunakan Browser
Ada dua kebutuhan yang perlu disiapkan:
- Percayai CA server. Impor
ca.crtke penyimpanan CA terpercaya yang digunakan browser atau sistem operasi. - Impor identitas klien. Impor
client.p12ke bagian sertifikat pribadi, kemudian masukkan password ekspornya.
Nama menu berbeda antara browser dan sistem operasi. Setelah selesai, buka:
https://secure.example.com
Browser dapat meminta Anda memilih sertifikat klien. Pilih Nirantara Client Demo.
Impor CA hanya pada perangkat yang memang dikelola untuk lingkungan ini, karena mempercayai CA berarti mempercayai sertifikat yang diterbitkannya.
10. Mengatasi Masalah Umum
| Masalah | Yang perlu diperiksa |
|---|---|
| Browser tidak mempercayai server | Apakah ca.crt sudah dipercaya pada penyimpanan yang digunakan browser |
| Nama domain tidak cocok | Apakah URL sesuai dengan SAN dalam sertifikat server |
| Browser tidak menawarkan sertifikat klien | Apakah client.p12 terpasang sebagai sertifikat pribadi beserta private key |
| Sertifikat klien ditolak | CA penerbit, masa berlaku, dan penggunaan clientAuth |
| Apache gagal berjalan | Hasil configtest, lokasi file, izin private key, dan log |
| Port 443 tidak dapat diakses | Firewall, listener Apache, dan aturan jaringan |
Periksa log layanan:
sudo journalctl -u httpd -n 50 --no-pager
sudo tail -n 50 /var/log/httpd/mtls_error.log
Periksa masa berlaku sertifikat:
openssl x509 -in client.crt -noout -dates
Periksa detail sertifikat server:
openssl x509 -in server.crt -noout -text
11. Pertimbangan untuk Produksi
Contoh ini menggunakan satu CA untuk memudahkan pembelajaran. Untuk produksi, siapkan pengelolaan sertifikat yang mencakup:
- Penyimpanan private key CA secara terpisah dan aman.
- Sertifikat unik untuk setiap pengguna, perangkat, atau service.
- Proses perpanjangan sebelum sertifikat kedaluwarsa.
- Pencabutan sertifikat dan konfigurasi pemeriksaan pencabutan ketika kredensial bocor.
- Pemetaan identitas sertifikat ke hak akses aplikasi.
- Pengujian kegagalan akses selain pengujian akses berhasil.
Jika menggunakan reverse proxy atau load balancer yang mengakhiri koneksi TLS, tentukan di mana mTLS diverifikasi. Browser tidak akan menunjukkan sertifikatnya langsung ke Apache apabila koneksi TLS berakhir di proxy tersebut.
Dengan konfigurasi ini, Apache mewajibkan klien membuktikan kepemilikan private key dari sertifikat yang dipercaya sebelum mengakses layanan. HTTPS melindungi komunikasi, sedangkan mTLS menambahkan autentikasi klien pada lapisan TLS.
Published by Nirantara
Nirantara is an Indonesian Enterprise AI company specializing in Enterprise AI, RAG, Intelligent Search, and AI Automation. Article written by jsturana.