Cara Mengamankan IPv6 di UFW VPS
Celah keamanan muncul jika firewall hanya memfilter IPv4 sementara layanan tetap terbuka di IPv6. Pelajari cara menutup celah pada VPS Ubuntu 24.04 Anda.
Jebakan firewall IPv6 dalam satu kalimat
Firewall Anda melindungi IPv4. VPS Anda hampir pasti memiliki alamat IPv6 publik, dan banyak layanan mendengarkan (listening) pada alamat tersebut secara default. Jika firewall Anda hanya mencakup IPv4, atau jika Anda mengandalkan firewall cloud yang hanya memfilter IPv4, maka setiap layanan tersebut dapat diakses dari seluruh internet melalui IPv6, sementara sisi IPv4 Anda terlihat aman. Anda menguji sebuah port dengan curl, melihat koneksi ditolak, dan merasa aman. Penyerang terhubung ke port yang sama melalui IPv6 dan berhasil masuk.
Panduan ini menunjukkan dari mana celah tersebut berasal pada VPS Ubuntu 24.04 standar, cara melihat secara tepat apa yang Anda ekspos, dan cara menutupnya. UFW bukan penyebab masalah ini. Pada instalasi Ubuntu modern, UFW sudah menangani IPv6. Eksposur tersebut berasal dari lapisan di sekitarnya, dan dari layanan yang tidak Anda ketahui sedang berjalan.
Mengapa VPS Anda menggunakan IPv6
Hampir setiap VPS saat ini dilengkapi dengan alamat IPv6 publik, sering kali berupa sebuah /64, di samping alamat IPv4 miliknya. Periksa milik 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 diakses dari mana saja di internet, sama seperti alamat IPv4 Anda. Sekarang lihat layanan yang sedang berjalan:
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 teliti. 0.0.0.0:22 berarti "mendengarkan pada setiap alamat IPv4." [::]:22 berarti "mendengarkan pada setiap alamat IPv6." 127.0.0.1:5432 terikat pada loopback dan tidak bersifat publik, sehingga baris Postgres aman. Dua baris [::] menanggapi seluruh internet melalui IPv6, dan baris docker-proxy adalah jenis yang sering terlupakan setelah dijalankan.
Sebagian besar daemon terikat pada :: secara default, karena pada Linux socket :: biasanya menerima IPv4 juga. Jadi, konfigurasi default server baru adalah "menjawab pada kedua stack, di mana saja." Firewall Anda adalah satu-satunya penghalang, itulah sebabnya firewall yang hanya memantau satu stack akan menjadi masalah serius.
Penyebab utama celah IPv6
Ada empat sumber umum. Pada satu server, Anda mungkin memiliki satu atau beberapa penyebab tersebut sekaligus.
1. Firewall cloud yang hanya memfilter IPv4. Banyak firewall penyedia layanan dan produk security-group dikembangkan untuk IPv4, sehingga mereka mengabaikan IPv6 atau memerlukan aturan IPv6 terpisah yang harus Anda tambahkan secara manual. Jika satu-satunya firewall Anda adalah firewall di dashboard penyedia dan tidak mencakup IPv6, layanan [::] Anda terbuka terlepas dari apa yang tertulis mengenai port 22 pada IPv4. Baca dokumentasi firewall penyedia Anda dan cari kata IPv6 secara spesifik.
2. Konfigurasi iptables manual tanpa ip6tables. Perintah iptables hanya memodifikasi tabel IPv4. IPv6 memiliki perintah yang sepenuhnya terpisah, yaitu ip6tables, dengan aturan terpisah pula. Jika Anda menulis skrip firewall yang penuh dengan baris iptables -A INPUT ... tanpa menulis aturan ip6tables yang sesuai, firewall IPv6 Anda akan kosong. Rantai INPUT yang kosong dengan kebijakan default ACCEPT akan mengizinkan semua koneksi:
sudo ip6tables -L INPUT -nChain INPUT (policy ACCEPT)
target prot opt source destinationOutput tersebut menunjukkan seluruh masalah dalam satu layar. IPv4 terfilter, sedangkan IPv6 menerima semua koneksi.
3. Docker mempublikasikan port melewati firewall Anda. Saat Anda menjalankan docker run -p 8080:80, Docker menyisipkan aturannya sendiri sebelum aturan UFW. Hal ini membuat port yang dipublikasikan tetap dapat diakses meskipun ufw status menyatakan port tersebut ditolak. Pada Docker modern, hal yang sama berlaku untuk IPv6. Mengapa Docker melewati UFW, dan cara memfilter port kontainer dengan benar menjelaskan mekanisme dan solusinya. Lihat dasar-dasar Docker Compose pada VPS untuk mengetahui cara deklarasi port yang dipublikasikan ini.
4. UFW dengan IPv6 dinonaktifkan. UFW dapat menangani IPv6, tetapi hanya jika diinstruksikan. Periksa pengaturannya:
grep IPV6 /etc/default/ufwUbuntu modern menyertakan IPV6=yes, sehingga UFW menerapkan setiap aturan ke kedua stack. Jika Anda melihat IPV6=no, yang berasal dari image lama atau panduan lama, setiap aturan UFW yang Anda tulis hanya berlaku untuk IPv4, dan IPv6 tidak terkelola.
Lihat apa yang Anda ekspos secara tepat
Jangan menebak. Lakukan pengukuran dari luar. Pertama, daftar semua listener Anda dan catat setiap listener yang terikat pada :::
sudo ss -tlnp | grep '::'Kemudian, dari mesin yang berbeda, hubungkan ke alamat IPv6 publik server dan coba port yang Anda anggap tertutup:
curl -6 -v http://[2001:db8:2a::1]:8080/Jika perintah tersebut mengembalikan halaman atau banner, berarti port tersebut terbuka pada IPv6. Port yang tertutup akan memberikan hasil Connection refused atau timeout. Untuk gambaran lengkap, lakukan pemindaian alamat IPv6 menggunakan nmap dari luar server:
nmap -6 2001:db8:2a::1Setiap port yang dilaporkan nmap sebagai terbuka melalui IPv6 adalah port yang dapat dijangkau oleh seluruh internet, terlepas dari hasil pemindaian IPv4 Anda. Membandingkan pemindaian IPv4 dan IPv6 secara berdampingan adalah cara tercepat untuk menemukan celah: apa pun yang terbuka pada -6 tetapi tertutup pada IPv4 adalah layanan yang terlewatkan oleh firewall Anda.
Close the gap
Buat UFW mencakup kedua stack, dan gunakan default deny. Konfirmasi perubahan tersebut, lalu atur kebijakan default-deny untuk inbound dan hanya izinkan apa yang Anda butuhkan:
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 saat Anda mengubah IPV6=yes, perubahan tidak akan berlaku sampai Anda menjalankan sudo ufw reload.
ufw status mencantumkan setiap aturan dua kali, satu dalam bentuk biasa dan satu lagi dengan akhiran (v6). Jika Anda melihat baris (v6), UFW sedang memfilter IPv6:
22/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)Jika Anda mengelola iptables secara manual, salin setiap aturan ke ip6tables, atau beralihlah ke nftables, yang tabel inet miliknya mencakup IPv4 dan IPv6 di satu tempat dan menghilangkan jenis kesalahan ini. Satu tabel filter nftables inet adalah solusi terbersih saat Anda menulis aturan sendiri.
Hubungkan layanan yang tidak ingin Anda publikasikan ke loopback. Database, panel admin, atau endpoint metrik jarang membutuhkan alamat publik. Hubungkan ke 127.0.0.1 dan ::1 agar layanan tersebut tidak mendengarkan pada alamat yang dapat dirutekan sejak awal. Untuk Postgres, atur listen_addresses = 'localhost'. Untuk server aplikasi, hubungkan ke 127.0.0.1 dan gunakan reverse proxy di depannya. Menutup listener lebih baik daripada menggunakan firewall, karena tidak akan ada koneksi yang bisa menjangkau layanan tersebut.
Jangan mengandalkan UFW untuk menjaga port Docker yang dipublikasikan. Publikasikan port kontainer ke alamat spesifik alih-alih ke semua interface, misalnya -p 127.0.0.1:8080:80, sehingga port tersebut hanya dapat dijangkau dari host dan apa pun yang Anda proxy secara sengaja. Ketika kontainer memang harus publik, letakkan di belakang reverse proxy Traefik dan publikasikan hanya proxy tersebut, bukan setiap aplikasi.
Tambahkan aturan IPv6 pada firewall penyedia Anda, atau terima bahwa itu bukan firewall Anda untuk IPv6 dan biarkan UFW atau nftables pada host yang melakukan tugas tersebut.
Verifikasi bahwa Anda benar-benar telah menutup akses
Jalankan kembali pengujian eksternal 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 harus melaporkan status filtered atau closed. Jika port masih terbuka, periksa kembali empat sumber di atas: layanan masih terikat pada :: tanpa aturan firewall, aturan Docker yang berada di depan UFW, atau firewall penyedia layanan yang tidak mendeteksi IPv6 sama sekali.
Menjauhkan layanan sensitif sepenuhnya dari internet publik adalah langkah yang lebih aman. Gunakan WireGuard VPN untuk SSH dan panel admin dan pasang firewall pada port tersebut agar hanya merespons melalui tunnel, sehingga masalah paparan IPv6 tidak lagi berlaku bagi layanan tersebut. Untuk memperlambat pemindaian brute-force pada layanan yang tetap publik, gunakan Fail2ban di depan SSH di atas firewall dengan kebijakan default-deny.
Jika Anda baru mengenal port, apa itu port dan cara layanan mendengarkan adalah panduan dasar yang harus dibaca terlebih dahulu.
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, dan ufw status menampilkan aturan IPv6 dengan akhiran (v6). Masalah muncul saat IPV6=no (dari image lama atau tutorial lama), saat Anda mengandalkan firewall penyedia yang hanya memfilter IPv4, atau saat Docker mempublikasikan port melewati UFW. Periksa pengaturan tersebut dengan grep IPV6 /etc/default/ufw.
Bagaimana cara memeriksa apa yang diekspos VPS saya pada IPv6?
Jalankan sudo ss -tlnp dan catat setiap listener yang alamat lokalnya dimulai dengan [::], yang berarti ia merespons pada setiap antarmuka IPv6. Kemudian, dari mesin lain, uji alamat IPv6 publik server secara langsung dengan curl -6 -v http://[YOUR:IPV6::ADDR]:PORT/, atau pindai dengan nmap -6 YOUR:IPV6::ADDR. Setiap port yang terbuka pada pemindaian IPv6 tetapi tertutup pada IPv4 adalah celah keamanan Anda.
Mengapa saya bisa mengakses port kontainer Docker saya padahal UFW menyatakan port tersebut diblokir?
Docker menyisipkan aturan firewall miliknya sendiri sebelum aturan UFW saat Anda mempublikasikan port dengan -p, sehingga port yang dipublikasikan tetap dapat diakses meskipun ufw status mencatatnya sebagai ditolak. Hal ini terjadi pada IPv4, dan juga pada IPv6 jika dukungan IPv6 Docker aktif. Publikasikan ke alamat spesifik seperti -p 127.0.0.1:8080:80, atau letakkan kontainer di belakang reverse proxy dan hanya publikasikan proxy tersebut.
Apakah saya masih butuh firewall IPv6 jika firewall IPv4 saya sudah aman?
Ya. IPv4 dan IPv6 adalah tumpukan jaringan terpisah dengan aturan firewall yang terpisah. Kumpulan aturan IPv4 yang sempurna tidak berpengaruh pada lalu lintas IPv6. Jika VPS Anda memiliki alamat IPv6 publik, dan hampir semua VPS memilikinya, maka layanan apa pun yang mendengarkan pada :: tetap dapat diakses melalui IPv6 sampai aturan firewall IPv6 atau pengikatan loopback menghentikannya.
Bagaimana cara membuat layanan hanya mendengarkan pada IPv4, atau hanya pada localhost?
Atur alamat bind layanan tersebut di dalam konfigurasinya sendiri. Bind ke 127.0.0.1 untuk hanya loopback IPv4, atau 0.0.0.0 untuk semua alamat IPv4 tanpa listener IPv6. Postgres menggunakan listen_addresses, SSH menggunakan ListenAddress, dan sebagian besar server aplikasi menyediakan flag host atau bind. Konfirmasi hasilnya dengan sudo ss -tlnp dan pastikan Local Address tidak lagi menampilkan [::].