I have a host which runs a few docker's containers.
This host has a few network interfaces, my goal is make some exposed ports from containers accessible only by certain interfaces, and prevent access from others.
I would like to use host's iptables for that.
But its imposible to do simply with:
iptables -I INPUT -i vlan2 --dport 80 -j DROP
because packets are forwarded by prerouting.
iptables -t nat -L PREROUTING 2
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- anywhere anywhere tcp dpt:mysql to:172.17.0.2:33066
DNAT tcp -- anywhere anywhere tcp dpt:http to:172.17.0.4:80
There are two exposed ports 80 and 3306 to different containers, and I want to make it inaccessible from interface vlan2
After I added this:
iptables -I FORWARD -i vlan2 -p tcp --dport 80 -j REJECT
Web server stopped to work, but
iptables -I FORWARD -i vlan2 -p tcp --dport 3306 -j REJECT
don't prevent connection to mysql, I am still able to connect. And tcpdump proves it:
tcpdump -n -i vlan2 port 3306
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vlan2, link-type EN10MB (Ethernet), capture size 262144 bytes
22:48:13.066636 IP 3.2.2.2.47259 > 1.1.2.3.3306: Flags [S], seq 3619220560, win 29200, options [mss 1460,sackOK,TS val 90183390 ecr 0,nop,wscale 7], length 0
22:48:13.066740 IP 1.1.2.3.3306 > 3.2.2.2.47259: Flags [S.], seq 2743923517, ack 3619220561, win 28960, options [mss 1460,sackOK,TS val 10989883 ecr 90183390,nop,wscale 7], length 0
And I can't understand the difference between these two rules.
How to use host's iptables to prevent access to containers
The issue is that your NAT rule in the
PREROUTING
chain of the nat table translates host's port3306
to172.17.0.2:
33066
and not to172.17.0.2:
3306
thus the rule in theFORWARD
chain of the filter table doesn't match anything since it tries to drop traffic forwarded to destination port3306
.