Empat database sudah berjalan di server lab kita sejak Bagian V dimulai: PostgreSQL di Bab 18, MySQL di Bab 19, MariaDB di Bab 20, dan MongoDB di Bab 21. Semuanya dikelola penuh lewat command line, mulai dari psql, mysql/mariadb, sampai mongosh. Cara ini sudah cukup untuk Sysadmin yang terbiasa bekerja di terminal, namun Developer yang hanya perlu memeriksa isi satu tabel atau menambahkan satu index kecil sering merasa command line terlalu lambat untuk tugas sesederhana itu, apalagi jika Developer tersebut baru bergabung dan belum menghafal seluruh sintaks SQL maupun query MongoDB. Kebutuhan itulah yang dipenuhi oleh web UI untuk manajemen database, yaitu aplikasi berbasis browser yang membungkus operasi CRUD, manajemen user, hingga eksekusi query mentah ke dalam antarmuka visual yang lebih ramah digunakan sehari-hari.
Bab ini memasang tiga web UI sekaligus, masing-masing untuk database yang berbeda: phpMyAdmin untuk MySQL/MariaDB, pgAdmin 4 untuk PostgreSQL yang kali ini dijalankan dalam web mode alih-alih aplikasi desktop, dan mongo-express untuk MongoDB yang dipasang lewat npm sesuai kebiasaan Node.js di Bab 15. Ketiganya akan diletakkan di balik virtual host Nginx tersendiri dengan subdomain masing-masing, mengikuti pola penambahan subdomain ke zone example.local yang sudah berulang kali kita praktikkan sejak Bab 12. Bab ini ditutup dengan bagian yang tidak boleh dilewatkan, yaitu menambahkan lapisan reverse proxy dan autentikasi tambahan. Hal ini penting karena ketiga tool ini pada dasarnya merupakan pintu masuk langsung ke seluruh data di server, sehingga menjadi target yang sangat menarik bagi Attacker jika sampai dibiarkan terbuka tanpa pengaman berlapis.
22.1 phpMyAdmin untuk MySQL/MariaDB
phpMyAdmin adalah web UI berbasis PHP untuk MySQL dan MariaDB yang sudah ada sejak akhir tahun 1990-an dan tetap menjadi salah satu tool administrasi database paling banyak dipakai di lapangan, terutama pada lingkungan shared hosting dan panel kontrol seperti cPanel. Karena phpMyAdmin berjalan di atas PHP-FPM yang sudah kita siapkan di Bab 14, instalasinya tidak membutuhkan komponen baru yang berat; kita cukup memanfaatkan ulang infrastruktur yang sudah ada.
22.1.1 Instalasi phpMyAdmin dari Repository Ubuntu
Ubuntu Server menyediakan phpMyAdmin langsung dari repository resminya sebagai paket phpmyadmin, tanpa perlu menambahkan repository pihak ketiga. Paket ini memakai dbconfig-common untuk menyiapkan sendiri database internalnya, tempat menyimpan fitur tambahan seperti bookmark query dan riwayat pencarian.
Langkah Praktik
- Perbarui daftar paket, lalu pasang phpMyAdmin.
sudo apt update sudo apt install phpmyadmin - Proses instalasi menampilkan dialog interaktif debconf. Pada pertanyaan pertama, "Web server to reconfigure automatically", jangan pilih apa pun karena pilihan yang tersedia hanya
apache2danlighttpd, sedangkan web server utama kita sejak Bab 12 adalah Nginx yang tidak ada di daftar tersebut. TekanTablaluEnteruntuk melanjutkan tanpa memilih satu pun. - Pada pertanyaan berikutnya, "Configure database for phpmyadmin with dbconfig-common?", setujui dengan menjawab
yes. KarenarootMySQL maupun MariaDB terkunci lewatauth_socket/unix_socket sejak Bagian 19.2.2 dan 20.1.2,dbconfig-commonyang berjalan dengan hak akses root sistem bisa langsung terhubung tanpa perlu password apa pun, lalu otomatis membuat databasephpmyadminbeserta satu account internal khusus untuk menyimpan konfigurasi tersebut di/etc/phpmyadmin/config-inc.php. - Pastikan ekstensi PHP yang dibutuhkan sudah aktif. Ekstensi
php-mbstringdan driverphp-mysqlseharusnya sudah terpasang sejak Bagian 14.1.2, jadi langkah ini sekadar konfirmasi.php -m | grep -Ei 'mbstring|mysqli'
Verifikasi dan Troubleshooting
- File aplikasi phpMyAdmin seharusnya sudah tersedia di
/usr/share/phpmyadmin. Konfirmasikan denganls /usr/share/phpmyadmin, direktori inilah yang nanti dijadikan document root virtual host Nginx pada Bagian 22.1.2. - Jika dialog debconf pada langkah kedua sempat terlewat karena instalasi berjalan secara non-interaktif, jalankan ulang
sudo dpkg-reconfigure phpmyadminuntuk memicu ulang seluruh pertanyaan tersebut. - Peringatan "The configuration file now needs a secret passphrase (blowfish_secret)" yang kadang muncul di halaman login berarti baris
$cfg['blowfish_secret']di/etc/phpmyadmin/config.inc.phpmasih kosong. Isi dengan string acak sepanjang minimal 32 karakter, lalu simpan ulang.
22.1.2 Virtual Host Nginx dan Integrasi PHP-FPM
Bagian ini menghubungkan phpMyAdmin ke Nginx lewat pola FastCGI yang identik dengan Bagian 14.3.1, hanya saja kali ini document root-nya langsung mengarah ke folder aplikasi phpMyAdmin, bukan folder example.local yang sudah ada.
Langkah Praktik
- Tambahkan record DNS baru untuk subdomain
phpmyadmin.example.local, mengikuti pola yang sama seperti subdomainblogpada Bagian 12.2.2 danapppada Bagian 16.2.2.sudo nano /etc/bind/db.example.local
Naikkan nomor Serial padaphpmyadmin IN A 192.168.1.20SOA, lalu validasi dan reload.sudo named-checkzone example.local /etc/bind/db.example.local sudo systemctl reload bind9 - Buat file virtual host baru.
sudo nano /etc/nginx/sites-available/phpmyadmin.example.local - Isi dengan konfigurasi berikut, memakai ulang socket PHP-FPM yang sama persis dengan Bagian 14.1.1.
server { listen 80; server_name phpmyadmin.example.local; root /usr/share/phpmyadmin; index index.php; location / { try_files $uri $uri/ =404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.4-fpm.sock; } } - Aktifkan virtual host ini, uji sintaks, lalu terapkan.
sudo ln -s /etc/nginx/sites-available/phpmyadmin.example.local /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx
Verifikasi dan Troubleshooting
- Uji reachability dulu lewat curl dari komputer lain di jaringan lab, cukup untuk memastikan Nginx sudah merespons dan meneruskan ke PHP-FPM dengan benar.
Output yang sehat menampilkan bariscurl -s http://phpmyadmin.example.local | grep -i title<title>phpMyAdmin</title>. - Pengujian login sungguhan tetap perlu lewat browser sungguhan, karena phpMyAdmin memakai sesi dan JavaScript yang tidak bisa diwakili curl. Buka
http://phpmyadmin.example.localdari browser di komputer lain pada jaringan lab yang sama. - Error
502 Bad Gatewaydi sini punya penyebab yang sama seperti catatan Bagian 14.3.1: PHP-FPM belum aktif atau path socket salah ketik. Periksa dengansystemctl status php8.4-fpm.service.
22.1.3 Login dan Verifikasi Akses ke MySQL/MariaDB
Sesuai dengan catatan lapangan pada Bagian 19.2.2, account yang mengandalkan auth_socket/unix_socket seperti root tidak bisa digunakan untuk login melalui phpMyAdmin karena koneksinya selalu melalui TCP, bukan Unix socket. Proses login harus menggunakan account yang memiliki password, seperti webapp_user yang sudah dibuat pada Bagian 19.3.2 untuk MySQL atau Bagian 20.3.1 untuk MariaDB.
Langkah Praktik
- Buka
http://phpmyadmin.example.locallewat browser. - Lakukan login menggunakan username
webapp_userbeserta password yang sudah dibuat sendiri pada bab sebelumnya, tergantung pada instance mana yang sedang aktif di server lab ini, baik MySQL dari Bab 19 maupun MariaDB dari Bab 20. - Setelah berhasil masuk, pilih database
webapp_dbdi panel kiri, lalu buka tab SQL dan jalankan query sederhana untuk membuktikan koneksi benar-benar berfungsi.SELECT DATABASE(), CURRENT_USER();
Verifikasi dan Troubleshooting
- Hasil query harus menampilkan
webapp_dbdanwebapp_user@localhost, identik dengan pengujian lewat command line di Bagian 19.3.2. - Pesan
#1045 Cannot log in to the MySQL serverpada halaman login biasanya berarti password salah ketik, bukan masalah konfigurasi phpMyAdmin itu sendiri, karena phpMyAdmin sekadar meneruskan credential apa adanya ke server database. - Catatan dari lapangan: jangan pernah membiarkan account
rootmemiliki password TCP yang dapat digunakan untuk login phpMyAdmin hanya demi kemudahan. Account terpisah dengan privilege terbatas sepertiwebapp_usertetap menjadi pilihan paling aman untuk akses rutin sehari-hari, sesuai dengan prinsip least privilege yang sudah kita terapkan sejak Bab 18.
22.2 pgAdmin 4 untuk PostgreSQL (Web Mode)
pgAdmin 4 adalah tool administrasi resmi yang direkomendasikan oleh komunitas PostgreSQL sendiri, serta tersedia dalam dua mode: desktop mode yang berjalan sebagai aplikasi Electron di laptop Developer, dan web mode yang dipasang di server lalu diakses melalui browser oleh banyak pengguna sekaligus. Bagian ini berfokus pada web mode, karena tujuannya adalah menyediakan akses terpusat ke server PostgreSQL lab tanpa membuat setiap Developer perlu memasang aplikasi desktop terpisah.
22.2.1 Instalasi pgAdmin 4 Web Mode dari Repository Resmi
pgAdmin 4 tidak tersedia di repository resmi Ubuntu, sehingga instalasinya perlu menambahkan repository resmi milik proyek pgAdmin sendiri, mengikuti pola yang sama seperti penambahan repository MongoDB di Bagian 21.2.1.
Langkah Praktik
- Unduh dan import public key resmi pgAdmin.
curl -fsS https://www.pgadmin.org/static/packages_pgadmin_org.pub | \ sudo gpg -o /usr/share/keyrings/packages-pgadmin-org.gpg --dearmor - Tambahkan repository ke
/etc/apt/sources.list.d/. Baris di bawah ini sengaja memakai codenamenoble(Ubuntu 24.04 LTS), bukanresolutemilik Ubuntu 26.04 yang sedang kita pakai, dengan alasan yang persis sama seperti catatan kompatibilitas MongoDB di Bagian 21.5: repository pihak ketiga butuh waktu untuk menyediakan build bagi setiap rilis Ubuntu baru. Periksa duluhttps://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/dists/untuk memastikan apakahresolutesudah tersedia sebelum mengikuti contoh ini apa adanya.echo "deb [signed-by=/usr/share/keyrings/packages-pgadmin-org.gpg] https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/noble pgadmin4 main" | \ sudo tee /etc/apt/sources.list.d/pgadmin4.list - Perbarui daftar paket, lalu pasang varian web-nya saja.
Paket ini menariksudo apt update sudo apt install pgadmin4-weblibapache2-mod-wsgi-py3sebagai dependency, karena pgAdmin 4 web mode berjalan sebagai aplikasi Python WSGI yang dijalankan langsung oleh Apache, bukan oleh Nginx maupun PHP-FPM.
Verifikasi dan Troubleshooting
- Error
404 Not Foundsaatapt updateyang mengarah ke pathdists/noble/pada domainftp.postgresql.orgberarti build untuk codename tersebut sudah dihentikan atau salah ketik, bukan masalah kompatibilitas rilis. Untuk kasus seperti ini periksa kembali daftar codename yang didukung di URL pada langkah kedua. - Paket
apache2yang sejak akhir Bab 14 sengaja dinonaktifkan (disabled, bukan dihapus) akan otomatis ikut ditarik sebagai dependency jika ternyata belum terpasang di server ini.
22.2.2 Menjalankan setup-web.sh dan Reverse Proxy Nginx
pgAdmin 4 web mode membutuhkan Apache agar dapat benar-benar berjalan, sedangkan Nginx masih memegang port 80 dan 443 sebagai web server utama sejak Bab 12. Solusinya adalah menjalankan Apache pada port lokal yang tidak digunakan oleh aplikasi lain, lalu membiarkan Nginx meneruskan traffic ke port tersebut melalui reverse proxy, sesuai dengan pola yang sama persis seperti konsep upstream pada Bagian 16.2.2.
Langkah Praktik
- Ubah port yang didengarkan oleh Apache agar tidak bentrok dengan Nginx. Ganti
Listen 80menjadi port lokal baru.sudo nano /etc/apache2/ports.confListen 127.0.0.1:8082 - Samakan virtual host default Apache agar cocok dengan port baru tersebut.
Ubah baris pembuka darisudo nano /etc/apache2/sites-available/000-default.conf<VirtualHost *:80>menjadi berikut.<VirtualHost 127.0.0.1:8082> - Uji konfigurasi, lalu aktifkan dan jalankan Apache.
sudo apache2ctl configtest sudo systemctl enable --now apache2 - Jalankan script konfigurasi resmi pgAdmin 4 untuk web mode.
Script ini interaktif, menanyakan alamat email dan password untuk akun administrator pertama pgAdmin, lalu menawarkan konfigurasi otomatis untuk Apache. Setujui tawaran konfigurasi Apache tersebut, karena kita sudah menyiapkan Apache khusus untuk keperluan ini.sudo /usr/pgadmin4/bin/setup-web.sh - Buat file virtual host Nginx baru untuk meneruskan traffic ke Apache.
sudo nano /etc/nginx/sites-available/pgadmin.example.localserver { listen 80; server_name pgadmin.example.local; location / { proxy_pass http://127.0.0.1:8082; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } - Tambahkan record DNS untuk
pgadmin.example.local, mengikuti pola yang sama seperti Bagian 22.1.2.sudo nano /etc/bind/db.example.localpgadmin IN A 192.168.1.20sudo named-checkzone example.local /etc/bind/db.example.local sudo systemctl reload bind9 - Aktifkan virtual host, uji sintaks, lalu terapkan.
sudo ln -s /etc/nginx/sites-available/pgadmin.example.local /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx
Verifikasi dan Troubleshooting
- Pastikan Apache benar-benar hanya mendengarkan di loopback, bukan seluruh interface.
Output yang benar menampilkanss -tlnp | grep 8082127.0.0.1:8082, bukan0.0.0.0:8082, karena Apache di sini hanya boleh diakses lewat perantara Nginx, tidak langsung dari jaringan luar. - Akses aplikasi lewat
http://pgadmin.example.local/pgadmin4/, bukan domain tanpa akhiran, karenasetup-web.shsecara default memasang aplikasinya di path/pgadmin4, bukan di root domain. - Error
502 Bad Gatewaydari Nginx berarti Apache belum berjalan atau masih mendengarkan di port lama. Konfirmasikan dengansystemctl status apache2dan ulangi langkah pertama jika perlu.
22.2.3 Login dan Menghubungkan Server PostgreSQL
pgAdmin baru benar-benar berguna setelah didaftarkan ke instance PostgreSQL yang ingin dikelola, karena aplikasi ini pada dasarnya hanya antarmuka, bukan database itu sendiri. Registrasi server dilakukan sekali saja dan tersimpan permanen di akun administrator yang baru dibuat pada Bagian 22.2.2.
Langkah Praktik
- Buka
http://pgadmin.example.local/pgadmin4/lewat browser, lalu login memakai email dan password administrator yang dibuat saat menjalankansetup-web.shpada Bagian 22.2.2. - Klik kanan pada Servers di panel kiri, pilih Register > Server, lalu isi tab General dengan nama bebas, misalnya
Lab PostgreSQL. - Pindah ke tab Connection, isi Host name/address dengan
127.0.0.1, Port dengan5432, Maintenance database denganwebapp_db, Username denganwebapp_user, dan password yang sudah dibuat di Bagian 18.3.1. Koneksi ini otomatis diizinkan oleh rulehost all all 127.0.0.1/32 scram-sha-256yang sudah ada sejak instalasi awal di Bagian 18.2.1, tanpa perlu menambah rule baru apa pun dipg_hba.conf. - Simpan, lalu buka Lab PostgreSQL > Databases > webapp_db > Schemas > public > Tables untuk memastikan table
notesdari Bagian 18.3.2 terlihat dengan isi datanya.
Verifikasi dan Troubleshooting
- Pesan
connection refusedsaat menyimpan server baru biasanya berarti PostgreSQL tidak berjalan di server yang sama dengan Apache/pgAdmin, periksa lagi denganpg_lsclustersdari Bagian 18.1.2. - Pesan
password authentication failed for user "webapp_user"menandakan password salah ketik saat mengisi form koneksi, bukan masalah pgAdmin itu sendiri. - Query tool bawaan pgAdmin (ikon petir di toolbar) bisa langsung dipakai menjalankan SQL mentah seperti
SELECT * FROM notes;, berguna untuk troubleshooting cepat tanpa perlu berpindah ke terminalpsql.
22.3 mongo-express untuk MongoDB
mongo-express adalah web UI berbasis Node.js dan Express untuk MongoDB, dipasang lewat npm alih-alih paket APT karena memang didistribusikan sebagai package Node.js biasa. Berbeda dari phpMyAdmin dan pgAdmin 4 yang aktif dikembangkan komunitas besar, ritme rilis mongo-express jauh lebih lambat dalam beberapa tahun terakhir. Periksa terlebih dahulu versi terbaru yang benar-benar tersedia sebelum melakukan instalasi, serta pertimbangkan bahwa tool ini lebih cocok untuk kebutuhan internal atau lab seperti series ini, bukan sebagai satu-satunya andalan administrasi MongoDB pada lingkungan production skala besar.
22.3.1 Instalasi via npm dan Konfigurasi Environment Variable
Bagian ini memasang mongo-express sebagai package global, mengikuti kebiasaan instalasi tool command line lewat npm install -g yang sudah dikenal di Bab 15, lalu menyiapkan user sistem tersendiri untuk menjalankannya sebagai service.
Langkah Praktik
- Periksa versi terbaru mongo-express yang benar-benar tersedia di registry npm sebelum instalasi, mengingat ritme rilisnya yang lambat seperti disinggung sebelumnya.
npm view mongo-express version - Pasang mongo-express secara global, memakai Node.js dari NodeSource yang sudah terpasang sejak Bab 15.
Jika instalasi gagal karena konflik peer dependency dengan versi Node.js terbaru, ulangi dengan flag tambahan berikut.sudo npm install -g mongo-expresssudo npm install -g mongo-express --legacy-peer-deps - Catat lokasi binary hasil instalasi global ini karena systemd nantinya membutuhkan path lengkap, persis seperti catatan penting pada Bagian 15.4.3 mengenai
ExecStart.which mongo-express - Buat user sistem khusus untuk service ini, mengikuti prinsip least privilege yang sama seperti Bagian 5.2.2 dan Bagian 15.4.3.
sudo useradd --system --no-create-home --shell /usr/sbin/nologin mongoexpress
Verifikasi dan Troubleshooting
- Perintah
which mongo-expressyang sehat mengembalikan path seperti/usr/bin/mongo-express, sesuai lokasi global bin npm hasil instalasi NodeSource. Simpan path ini karena dipakai langsung di Bagian 22.3.2. - Error
EACCES: permission deniedsaatnpm install -gbiasanya berarti perintah dijalankan tanpasudo, karena direktori global npm hasil instalasi NodeSource dimilikiroot.
22.3.2 Service systemd dan Reverse Proxy Nginx
mongo-express dikonfigurasi secara murni melalui environment variable tanpa file konfigurasi terpisah yang perlu diedit, sehingga seluruh pengaturan koneksi ke MongoDB dan kredensial akses cukup dituliskan langsung pada unit file systemd.
Langkah Praktik
- Buat file unit baru.
sudo nano /etc/systemd/system/mongo-express.service - Isi dengan konfigurasi berikut. Ganti nilai
ME_CONFIG_MONGODB_ADMINPASSWORDdanME_CONFIG_BASICAUTH_PASSWORDdengan password kuat milik sendiri sebelum dipraktikkan di server sungguhan.
Nilai[Unit] Description=mongo-express Web UI untuk MongoDB After=network-online.target mongod.service Wants=network-online.target [Service] Type=simple User=mongoexpress Group=mongoexpress Environment=ME_CONFIG_MONGODB_SERVER=127.0.0.1 Environment=ME_CONFIG_MONGODB_PORT=27017 Environment=ME_CONFIG_MONGODB_ADMINUSERNAME=admin Environment=ME_CONFIG_MONGODB_ADMINPASSWORD=AdminMongoAman!2026 Environment=ME_CONFIG_MONGODB_AUTH_DATABASE=admin Environment=ME_CONFIG_MONGODB_ENABLE_ADMIN=true Environment=ME_CONFIG_SITE_HOST=127.0.0.1 Environment=ME_CONFIG_SITE_PORT=8081 Environment=ME_CONFIG_BASICAUTH_USERNAME=sysadmin Environment=ME_CONFIG_BASICAUTH_PASSWORD=UbahDariDefault!2026 ExecStart=/usr/bin/mongo-express Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.targetME_CONFIG_MONGODB_ADMINUSERNAMEdanME_CONFIG_MONGODB_ADMINPASSWORDmengacu langsung ke accountadminyang sudah dibuat di Bagian 21.4.1. Dua variableME_CONFIG_BASICAUTH_*mengatur HTTP Basic Authentication bawaan mongo-express sendiri, lapisan pertama sebelum lapisan tambahan yang akan kita pasang lagi di Bagian 22.4. Catatan dari lapangan yang sangat penting: versi mongo-express lama memakai kredensial basic auth defaultadmin/passyang sudah dikenal luas dan sering dicoba otomatis oleh Attacker yang men-scan internet mencari instance yang lupa diganti, jadi jangan pernah membiarkan nilai bawaan ini apa adanya. - Sesuaikan path pada
ExecStartjika hasilwhich mongo-expressdi Bagian 22.3.1 tidak persis/usr/bin/mongo-express. - Reload systemd, lalu enable dan jalankan service.
sudo systemctl daemon-reload sudo systemctl enable --now mongo-express.service - Buat file virtual host Nginx untuk meneruskan traffic ke mongo-express.
sudo nano /etc/nginx/sites-available/mongoexpress.example.localserver { listen 80; server_name mongoexpress.example.local; location / { proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } - Tambahkan record DNS untuk
mongoexpress.example.local.sudo nano /etc/bind/db.example.localmongoexpress IN A 192.168.1.20sudo named-checkzone example.local /etc/bind/db.example.local sudo systemctl reload bind9 - Aktifkan virtual host, uji sintaks, lalu terapkan.
sudo ln -s /etc/nginx/sites-available/mongoexpress.example.local /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx
Verifikasi dan Troubleshooting
- Periksa log service jika mongo-express gagal start.
sudo journalctl -u mongo-express -n 50 - Buka
http://mongoexpress.example.locallewat browser. Browser akan menampilkan dialog login HTTP Basic Auth bawaan mongo-express terlebih dahulu, minta username dan password sesuaiME_CONFIG_BASICAUTH_USERNAME/ME_CONFIG_BASICAUTH_PASSWORDyang sudah diisi di langkah kedua, sebelum masuk ke tampilan utama berisi databasewebapp_catalogdari Bagian 21.3.2. - Error
MongoServerError: Authentication failedyang tampil dijournalctlmenandakan kombinasi username dan password admin MongoDB salah, cocokkan lagi dengan yang dibuat di Bagian 21.4.1.
22.4 Keamanan Akses: Reverse Proxy dan Autentikasi Tambahan
Ketiga web UI di atas sekarang bisa diakses siapa pun yang tahu subdomain-nya dan berada di jaringan yang bisa menjangkau port 80 server ini. Hal ini merupakan masalah serius. phpMyAdmin, pgAdmin 4, dan mongo-express masing-masing merupakan pintu masuk langsung ke seluruh data di server. Selain itu, riwayat insiden keamanan nyata di internet penuh dengan kasus panel administrasi database yang terekspos tanpa proteksi tambahan lalu dieksploitasi oleh Attacker dalam hitungan jam. Prinsip defense in depth mengharuskan kita menambahkan lapisan proteksi pada level Nginx, terpisah dari autentikasi masing-masing aplikasi, sehingga satu lapisan yang gagal atau ter-bypass tidak langsung membuka akses secara penuh.
22.4.1 Lapisan HTTP Basic Auth dengan htpasswd
Menambahkan HTTP Basic Authentication pada level Nginx berarti Attacker harus melewati dua lapisan credential sebelum sampai ke halaman login aplikasi yang sesungguhnya: satu dari Nginx dan satu lagi dari aplikasi itu sendiri (phpMyAdmin, pgAdmin 4, atau basic auth bawaan mongo-express dari Bagian 22.3.2).
Langkah Praktik
- Pasang
apache2-utilsuntuk mendapatkan perintahhtpasswd. Paket ini aman dipasang meski Apache sendiri sedang nonaktif, karenahtpasswdadalah utilitas standalone yang tidak bergantung pada service Apache berjalan.sudo apt install apache2-utils - Buat file password baru untuk Sysadmin pertama, memakai flag
-chanya sekali untuk membuat file baru.sudo htpasswd -c /etc/nginx/.htpasswd-dbadmin sysadmin - Buat satu file snippet terpisah agar aturan yang sama bisa dipakai ulang di ketiga virtual host tanpa menulis ulang baris yang identik, mengikuti kebiasaan
includeyang sudah kita pakai untuksnippets/fastcgi-php.confsejak Bagian 14.3.1.sudo nano /etc/nginx/snippets/dbadmin-restrict.confauth_basic "Area Terbatas - Database Admin"; auth_basic_user_file /etc/nginx/.htpasswd-dbadmin; - Sertakan snippet ini ke dalam ketiga file virtual host yang sudah dibuat di Bagian 22.1.2, 22.2.2, dan 22.3.2. Tambahkan satu baris berikut di dalam blok
server { }masing-masing file, misalnya untukphpmyadmin.example.local.sudo nano /etc/nginx/sites-available/phpmyadmin.example.local
Ulangi barisserver { listen 80; server_name phpmyadmin.example.local; include snippets/dbadmin-restrict.conf; root /usr/share/phpmyadmin; index index.php; ... }includeyang sama persis untukpgadmin.example.localdanmongoexpress.example.local. - Uji sintaks, lalu terapkan ke ketiga virtual host sekaligus.
sudo nginx -t sudo systemctl reload nginx
Verifikasi dan Troubleshooting
- Akses tanpa credential harus ditolak dengan status
401 Unauthorized.curl -I http://phpmyadmin.example.local - Akses dengan credential yang benar harus berhasil melewati lapisan ini.
curl -I -u sysadmin http://phpmyadmin.example.local - Tambahkan user lain ke file password yang sama tanpa flag
-c, karena flag tersebut akan menimpa seluruh isi file yang sudah ada.sudo htpasswd /etc/nginx/.htpasswd-dbadmin developer
22.4.2 Membatasi Akses Berdasarkan Source IP
Lapisan kedua membatasi akses berdasarkan alamat IP asal dengan mengevaluasi rule secara berurutan dari atas ke bawah, persis seperti cara kerja pg_hba.conf yang sudah dibahas pada Bagian 18.2.1. Perlu dicatat, pembatasan ini tidak bisa dilakukan lewat UFW seperti pada Bagian 18.4.2 atau 19.4.1, karena UFW memfilter berdasarkan port, sedangkan ketiga subdomain ini berbagi port 80 yang sama persis dengan example.local dan domain publik lain yang justru harus tetap terbuka untuk Visitor umum. Nginx yang sudah tahu domain mana yang sedang diminta lewat header Host menjadi satu-satunya lapisan yang bisa membedakan akses per subdomain seperti ini.
Langkah Praktik
- Tambahkan rule
allowdandenyke file snippet yang sama dari Bagian 22.4.1, diletakkan sebelum directiveauth_basic.sudo nano /etc/nginx/snippets/dbadmin-restrict.confallow 192.168.1.0/24; deny all; auth_basic "Area Terbatas - Database Admin"; auth_basic_user_file /etc/nginx/.htpasswd-dbadmin; - Uji sintaks, lalu terapkan.
sudo nginx -t sudo systemctl reload nginx
Verifikasi dan Troubleshooting
- Akses dari IP di luar
192.168.1.0/24harus langsung ditolak dengan status403 Forbidden, bahkan sebelum sempat diminta credential HTTP Basic Auth, karena directiveallow/denydievaluasi lebih dulu dibandingauth_basic. - Kombinasi
allow/denydanauth_basicini adalah dua lapisan yang saling melengkapi, bukan pengganti satu sama lain. IP yang diizinkan tetap wajib memasukkan credential yang benar, sedangkan credential yang benar sekalipun tidak akan berguna jika IP asalnya tidak termasuk dalam ruleallow. - Untuk keamanan yang lebih lengkap, ketiga subdomain ini sebaiknya juga dilindungi TLS memakai self-signed certificate SAN yang sama seperti Bagian 17.3.1, karena traffic HTTP Basic Auth pada dasarnya hanya di-encode lewat Base64, bukan dienkripsi, sehingga tetap bisa dibaca Attacker yang berhasil menyadap jaringan jika belum berjalan di atas HTTPS.
Sampai di sini, server sudah punya tiga web UI database yang berjalan berdampingan: phpMyAdmin untuk MySQL/MariaDB, pgAdmin 4 web mode untuk PostgreSQL, dan mongo-express untuk MongoDB, masing-masing di subdomain terpisah dan dilindungi dua lapisan sekaligus, HTTP Basic Auth serta pembatasan IP, di luar autentikasi bawaan aplikasi itu sendiri. Bab 23 melanjutkan Bagian V dengan topik yang tidak kalah penting, backup dan restore database, mencakup keempat database yang sudah kita pasang sejak Bab 18 sampai Bab 21.

