SSD Nodes Learn
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-07-24

cara tutup lubang keselamatan IPv6 UFW

Periksa jika perkhidmatan VPS anda terdedah melalui IPv6 walaupun IPv4 sudah selamat. Ketahui cara menutup jurang keselamatan pada Ubuntu 24.04 dengan mudah.

Perangkap firewall IPv6 dalam satu ayat

Firewall anda melindungi IPv4. VPS anda hampir pasti mempunyai alamat IPv6 awam, dan banyak perkhidmatan mendengarnya secara lalai. Jika firewall anda hanya merangkumi IPv4, atau jika anda bergantung pada firewall awan yang hanya menapis IPv4, setiap perkhidmatan tersebut boleh dicapai dari seluruh internet melalui IPv6 walaupun bahagian IPv4 anda kelihatan selamat. Anda menguji port dengan curl, melihat sambungan ditolak, dan merasa selamat. Penyerang menyambung ke port yang sama melalui IPv6 dan berjaya masuk.

Panduan ini menunjukkan punca jurang tersebut pada VPS Ubuntu 24.04 biasa, cara melihat apa yang anda dedahkan secara tepat, dan cara menutupnya. UFW bukan puncanya di sini. Pada pemasangan Ubuntu moden, UFW sudah mengendalikan IPv6. Pendedahan berlaku disebabkan oleh lapisan di sekelilingnya, dan daripada perkhidmatan yang anda tidak tahu sedang mendengarnya.

Mengapa VPS anda menggunakan IPv6 pada asalnya

Hampir setiap VPS hari ini disertakan dengan alamat IPv6 awam, selalunya sebuah /64 yang lengkap, bersama dengan alamat IPv4. Semak milik anda:

ip -6 addr show scope global
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
    inet6 2001:db8:2a::1/64 scope global

2001:db8:2a::1 tersebut boleh dihubungkan dari mana-mana sahaja di internet, sama seperti alamat IPv4 anda. Sekarang lihat servis yang sedang aktif:

sudo ss -tlnp
State   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-proxy

Baca lajur Local Address dengan teliti. 0.0.0.0:22 bermaksud "mendengar pada setiap alamat IPv4." [::]:22 bermaksud "mendengar pada setiap alamat IPv6." 127.0.0.1:5432 terikat pada loopback dan tidak bersifat awam, jadi baris Postgres adalah selamat. Dua baris [::] menjawab seluruh internet melalui IPv6, dan baris docker-proxy adalah jenis yang anda terlupa telah dimulakan.

Kebanyakan daemon terikat pada :: secara lalai, kerana pada Linux, soket :: biasanya menerima IPv4 juga. Jadi, tetapan asal pelayan baharu adalah "jawab pada kedua-dua stack, di mana-mana sahaja." Firewall anda adalah satu-satunya penghalang, sebab itu firewall yang hanya melihat satu stack adalah masalah besar.

Punca sebenar jurang IPv6

Terdapat empat punca biasa. Pada sesebuah pelayan, anda mungkin mempunyai satu atau beberapa punca ini secara serentak.

1. Firewall awan yang hanya menapis IPv4. Banyak produk firewall penyedia dan kumpulan keselamatan (security-group) dibina berasaskan IPv4. Ia sama ada mengabaikan IPv6 atau memerlukan peraturan IPv6 berasingan yang perlu ditambah secara manual. Jika satu-satunya firewall anda adalah yang terdapat dalam papan pemuka penyedia dan ia tidak merangkumi IPv6, perkhidmatan [::] anda adalah terbuka tanpa mengira apa yang dinyatakan tentang port 22 pada IPv4. Baca dokumentasi firewall penyedia anda dan cari perkataan IPv6 secara khusus.

2. iptables buatan sendiri tanpa ip6tables. Perintah iptables hanya menyentuh jadual IPv4 sahaja. IPv6 mempunyai perintah yang berbeza sepenuhnya, iaitu ip6tables, dengan peraturan tersendiri. Jika anda menulis skrip firewall yang penuh dengan baris iptables -A INPUT ... dan tidak pernah menulis peraturan ip6tables yang sepadan, firewall IPv6 anda adalah kosong. Rantaian INPUT yang kosong dengan polisi ACCEPT lalai akan membenarkan semua trafik:

sudo ip6tables -L INPUT -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Output tersebut adalah keseluruhan masalah dalam satu skrin. IPv4 ditapis, manakala IPv6 menerima semua trafik.

