SSD Nodes Learn Hosting plans →
మార్గదర్శకాలు Matt Connorద్వారా Matt Connor · అప్‌డేట్ చేయబడింది 2026-08-30

Docker UFW ను ఎందుకు దాటుతుంది? పరిష్కారాలు ఏమిటి

Docker ports ను iptables నియమాలతో UFW దాటి publish చేస్తుంది. అందుకే deny చేసిన port 8080 కూడా internet నుంచి స్పందిస్తుంది. కారణం, పనిచేసే పరిష్కారాలు చూడండి.

Docker, UFW ను ఎలా దాటుతుంది

Docker ప్రచురించిన container ports, UFW నిర్వహించే firewall rules ద్వారా వెళ్లవు. అందువల్ల Docker, UFW ను దాటుతుంది. మీరు docker run -p 8080:80 అమలు చేసినప్పుడు, Docker kernel యొక్క nat table లోని PREROUTING chain కు DNAT (destination network address translation) rule ను రాస్తుంది. Kernel packet ఎక్కడికి వెళ్లాలో నిర్ణయించే ముందు, ఆ rule ప్రతి packet యొక్క destination ను container యొక్క private address కు మార్చుతుంది. తరువాత మార్చబడిన packet, Docker నియంత్రించే FORWARD chain ద్వారా container కు forward అవుతుంది. UFW rules INPUT chain లో ఉంటాయి. Packet ఆ chain లోకి ఎప్పుడూ ప్రవేశించదు. అందువల్ల ufw status default deny చూపించినా, sudo ufw deny 8080 విజయాన్ని నివేదించినా, port 8080 మొత్తం internet కు ఇంకా స్పందిస్తుంది.

ఇది Docker bug కాదు. UFW కూడా broken కాలేదు. రెండు tools ఒకే kernel firewall ను configure చేస్తాయి. Packet ప్రయాణంలో Docker rules ముందుగానే పనిచేస్తాయి. అందువల్ల UFW ను అసలు సంప్రదించాల్సిన పరిస్థితి రాదు. ఈ guide bypass ఎలా జరుగుతుందో చూపిస్తుంది, దాని విధానాన్ని వివరిస్తుంది, తరువాత పనిచేసే రెండు పరిష్కారాలను అందిస్తుంది: ports ను 127.0.0.1 పై publish చేయడం, మరియు DOCKER-USER chain లో filtering చేయడం. UFW మీకు కొత్తైతే, ముందుగా UFW firewall ప్రాథమికాల guide తో దాన్ని ఏర్పాటు చేయండి. ఎందుకంటే default-deny firewall, server లోని మిగతా అన్నింటికీ సరైన ప్రాథమిక భద్రతా పొరగా ఉంటుంది.

మీ స్వంత server పై bypass ను చూడండి

Incoming traffic కోసం default deny policyతో UFW activeగా ఉన్న VPS నుంచి ప్రారంభించండి. Published portతో web containerను నడపండి:

sudo ufw status verbose
docker run -d --name web -p 8080:80 nginx:1.29-alpine

ufw status verboseలో Default: deny (incoming), allow (outgoing) కనిపిస్తుంది; port 8080 కోసం ఎలాంటి rule ఉండదు. Firewall స్వయంగా ఇచ్చే report ప్రకారం, ఈ port closedగా ఉంది. ఇప్పుడు server నుంచే కాకుండా, వేరే machine నుంచి పరీక్షించండి:

curl -I http://your-vps-ip:8080/
HTTP/1.1 200 OK

Container స్పందిస్తుంది. Explicit deny ruleను జోడించి, మళ్లీ పరీక్షించండి:

sudo ufw deny 8080/tcp

Deny rule packet ఎప్పుడూ చేరని chainలో ఉన్నందున, port ఇంకా స్పందిస్తుంది. UFW విఫలంకాలేదు. దాన్ని అసలు సంప్రదించలేదు. అందుకే ఈ సమస్యను గుర్తించడం కూడా కష్టం: ఎక్కడా error కనిపించదు, deploy సఫలమవుతుంది, firewall status output కూడా సరిగా lock down చేసిన server‌దానిలానే కనిపిస్తుంది.

యంత్రాంగం: INPUT కంటే ముందు PREROUTING అమలవుతుంది

