

I believe right now Docker doesn't put anything in *raw or *mangle so its safe to add your own rules there. It's still unsatisfying that you are allowing traffic to port 25. A DOCKER-USER -j REJECT -reject-with icmp-host-prohibited A DOCKER-USER -i eth0 -m state -state NEW -m tcp -p tcp -dport 25 -j ACCEPT # is only accessible via `FORWARD` and not `INPUT`. # Service on real host port 25 should still be inaccessible because DOCKER-USER # This says dport 25, but is actually 465. A DOCKER-USER -i eth0 -m state -state ESTABLISHED,RELATED -j ACCEPT

# Rules for services running in containers: A INPUT -j REJECT -reject-with icmp-host-prohibited A INPUT -m state -state NEW -m tcp -p tcp -dport 443 -j ACCEPT A INPUT -m state -state NEW -m tcp -p tcp -dport 80 -j ACCEPT A INPUT -m state -state NEW -m tcp -p tcp -dport 22 -j ACCEPT A INPUT -m state -state ESTABLISHED,RELATED -j ACCEPT # Rules for services running on the host: You could go down the explicit is better than implicit route and split the host vs docker rules: *filter Obviously you don't want to allow access to all port 25 because that includes your host's port 25.Īll the usual tricks you'd do at this point are made that much more difficult because of Docker. So I reckon if you allowed traffic to port 25, then actually you would be able to access port 465 too. And this happens before the filter tables INPUT chain runs. So this rule is executed in the PREROUTING phase and rewrites the incoming packet to look like it was always for port 25 and not port 465. A DOCKER ! -i br-abbaabbaabba -p tcp -m tcp -dport 465 -j DNAT -to-destination 172.18.0.10:25 You'll probably see something that looks like this in the *nat section: -A PREROUTING -m addrtype -dst-type LOCAL -j DOCKER
Docker container port mapping full#
If you look at your full firewall config with iptables-save you'll see a bunch of NAT rules. In your example: docker run -rm -it -p 465:25 python:3.6 python3 -m rver 25 I've actually looked into this issue before without someone else who noticed it and I think I know whats happening. Thanks for reaching out to me on Twitter. REJECT all - anywhere anywhere reject-with icmp-host-prohibited REJECT all - loopback/8 anywhere reject-with icmp-port-unreachableĪCCEPT icmp - anywhere anywhere icmp anyĭOCKER-ISOLATION-STAGE-1 all - anywhere anywhereĪCCEPT all - anywhere anywhere ctstate RELATED,ESTABLISHEDĪCCEPT tcp - anywhere 172.19.0.4 tcp dpt:3000ĪCCEPT tcp - anywhere 172.17.0.3 tcp dpt:smtpĬhain DOCKER-ISOLATION-STAGE-1 (1 references)ĭOCKER-ISOLATION-STAGE-2 all - anywhere anywhereĬhain DOCKER-ISOLATION-STAGE-2 (3 references)ĪCCEPT all - anywhere anywhere state RELATED,ESTABLISHEDĪCCEPT tcp - anywhere anywhere state NEW tcp dpt:sshĪCCEPT tcp - anywhere anywhere state NEW tcp dpt:httpĪCCEPT tcp - anywhere anywhere state NEW tcp dpt:httpsĪCCEPT tcp - anywhere anywhere state NEW tcp dpt:urd Here are the complete iptables rules in the failing scenario ( 465:25 mapping): $ sudo iptables -L How should I modify my iptables so that I can access my container from the outside, whatever the port mapping? A FILTERS -j REJECT -reject-with icmp-host-prohibited A FILTERS -m state -state NEW -m tcp -p tcp -dport 465 -j ACCEPT A FILTERS -m state -state NEW -m tcp -p tcp -dport 443 -j ACCEPT A FILTERS -m state -state NEW -m tcp -p tcp -dport 80 -j ACCEPT A FILTERS -m state -state NEW -m tcp -p tcp -dport 22 -j ACCEPT A FILTERS -m state -state ESTABLISHED,RELATED -j ACCEPT A INPUT -p icmp -icmp-type any -j ACCEPT This whole problem is due to my iptables definition: I know that because when I flush the iptables rules, I do manage to access the service from outside, whatever the port mapping. Then I can access the service from the outside: $ curl :465 In other words, when I run on the host: $ docker run -rm -it -p 465:465 python:3.6 python3 -m rver 465

However, and here comes the interesting part, I do manage to access the service if the port on the host maps to the same port in the container. My problem is that I cannot access port 465 on my server from the outside: $ curl :465Ĭurl: (7) Failed to connect to port 465: No route to host
Docker container port mapping how to#
Here's how to simulate such a service: $ docker run -rm -it -p 465:25 python:3.6 python3 -m rver 25 Port 465 maps to port 25 in the container. I am running a docker container that exposes a service on port 465 on the host. The configuration described in this blog post has served me well for a long time, but I'm now facing a problem I never had before. Iptables rules are notoriously difficult to set up when Docker is running on the host, and I thought I had a definitive solution in this fantastic blog post:
