UFW dan IPv6: Celah Terbuka di VPS Anda
Aturan UFW dan cloud firewall bisa hanya melindungi IPv4. Pelajari penyebab service terbuka lewat IPv6 di Ubuntu 24.04 dan cara menutup celahnya.
Jebakan firewall IPv6 dalam satu kalimat
Firewall Anda melindungi IPv4. VPS Anda hampir pasti juga memiliki alamat IPv6 publik, dan banyak service secara default mendengarkan pada alamat tersebut. Jika firewall Anda hanya mencakup IPv4, atau Anda mengandalkan cloud firewall yang hanya memfilter IPv4, semua service tersebut dapat diakses dari seluruh Internet melalui IPv6, sementara sisi IPv4 Anda terlihat terkunci. Anda menguji port dengan curl, melihat koneksi ditolak, lalu merasa aman. Penyerang terhubung ke port yang sama melalui IPv6 dan dapat masuk.
Panduan ini menjelaskan sumber celah tersebut pada VPS Ubuntu 24.04 biasa, cara melihat secara tepat apa yang Anda ekspose, dan cara menutupnya. UFW bukan penyebabnya. Pada instalasi Ubuntu modern, UFW sudah menangani IPv6. Eksposur tersebut berasal dari lapisan di sekitarnya dan dari service yang tidak Anda ketahui sedang mendengarkan.
Mengapa VPS Anda menggunakan IPv6
Saat ini, hampir setiap VPS menyediakan alamat IPv6 publik, sering kali satu /64 penuh, selain alamat IPv4. Periksa VPS Anda:
ip -6 addr show scope global2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
inet6 2001:db8:2a::1/64 scope global2001:db8:2a::1 tersebut dapat dirutekan dari mana saja di Internet, sama seperti alamat IPv4 Anda. Sekarang, lihat layanan yang sedang listen:
sudo ss -tlnpState Recv-Q Local Address:Port Process
LISTEN 0 0.0.0.0:22 sshd
LISTEN 0 [::]:22 sshd
LISTEN 0 127.0.0.1:5432 postgres
LISTEN 0 [::]:8080 docker-proxyPerhatikan kolom Local Address dengan saksama. 0.0.0.0:22 berarti "listen pada setiap alamat IPv4". [::]:22 berarti "listen pada setiap alamat IPv6". 127.0.0.1:5432 terikat ke loopback dan sama sekali tidak publik, sehingga baris Postgres tersebut aman. Kedua baris [::] menerima koneksi dari seluruh Internet melalui IPv6, sedangkan baris docker-proxy adalah jenis layanan yang sering terlupakan setelah Anda menjalankannya.
Sebagian besar daemon secara default terikat ke ::, karena pada Linux, socket :: biasanya juga menerima koneksi IPv4. Jadi, konfigurasi awal server baru adalah "menerima koneksi pada kedua stack, di semua alamat". Firewall Anda adalah satu-satunya lapisan yang menghalangi akses tersebut. Karena itu, firewall yang hanya memeriksa satu stack merupakan masalah serius.
Sumber sebenarnya dari celah IPv6
Ada empat sumber umum. Pada server tertentu, Anda mungkin mengalami salah satunya atau beberapa sekaligus.
1. Firewall cloud yang hanya memfilter IPv4. Banyak firewall dari provider dan produk security group awalnya dibuat untuk IPv4. Produk tersebut mungkin mengabaikan IPv6 atau memerlukan aturan IPv6 terpisah yang harus Anda tambahkan secara manual. Jika satu-satunya firewall Anda adalah firewall pada dashboard provider dan firewall tersebut tidak mencakup IPv6, layanan [::] Anda terbuka, apa pun keterangan tentang port 22 pada IPv4. Baca dokumentasi firewall provider Anda dan cari kata IPv6 secara khusus.
2. iptables yang dibuat manual tanpa ip6tables. Perintah iptables hanya memengaruhi tabel IPv4. IPv6 memiliki perintah yang sepenuhnya terpisah, yaitu ip6tables, dengan aturan terpisah. Jika Anda menulis skrip firewall yang berisi banyak baris iptables -A INPUT ... tetapi tidak pernah menulis aturan ip6tables yang sesuai, firewall IPv6 Anda kosong. Rantai INPUT kosong dengan kebijakan default ACCEPT mengizinkan semua trafik:
sudo ip6tables -L INPUT -nChain INPUT (policy ACCEPT)
target prot opt source destinationOutput tersebut menunjukkan seluruh masalah dalam satu layar. IPv4 difilter, sedangkan IPv6 menerima trafik dari mana saja.
3. Docker menerbitkan port langsung melewati firewall Anda. Saat Anda menjalankan docker run -p 8080:80, Docker menyisipkan aturannya sendiri sebelum aturan UFW. Akibatnya, port yang diterbitkan tetap dapat diakses meskipun ufw status menyatakan bahwa port tersebut ditolak. Pada Docker modern, hal yang sama juga berlaku melalui IPv6. Mengapa Docker melewati UFW dan cara memfilter port container dengan benar menjelaskan mekanisme dan solusinya. Lihat dasar-dasar Docker Compose pada VPS untuk mengetahui cara mendeklarasikan port yang diterbitkan tersebut.
4. UFW dengan IPv6 dinonaktifkan. UFW mendukung IPv6, tetapi hanya jika fitur tersebut diaktifkan. Periksa pengaturannya:
grep IPV6 /etc/default/ufwUbuntu modern menyertakan IPV6=yes, sehingga UFW menerapkan setiap aturan pada kedua stack. Jika Anda melihat IPV6=no, yang berasal dari image lama atau panduan lama, semua aturan UFW yang Anda tulis hanya berlaku untuk IPv4, sedangkan IPv6 tidak dikelola.
Lihat dengan tepat apa yang Anda ekspos
Jangan menebak. Ukur dari luar. Pertama, tampilkan semua listener dan catat setiap listener yang terikat ke :::
sudo ss -tlnp | grep '::'Kemudian, dari mesin lain, sambungkan ke alamat IPv6 publik server dan coba port yang Anda yakini tertutup:
curl -6 -v http://[2001:db8:2a::1]:8080/Jika perintah tersebut mengembalikan halaman atau banner, port itu terbuka pada IPv6. Port yang tertutup mengembalikan Connection refused atau mengalami timeout. Kedua kegagalan tersebut bukan sinyal yang sama, dan perbedaan antara koneksi yang ditolak dan timeout menunjukkan apakah host merespons lalu menolak koneksi Anda, atau firewall membuang paket Anda tanpa respons. Untuk memperoleh gambaran lengkap, pindai alamat IPv6 dengan nmap dari luar server:
nmap -6 2001:db8:2a::1Setiap port yang dilaporkan nmap sebagai terbuka melalui IPv6 adalah port yang dapat dijangkau seluruh Internet, apa pun hasil pemindaian IPv4 Anda. Membandingkan pemindaian IPv4 dan IPv6 secara berdampingan adalah cara tercepat untuk menemukan celah tersebut: apa pun yang terbuka pada -6 tetapi tertutup pada IPv4 adalah service yang belum ditangani firewall Anda.
Tutup celah
Buat UFW mencakup kedua stack, lalu gunakan kebijakan default deny. Konfirmasikan perubahan tersebut, kemudian tetapkan kebijakan default-deny untuk koneksi masuk dan izinkan hanya yang diperlukan:
sudo sed -i 's/^IPV6=no/IPV6=yes/' /etc/default/ufw
sudo ufw default deny incoming
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verboseJika UFW sudah aktif ketika Anda mengubah IPV6=yes, perubahan tersebut baru berlaku setelah Anda menjalankan sudo ufw reload.
ufw status menampilkan setiap aturan dua kali, sekali tanpa akhiran dan sekali dengan akhiran (v6). Jika Anda melihat baris (v6), berarti UFW memfilter IPv6:
22/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)Jika Anda mengelola iptables secara manual, buat aturan yang sama di ip6tables, atau gunakan nftables. Tabel inet pada nftables mencakup IPv4 dan IPv6 dari satu tempat, sehingga menghilangkan seluruh kelas kesalahan ini. Satu tabel filter inet nftables adalah solusi paling rapi jika Anda menulis aturan sendiri. Jika VPS Anda menjalankan Rocky atau AlmaLinux, bukan Ubuntu, tidak ada UFW yang perlu dikonfigurasi. firewalld adalah front end yang Anda kelola sebagai gantinya, dan aturan zonanya diterapkan ke kedua stack sekaligus.
Ikat service yang tidak boleh diakses publik ke loopback. Database, panel admin, atau endpoint metrik biasanya sama sekali tidak memerlukan alamat publik. Ikat service tersebut ke 127.0.0.1 dan ::1 agar sejak awal tidak pernah listen pada alamat yang dapat dirutekan. Untuk Postgres, tetapkan listen_addresses = 'localhost'. Untuk application server, ikat ke 127.0.0.1 dan tempatkan reverse proxy di depannya. Menutup listener lebih efektif daripada memblokirnya dengan firewall karena tidak ada lagi yang dapat diakses.
Jangan mengandalkan UFW untuk melindungi port yang dipublikasikan Docker. Publikasikan port container ke alamat tertentu, bukan ke semua interface, misalnya -p 127.0.0.1:8080:80, agar port tersebut hanya dapat diakses dari host dan dari apa pun yang sengaja Anda teruskan melalui proxy. Jika container memang harus dapat diakses publik, tempatkan di belakang reverse proxy Traefik dan publikasikan hanya proxy tersebut, bukan setiap aplikasi.
Tambahkan aturan IPv6 ke firewall provider Anda, atau akui bahwa firewall tersebut tidak melindungi IPv6 dan biarkan UFW atau nftables pada host menjalankan tugas itu.
Pastikan layanan benar-benar tertutup
Jalankan kembali pengujian dari luar yang sama setelah melakukan perubahan:
curl -6 -v http://[2001:db8:2a::1]:8080/
nmap -6 2001:db8:2a::1Port yang sebelumnya merespons seharusnya sekarang menolak koneksi atau mengalami timeout, dan nmap seharusnya melaporkannya sebagai filtered atau closed. Jika port masih terbuka, periksa kembali empat sumber sebelumnya: service yang masih terikat pada :: tanpa rule di depannya, rule Docker yang berada sebelum UFW, atau firewall provider yang sama sekali tidak memproses IPv6.
Menjauhkan service sensitif sepenuhnya dari Internet publik lebih aman. Tempatkan SSH dan panel admin di balik VPN WireGuard lalu firewall port tersebut agar hanya merespons melalui tunnel. Dengan demikian, masalah paparan IPv6 tidak lagi berlaku untuk service tersebut. Untuk memperlambat pemindaian brute-force yang menargetkan layanan yang tetap publik, tambahkan Fail2ban di depan SSH di atas firewall dengan kebijakan default-deny.
Jika konsep port masih baru bagi Anda, baca terlebih dahulu penjelasan tentang port dan cara service melakukan listen.
FAQ
Apakah UFW memblokir IPv6 secara default?
Pada instalasi Ubuntu 24.04 modern, ya. UFW membaca IPV6=yes dari /etc/default/ufw dan menerapkan setiap aturan ke IPv4 dan IPv6, sedangkan ufw status menampilkan aturan IPv6 dengan suffix (v6). Masalah muncul ketika IPV6=no (dari image lama atau tutorial lama), ketika Anda mengandalkan firewall provider yang hanya memfilter IPv4, atau ketika Docker memublikasikan port melewati UFW. Periksa pengaturan tersebut dengan grep IPV6 /etc/default/ufw.
Bagaimana cara memeriksa apa saja yang diekspos VPS saya melalui IPv6?
Jalankan sudo ss -tlnp dan perhatikan setiap listener yang alamat lokalnya diawali [::], yang berarti listener tersebut menerima koneksi pada semua interface IPv6. Kemudian, dari mesin lain, uji alamat IPv6 publik server secara langsung dengan curl -6 -v http://[YOUR:IPV6::ADDR]:PORT/, atau pindai alamat tersebut dengan nmap -6 YOUR:IPV6::ADDR. Port yang terbuka pada pemindaian IPv6 tetapi tertutup pada IPv4 merupakan celah konfigurasi Anda.
Mengapa saya dapat mengakses port container Docker ketika UFW menyatakan port tersebut diblokir?
Docker memasukkan aturan firewall-nya sendiri sebelum aturan UFW ketika Anda memublikasikan port dengan -p. Karena itu, port yang dipublikasikan tetap dapat diakses meskipun ufw status mencantumkannya sebagai ditolak. Hal ini terjadi pada IPv4, dan juga pada IPv6 jika dukungan IPv6 Docker aktif. Publikasikan port ke alamat tertentu seperti -p 127.0.0.1:8080:80, atau tempatkan container di belakang reverse proxy dan publikasikan hanya proxy tersebut.
Apakah saya tetap memerlukan firewall IPv6 jika firewall IPv4 saya sudah kuat?
Ya. IPv4 dan IPv6 merupakan stack jaringan terpisah dengan aturan firewall yang terpisah. Aturan IPv4 yang sempurna tidak berpengaruh terhadap trafik IPv6. Jika VPS Anda memiliki alamat IPv6 publik, dan hampir semua VPS memilikinya, layanan apa pun yang listening pada :: tetap dapat diakses melalui IPv6 sampai aturan firewall IPv6 atau binding ke loopback menghentikannya.
Bagaimana cara membuat service hanya listen pada IPv4, atau hanya pada localhost?
Atur alamat bind service pada konfigurasinya sendiri. Bind ke 127.0.0.1 untuk loopback IPv4 saja, atau ke 0.0.0.0 untuk semua alamat IPv4 tanpa listener IPv6. Postgres menggunakan listen_addresses, SSH menggunakan ListenAddress, dan sebagian besar server aplikasi menyediakan host atau flag bind. Konfirmasikan hasilnya dengan sudo ss -tlnp dan pastikan Local Address tidak lagi menampilkan [::].