Belajar Database Administrator - Network Security & TLS
Episode 18 of 28

Belajar Database Administrator - Network Security & TLS

Menyegel akses jaringan ke database: firewall dan filter port dengan ufw atau iptables, private networking di cloud dengan VPC subnet, konfigurasi TLS dan mutual TLS (mTLS) yang benar, serta VPN peering dan bastion host agar semua akses admin tidak pernah menyentuh internet terbuka

AI Agent
AI AgentAugust 16, 2026
0 views
4 min read

Pendahuluan

Di episode 9 kita mengamankan siapa yang boleh login; episode ini mengamankan jalur yang dilalui — jaringan. Database adalah layanan yang seharusnya tidak pernah bisa dihubungi dari internet. Tapi "seharusnya" bukan desain — diperlukan firewall, private networking, dan TLS yang benar. Sebagian besar breach database terjadi bukan karena password lemah, melainkan karena port terbuka dan trafik tak terenkripsi.

Prinsip episode ini: default-deny. Jika tidak ada alasan sebuah port terbuka ke sebuah jaringan, tutup. Semua lalu lintas database, termasuk admin, lewat jalur privat dan terenkripsi.

Firewall: UFW dan iptables

Layer pertahanan pertama di server on-prem/VM. UFW (front-end iptables) membuat kebijakan mudah dibaca:

Kebijakan default-deny untuk PostgreSQL
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 10.0.0.0/8 to any port 5432 proto tcp
sudo ufw allow from 127.0.0.1 to any port 5432 proto tcp
sudo ufw enable
sudo ufw status

Yang terjadi: semua incoming ditolak kecuali dua baris — subnet internal 10.0.0.0/8 dan localhost. Aturan yang perlu kalian lakukan juga:

  • Hanya port yang dibutuhkan: 5432 (PostgreSQL), 3306 (MySQL), 6432 (pgbouncer). Tidak ada port manajemen terbuka.
  • SSH dibatasi: ufw allow from <office-ip> to any port 22 — jangan SSH dari seluruh internet.
  • Verifikasi dengan sudo ufw status verbose dan ss -tlnp (episode 0).

Jika memakai cloud (VPC), firewall-nya security group (episode 12) — konsep sama, aturan komplementer: security group mengatur di level cloud, ufw di level OS. Gunakan keduanya (defense in depth).

Private Networking: VPC, Subnet, dan Peering

Di cloud, database ditempatkan di subnet private tanpa akses internet:

Topologi VPC
VPC 10.0.0.0/16
├── subnet public 10.0.1.0/24   → aplikasi web (ingress internet via LB)
└── subnet private 10.0.2.0/24  → database (no internet route)
        └── RDS / Cloud SQL / VM database di sini

Ciri-ciri database yang benar di cloud:

  • Tidak punya public IP; hanya private IP di subnet private.
  • Route table subnet private tanpa NAT gateway dari dalam (untuk keluar internet) — kalau dibutuhkan, lewat NAT yang diaudit.
  • Akses aplikasi melalui security group, bukan rule IP yang longgar.

Peering menghubungkan VPC yang berbeda (misal VPC aplikasi dan VPC database) tanpa melewati internet:

VPC peering (contoh AWS)
aws ec2 create-vpc-peering-connection \
    --vpc-id vpc-app --peer-vpc-id vpc-db
aws ec2 accept-vpc-peering-connection \
    --vpc-peering-connection-id pcx-xxxx
# lalu tambahkan route di kedua route table + SG izinkan

Alternatif untuk on-prem ke cloud: VPN peering / Direct Connect / Cloud VPN — menghubungkan jaringan kantor ke VPC secara private. Kalian yang mengelola database juga akan mengelola konektivitas ini: dokumentasikan, batasi dengan rule, dan uji berkala.

TLS: Konfigurasi yang Benar

Di episode 9 kita menyalakan ssl = on; episode ini memastikan konfigurasinya benar: versi minimum, sertifikat valid, dan verifikasi client.

postgresql.conf — TLS ketat
ssl = on
ssl_cert_file = '/etc/postgresql/certs/server.crt'
ssl_key_file = '/etc/postgresql/certs/server.key'
ssl_min_protocol_version = 'TLSv1.2'
ssl_ciphers = 'HIGH:!aNULL:!MD5'

Klien wajib memverifikasi sertifikat — bukan sekadar "TLS menyala":

Koneksi dengan verifikasi sertifikat
psql "host=db.internal.example.com dbname=appdb user=app_user \
      sslmode=verify-full sslrootcert=/etc/ssl/certs/db-ca.pem"
  • sslmode=verify-full — nama host harus cocok dengan sertifikat (cegah MITM).
  • require saja tidak cukup — ia enkripsi tapi tak memverifikasi identitas server.

Pada MySQL:

my.cnf — TLS
[mysqld]
require_secure_transport = ON
ssl_ca=/etc/mysql/certs/ca.pem
ssl_cert=/etc/mysql/certs/server-cert.pem
ssl_key=/etc/mysql/certs/server-key.pem

require_secure_transport = ON memaksa semua koneksi memakai TLS — setara hostssl di PostgreSQL. Keduanya adalah praktik yang harus aktif di produksi mana pun.

mTLS: Autentikasi Dua Arah

Mutual TLS (mTLS) memverifikasi kedua arah: server memvalidasi client, dan client memvalidasi server. Hasilnya, hanya client dengan sertifikat dari CA yang kalian percaya bisa terhubung — autentikasi tanpa password, dan sangat sulit dispoofing.

Contoh di PostgreSQL memakai extension sslinfo (untuk inspeksi) dan konfigurasi sertifikat client di sisi aplikasi. Di MySQL, mTLS diaktifkan dengan menerbitkan client cert:

Klien mTLS MySQL
[client]
ssl-ca=/etc/mysql/certs/ca.pem
ssl-cert=/etc/mysql/certs/client-cert.pem
ssl-key=/etc/mysql/certs/client-key.pem

Kapan mTLS dipakai: service-to-service (mikroservis), koneksi aplikasi backend ke database di jaringan zero-trust, dan akses admin. Biayanya manajemen sertifikat (issue, rotate, revoke) — ini pekerjaan yang bisa diotomasi dengan cert-manager atau Vault (episode 19).

Note

mTLS tidak menggantikan otorisasi database (roles/grants dari episode 9) — ia menambah lapisan autentikasi di level transport. Keduanya berjalan bersama: mTLS menjawab "siapa yang boleh masuk jaringan", roles/grants menjawab "siapa yang boleh melakukan apa di dalam". Jangan menukar yang satu untuk yang lain.

Bastion Host: Pintu Masuk Admin yang Terkontrol

Admin tidak boleh masuk database langsung dari internet. Pola standar: bastion host (jump host) — satu mesin yang menjadi satu-satunya pintu masuk, diaudit dan di-monitor.

Akses admin via bastion
Laptop Anda --SSH--> bastion --SSH/tunnel--> DB (subnet private)
     (internet, 22)      (private network, 5432)

Praktik bastion yang baik:

  • Hanya menerima koneksi dari IP/identitas yang diizinkan (dan login via SSO/MFA).
  • Menjadi relay — DB sendiri tetap tidak punya route masuk dari luar.
  • Log semua sesi (auditd, sudo journald); ini sekaligus bahan audit episode 16.
  • Akses database lewat port forwarding:
SSH tunnel ke database
ssh -L 15432:db-private:5432 user@bastion
psql -h 127.0.0.1 -p 15432 -U app_user -d appdb

Sekarang kalian bisa psql ke database privat, tapi tanpa pernah membuka port 5432 ke internet — koneksi berjalan di dalam tunnel SSH.

Checklist Penutup Jaringan

Sebelum menyebut "aman", verifikasi empat hal:

  • ufw status / security group: hanya port yang dibutuhkan, hanya dari sumber yang diizinkan.
  • Database tanpa public IP; akses lewat subnet private + peering/VPN.
  • ssl_min_protocol_version / require_secure_transport aktif; sslmode=verify-full di semua client.
  • Admin hanya lewat bastion; log sesi terekam.

Penutup

Inti yang harus dibawa pulang:

  • Firewall default-deny (ufw/SG): hanya port yang dibutuhkan, hanya dari sumber sah.
  • Private networking: subnet private, tanpa public IP, peering/VPN untuk koneksi lintas VPC/on-prem.
  • TLS benar = versi minimum + verify-full; MySQL require_secure_transport = ON.
  • mTLS untuk service-to-service; bastion host untuk akses admin yang diaudit.

Di episode 19 selanjutnya kita mengunci lapisan terdalam: encryption & key management — enkripsi at rest dan in transit yang menyeluruh, pengelolaan kunci dengan KMS dan Vault, sampai transparent data encryption (TDE) untuk memahami setiap lapis data kita terlindungi kapan pun. Sampai jumpa di episode 19!

Belajar Database Administrator - Network Security & TLS | Belajar Database Administrator