User yang dikelola dengan least privilege masih bisa bocor bila pintu servernya sendiri terbuka lebar: instalasi default yang mendengarkan semua antarmuka jaringan, akun root yang bisa diakses dari mana saja, koneksi plaintext yang bisa disadap, dan variabel lama yang dibiarkan aktif demi kenyamanan. Chapter penutup section ini merangkai pengaturan-pengaturan konfigurasi yang paling menentukan permukaan serangan server MySQL. Kita memeriksa tiap pengaturan secara nyata di server latihan, memahami artinya bagi keamanan, dan menyusun daftar periksa konfigurasi yang bisa dipakai saat meninjau server produksi.
Bind Address dan Permukaan Jaringan #
Secara default, MySQL mendengarkan koneksi pada bind-address tertentu; instalasi paket modern umumnya mengaturnya ke 127.0.0.1 sehingga hanya proses lokal yang bisa terhubung. Kita bisa memeriksa nilai yang sedang berlaku:
SHOW VARIABLES LIKE 'bind_address';Output yang Dihasilkan:
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| bind_address | 127.0.0.1 |
+---------------+-----------+
1 row in set (0.00 sec)Nilai 127.0.0.1 berarti server hanya menerima koneksi dari mesin yang sama — pencari celah dari luar tidak akan pernah sampai ke port MySQL. Ketika aplikasi berjalan di server terpisah, bind-address diubah ke alamat IP internal server database, dan yang penting: bukan 0.0.0.0 yang mendengarkan semua antarmuka. Bila 0.0.0.0 terpaksa dipakai, lapisan berikutnya — firewall dan akun host yang ketat — menjadi penjaga utama. Aturan praktisnya: setiap antarmuka yang mendengarkan adalah pintu yang harus dijaga, jadi buka sesedikit mungkin.
Menutup Akses Root dari Jarak Jauh #
Akun root@localhost hanya bisa dipakai dari mesin server itu sendiri. Bahaya muncul saat seseorang membuat root dengan host wildcard. Kita audit daftar user administratif dan host yang diizinkan:
SELECT user, host, plugin FROM mysql.user ORDER BY user, host;Output yang Dihasilkan:
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+
4 rows in set (0.00 sec)Daftar ini adalah inventaris pintu masuk server. Setiap baris dengan host berupa % berarti akun tersebut bisa datang dari alamat mana pun di jaringan yang dijangkau server. Prinsip yang sehat: akun administratif selalu localhost atau satu alamat IP kantor yang tetap; akun aplikasi boleh lebih longgar host-nya tetapi privilege-nya minimum. Selain itu, perhatikan kolom plugin — seluruh akun sebaiknya memakai caching_sha2_password, bukan mekanisme autentikasi lawas yang penyandian keamanannya lebih lemah.
Memaksa Koneksi Terenkripsi #
Tanpa TLS, kredensial dan data melintas jaringan sebagai teks polos yang bisa disadap di tengah jalan. MySQL mendukung koneksi terenkripsi dan menyediakan variabel untuk memaksa seluruh koneksi memakainya:
SHOW VARIABLES LIKE 'require_secure_transport';Output yang Dihasilkan:
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| require_secure_transport | OFF |
+--------------------------+-------+
1 row in set (0.00 sec)Nilai OFF berarti koneksi tidak terenkripsi masih diterima — wajar untuk server latihan lokal, tetapi berisiko di produksi. Dengan SET PERSIST require_secure_transport = ON, server menolak semua koneksi plaintext mulai saat itu tanpa perlu direstart, dan nilainya tetap bertahan setelah restart. Sebelum mengaktifkannya di produksi, pastikan seluruh klien memang sanggup TLS dengan certificate yang valid; kalau tidak, aplikasi akan terputus semua seketika. Status enkripsi tiap koneksi aktif dapat diperiksa dari performance_schema atau ssl_accepts pada SHOW STATUS di server yang mengaktifkannya.
Meninjau Variabel Berisiko #
Beberapa pengaturan lama terus hidup demi kompatibilitas dan diam-diam membuka celah bila dibiarkan. Tabel berikut merangkum yang paling sering muncul dalam audit keamanan:
| Variabel | Nilai berisiko | Kenapa berisiko | Tindakan |
|---|---|---|---|
local_infile | ON | LOAD DATA LOCAL bisa dipakai membaca file klien oleh server palsu | SET PERSIST local_infile = OFF kecuali benar-benar dipakai |
secure_file_priv | kosong | SELECT ... INTO OUTFILE bisa menulis ke mana pun di disk | Batasi ke direktori khusus |
sql_mode tanpa STRICT | longgar | Data salah diam-diam dipangkas/dinolkan | Pertahankan mode ketat default 8.x |
skip_name_resolve | OFF | Resolusi DNS memperlambat + DNS spoofing host check | Aktifkan dan pakai IP di grant |
Kita periksa dua variabel pertama di server latihan:
SHOW VARIABLES LIKE 'local_infile';
SHOW VARIABLES LIKE 'secure_file_priv';Output yang Dihasilkan:
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| local_infile | OFF |
+---------------+-------+
1 row in set (0.00 sec)
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | NULL |
+------------------+-------+
1 row in set (0.00 sec)Nilai-nilai ini dibaca bersama konteks penerapan: local_infile aktif masih masuk akal untuk pipeline pemuatan data yang terkontrol, dan secure_file_priv yang menunjuk satu direktori adalah praktik baik yang sudah menjadi default di banyak instalasi. Yang penting adalah keputusan sadar — bukan nilai bawaan yang tidak pernah ditinjau.
Prinsip Defense in Depth #
Tidak ada satu pengaturan tunggal yang membuat server aman. Keamanan yang tangguh menumpuk lapisan yang saling menutup celah satu sama lain: jaringan hanya membuka port yang perlu (bind-address dan firewall), transportasi terenkripsi (TLS), autentikasi kuat (plugin modern dan password policy), otorisasi minimum (least privilege dan role), konfigurasi ditinjau (variabel berisiko), dan pemantauan berjalan (slow log, error log, dan audit atas SHOW PROCESSLIST). Penyerang harus menembus semua lapisan itu berurutan; satu kegagalan kita di satu lapisan tidak serta-merta menjadi kebocoran total. Kebalikannya juga benar: satu lapisan yang dibiarkan terbuka — root dengan host %, misalnya — bisa membatalkan kerapian seluruh lapisan lain. Daftar periksa berikut bisa dipakai rutin, misalnya tiap kuartal atau setiap kali server baru disiapkan:
- Baca
bind-addressdan pastikan antarmuka yang mendengarkan memang diperlukan. - Audit
mysql.user: tidak ada akun admin ber-host wildcard, plugin autentikasi modern. - Pastikan
require_secure_transport ONdan seluruh klien sanggup TLS. - Tinjau
local_infile,secure_file_priv, dansql_mode. - Jalankan
SHOW GRANTSuntuk setiap akun aplikasi — hanya privilege yang benar-benar dipakai. - Aktifkan slow query log dan error log, lalu tinjau isinya secara berkala.
Referensi #
- Connection Management — MySQL 8.4 Reference Manual
- Server System Variables — MySQL 8.4 Reference Manual
- Security — MySQL 8.4 Reference Manual
- Server Logs — MySQL 8.4 Reference Manual
Section user management dan keamanan tuntas: user, privilege, role, autentikasi, hingga konfigurasi server yang mengeraskan seluruhnya. Perjalanan berikutnya berpindah ke kursi administrator — section administrasi MySQL, dimulai dari membaca dan mengubah konfigurasi server.