Kembali ke Beranda
Networking

Mengamankan Apache dengan mTLS: Autentikasi Klien Menggunakan Sertifikat SSL

Tutorial konfigurasi mutual TLS (mTLS) pada Apache HTTP Server menggunakan OpenSSL. Mulai dari membuat Certificate Authority, menerbitkan sertifikat server dan klien, mengaktifkan SSLVerifyClient, hingga menguji akses melalui browser dan curl.

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:

FileFungsi
ca.keyPrivate key CA untuk menandatangani sertifikat
ca.crtSertifikat 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

DirektifFungsi
SSLEngine onMengaktifkan TLS pada VirtualHost
SSLCertificateFileMenentukan sertifikat server
SSLCertificateKeyFileMenentukan private key server
SSLCACertificateFileMenentukan CA yang dipercaya untuk memverifikasi klien
SSLVerifyClient requireMewajibkan sertifikat klien yang valid
SSLVerifyDepth 1Membatasi 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:

  • --cacert digunakan curl untuk memverifikasi server.
  • --cert memberikan sertifikat klien.
  • --key memberikan 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:

  1. Percayai CA server. Impor ca.crt ke penyimpanan CA terpercaya yang digunakan browser atau sistem operasi.
  2. Impor identitas klien. Impor client.p12 ke 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

MasalahYang perlu diperiksa
Browser tidak mempercayai serverApakah ca.crt sudah dipercaya pada penyimpanan yang digunakan browser
Nama domain tidak cocokApakah URL sesuai dengan SAN dalam sertifikat server
Browser tidak menawarkan sertifikat klienApakah client.p12 terpasang sebagai sertifikat pribadi beserta private key
Sertifikat klien ditolakCA penerbit, masa berlaku, dan penggunaan clientAuth
Apache gagal berjalanHasil configtest, lokasi file, izin private key, dan log
Port 443 tidak dapat diaksesFirewall, 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.

apachehttp serveropensslssltlsmtlssslverifyclientkeamanan weblinuxdevops
Nirantara Logo

Published by Nirantara

Nirantara is an Indonesian Enterprise AI company specializing in Enterprise AI, RAG, Intelligent Search, and AI Automation. Article written by jsturana.

Learn more about Nirantara