0

I'm trying to set up iptables on a server running Docker containers. Default rules generated by Docker set default policy to ACCEPT but I'd prefer to have it in a more restrictive manner: set default policy to DROP and expose to the Internet only specific ports (HTTP, SSH, etc).

I have an app container running with -p 0.0.0.0:8080:3000 as an upstream for nginx reverse proxy on port 80.

Here are iptables rules I currently have:

*nat
:PREROUTING ACCEPT [259:17205]
:INPUT ACCEPT [112:6660]
:OUTPUT ACCEPT [100:6000]
:POSTROUTING ACCEPT [45:2680]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.4:3000
COMMIT
# Completed on Thu Feb 18 12:57:58 2016
# Generated by iptables-save v1.4.21 on Thu Feb 18 12:57:58 2016
*filter
:INPUT DROP [9:449]
:FORWARD DROP [0:0]
:OUTPUT DROP [5:300]
:DOCKER - [0:0]
:DOCKER-ISOLATION - [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -m tcp --dport 2376 -j ACCEPT
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p udp -m udp --sport 53 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A FORWARD -j DOCKER-ISOLATION
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m state --state ESTABLISHED -m tcp --sport 2376 -j ACCEPT
-A OUTPUT -p tcp -m state --state ESTABLISHED -m tcp --sport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A DOCKER -d 172.17.0.4/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 3000 -j ACCEPT
-A DOCKER-ISOLATION -j RETURN
COMMIT

The problem is that they are too restrictive: nginx can't access the container.

I discovered that if I run:

iptables -I INPUT -i docker0 -j ACCEPT
iptables -I OUTPUT -o docker0 -j ACCEPT

it would work but also would made the container accessible from the Internet.

I tried adding -s 0.0.0.0 but it didn't help.

What am I doing wrong?

0

When I removed

-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE

from nat table and

-A DOCKER -d 172.17.0.4/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 3000 -j ACCEPT

from filter table everything worked like I wanted it to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.