Web UI untuk Manajemen Database

Web UI untuk Manajemen Database

Bitnesia • Aug 27, 2026 92 •EN

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

  1. Perbarui daftar paket, lalu pasang phpMyAdmin.
    sudo apt update
    sudo apt install phpmyadmin
  2. Proses instalasi menampilkan dialog interaktif debconf. Pada pertanyaan pertama, "Web server to reconfigure automatically", jangan pilih apa pun karena pilihan yang tersedia hanya apache2 dan lighttpd, sedangkan web server utama kita sejak Bab 12 adalah Nginx yang tidak ada di daftar tersebut. Tekan Tab lalu Enter untuk melanjutkan tanpa memilih satu pun.
  3. Pada pertanyaan berikutnya, "Configure database for phpmyadmin with dbconfig-common?", setujui dengan menjawab yes. Karena root MySQL maupun MariaDB terkunci lewat auth_socket/unix_socket sejak Bagian 19.2.2 dan 20.1.2, dbconfig-common yang berjalan dengan hak akses root sistem bisa langsung terhubung tanpa perlu password apa pun, lalu otomatis membuat database phpmyadmin beserta satu account internal khusus untuk menyimpan konfigurasi tersebut di /etc/phpmyadmin/config-inc.php.
  4. Pastikan ekstensi PHP yang dibutuhkan sudah aktif. Ekstensi php-mbstring dan driver php-mysql seharusnya 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 dengan ls /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 phpmyadmin untuk 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.php masih 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

  1. Tambahkan record DNS baru untuk subdomain phpmyadmin.example.local, mengikuti pola yang sama seperti subdomain blog pada Bagian 12.2.2 dan app pada Bagian 16.2.2.
    sudo nano /etc/bind/db.example.local
    phpmyadmin	IN	A	192.168.1.20
    Naikkan nomor Serial pada SOA, lalu validasi dan reload.
    sudo named-checkzone example.local /etc/bind/db.example.local
    sudo systemctl reload bind9
  2. Buat file virtual host baru.
    sudo nano /etc/nginx/sites-available/phpmyadmin.example.local
  3. 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;
        }
    }
  4. 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.
    curl -s http://phpmyadmin.example.local | grep -i title
    Output yang sehat menampilkan baris <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.local dari browser di komputer lain pada jaringan lab yang sama.
  • Error 502 Bad Gateway di sini punya penyebab yang sama seperti catatan Bagian 14.3.1: PHP-FPM belum aktif atau path socket salah ketik. Periksa dengan systemctl 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

  1. Buka http://phpmyadmin.example.local lewat browser.
  2. Lakukan login menggunakan username webapp_user beserta 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.
  3. Setelah berhasil masuk, pilih database webapp_db di 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_db dan webapp_user@localhost, identik dengan pengujian lewat command line di Bagian 19.3.2.
  • Pesan #1045 Cannot log in to the MySQL server pada 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 root memiliki password TCP yang dapat digunakan untuk login phpMyAdmin hanya demi kemudahan. Account terpisah dengan privilege terbatas seperti webapp_user tetap 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

  1. 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
  2. Tambahkan repository ke /etc/apt/sources.list.d/. Baris di bawah ini sengaja memakai codename noble (Ubuntu 24.04 LTS), bukan resolute milik 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 dulu https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/dists/ untuk memastikan apakah resolute sudah 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
  3. Perbarui daftar paket, lalu pasang varian web-nya saja.
    sudo apt update
    sudo apt install pgadmin4-web
    Paket ini menarik libapache2-mod-wsgi-py3 sebagai 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 Found saat apt update yang mengarah ke path dists/noble/ pada domain ftp.postgresql.org berarti 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 apache2 yang 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

  1. Ubah port yang didengarkan oleh Apache agar tidak bentrok dengan Nginx. Ganti Listen 80 menjadi port lokal baru.
    sudo nano /etc/apache2/ports.conf
    Listen 127.0.0.1:8082
  2. Samakan virtual host default Apache agar cocok dengan port baru tersebut.
    sudo nano /etc/apache2/sites-available/000-default.conf
    Ubah baris pembuka dari <VirtualHost *:80> menjadi berikut.
    <VirtualHost 127.0.0.1:8082>
  3. Uji konfigurasi, lalu aktifkan dan jalankan Apache.
    sudo apache2ctl configtest
    sudo systemctl enable --now apache2
  4. Jalankan script konfigurasi resmi pgAdmin 4 untuk web mode.
    sudo /usr/pgadmin4/bin/setup-web.sh
    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.
  5. Buat file virtual host Nginx baru untuk meneruskan traffic ke Apache.
    sudo nano /etc/nginx/sites-available/pgadmin.example.local
    server {
        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;
        }
    }
  6. Tambahkan record DNS untuk pgadmin.example.local, mengikuti pola yang sama seperti Bagian 22.1.2.
    sudo nano /etc/bind/db.example.local
    pgadmin	IN	A	192.168.1.20
    sudo named-checkzone example.local /etc/bind/db.example.local
    sudo systemctl reload bind9
  7. 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.
    ss -tlnp | grep 8082
    Output yang benar menampilkan 127.0.0.1:8082, bukan 0.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, karena setup-web.sh secara default memasang aplikasinya di path /pgadmin4, bukan di root domain.
  • Error 502 Bad Gateway dari Nginx berarti Apache belum berjalan atau masih mendengarkan di port lama. Konfirmasikan dengan systemctl status apache2 dan 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

  1. Buka http://pgadmin.example.local/pgadmin4/ lewat browser, lalu login memakai email dan password administrator yang dibuat saat menjalankan setup-web.sh pada Bagian 22.2.2.
  2. Klik kanan pada Servers di panel kiri, pilih Register > Server, lalu isi tab General dengan nama bebas, misalnya Lab PostgreSQL.
  3. Pindah ke tab Connection, isi Host name/address dengan 127.0.0.1, Port dengan 5432, Maintenance database dengan webapp_db, Username dengan webapp_user, dan password yang sudah dibuat di Bagian 18.3.1. Koneksi ini otomatis diizinkan oleh rule host all all 127.0.0.1/32 scram-sha-256 yang sudah ada sejak instalasi awal di Bagian 18.2.1, tanpa perlu menambah rule baru apa pun di pg_hba.conf.
  4. Simpan, lalu buka Lab PostgreSQL > Databases > webapp_db > Schemas > public > Tables untuk memastikan table notes dari Bagian 18.3.2 terlihat dengan isi datanya.