3. Docker menerbitkan port terus melepasi firewall anda. Apabila anda menjalankan docker run -p 8080:80, Docker memasukkan peraturan sendiri sebelum peraturan UFW. Oleh itu, port yang diterbitkan boleh dicapai walaupun ufw status menyatakan port tersebut dilarang, dan pada Docker moden, perkara yang sama berlaku pada IPv6. Mengapa Docker memintas UFW, dan cara menapis port kontena dengan betul menjelaskan mekanisme dan cara penyelesaiannya. Lihat asas Docker Compose pada VPS untuk cara port yang diterbitkan ini diisytiharkan.

4. UFW dengan IPv6 dimatikan. UFW boleh mengendalikan IPv6, tetapi hanya apabila ia diarahkan. Semak tetapan tersebut:

grep IPV6 /etc/default/ufw

Ubuntu moden menyertakan IPV6=yes, jadi UFW akan melaksanakan setiap peraturan pada kedua-dua stack. Jika anda melihat IPV6=no, daripada imej lama atau panduan lama, setiap peraturan UFW yang anda tulis adalah untuk IPv4 sahaja, dan IPv6 dibiarkan tanpa pengurusan.

Lihat dengan tepat apa yang anda dedahkan

Jangan membuat tekaan. Ukur dari luar. Pertama, senaraikan pendengar (listeners) anda dan catat setiap satu yang terikat pada :::

sudo ss -tlnp | grep '::'

Kemudian, dari mesin yang berbeza, sambung ke alamat IPv6 awam pelayan dan cuba port yang anda percaya telah ditutup:

curl -6 -v http://[2001:db8:2a::1]:8080/

Jika ia memulangkan halaman atau banner, port tersebut terbuka pada IPv6. Port yang ditutup akan memberikan Connection refused atau timeout. Untuk gambaran penuh, imbas alamat IPv6 dengan nmap dari luar pelayan:

nmap -6 2001:db8:2a::1

Setiap port yang dilaporkan nmap sebagai terbuka melalui IPv6 adalah port yang boleh dicapai oleh seluruh internet, tidak kira apa yang ditunjukkan oleh imbasan IPv4 anda. Membandingkan imbasan IPv4 dan IPv6 secara bersebelahan adalah cara terpantas untuk mencari jurang: apa-apa yang terbuka pada -6 tetapi ditutup pada IPv4 adalah perkhidmatan yang terlepas daripada firewall anda.

Tutup jurang

Pastikan UFW melindungi kedua-dua stack, dan tetapkan kepada deny secara lalai. Sahkan pertukaran tersebut, kemudian tetapkan polisi inbound default-deny dan hanya benarkan apa 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 verbose

Jika UFW sudah aktif semasa anda menukar IPV6=yes, perubahan tidak akan berkesan sehingga anda menjalankan sudo ufw reload.

ufw status menyenaraikan setiap peraturan sebanyak dua kali, sekali secara biasa dan sekali dengan akhiran (v6). Apabila anda melihat baris (v6), UFW sedang menapis IPv6:

22/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)

Jika anda mengurus iptables secara manual, salin setiap peraturan ke dalam ip6tables, atau beralih ke nftables, di mana jadual inet merangkumi IPv4 dan IPv6 di satu tempat dan menghapuskan ralat jenis ini. Satu jadual penapis nftables inet adalah penyelesaian paling bersih apabila anda menulis peraturan sendiri.

Ikat perkhidmatan yang tidak mahu didedahkan kepada awam ke loopback. Pangkalan data, panel admin, atau titik akhir metrik jarang memerlukan alamat awam. Ikat ia ke 127.0.0.1 dan ::1 supaya ia tidak mendengar pada alamat yang boleh dihalakan (routable) dari awal lagi. Untuk Postgres, tetapkan listen_addresses = 'localhost'. Untuk pelayan aplikasi, ikat ia ke 127.0.0.1 dan letakkan reverse proxy di hadapannya. Menutup pendengar (listener) adalah lebih baik daripada menggunakan firewall, kerana tiada apa yang boleh dicapai.

Jangan bergantung kepada UFW untuk melindungi port Docker yang diterbitkan. Terbitkan port kontena ke alamat khusus dan bukannya ke semua antara muka, contohnya -p 127.0.0.1:8080:80, supaya port tersebut hanya boleh dicapai dari hos dan apa sahaja yang anda halakan (proxy) secara sengaja kepadanya. Apabila kontena sememangnya perlu bersifat awam, letakkannya di belakang reverse proxy Traefik dan terbitkan hanya proxy tersebut, bukan setiap aplikasi.

Tambah peraturan IPv6 pada firewall pembekal anda, atau terima bahawa ia bukan firewall anda untuk IPv6 dan biarkan UFW atau nftables pada hos melakukan tugas tersebut sebagai ganti.