కెర్నల్ వచ్చే packet ను నిర్ణీత క్రమంలో process చేస్తుంది. మొత్తం సమస్య ఆ క్రమంలోనే ఉంటుంది.

  1. PREROUTING ముందుగా అమలవుతుంది. ఇక్కడి rules packet యొక్క destination ను మార్చవచ్చు. Published port కోసం Docker ఉపయోగించే rule ఇదే చేస్తుంది.
  2. తరువాత routing decision జరుగుతుంది. Host‌కే address చేసిన packet INPUT chain కు వెళ్తుంది. ఇతర machine కు address చేసిన packet FORWARD chain కు వెళ్తుంది.
  3. UFW rules INPUT లో ఉంటాయి. Docker rules FORWARD లో ఉంటాయి.

మీరు ఇప్పుడే ప్రారంభించిన container కోసం Docker rule ను చూడండి:

sudo iptables -t nat -L DOCKER -n
Chain DOCKER (2 references)
target   prot opt source       destination
RETURN   0    --  0.0.0.0/0    0.0.0.0/0
DNAT     6    --  0.0.0.0/0    0.0.0.0/0    tcp dpt:8080 to:172.17.0.2:80

DNAT lineలోనే మొత్తం విషయం ఉంది. Port 8080 కోసం వచ్చే ప్రతి packet యొక్క destination ను 172.17.0.2:80 కు మార్చుతుంది. ఇది Docker private bridge network లోని container address. ఈ మార్పు తరువాత packet host కు address చేయబడదు. అందువల్ల routing decision దాన్ని FORWARD path లోకి పంపుతుంది. అక్కడ Docker తన స్వంత networks లోకి traffic ను అనుమతించే rules ను ఇప్పటికే జోడించింది. మీ deny 8080/tcp rule INPUT లో వేచి ఉంటుంది. కానీ ఆ packet అక్కడికి ఎప్పుడూ రాదు.

Ubuntu 24.04లో iptables command nftables పై front end గా పనిచేస్తుంది. అయితే chain order మరియు ఫలితం ఒకటే. UFW మరియు Docker రెండూ ఒకే kernel packet pipeline లోకి rules రాస్తాయి. Docker entry point ముందుగా ఉంటుంది. ఇది UFWకు మాత్రమే ప్రత్యేకమైన విషయం కాదు: Rocky లేదా AlmaLinux VPSలో firewalld కూడా ఆ pipelineలో అదే స్థాయిలో traffic ను filter చేస్తుంది. అదే DNAT rule దాని filtering ను కూడా పక్కకు తప్పిస్తుంది. అందువల్ల క్రింద పేర్కొన్న fixes అక్కడ కూడా ఉపయోగించాలి.

రోజువారీ పరిష్కారం: ports ను 127.0.0.1 పై publish చేయండి

చాలా containers ను మొదటి నుంచే public గా ఉంచాల్సిన అవసరం లేదు. Database, reverse proxy వెనుక ఉన్న app server, admin panel, metrics endpoint — వీటిలో ఏదీ internet కు నేరుగా స్పందించకూడదు. వాటిని loopback address పై publish చేయండి:

docker run -d --name web -p 127.0.0.1:8080:80 nginx:1.29-alpine

లేదా Compose file లో:

services:
  web:
    image: nginx:1.29-alpine
    ports:
      - "127.0.0.1:8080:80"

ఇది పనిచేయడానికి కారణం, Docker యొక్క DNAT rule ఇప్పుడు 127.0.0.1 కు address చేసిన packets కు మాత్రమే match అవుతుంది. Internet నుంచి వచ్చే packet ఏదీ ఆ destination ను చట్టబద్ధంగా కలిగి ఉండదు. అందువల్ల firewall rule అమలయ్యే ముందే kernel దాన్ని drop చేస్తుంది. ఆ port host నుంచి అందుబాటులో ఉంటుంది. మరే ఇతర స్థానం నుంచి అందుబాటులో ఉండదు. Binding ను నిర్ధారించండి:

sudo ss -tlnp | grep 8080

Output లో 127.0.0.1:8080 ఉండాలి. 0.0.0.0:8080 లేదా [::]:8080 ఉండకూడదు. తరువాత మరొక machine నుంచి curl http://your-vps-ip:8080/ refused అవుతుందో నిర్ధారించండి.

