SSD Nodes Learn Hosting plans →
Mga Gabay Matt ConnorNi Matt Connor · Na-update 2026-08-31

UFW at IPv6: Paano Isara ang Bukas na VPS

Maaaring IPv4 lang ang saklaw ng UFW o cloud firewall. Alamin kung bakit exposed ang VPS sa IPv6 at paano isara ang mga serbisyong bukas sa buong internet.

Ang patibong sa IPv6 firewall sa isang pangungusap

Pinoprotektahan ng firewall mo ang IPv4. Halos tiyak na mayroon ding public IPv6 address ang VPS mo, at maraming serbisyo ang nakikinig dito bilang default. Kung IPv4 lamang ang saklaw ng firewall mo, o umaasa ka sa cloud firewall na IPv4 lamang ang sine-filter, maa-access ang bawat serbisyong iyon mula sa buong internet sa pamamagitan ng IPv6 kahit mukhang mahigpit na naka-lock down ang IPv4 side mo. Sinubukan mo ang isang port gamit ang curl, nakakita ka ng refused connection, at inakala mong ligtas ka. Kumokonekta ang attacker sa parehong port sa pamamagitan ng IPv6 at nakakapasok.

Ipinapakita ng gabay na ito kung saan nagmumula ang gap na iyon sa isang karaniwang Ubuntu 24.04 VPS, kung paano eksaktong makita ang mga inilalantad mong serbisyo, at kung paano ito isara. Hindi ang UFW ang problema rito. Sa modernong Ubuntu installation, awtomatikong hinahawakan na ng UFW ang IPv6. Nagmumula ang exposure sa mga layer sa paligid nito at sa mga serbisyong hindi mo alam na nakikinig.

Bakit IPv6 ang gamit ng iyong VPS

Halos lahat ng VPS ngayon ay may public IPv6 address, kadalasan ay isang buong /64, kasama ng IPv4 address nito. Suriin ang sa iyo:

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

Ang 2001:db8:2a::1 na iyon ay routable mula sa kahit saan sa internet, gaya mismo ng iyong IPv4 address. Tingnan naman kung ano ang nakikinig:

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

Basahing mabuti ang column na Local Address. Ang 0.0.0.0:22 ay nangangahulugang “makinig sa bawat IPv4 address.” Ang [::]:22 ay nangangahulugang “makinig sa bawat IPv6 address.” Ang 127.0.0.1:5432 ay naka-bind sa loopback at hindi talaga public, kaya ligtas ang linya ng Postgres. Ang dalawang linya ng [::] ay sumasagot sa buong internet sa pamamagitan ng IPv6, at ang docker-proxy ay ang uri ng service na madaling makalimutang sinimulan mo.

Karamihan sa daemon ay naka-bind sa :: bilang default, dahil sa Linux, karaniwang tumatanggap din ng IPv4 ang :: socket. Kaya ang default na configuration ng bagong server ay “sumagot sa parehong stack, kahit saan.” Ang firewall lang ang humaharang bago makarating doon ang traffic. Kaya seryosong problema ang firewall na isang stack lang ang nakikita.

Saan talaga nagmumula ang IPv6 gap

May apat na karaniwang pinagmumulan. Sa isang server, maaaring isa lang dito o ilan ang sabay-sabay na umiiral.

1. Cloud firewall na IPv4 lang ang bina-filter. Maraming provider firewall at security-group product ang orihinal na ginawa para sa IPv4. Maaaring hindi nila pansinin ang IPv6, o kailangan mong manu-manong magdagdag ng hiwalay na IPv6 rules. Kung ang tanging firewall mo ay ang nasa provider dashboard at hindi nito sinasaklaw ang IPv6, bukas ang iyong [::] services kahit ano pa ang nakasaad nito tungkol sa port 22 sa IPv4. Basahin ang firewall documentation ng provider at partikular na hanapin ang salitang IPv6.

2. Sariling iptables configuration na walang ip6tables. Ang iptables command ay IPv4 tables lang ang ina-access. May hiwalay na command ang IPv6, ang ip6tables, at sarili rin nitong mga rule. Kung gumawa ka ng firewall script na puno ng mga iptables -A INPUT ... line ngunit hindi gumawa ng katumbas na ip6tables rules, walang laman ang iyong IPv6 firewall. Kapag walang laman ang INPUT chain at default ACCEPT ang policy, pinapayagan ang lahat:

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

Ipinapakita ng output na iyon ang buong problema sa iisang screen. Naka-filter ang IPv4, ngunit tinatanggap ng IPv6 ang traffic mula sa kahit saan.

