Chapter pg_hba.conf ditutup dengan satu pengamatan: di server latihan kita tidak ada satu pun baris hostssl, karena memang parameter ssl masih off — seluruh latihan sejauh ini berjalan di jalur tak terenkripsi. Tanpa TLS, sandi SCRAM memang tetap tidak bocor (protokolnya memang dirancang untuk itu), tetapi seluruh hasil query — data pelanggan, harga, alamat — mengalir sebagai teks yang bisa disadap di jaringan. Bagi aplikasi yang berjalan lintas mesin, enkripsi jalur bukan pelengkap: pg_hba.conf bisa memaksa koneksi TLS lewat baris hostssl, dan klien mengatur tingkat ketatnya lewat satu parameter — sslmode. Chapter ini membedah keduanya dari dua arah: server yang menyalakan TLS, dan klien yang memverifikasi bahwa jalurnya benar-benar terenkripsi serta servernya memang yang diklaim.
Kondisi TLS di Server Latihan #
Delapan parameter mengatur TLS di sisi server. Query berikut membaca semuanya dari pg_settings — hasilnya adalah kondisi nyata server kita, dan kolom context akan menentukan cara menerapkan perubahannya:
-- Parameter TLS di server latihan: ssl masih off, sementara seluruh
-- parameter pendukungnya sudah tersedia dengan nilai bawaan.
-- Kolom context bernilai sighup: cukup reload untuk menerapkan.
SELECT name, setting, context
FROM pg_settings
WHERE name IN ('ssl', 'ssl_min_protocol_version', 'ssl_max_protocol_version',
'ssl_cert_file', 'ssl_key_file', 'ssl_ca_file',
'ssl_ciphers', 'ssl_prefer_server_ciphers')
ORDER BY name;Output yang Dihasilkan:
name | setting | context
---------------------------+--------------------------+---------
ssl | off | sighup
ssl_ca_file | | sighup
ssl_cert_file | server.crt | sighup
ssl_ciphers | HIGH:MEDIUM:+3DES:!aNULL | sighup
ssl_key_file | server.key | sighup
ssl_max_protocol_version | | sighup
ssl_min_protocol_version | TLSv1.2 | sighup
ssl_prefer_server_ciphers | on | sighup
(8 rows)Baris-baris hasil itu bisa dibaca sebagai daftar periksaperalatan TLS kita:
ssl = off— saklar utama; TLS belum menyala di server latihan.ssl_cert_file = server.crtdanssl_key_file = server.key— nama file sertifikat dan kunci privat. Nama relatif ini dicari di direktori data (PGDATA); path absolut juga sah bila diperlukan.ssl_min_protocol_version = TLSv1.2— protokol di bawah TLS 1.2 ditolak; nilaissl_max_protocol_versionyang kosong berarti mengikuti versi tertinggi yang didukung pustaka.ssl_ciphers = HIGH:MEDIUM:+3DES:!aNULL— daftar cipher yang ditawarkan, denganssl_prefer_server_ciphers = onberarti urutan pilihan dipegang server, bukan klien.ssl_ca_fileyang kosong — belum ada Certificate Authority (CA) yang dipasang; file inilah yang nantinya dipakai untuk memverifikasi sertifikat klien.context = sighuppada seluruh baris — menerapkan perubahan delapan parameter ini cukup denganreload(misalnyaSELECT pg_reload_conf();sebagaimana dilatih di chapterpg_hba.conf), tanpa memulai ulang server.
Menyalakan TLS #
Prosedur menyalakan TLS membutuhkan sepasang kunci privat dan sertifikat. Untuk latihan, openssl bisa membuatnya dalam satu perintah; untuk produksi, sertifikat sebaiknya diterbitkan CA internal perusahaan atau CA publik yang sudah dikenali klien:
# kunci privat tanpa passphrase + sertifikat self-signed, 30 hari
openssl req -new -x509 -days 30 -nodes \
-subj "/CN=db.example.com" \
-keyout server.key -out server.crt
# kunci privat hanya boleh dibaca pemiliknya -- server menolak
# menjalankan TLS dengan kunci yang terlalu terbuka
chmod 600 server.keySelanjutnya pasang kedua file itu di direktori data, lalu nyalakan saklarnya di postgresql.conf:
ssl = on
# ssl_cert_file = 'server.crt'
# ssl_key_file = 'server.key'
# ssl_min_protocol_version = 'TLSv1.2'Begitu ssl = on dimuat ulang, server menawarkan TLS pada koneksi TCP; klien lama yang memakai sslmode=disable atau allow tetap terhubung tanpa TLS, sehingga penyalakan ini tidak memutus aplikasi yang sedang berjalan. Memaksa enkripsi penuh baru terjadi lewat pg_hba.conf — mengganti baris host yang sensitif menjadi hostssl — atau dari sisi klien lewat sslmode=require. Satu pengecualian perlu diingat: unix socket tidak melalui jaringan, jadi TLS tidak berlaku untuk baris local — inilah alasan server latihan kita aman menjalankan trust di socket sembari ssl = off.
Parameter sslmode dari Sisi Klien #
Klien libpq — psql dan hampir semua driver aplikasi — memilih perilaku TLS lewat parameter koneksi sslmode. Enam nilainya membentuk tangga jaminan yang menaik:
sslmode | Terenkripsi? | Memverifikasi sertifikat server? | Perilaku khas |
|---|---|---|---|
disable | tidak | tidak | TLS tidak dicoba sama sekali |
allow | bila terpaksa | tidak | Coba polos dulu; TLS hanya bila polos gagal |
prefer | bila tersedia | tidak | Coba TLS dulu; jatuh ke polos bila server tak mendukung |
require | ya | tidak | Polos ditolak; identitas server tidak diperiksa |
verify-ca | ya | ya, terhadap CA | Sertifikat harus diterbitkan CA yang dikenal |
verify-full | ya | ya, CA + hostname | Ditambah: nama host harus cocok dengan sertifikat |
Bawaan libpq adalah prefer — pilihan yang nyaman untuk internet yang bercampur, tetapi berbahaya sebagai kebijakan: koneksi yang diam-diam jatuh ke jalur polos tetap dianggap sukses. Untuk server produksi yang sudah jelas mendukung TLS, naikkan minimal ke require, dan untuk aplikasi lintas jaringan publik gunakan verify-full — pengecualian hostname pada verify-ca masih membuka celah server-bukan-server yang sertifikatnya sah.
Pemakaian sslmode dalam connection string cukup satu pasangan kunci-nilai, dan sertifikat CA untuk verifikasi diarahkan lewat parameter pendamping:
postgresql://[email protected]:5432/penjualan?sslmode=verify-full&sslrootcert=/etc/app/ca.crtMemeriksa Enkripsi Koneksi Berjalan #
Setelah tersambung, klaim “koneksi ini terenkripsi” bisa diverifikasi — bukan dianggap. View pg_stat_ssl menyimpan status TLS setiap koneksi backend: kolom ssl menandakan terenkripsi atau tidak, version mencatat protokol, cipher dan bits menjelaskan algoritma serta panjang kuncinya, dan tiga kolom terakhir (client_dn, client_serial, issuer_dn) terisi hanya bila klien mengirim sertifikat. File berikut memeriksa koneksi kita sendiri dengan memfilter pid milik sesi ini:
-- Status TLS koneksi kita sendiri, dibaca dari view pg_stat_ssl:
-- ssl bernilai f karena server belum menyalakan TLS, sehingga kolom
-- versi protokol, nama cipher, dan panjang kunci tidak terisi.
SELECT ssl, version, cipher, bits
FROM pg_stat_ssl
WHERE pid = pg_backend_pid();Output yang Dihasilkan:
ssl | version | cipher | bits
-----+---------+--------+------
f | | |
(1 row)Hasilnya jujur: ssl bernilai f dengan kolom protokol, cipher, dan panjang kunci kosong — koneksi ini benar-benar tidak terenkripsi, sebagaimana dugaan kita dari ssl = off. Di server yang sudah menyala TLS-nya, baris yang sama akan memperlihatkan misalnya version = TLSv1.3, nama cipher seperti TLS_AES_256_GCM_SHA384, dan bits = 256. Di sisi klien, psql menyediakan perintah meta \connectioninfo yang meringkas jalur koneksi aktif — termasuk status enkripsinya — dalam satu baris. View ini juga alat audit yang praktis: query SELECT ssl, count(*) FROM pg_stat_ssl GROUP BY ssl memetakan berapa koneksi produksi yang masih polos; jalankan setelah menyalakan hostssl untuk mengukur sisa klien yang belum ikut.
Sertifikat Server dan Verifikasi Identitas #
TLS memakai sertifikat untuk memecahkan masalah yang sandi tidak sentuh: memastikan server di ujung koneksi adalah pemilik sah dari alamat yang dituju. Sertifikat server memuat nama host di field Subject Alternative Name (SAN) dan ditandatangani oleh CA. Klien dengan sslmode=verify-ca memeriksa tanda tangan itu terhadap salinan sslrootcert; klien dengan verify-full menambahkan satu pemeriksaan — nama host yang dikoneksikan harus sama dengan nama pada sertifikat. Karena itu sertifikat dengan CN=db.example.com sah untuk koneksi ke db.example.com, tetapi gagal verify-full bila klien mengalamatkan server dengan nama lain atau alamat IP.
Protokol lama juga ikut tersaring: ssl_min_protocol_version = TLSv1.2 menolak SSLv3 dan TLS 1.0/1.1 yang telah dinyatakan usang, dan daftar ssl_ciphers menyaring algoritma enkripsi yang lemah. Kombinasi kebijakan server ini plus verify-full di klien menghasilkan jalur yang terenkripsi dan terautentikasi dua arah penuh.
Sertifikat Klien dan Metode cert #
TLS bisa bekerja dua arah: server memverifikasi klien dengan sertifikat, bukan sandi. Metode cert dari chapter Authentication
memanfaatkan persis mekanisme ini — pg_hba.conf menuliskannya pada baris hostssl karena sertifikat klien hanya terkirim selama handshake TLS:
# TYPE DATABASE USER ADDRESS METHOD
hostssl penjualan app_web 10.0.0.0/24 cert map=webmapServer memeriksa tanda tangan sertifikat klien terhadap ssl_ca_file, lalu mencocokkan nama CN pada sertifikat dengan nama role PostgreSQL — pemetaan yang bisa diubah lewat map bila penamaan sertifikat dan role tidak identik. Opsi clientcert=verify-full juga bisa dipasang pada metode lain (misalnya scram-sha-256 clientcert=verify-full): klien tetap mengirim sandi, dan sertifikat menjadi faktor kedua — pola two-factor yang disarankan untuk server yang menghadap jaringan publik. Sertifikat klien tidak bisa digandakan semudah sandi dan pencabutannya cukup dengan mengeluarkan dari daftar CA.
Jalur kini tertutup rapi: pg_hba.conf menyeleksi siapa yang boleh masuk, scram-sha-256 membuktikan identitas tanpa mengirim sandi, dan TLS mengenkripsi sekaligus memverifikasi kedua arah. Tetapi semua lapisan itu menjaga jalur — bukan isi query-nya. Aplikasi yang merangkai SQL dengan menempelkan input pengguna begitu saja akan membocorkan dan merusak data lewat jalur yang sudah terenkripsi sekalipun. Serangan itu bernama SQL injection, dan tiga chapter terakhir section ini membongkarnya: anatomi serangannya, pertahanan utamanya, lalu prinsip hak akses minimum yang membatasi ledakannya.
Referensi #
- Secure TCP/IP Connections with SSL/TLS
- SSL Support (libpq)
- Connection Strings (libpq)
- Certificate Authentication
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
cek-koneksi.sql
Unduh berkas-- Status TLS koneksi kita sendiri, dibaca dari view pg_stat_ssl:
-- ssl bernilai f karena server belum menyalakan TLS, sehingga kolom
-- versi protokol, nama cipher, dan panjang kunci tidak terisi.
SELECT ssl, version, cipher, bits
FROM pg_stat_ssl
WHERE pid = pg_backend_pid();
status-ssl.sql
Unduh berkas-- Parameter TLS di server latihan: ssl masih off, sementara seluruh
-- parameter pendukungnya sudah tersedia dengan nilai bawaan.
-- Kolom context bernilai sighup: cukup reload untuk menerapkan.
SELECT name, setting, context
FROM pg_settings
WHERE name IN ('ssl', 'ssl_min_protocol_version', 'ssl_max_protocol_version',
'ssl_cert_file', 'ssl_key_file', 'ssl_ca_file',
'ssl_ciphers', 'ssl_prefer_server_ciphers')
ORDER BY name;