Internet కు అందుబాటులో ఉండాల్సిన services కోసం ports 80 మరియు 443 ను స్వాధీనం చేసుకుని hostname ఆధారంగా routing చేసే ఒక reverse proxy ను నడపండి. మరే ఇతర port ను publish చేయవద్దు. Traefik reverse proxy guide నిర్మించేది ఇదే విధానం. VPS పై Nextcloud వంటి self-hosted app తన proxy ద్వారా తప్ప మరే మార్గంలోనూ అందుబాటులో లేకుండా ఉండటానికి ఇదే విధానం ఉపయోగపడుతుంది. ports: entries ఎలా declare చేయాలి, అలాగే మిగిలిన Compose workflow గురించి Docker Compose basics guide లో వివరించారు.

ప్రతి internal container loopback పై ఉన్నప్పుడు, UFW తన సాధారణ పనికి తిరిగి వస్తుంది: host స్వయంగా అందించే ports ను రక్షించడం. ఇక్కడ ఆ rule set ను రూపొందించి, తరువాత commands ను క్రమంలో అమలు చేయండి:

ToolUFW rule generator

నిజమైన filtering: DOCKER-USER chain

కొన్నిసార్లు ఒక container port network కు published గా ఉండాలి, కానీ దానికి పరిమితులు విధించాలి. ఉదాహరణకు, database replica port ను ఒక office address మాత్రమే చేరుకునేలా చేయవచ్చు. ఇందుకోసం Docker DOCKER-USER chain ను అందిస్తుంది. ఏ container కు వెళ్లే ప్రతి packet అయినా Docker యొక్క స్వంత accept rules కు ముందుగా DOCKER-USER గుండా వెళ్తుంది. Docker ఈ chain లో ఎలాంటి rules రాయదు. ఈ chain మీ rules కోసం ఉంటుంది. Daemon restart అయినా Docker దాని contents ను మార్చదు.

Command అమలు చేయడానికి ముందు ఒక ముఖ్యమైన విషయం ఉంది. Packet DOCKER-USER కు చేరే సమయానికి DNAT rewrite ఇప్పటికే పూర్తయి ఉంటుంది. Packet యొక్క destination port published port (8080) కాదు; container port (80). కాబట్టి --dport 8080 కు సరిపోలే rule ఏ packet ను match చేయదు. Client మొదట ఉపయోగించిన port ను match చేయడం సరైన పద్ధతి. ఆ port ను kernel యొక్క connection tracker గుర్తుంచుకుంటుంది:

sudo iptables -I DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 8080 --ctdir ORIGINAL ! -s 10.0.0.10 -j DROP

దీనిని ఇలా అర్థం చేసుకోవాలి: eth0 ద్వారా ప్రవేశించిన, original destination port 8080 కలిగిన connection కు చెందిన packets లో 10.0.0.10 నుంచి పంపనివన్నీ drop చేయాలి. --ctdir ORIGINAL match ను ఉపయోగించడం వల్ల rule client-to-container దిశకు మాత్రమే పరిమితం అవుతుంది. అందువల్ల reply packets పొరపాటున match కావు. eth0 స్థానంలో మీ public interface పేరు ఇవ్వండి. ip route | grep default దాని పేరును చూపిస్తుంది. మునుపటిలాగే test చేయండి: అనుమతించిన address నుంచి curl విజయవంతమవుతుంది. ఇతర ఏ ప్రదేశం నుంచైనా connection timeout అవుతుంది. ఈ విధంగా connection hang కావడం DROP rule సరిగ్గా పనిచేస్తోందని సూచిస్తుంది. Service వెనుక ఏదీ లేకపోవడం వల్ల port పని చేయకపోవడం దీనికి భిన్నం. Filter చేయబడిన port ను service వినడం లేదనే పరిస్థితి నుంచి గుర్తించడానికి connection refused కావడం మరియు timeout కావడం మధ్య తేడా అత్యంత వేగమైన మార్గం.

iptables command తో జోడించిన rules reboot సమయంలో తొలగిపోతాయి. UFW ఇప్పటికే ఈ firewall ను నిర్వహిస్తున్నందున, వాటిని నిల్వ చేయడానికి సరైన స్థలం /etc/ufw/after.rules. File చివర ఒక block ను జోడించండి:

*filter
:DOCKER-USER - [0:0]
-A DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 8080 --ctdir ORIGINAL ! -s 10.0.0.10 -j DROP
COMMIT

