Skip to content

flavienbwk/docker-iptables

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 

Repository files navigation

docker-iptables

Secure your Docker install with additional and understandable iptables.

Use case

A lot of solutions on the web are suggesting ways to restrict external access to containers running on a server. Most of them are about disabling Docker's iptables (which causes containers to not be able to access the external network) or using Docker's DOCKER-USER and ufw-user-forward iptables chains which doesn't allow managing published port.

Let's say you want to secure a production server exposed on your network where you deployed your Docker applications. You want to be able to block all ports but the ones you want to expose.

Problem

Docker iptables and UFW iptables are independent. Meaning that you can try enabling UFW blocking all ports and find your containers still accessible.

This is due to Docker using its own iptables chains : DOCKER and DOCKER-USER, which are evaluated before the classic FORWARD chain (managed by UFW).

Combining UFW with iptables

I recommend combining UFW with iptables managing our Docker network. BTW : UFW uses iptables under the hood. The technics described here does not require disabling iptables in the Docker daemon. Which is good.

  • UFW : managing non-Docker / system ports
  • custom Docker iptables : managing Docker apps ports

Install first UFW (example with apt) :

ℹ️ Installing UFW won't directly enable it

sudo apt install -y ufw

You will probably want to allow port 22 for SSH. Allow the system ports you want to expose with the following command :

sudo ufw allow 22

When you're ready to go, enable UFW with :

sudo ufw enable

ℹ️ If you currently have running containers, you can try accessing any port exposed by a container and see that it is accessible although we've blocked EVERTHING but port 22, as explained before.

Now let's configure Docker's iptables.

Here, we want to expose a container publishing port 8080. E.g: docker run -i nginx -p 80:8080.

ℹ️ To find your network interface (eth0 for the example), type the ip a command. This should be eth0 or a name prefixed by eth, enp or esp. Eventually wlan or wls if you are working over Wi-Fi.

iptables -I DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 8080 -j ACCEPT

If you have multiple ports published (e.g: 8080, 4444...), this snippet might be handy :

NETWORK_INTERFACE=eth0
for DOCKER_PORT in 8080 4444
do
    iptables -I DOCKER-USER -i "$NETWORK_INTERFACE" -p tcp -m conntrack --ctorigdstport $DOCKER_PORT -j ACCEPT
done

Finally, we need to make sure internal networks can communicate :

sudo iptables -I DOCKER-USER -j RETURN -s 10.0.0.0/8
sudo iptables -I DOCKER-USER -j RETURN -s 172.16.0.0/12
sudo iptables -I DOCKER-USER -j RETURN -s 192.168.0.0/16
sudo ufw allow from 172.16.0.0/12
sudo ufw allow from 192.168.0.0/16

About

Secure your Docker install with additional and understandable IPTables.

Topics

Resources

Stars

Watchers

Forks