3. Direktang pag-publish ng Docker ng mga port lampas sa iyong firewall. Kapag nagpatakbo ka ng docker run -p 8080:80, naglalagay ang Docker ng sarili nitong rules bago ang rules ng UFW. Dahil dito, maa-access ang isang published port kahit sinasabi ng ufw status na denied ang port na iyon. Sa mga modernong bersyon ng Docker, pareho rin ito sa IPv6. Ipinaliliwanag ng Bakit nilalampasan ng Docker ang UFW at kung paano wastong i-filter ang mga port ng container ang mekanismo at mga solusyon. Tingnan ang mga pangunahing kaalaman sa Docker Compose sa isang VPS para malaman kung paano dine-declare ang mga published port na ito.

4. Naka-off ang IPv6 sa UFW. Sinusuportahan ng UFW ang IPv6, ngunit gagana lamang ito kapag naka-enable. Suriin ang setting:

grep IPV6 /etc/default/ufw

Kasama sa mga modernong bersyon ng Ubuntu ang IPV6=yes, kaya inilalapat ng UFW ang bawat rule sa parehong stack. Kung makita mo ang IPV6=no, mula sa lumang image o lumang guide, IPv4 lang ang saklaw ng lahat ng UFW rule na isinulat mo, at hindi napapamahalaan ang IPv6.

Tingnan nang eksakto kung ano ang inilalantad mo

Huwag manghula. Sukatin ito mula sa labas. Ilista muna ang mga listener at tandaan ang bawat naka-bind sa :::

sudo ss -tlnp | grep '::'

Pagkatapos, mula sa ibang machine, kumonekta sa public IPv6 address ng server at subukan ang port na inaakala mong sarado:

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

Kung nagbalik ito ng page o banner, bukas ang port sa IPv6. Ang saradong port ay nagbibigay ng Connection refused o timeout. Hindi pareho ang signal ng dalawang failure na ito, at sinasabi sa iyo ng pagkakaiba ng refused at timed out kung sumagot ang host at tinanggihan ka nito o tahimik na ibinagsak ng firewall ang packet mo. Para sa kumpletong larawan, i-scan ang IPv6 address gamit ang nmap mula sa labas ng server:

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

Ang bawat port na iniulat ng nmap na bukas sa IPv6 ay port na maaabot ng buong internet, anuman ang ipinakita ng IPv4 scan mo. Ang paghahambing ng IPv4 at IPv6 scan nang magkatabi ang pinakamabilis na paraan upang makita ang puwang: anumang bukas sa -6 ngunit sarado sa IPv4 ay serbisyong hindi saklaw ng firewall mo.

Isara ang puwang

Gawing saklaw ng UFW ang parehong stack, at itakda ang default na pagtanggi. Kumpirmahin ang switch, pagkatapos ay magtakda ng default-deny inbound policy at payagan lamang ang kailangan mo:

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

Kung aktibo na ang UFW nang i-enable mo ang IPV6=yes, hindi magkakabisa ang pagbabago hanggang patakbuhin mo ang sudo ufw reload.

Inililista ng ufw status ang bawat rule nang dalawang beses: una sa karaniwang anyo at ikalawa na may suffix na (v6). Kapag nakita mo ang mga linyang (v6), nagfi-filter ang UFW ng IPv6:

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

Kung mano-mano mong pinamamahalaan ang iptables, itugma ang bawat rule sa ip6tables, o lumipat sa nftables, na may mga inet table na sumasaklaw sa IPv4 at IPv6 sa iisang lugar at nag-aalis sa buong uri ng pagkakamaling ito. Pinakamalinis na solusyon ang isang nftables inet filter table kapag ikaw mismo ang nagsusulat ng mga rule. Kung Rocky o AlmaLinux sa halip na Ubuntu ang pinapatakbo ng iyong VPS, walang UFW na iko-configure at firewalld ang front end na sa halip ay pamamahalaan mo, na sabay na nag-aapply ng mga zone rule nito sa parehong stack.

I-bind ang mga service na ayaw mong gawing public sa loopback. Karaniwang hindi naman kailangan ng database, admin panel, o metrics endpoint ng public address. I-bind ito sa 127.0.0.1 at ::1 upang hindi ito kailanman makinig sa routable address. Para sa Postgres, itakda ang listen_addresses = 'localhost'. Para sa app server, i-bind ito sa 127.0.0.1 at maglagay ng reverse proxy sa harap nito. Mas mabuti ang pagsasara ng listener kaysa paglalagay rito ng firewall rule, dahil wala nang maaabot.

Huwag umasa sa UFW para protektahan ang mga port na na-publish ng Docker. I-publish ang mga port ng container sa isang partikular na address sa halip na sa lahat ng interface, halimbawa -p 127.0.0.1:8080:80, upang maabot lamang ang port mula sa host at sa anumang sadyang ipinapadaan mo rito sa pamamagitan ng proxy. Kapag kailangang maging public ang isang container, ilagay ito sa likod ng Traefik reverse proxy at ang proxy lamang ang i-publish, hindi ang bawat app.