తరువాత sudo ufw reload అమలు చేయండి. ప్రతి reload మరియు ప్రతి boot సమయంలో UFW ఆ file ను మళ్లీ అమలు చేస్తుంది. అందువల్ల container filtering మిగతా firewall rules ఉన్న అదే స్థలంలో ఉంటుంది. ఇది reboot మరియు Docker upgrade రెండింటి తర్వాత కూడా కొనసాగుతుంది.

Docker యొక్క iptables integration ను ఎందుకు disable చేయకూడదు

ఈ సమస్యకు సంబంధించిన పాత సమాధానాల్లో /etc/docker/daemon.json లో { "iptables": false } సెట్ చేయాలని సూచిస్తారు. అలా చేయకండి. Docker యొక్క firewall rules port publishing కంటే చాలా ఎక్కువ పనులు చేస్తాయి. Masquerade rule వల్ల containers host యొక్క address ద్వారా outbound internet access పొందుతాయి. ఈ integration ను disable చేస్తే containers images ను pull చేయలేవు, package mirrors ను చేరుకోలేవు, అలాగే ఏ external API (application programming interface) ను call చేయలేవు. -p పనిచేయడానికి DNAT rules అవసరం. అందువల్ల published ports పూర్తిగా పనిచేయడం ఆగిపోతుంది. వేర్వేరు Compose networks ను పరస్పరం వేరుగా ఉంచే isolation rules కూడా తొలగిపోతాయి. ఈ bypass ను పరిష్కరించడానికి container networking ను విచ్ఛిన్నం చేయాల్సి వస్తుంది. ఆ rules అన్నింటినీ మీరు స్వయంగా రాసి, manual గా నిర్వహించాల్సి ఉంటుంది. Docker యొక్క స్వంత documentation ప్రకారం, ఈ setting ను అలా చేయాలనుకునే వారికోసమే ఉద్దేశించారు. ఎవరికీ ఈ switch అవసరం లేకుండా ఉండేందుకే DOCKER-USER chain ఉంది.

అదే సమస్యలోని IPv6 భాగం

ముందుగా IPv6లో published port ఎలా కనిపిస్తుందో చూడండి:

sudo ss -tlnp | grep 8080

Docker Engine 27 నుంచి Docker డిఫాల్ట్‌గా ip6tables ను నిర్వహిస్తుంది. IPv6 ప్రారంభించబడిన Docker network లో published port కు IPv6 tables లో కూడా అదే DNAT విధానం వర్తిస్తుంది. అందువల్ల అదే bypass అక్కడ కూడా ఉంటుంది, అదే పరిష్కారం వర్తిస్తుంది: ip6tables లో కూడా DOCKER-USER chain ఉంటుంది. కాబట్టి మీ rule ను sudo ip6tables -I DOCKER-USER ... తో mirror చేసి, మీ server యొక్క public IPv6 address కు curl పంపడం ద్వారా బయట నుంచి పరీక్షించండి. ఉదాహరణకు curl -6 http://[2001:db8:2a::1]:8080/.

IPv6 లేని network లో IPv6 clients ను docker-proxy నిర్వహిస్తుంది. ఇది సాధారణ user-space process. ఇది [::]:8080 పై listen చేసి, traffic ను IPv4 ద్వారా container లోకి forward చేస్తుంది. Host process కు వెళ్లే traffic INPUT గుండా వెళుతుంది. కాబట్టి UFW ఆ మార్గాన్ని filter చేయగలదు. అయితే UFW IPv6 ను నిర్వహిస్తున్నప్పుడు మాత్రమే ఇది సాధ్యమవుతుంది. UFW IPv6 ను నిర్వహిస్తుందా, అలాగే VPS లో IPv6 gap ఏర్పడే ఇతర మార్గాలు ఏమిటి అనే విషయం UFW మరియు IPv6 guide లో వివరించబడింది.

Loopback పై publishing చేస్తే ఈ మొత్తం ప్రశ్న తప్పించుకోవచ్చు: -p 127.0.0.1:8080:80 కేవలం IPv4 loopback కు bind అవుతుంది. అందువల్ల IPv6 listener ఉండదు. బయట నుంచి ఏ network stack ద్వారానూ చేరుకోగల endpoint ఉండదు.

