7
votes

I'm running a docker container that has the port 9000:9000 binding to the host, but I also have ufw enabled. The only ports I've allowed are 22, 80, 443.

So why is it that I'm able to connect to this container using the host's IP address? Shouldn't port 9000 be blocked by ufw?

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                      NAMES
14417c4f71fb        dockerui/dockerui   "/dockerui"              2 seconds ago       Up 2 seconds        0.0.0.0:9000->9000/tcp     docker_ui

root@docker:~# ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere
80                         ALLOW       Anywhere
443                        ALLOW       Anywhere
22 (v6)                    ALLOW       Anywhere (v6)
80 (v6)                    ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

Aren't all ports blocked by default when you enable ufw?

4

4 Answers

2
votes

Docker silently modifies iptables. You can start the Docker daemon with the --iptables=false option by editing DOCKER_OPTS in /etc/default/docker

1
votes

Docker modifies iptables and UFW is not aware of this.

This answer describes what is happening and how to fix: https://stackoverflow.com/a/46266757

Please follow it.

1
votes

adding "--iptables=false" is not a good solution as I said here https://stackoverflow.com/a/54486957/1712906

a better solution is to add these lines to /etc/ufw/after.rules

# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16

-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN

-A DOCKER-USER -j ufw-user-forward

-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12

-A DOCKER-USER -j RETURN
COMMIT
# END UFW AND DOCKER
1
votes

As mentioned by @kliew, Docker will add its own iptables chain, granting access to all exposed ports and pre-empting any rules that you define using ufw.

If you're not comfortable completely disabling Docker's control over iptables, though, there is another documented way to have your own rules respected. From the same docs:

If you need to add rules which load before Docker’s rules, add them to the DOCKER-USER chain. These rules are applied before any rules Docker creates automatically.

Source: https://docs.docker.com/network/iptables/#add-iptables-policies-before-dockers-rules

This would preclude the use of ufw, though, because ufw only operates within its own iptables chains and doesn't give you control over the DOCKER-USER chain. You'll have to do this using iptables directly.