SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-29

Cara Tutup Port IPv6 Terbuka pada VPS Ubuntu

Ramai pengguna VPS tidak sedar servis mereka terdedah melalui IPv6 walaupun UFW aktif. Ketahui punca sebenar pendedahan ini dan cara mengunci konfigurasi IPv6 anda.

Perangkap firewall IPv6 dalam satu ayat

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

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

Mengapa VPS anda mempunyai IPv6 sejak awal lagi

Hampir setiap VPS hari ini dibekalkan dengan alamat IPv6 awam, selalunya satu /64 penuh, di samping 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 dihalakan dari mana-mana sahaja di internet, sama seperti alamat IPv4 anda. Sekarang lihat apa yang sedang mendengar (listening):

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 "dengar pada setiap alamat IPv4." [::]:22 bermaksud "dengar pada setiap alamat IPv6." 127.0.0.1:5432 terikat pada loopback dan tidak bersifat awam sama sekali, jadi baris Postgres adalah selamat. Dua baris [::] menjawab seluruh internet melalui IPv6, dan baris docker-proxy adalah jenis yang anda terlupa anda telah mulakan.

Kebanyakan daemon terikat pada :: secara lalai, kerana pada Linux, soket :: biasanya menerima IPv4 juga. Jadi, pendirian lalai bagi pelayan baharu ialah "menjawab pada kedua-dua stack, di mana-mana sahaja." Firewall anda adalah satu-satunya perkara yang menghalang perkara itu, itulah sebabnya firewall yang hanya melihat satu stack merupakan masalah sebenar.

Dari mana sebenarnya jurang IPv6 berpunca

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

1. Firewall awan yang hanya menapis IPv4. Banyak produk firewall dan security-group pembekal berkembang berasaskan IPv4 dan sama ada mengabaikan IPv6 atau memerlukan peraturan IPv6 berasingan yang perlu anda tambah secara manual. Jika satu-satunya firewall anda ialah firewall pada papan pemuka pembekal dan ia tidak melindungi IPv6, servis [::] anda terdedah tidak kira apa yang dinyatakan mengenai port 22 pada IPv4. Baca dokumentasi firewall pembekal anda dan cari perkataan IPv6 secara khusus.

2. iptables yang ditulis sendiri tanpa ip6tables. Perintah iptables hanya menyentuh jadual IPv4. IPv6 mempunyai perintah yang berasingan sepenuhnya, 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 kosong, dan rantaian INPUT yang kosong dengan polisi lalai ACCEPT membenarkan segala-galanya:

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

Output tersebut adalah perangkap utama yang dapat dilihat pada satu skrin. IPv4 ditapis, manakala IPv6 menerima trafik daripada seluruh dunia.

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

4. UFW dengan IPv6 dimatikan. UFW memang mengendalikan IPv6, tetapi hanya apabila ia diarahkan untuk berbuat demikian. Semak suis tersebut:

grep IPV6 /etc/default/ufw

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

Lihat dengan tepat apa yang anda dedahkan

Jangan meneka. Ukur ia dari luar. Mula-mula, senaraikan pendengar anda dan catatkan setiap satu yang terikat pada :::

sudo ss -tlnp | grep '::'

Kemudian, dari mesin yang berbeza, sambungkan ke alamat IPv6 awam pelayan dan cuba port yang anda percaya tertutup:

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

Jika ia memaparkan halaman atau sepanduk, port tersebut terbuka pada IPv6. Port yang tertutup akan memberikan anda Connection refused atau tamat masa (timeout). Kedua-dua kegagalan ini bukanlah isyarat yang sama, dan perbezaan antara ditolak dan tamat masa memberitahu anda sama ada hos menjawab dan menolak anda atau firewall menggugurkan paket anda secara senyap. Untuk gambaran penuh, imbas alamat IPv6 dengan nmap dari luar pelayan:

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

Setiap port yang dilaporkan terbuka oleh nmap melalui IPv6 ialah 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 tertutup pada IPv4 ialah servis yang terlepas daripada firewall anda.

Tutup jurang tersebut

Pastikan UFW meliputi kedua-dua stack, dan tetapkan dasar lalai kepada deny. Sahkan penukaran tersebut, kemudian tetapkan dasar inbound default-deny dan benarkan hanya trafik 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 tersebut tidak akan berkuat kuasa sehingga anda menjalankan sudo ufw reload.

ufw status menyenaraikan setiap peraturan sebanyak dua kali, sekali dalam bentuk 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 menguruskan iptables secara manual, cerminkan setiap peraturan dalam ip6tables, atau beralih kepada nftables, yang mana jadual inet miliknya meliputi IPv4 dan IPv6 di satu tempat dan menghapuskan keseluruhan kelas kesilapan ini. Jadual penapis inet nftables tunggal merupakan penyelesaian paling kemas apabila anda menulis peraturan sendiri. Jika VPS anda menjalankan Rocky atau AlmaLinux dan bukannya Ubuntu, tiada UFW untuk dikonfigurasikan dan firewalld ialah front end yang anda uruskan sebaliknya, yang menggunakan peraturan zonnya kepada kedua-dua stack serentak.

