Reverse proxy: kenapa port 8080 dan 3000 tidak sepatutnya terbuka, dan semakan 20 minit untuk menutupnya
Pelayan aplikasi tidak dibina untuk bercakap terus dengan internet, dan port 3000, 8000 atau 8080 yang terbuka membuktikannya. Pos ini menunjukkan angka sebenar, konfigurasi asas nginx dan semakan 20 minit pada pelayan sendiri.
Aplikasi web jarang dibina untuk bercakap terus dengan internet. Pelayan Node.js lazimnya mendengar pada port 3000, Gunicorn dan Flask pada 8000, aplikasi Java atau Lucee pada 8080, dan PHP-FPM pada 9000. Port itu disediakan untuk proses dalam mesin yang sama, bukan untuk pelawat dari luar. Begitu aplikasi dibenarkan mendengar pada 0.0.0.0, iaitu semua antara muka rangkaian, sesiapa yang boleh menghantar paket ke alamat IP pelayan boleh mencuba port itu terus: tanpa penyulitan, tanpa sekat kadar, dan tanpa apa-apa penapis di hadapannya.
Reverse proxy membalikkan susunan itu. Hanya satu perisian, sama ada nginx, Apache atau Caddy, yang mendengar pada port 80 dan 443. Aplikasi hanya mendengar pada 127.0.0.1, alamat yang bermaksud mesin ini sahaja. Dokumentasi rasmi nginx menerangkan tiga langkah yang berlaku setiap kali proksi menerima permintaan: ia menghantar permintaan kepada pelayan proksi yang ditetapkan, mengambil jawapan, kemudian menghantar jawapan itu kembali kepada klien. Contoh rasmi untuk aplikasi tempatan ditulis sebagai proxy_pass http://127.0.0.1:8000, dan angka itu sendiri sudah menetapkan bahawa pelayan aplikasi hanya perlu didengar dari mesin yang sama.
Apa yang hilang apabila port aplikasi terbuka
- TLS dan sijil. Laman awam memerlukan https pada port 443. Let's Encrypt mengeluarkan sijil sah 90 hari dan menyarankan pembaharuan setiap 60 hari, dan pada 2 Disember 2025 ia mengumumkan pelan memendekkan jangka hayat sijil kepada 45 hari menjelang Februari 2028. Dengan proksi, hanya satu tempat memegang sijil dan menjadualkan pembaharuannya.
- HSTS, satu baris yang memaksa pelawat kekal pada https. Halaman hstspreload.org meminta max-age=63072000, iaitu dua tahun, bersama includeSubDomains dan preload. MDN menyatakan bahawa senarai preload hanya menerima max-age sekurang-kurangnya 31536000, iaitu satu tahun.
- Had saiz permintaan dan penimbal jawapan. nginx menimbal jawapan daripada pelayan aplikasi; contoh rasmi menggunakan proxy_buffers 16 4k dan proxy_buffer_size 2k. Saiz permintaan dihadkan oleh client_max_body_size, dan nilai lalainya 1m, jadi muat naik yang lebih besar daripada itu ditolak dengan ralat 413 sebelum sempat sampai ke aplikasi.
- Satu titik untuk menutup dan mencatat. Sekatan kadar, penapisan alamat IP dan log akses hanya berguna kalau semua trafik melalui satu pintu. Kalau port 8080 terbuka di samping port 443, penyerang memilih pintu yang tidak tercatat.
- Risiko yang sudah dicari mesin orang lain. Yayasan Shadowserver menyatakan bahawa laporan HTTP mereka menumpukan kelemahan yang boleh melaksanakan kod tanpa pengesahan (pre-auth RCE) pada perkhidmatan HTTP yang terdedah, dan mereka mengimbas setiap alamat IPv4 dengan permintaan GET /.git/config semata-mata untuk mengesan folder .git yang bocor. Halaman laporan itu dikemas kini pada 29 September 2026.
Angka insiden Malaysia, sembilan bulan pertama 2026
Statistik insiden MyCERT bagi Januari hingga September 2026 mencatatkan 7,416 kes. Pecahan angka itu: 6,258 fraud, 256 percubaan pencerobohan, 178 pencerobohan, 168 kod berniat jahat, 391 kandungan berkaitan, 86 spam, 71 laporan kelemahan dan 8 kes penafian perkhidmatan. Jumlah terbesar, fraud, datang daripada laman atau akaun yang disalahgunakan, dan bahagian itu tidak pernah memerlukan kelemahan pelayan; tetapi baki ratusan kes yang menyentuh pencerobohan dan laporan kelemahan biasanya bermula pada satu perkhidmatan yang boleh dicapai dari luar.
Port yang terdedah tidak muncul sebagai kategori berasingan dalam jadual itu. Namun advisori MyCERT menyentuh perisian yang berada di barisan hadapan laman: MA-1444.052026 mengenai Apache HTTP Server pada 13 Mei 2026, dan MA-1438.052026 mengenai cPanel, WHM dan WP Squared dengan CVE-2026-41940 pada 6 Mei 2026. Perbezaan praktikalnya mudah. Kalau perisian itu berdiri di belakang proksi, hanya satu perkhidmatan perlu ditampal, dipantau dan disekat. Kalau setiap aplikasi didedahkan terus, setiap satu menjadi sasaran yang perlu dijaga sendiri, dan satu yang terlupa sudah cukup untuk membuka jalan masuk.
Semakan 20 minit: empat arahan pada pelayan sendiri
# 1. Apa yang sedang mendengar, selain 127.0.0.1?
ss -tlnp | grep -v '127.0.0.1'
# 2. Port aplikasi: pada antara muka mana ia terikat?
ss -tlnp | grep -E '3000|8000|8080|9000'
# 3. Ujian dari mesin LAIN, bukan dari pelayan sendiri
curl -sS -o /dev/null -w '%{http_code}\n' http://ALAMAT-IP-PELAYAN:8080
# 4. Apa yang pelawat lihat pada pintu awam?
curl -sS -I https://laman-awak.my | head -5
Arahan pertama menyenaraikan soket yang sedang mendengar, kecuali yang terikat pada 127.0.0.1. Apa sahaja yang tinggal dan menyebut 0.0.0.0 atau alamat IP awam pelayan itu boleh dicuba dari luar. Arahan ketiga mesti dijalankan dari mesin lain; kalau ia dijalankan pada pelayan sendiri, jawapannya tidak membuktikan apa-apa kerana mesin itu memang boleh menghubungi dirinya. Firewall pula menjadi tali pinggang kedua: benarkan 80, 443 dan port SSH yang digunakan, tolak selebihnya. Dua arahan pertama biasanya mengambil masa kurang daripada satu minit, sementara ujian dari luar dan semakan konfigurasi proksi memakan baki masa.
Konfigurasi asas nginx untuk satu pintu
server {
listen 443 ssl;
server_name laman-awak.my;
ssl_certificate /etc/letsencrypt/live/laman-awak.my/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/laman-awak.my/privkey.pem;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
client_max_body_size 20m;
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
Empat tetapan dalam blok itu yang paling kerap menjimatkan masa. proxy_pass menunjuk ke 127.0.0.1 supaya aplikasi tidak pernah berada pada antara muka awam. proxy_set_header Host $host mengekalkan nama domain yang diminta pelawat, bukan nama hos dalaman, dan itu penting untuk laman yang menjana pautan sendiri. client_max_body_size 20m menaikkan had lalai 1m yang menjadi punca ralat 413 pada muat naik gambar atau fail PDF. add_header Strict-Transport-Security menambah HSTS, tetapi hanya selepas laman benar-benar stabil pada https, kerana baris itu sukar ditarik balik daripada pelayar yang sudah menyimpannya.
Tiga masalah yang muncul selepas port ditutup
- Log aplikasi menunjukkan setiap pelawat sebagai 127.0.0.1. Betulkan dengan proxy_set_header X-Real-IP $remote_addr dan X-Forwarded-For, kemudian pastikan aplikasi benar-benar membaca tajuk itu. Tanpa langkah kedua, penyekatan alamat IP dan analisis log hilang gunanya.
- Gelung ubah hala yang tidak berhenti. Selalunya berlaku apabila aplikasi turut cuba memaksa https, sedangkan ia menerima permintaan dalaman sebagai http. Hantar X-Forwarded-Proto $scheme dan biarkan hanya proksi menguruskan ubah hala.
- Muat naik gagal dengan 413, atau sambungan WebSocket putus setiap beberapa saat. Dua pembetulan: naikkan client_max_body_size mengikut saiz fail sebenar, dan tambah proxy_set_header Upgrade serta Connection "upgrade" untuk aplikasi yang menggunakan WebSocket.
Apa yang proksi tidak selesaikan
Proksi bukan pengganti tampalan. Kelemahan di dalam aplikasi masih boleh dicuba melalui permintaan yang sah, kerana nginx meneruskan permintaan itu apa adanya dan tidak menilai sama ada parameter di dalamnya selamat. Ia juga tidak menghentikan cubaan masuk yang menggunakan kata laluan yang benar, dan ia tidak mengurangkan beban aplikasi kalau sekat kadar tidak dikonfigurasi pada peringkat proksi. Tiga perkara yang proksi memang bantu: menyembunyikan versi perisian dan nombor port aplikasi daripada imbasan automatik, memusatkan penyulitan dan pembaharuan sijil pada satu fail, dan memberi satu tempat untuk membaca log apabila berlaku perkara yang tidak dijangka. Selebihnya, seperti menampal kelemahan dan menjaga pangkalan data, kekal kerja berasingan yang tidak boleh dipindahkan ke proksi.
Apa yang perlu disemak selepas itu
- curl -I https://laman-awak.my memberi jawapan 200, atau 301 ke https yang betul, bukan 502.
- Tajuk Strict-Transport-Security hadir dengan nilai max-age yang awak pilih sendiri.
- Port aplikasi tidak menjawab dari mesin lain, walaupun permintaan diulang tiga kali.
- Log aplikasi menunjukkan alamat IP sebenar pelawat, bukan 127.0.0.1.
- Pembaharuan sijil automatik diuji sekurang-kurangnya sebulan sebelum sijil 90 hari itu tamat.
- Fail konfigurasi proksi disandarkan bersama kod, kerana satu fail yang hilang boleh menutup laman sepenuhnya.
- Port SSH kekal untuk kunci sahaja, bukan kata laluan.
Bila cara ini tidak sesuai
Kalau laman berada pada hosting dikongsi, proksi sudah diuruskan oleh penyedia dan pengguna biasanya tidak boleh mengubahnya; yang tinggal ialah memastikan aplikasi tidak menambah port sendiri di luar kawalan penyedia. Kalau aplikasi perlu diuji terus dari luar untuk masa yang singkat, buka ikatan pada antara muka awam, catat tarikh, dan tutup semula pada hari yang sama. Port ujian yang dibuka sementara dan kemudian terlupa ialah antara punca paling biasa sesuatu perkhidmatan dalaman terdedah berbulan-bulan. Cara yang lebih selamat untuk ujian ialah terowong SSH dari mesin sendiri, dan laluan itu tidak memerlukan port tambahan dibuka kepada dunia.
Halaman ini dicetak tanpa menu, borang langgan dan jalur sisi.
Baca juga di laman ini
- Membaca log nginx tanpa menjadi jurutera Cara membaca access.log dan error.log apabila trafik sudah melalui proksi.
- Keselamatan SSH: lima perubahan kecil pada sshd_config Menutup pintu pentadbir supaya hanya kunci yang berfungsi.
- Hosting dikongsi lawan VPS Beza kawalan konfigurasi antara dua jenis hosting.
- Keselamatan CFML: CVE dan pengukuhan pelayan Langkah pengukuhan untuk pelayan aplikasi CFML.
- Pindah pelayan tanpa waktu henti Susunan kerja apabila proksi dan aplikasi perlu dipindahkan.
Sumber yang disemak
Maklumat dalam tulisan ini disemak dengan sumber di bawah. Bila keadaan berubah (harga, waktu, terma), sumber inilah yang paling tepat - bukan halaman ini.
- NGINX Documentation - NGINX Reverse Proxy
- nginx.org - Module ngx_http_core_module (client_max_body_size, lalai 1m)
- nginx.org - Module ngx_http_proxy_module (proxy_pass, proxy_set_header)
- The Shadowserver Foundation - Vulnerable HTTP Report (dikemas kini 29 September 2026)
- MyCERT - Incident Statistics 2026 (7,416 insiden Januari-September)
- MyCERT Advisory MA-1444.052026 - Apache HTTP Server Multiple Vulnerabilities (13 Mei 2026)
- Let's Encrypt - Decreasing Certificate Lifetimes to 45 Days (2 Disember 2025)
- MDN Web Docs - Strict-Transport-Security header
- HSTS Preload List Submission - syarat penyerahan
Dapat tulisan baharu terus ke e-mel
Sekali sekala sahaja: panduan web, berita AI, dan tempat menarik di Kelantan. Tiada iklan, dan e-mel encik tidak dikongsi dengan sesiapa.