Magdagdag ng mga IPv6 rule sa firewall ng iyong provider, o tanggapin na hindi ito ang firewall mo para sa IPv6 at hayaan ang UFW o nftables sa host ang humawak sa gawaing iyon sa halip.

Tiyaking talagang sarado na

Ulitin ang parehong external test pagkatapos ng iyong mga pagbabago:

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

Ang port na sumagot dati ay dapat nang tumanggi sa koneksyon o mag-time out, at dapat iulat ng nmap na filtered o closed ito. Kung bukas pa rin ang isang port, balikan ang apat na source sa itaas: isang service na nakabind pa rin sa :: na walang rule sa unahan nito, isang Docker rule na nauuna sa UFW, o isang provider firewall na hindi kailanman nakakita ng IPv6.

Mas ligtas kung hindi talaga ilalantad sa public internet ang mga sensitibong service. Ilagay ang SSH at admin panel sa likod ng WireGuard VPN at i-firewall ang mga port nito para sa tunnel lamang sila sumagot. Sa ganitong paraan, hindi na naaangkop sa mga ito ang tanong tungkol sa IPv6 exposure. Para mapabagal ang brute-force scan na tumatama sa anumang nananatiling public, idagdag ang Fail2ban sa harap ng SSH bilang karagdagang layer sa ibabaw ng default-deny firewall.

Kung bago pa sa iyo ang mga port, basahin muna ang kung ano ang mga port at paano nakikinig ang mga service.

FAQ

Naka-block ba ng UFW ang IPv6 bilang default?

Sa modernong Ubuntu 24.04 install, oo. Binabasa ng UFW ang IPV6=yes mula sa /etc/default/ufw at inilalapat ang bawat rule sa IPv4 at IPv6. Ipinapakita naman ng ufw status ang mga IPv6 rule na may suffix na (v6). Nagkakaroon ng problema kapag IPV6=no (mula sa lumang image o lumang tutorial), kapag umaasa ka sa provider firewall na IPv4 lamang ang hina-handle, o kapag nag-publish ang Docker ng port na lumalampas sa UFW. Suriin ang switch gamit ang grep IPV6 /etc/default/ufw.

Paano ko malalaman kung ano ang inilalantad ng aking VPS sa IPv6?

Patakbuhin ang sudo ss -tlnp at itala ang bawat listener na ang local address ay nagsisimula sa [::]. Ibig sabihin nito, tumatanggap ito ng koneksyon sa lahat ng IPv6 interface. Pagkatapos, mula sa ibang machine, direktang i-test ang public IPv6 address ng server gamit ang curl -6 -v http://[YOUR:IPV6::ADDR]:PORT/, o i-scan ito gamit ang nmap -6 YOUR:IPV6::ADDR. Ang anumang port na bukas sa IPv6 scan ngunit sarado sa IPv4 ang puwang sa configuration.

Bakit naa-access ko ang port ng Docker container kahit sinasabi ng UFW na naka-block ito?

Inilalagay ng Docker ang sarili nitong firewall rule bago ang mga rule ng UFW kapag nag-publish ka ng port gamit ang -p. Dahil dito, naa-access ang published port kahit inililista ito ng ufw status bilang denied. Nangyayari ito sa IPv4, at pati sa IPv6 kapag naka-enable ang IPv6 support ng Docker. Mag-publish sa isang partikular na address gaya ng -p 127.0.0.1:8080:80, o ilagay ang container sa likod ng reverse proxy at ang proxy lamang ang i-publish.

Kailangan ko pa rin ba ng IPv6 firewall kung maayos ang aking IPv4 firewall?

Oo. Magkahiwalay na network stack ang IPv4 at IPv6, at magkahiwalay din ang kanilang firewall rule. Walang epekto sa IPv6 traffic ang perpektong set ng IPv4 rule. Kung may public IPv6 address ang iyong VPS, at halos lahat ay mayroon nito, mananatiling naa-access sa IPv6 ang anumang serbisyong nakikinig sa :: hanggang mapigilan ito ng IPv6 firewall rule o loopback binding.

Paano ko itatakda ang isang serbisyo na IPv4 lamang ang pakinggan nito, o localhost lamang?

Itakda ang bind address ng serbisyo sa sarili nitong config. I-bind ito sa 127.0.0.1 para sa IPv4 loopback lamang, o sa 0.0.0.0 para sa lahat ng IPv4 address na walang IPv6 listener. Gumagamit ang Postgres ng listen_addresses, gumagamit ang SSH ng ListenAddress, at karamihan ng app server ay may host o bind flag. Kumpirmahin ang resulta gamit ang sudo ss -tlnp at tiyaking hindi na ipinapakita ng Local Address ang [::].