Verifikasi dan Troubleshooting

  • Pesan connection refused saat menyimpan server baru biasanya berarti PostgreSQL tidak berjalan di server yang sama dengan Apache/pgAdmin, periksa lagi dengan pg_lsclusters dari 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 terminal psql.

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

  1. 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
  2. Pasang mongo-express secara global, memakai Node.js dari NodeSource yang sudah terpasang sejak Bab 15.
    sudo npm install -g mongo-express
    Jika instalasi gagal karena konflik peer dependency dengan versi Node.js terbaru, ulangi dengan flag tambahan berikut.
    sudo npm install -g mongo-express --legacy-peer-deps
  3. 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
  4. 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-express yang 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 denied saat npm install -g biasanya berarti perintah dijalankan tanpa sudo, karena direktori global npm hasil instalasi NodeSource dimiliki root.

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

  1. Buat file unit baru.
    sudo nano /etc/systemd/system/mongo-express.service
  2. Isi dengan konfigurasi berikut. Ganti nilai ME_CONFIG_MONGODB_ADMINPASSWORD dan ME_CONFIG_BASICAUTH_PASSWORD dengan password kuat milik sendiri sebelum dipraktikkan di server sungguhan.
    [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.target
    Nilai ME_CONFIG_MONGODB_ADMINUSERNAME dan ME_CONFIG_MONGODB_ADMINPASSWORD mengacu langsung ke account admin yang sudah dibuat di Bagian 21.4.1. Dua variable ME_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 default admin/pass yang 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.
  3. Sesuaikan path pada ExecStart jika hasil which mongo-express di Bagian 22.3.1 tidak persis /usr/bin/mongo-express.
  4. Reload systemd, lalu enable dan jalankan service.
    sudo systemctl daemon-reload
    sudo systemctl enable --now mongo-express.service
  5. Buat file virtual host Nginx untuk meneruskan traffic ke mongo-express.
    sudo nano /etc/nginx/sites-available/mongoexpress.example.local
    server {
        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;
        }
    }
  6. Tambahkan record DNS untuk mongoexpress.example.local.
    sudo nano /etc/bind/db.example.local
    mongoexpress	IN	A	192.168.1.20
    sudo named-checkzone example.local /etc/bind/db.example.local
    sudo systemctl reload bind9
  7. 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.local lewat browser. Browser akan menampilkan dialog login HTTP Basic Auth bawaan mongo-express terlebih dahulu, minta username dan password sesuai ME_CONFIG_BASICAUTH_USERNAME/ME_CONFIG_BASICAUTH_PASSWORD yang sudah diisi di langkah kedua, sebelum masuk ke tampilan utama berisi database webapp_catalog dari Bagian 21.3.2.
  • Error MongoServerError: Authentication failed yang tampil di journalctl menandakan 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

  1. Pasang apache2-utils untuk mendapatkan perintah htpasswd. Paket ini aman dipasang meski Apache sendiri sedang nonaktif, karena htpasswd adalah utilitas standalone yang tidak bergantung pada service Apache berjalan.
    sudo apt install apache2-utils
  2. Buat file password baru untuk Sysadmin pertama, memakai flag -c hanya sekali untuk membuat file baru.
    sudo htpasswd -c /etc/nginx/.htpasswd-dbadmin sysadmin
  3. Buat satu file snippet terpisah agar aturan yang sama bisa dipakai ulang di ketiga virtual host tanpa menulis ulang baris yang identik, mengikuti kebiasaan include yang sudah kita pakai untuk snippets/fastcgi-php.conf sejak Bagian 14.3.1.
    sudo nano /etc/nginx/snippets/dbadmin-restrict.conf
    auth_basic "Area Terbatas - Database Admin";
    auth_basic_user_file /etc/nginx/.htpasswd-dbadmin;
  4. 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 untuk phpmyadmin.example.local.
    sudo nano /etc/nginx/sites-available/phpmyadmin.example.local
    server {
        listen 80;
        server_name phpmyadmin.example.local;
    
        include snippets/dbadmin-restrict.conf;
    
        root /usr/share/phpmyadmin;
        index index.php;
        ...
    }
    Ulangi baris include yang sama persis untuk pgadmin.example.local dan mongoexpress.example.local.
  5. 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

  1. Tambahkan rule allow dan deny ke file snippet yang sama dari Bagian 22.4.1, diletakkan sebelum directive auth_basic.
    sudo nano /etc/nginx/snippets/dbadmin-restrict.conf
    allow 192.168.1.0/24;
    deny all;
    
    auth_basic "Area Terbatas - Database Admin";
    auth_basic_user_file /etc/nginx/.htpasswd-dbadmin;
  2. Uji sintaks, lalu terapkan.
    sudo nginx -t
    sudo systemctl reload nginx

Verifikasi dan Troubleshooting

  • Akses dari IP di luar 192.168.1.0/24 harus langsung ditolak dengan status 403 Forbidden, bahkan sebelum sempat diminta credential HTTP Basic Auth, karena directive allow/deny dievaluasi lebih dulu dibanding auth_basic.
  • Kombinasi allow/deny dan auth_basic ini 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 rule allow.
  • 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.