Sahkan bahawa anda benar-benar telah ditutup

Jalankan semula ujian luaran yang sama selepas perubahan anda:

curl -6 -v http://[2001:db8:2a::1]:8080/
nmap -6 2001:db8:2a::1

Port yang menjawab sebelum ini sepatutnya menolak sambungan atau mengalami masa tamat (time out), dan nmap harus melaporkannya sebagai filtered atau closed. Jika port masih terbuka, semak semula empat sumber di atas: perkhidmatan masih terikat pada :: tanpa sebarang peraturan di hadapannya, peraturan Docker yang berada di hadapan UFW, atau firewall penyedia yang tidak mengesan IPv6 sama sekali.

Menutup perkhidmatan sensitif daripada internet awam sepenuhnya adalah lebih selamat. Letakkan SSH dan panel admin di belakang WireGuard VPN dan tetapkan firewall pada port tersebut supaya ia hanya menjawab melalui terowong (tunnel), maka isu pendedahan IPv6 tidak lagi terpakai untuknya. Untuk melambatkan imbasan brute-force yang menyerang perkhidmatan awam, gunakan Fail2ban di hadapan SSH di atas firewall default-deny.

Jika anda baru mengenali port, apa itu port dan bagaimana perkhidmatan mendengar adalah panduan asas yang perlu dibaca terlebih dahulu.

FAQ

Adakah UFW menyekat IPv6 secara lalai?

Pada pemasangan Ubuntu 24.04 moden, ya. UFW membaca IPV6=yes daripada /etc/default/ufw dan melaksanakan setiap peraturan kepada IPv4 dan IPv6, dan ufw status memaparkan peraturan IPv6 dengan akhiran (v6). Masalah berlaku apabila IPV6=no (daripada imej lama atau tutorial lama), apabila anda bergantung pada tembok api pembekal yang hanya menapis IPv4, atau apabila Docker menerbitkan port melepasi UFW. Semak suis tersebut dengan grep IPV6 /etc/default/ufw.

Bagaimanakah saya menyemak apa yang didedahkan oleh VPS saya pada IPv6?

Jalankan sudo ss -tlnp dan catat setiap pendengar (listener) yang alamat tempatannya bermula dengan [::], yang bermaksud ia menjawab pada setiap antara muka IPv6. Kemudian, dari mesin lain, uji alamat IPv6 awam pelayan secara terus dengan curl -6 -v http://[YOUR:IPV6::ADDR]:PORT/, atau imbas ia dengan nmap -6 YOUR:IPV6::ADDR. Sebarang port yang terbuka pada imbasan IPv6 tetapi tertutup pada IPv4 adalah kelemahan anda.

Mengapakah saya boleh mengakses port bekas (container) Docker saya apabila UFW menyatakan ia disekat?

Docker memasukkan peraturan tembok api sendiri sebelum UFW apabila anda menerbitkan port dengan -p, jadi port yang diterbitkan boleh dicapai walaupun ufw status menyenaraikannya sebagai dilarang. Ini berlaku pada IPv4, dan pada IPv6 juga apabila sokongan IPv6 Docker diaktifkan. Terbitkan ke alamat khusus seperti -p 127.0.0.1:8080:80, atau letakkan bekas di belakang proksi terbalik (reverse proxy) dan terbitkan proksi sahaja.

Adakah saya masih memerlukan tembok api IPv6 jika tembok api IPv4 saya sudah kukuh?

Ya. IPv4 dan IPv6 adalah timbunan rangkaian (network stacks) yang berasingan dengan peraturan tembok api yang berasingan. Set peraturan IPv4 yang sempurna tidak memberi kesan kepada trafik IPv6. Jika VPS anda mempunyai alamat IPv6 awam, dan hampir semua VPS mempunyainya, maka sebarang perkhidmatan yang mendengar pada :: akan kekal boleh dicapai melalui IPv6 sehingga peraturan tembok api IPv6 atau ikatan loopback menghentikannya.

Bagaimanakah saya membuatkan perkhidmatan hanya mendengar pada IPv4, atau hanya pada localhost?

Tetapkan alamat ikatan (bind address) perkhidmatan dalam konfigurasinya sendiri. Ikat ke 127.0.0.1 untuk loopback IPv4 sahaja, atau 0.0.0.0 untuk semua alamat IPv4 tanpa pendengar IPv6. Postgres menggunakan listen_addresses, SSH menggunakan ListenAddress, dan kebanyakan pelayan aplikasi menyediakan flag host atau bind. Sahkan hasilnya dengan sudo ss -tlnp dan pastikan Local Address tidak lagi menunjukkan [::].