బలంగా పనిచేసే నమూనా

  • ప్రతి అంతర్గత port ను 127.0.0.1 పై publish చేయండి. అందువల్ల అది మొదటి నుంచే బయటికి expose కాదు.
  • public వైపు port 80 మరియు 443 ను స్వాధీనం చేసుకునే ఒకే reverse proxy కి అప్పగించండి.
  • host కోసం UFW default deny విధానాన్ని కొనసాగించండి. SSH మరియు proxy ports కు మాత్రమే అనుమతి ఇవ్వండి.
  • వాస్తవంగా public గా ఉండాల్సిన container ports ను DOCKER-USER లో filter చేయండి. ఈ నియమాలను అసలు destination port ఆధారంగా match చేసి, /etc/ufw/after.rules లో persist చేయండి.
  • Docker యొక్క iptables integration ను ఆన్‌లో ఉంచండి.

ఒక్కసారి దీన్ని ఏర్పాటు చేస్తే అనుకోని exposure ఉండదు: ufw status host ను వివరిస్తుంది, DOCKER-USER containers ను వివరిస్తుంది. ఏదీ పొరపాటున publish కాదు. మీరు తరువాత టైప్ చేసే docker run -p మీరు ఉద్దేశించినదానినే ఖచ్చితంగా expose చేస్తుంది.

FAQ

UFW portను block చేసినా Docker containerను ఎందుకు చేరుకోగలుగుతున్నాను?

ఎందుకంటే Docker PREROUTING chainలో DNAT rule ద్వారా portను publish చేస్తుంది. ఏ filtering జరగకముందే ఈ rule packet destinationను container addressకు మార్చుతుంది. ఆ తర్వాత packet FORWARD pathలో ప్రయాణిస్తుంది. UFW rules INPUTలో ఉంటాయి, కానీ packet ఆ chainలోకి ఎప్పుడూ ప్రవేశించదు. Firewallను అసలు సంప్రదించకపోవడం వల్ల published container portsపై దాని deny rules ప్రభావం చూపవు.

Docker published portsను UFW ద్వారా ఎలా block చేయాలి?

UFW స్వయంగా దీన్ని చేయలేరు. కారణం, దాని rules తప్పు chainలో ఉన్నాయి. Portను publish చేయకుండా ఆపండి. దాన్ని 127.0.0.1:8080:80గా publish చేస్తే host మాత్రమే దాన్ని చేరుకోగలదు. ప్రత్యామ్నాయంగా, అసలు destination portను conntrack ద్వారా సరిపోల్చే iptables ruleతో DOCKER-USER chainలో filtering చేయండి. Rebootలు మరియు ufw reload తర్వాత కూడా rule కొనసాగాలంటే దాన్ని /etc/ufw/after.rulesలో persist చేయండి.

Docker daemon.jsonలో "iptables": false సెట్ చేయాలా?

వద్దు. ఆ setting Dockerకు సంబంధించిన అన్ని firewall మరియు NAT rulesను తొలగిస్తుంది. దాంతో bypass సమస్యకన్నా చాలా ఎక్కువ కార్యాచరణ దెబ్బతింటుంది. masquerade rule తొలగిపోవడం వల్ల containersకు outbound internet access ఉండదు. DNAT rules తొలగిపోవడం వల్ల published ports పనిచేయవు. బదులుగా loopback publishing మరియు DOCKER-USER chainను ఉపయోగించండి. ఇవి container networkingను దెబ్బతీయకుండా exposure సమస్యను పరిష్కరిస్తాయి.

IPv6లో కూడా Docker UFWను bypass చేస్తుందా?

Docker Engine 27 మరియు తదుపరి versionsలో ip6tables management defaultగా enabled ఉంటుంది. అందువల్ల IPv6-enabled Docker networkపై publish చేసిన port IPv4లోలాగే UFWను దాటే విధంగా rewrite అవుతుంది. అదే DOCKER-USER ruleను ip6tablesతో mirror చేయాలి. IPv6 లేని networksలో docker-proxy process [::]పై listen చేస్తుంది. ఆ traffic INPUT ద్వారా వెళ్తుంది. UFW IPv6ను manage చేస్తే అక్కడ దాన్ని filter చేయగలదు. 127.0.0.1పై publishing చేస్తే రెండు సందర్భాలనూ నివారించవచ్చు. కారణం, IPv6పై ఏదీ listen చేయదు.