Bind servis yang anda tidak mahu didedahkan kepada umum kepada loopback. Pangkalan data, panel admin atau titik akhir metrik jarang sekali memerlukan alamat awam. Bind servis tersebut kepada 127.0.0.1 dan ::1 supaya ia tidak mendengar pada alamat yang boleh dihalakan sejak awal lagi. Untuk Postgres, tetapkan listen_addresses = 'localhost'. Untuk pelayan aplikasi, bind ia kepada 127.0.0.1 dan letakkan reverse proxy di hadapan. Menutup listener adalah lebih baik daripada memfirewall-kannya, kerana dengan cara itu tiada apa yang boleh dicapai.

Jangan percaya UFW untuk mengawal port yang diterbitkan oleh Docker. Terbitkan port kontena kepada alamat tertentu dan bukannya setiap antara muka, contohnya -p 127.0.0.1:8080:80, supaya port tersebut hanya boleh dicapai daripada hos dan apa sahaja yang anda proksikan kepadanya secara sengaja. Apabila sesuatu kontena benar-benar perlu menjadi awam, letakkannya di belakang reverse proxy Traefik dan terbitkan hanya proksi tersebut, bukan setiap aplikasi.

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

Sahkan port benar-benar ditutup

Jalankan ujian luaran yang sama sekali lagi selepas anda membuat perubahan:

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

Port yang menjawab sebelum ini kini sepatutnya menolak sambungan atau tamat masa, dan nmap sepatutnya melaporkan status sebagai filtered atau closed. Jika port masih terbuka, semak semula empat punca di atas: servis yang masih terikat pada :: tanpa peraturan di hadapannya, peraturan Docker yang berada di hadapan UFW, atau firewall penyedia yang tidak mengesan IPv6 sama sekali.

Menjauhkan servis sensitif daripada internet awam sepenuhnya adalah langkah yang lebih kukuh. Letakkan SSH dan panel admin di sebalik WireGuard VPN dan tetapkan firewall pada port tersebut supaya ia hanya menjawab melalui tunnel, dan isu pendedahan IPv6 tidak lagi terpakai kepada servis tersebut. Untuk melambatkan imbasan brute-force yang menyasarkan apa sahaja yang kekal awam, lapiskan Fail2ban di hadapan SSH di atas firewall dengan polisi default-deny.

Jika konsep port masih baharu bagi anda, apakah itu port dan bagaimana servis 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 menggunakan setiap peraturan pada IPv4 dan IPv6, dan ufw status memaparkan peraturan IPv6 dengan akhiran (v6). Perangkap berlaku apabila IPV6=no (daripada imej lama atau tutorial lama), apabila anda bergantung pada firewall penyedia yang hanya menapis IPv4, atau apabila Docker menerbitkan port melepasi UFW. Semak suis tersebut dengan grep IPV6 /etc/default/ufw.

Bagaimanakah cara saya menyemak perkara yang didedahkan oleh VPS saya pada IPv6?

Jalankan sudo ss -tlnp dan perhatikan setiap pendengar yang alamat tempatannya bermula dengan [::], yang bermaksud ia menjawab pada setiap antara muka IPv6. Kemudian, daripada mesin yang berbeza, uji alamat IPv6 awam pelayan secara terus dengan curl -6 -v http://[YOUR:IPV6::ADDR]:PORT/, atau imbasnya dengan nmap -6 YOUR:IPV6::ADDR. Mana-mana port yang terbuka pada imbasan IPv6 tetapi tertutup pada IPv4 adalah kelemahan anda.

Mengapakah saya boleh mencapai port bekas Docker saya sedangkan UFW menyatakan ia disekat?

Docker memasukkan peraturan firewallnya sendiri sebelum peraturan UFW apabila anda menerbitkan port dengan -p, jadi port yang diterbitkan boleh dicapai walaupun ufw status menyenaraikannya sebagai dinafikan. Ini berlaku pada IPv4, dan juga pada IPv6 apabila sokongan IPv6 Docker dihidupkan. Terbitkan pada alamat tertentu seperti -p 127.0.0.1:8080:80, atau letakkan bekas di belakang reverse proxy dan terbitkan hanya proksi tersebut.

Adakah saya masih memerlukan firewall IPv6 jika firewall IPv4 saya kukuh?

Ya. IPv4 dan IPv6 ialah tindanan rangkaian yang berasingan dengan peraturan firewall yang berasingan. Set peraturan IPv4 yang sempurna tidak memberi kesan kepada trafik IPv6. Jika VPS anda mempunyai alamat IPv6 awam, dan hampir semua mempunyainya, maka mana-mana servis yang mendengar pada :: kekal boleh dicapai melalui IPv6 sehingga peraturan firewall IPv6 atau pengikatan loopback menghentikannya.

Bagaimanakah cara saya membuat servis mendengar pada IPv4 sahaja, atau pada localhost sahaja?

Tetapkan alamat ikat (bind address) servis dalam konfigurasinya sendiri. Ikat pada 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 mendedahkan flag host atau bind. Sahkan keputusan dengan sudo ss -tlnp dan pastikan Local Address tidak lagi menunjukkan [::].