Search code examples
dockernetwork-programmingubuntu-18.04ufw

Docker localhost connection blocked by UFW


Situation

I'm trying to learn how to use docker on my local machine. The local machine is set up to only route traffic through a VPN. The default UFW policy is to DENY all incoming and outgoing traffic (except through a VPN).

Problem

When I try to launch a Docker container docker container run -p 80:80 nginx, I cannot connect to the nginx container using localhost in my browser.

However, I can connect to the local nginx container through telnet

$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.

The reason I know that UFW may be causing this is because once I disable UFW, I'm able to connect to localhost in the browser with no problem.

Question

How do I connect to my local nginx container from my browser when UFW is set to deny all connections?


Solution

  • I found the solution to my problem.

    Solution

    ufw allow out on docker0 from 172.17.0.0/16
    

    Since I know the specific port that nginx uses, I can also make this rule more strict by doing

    ufw allow out on docker0 from 172.17.0.0/16 port 80 proto tcp
    

    Explanation

    Docker creates a new interface for containers and you can see it by running ifconfig:

    docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
            ether 02:42:a4:5e:e9:9c  txqueuelen 0  (Ethernet)
            RX packets 87  bytes 17172 (17.1 KB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 117  bytes 14956 (14.9 KB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    

    This interface routes traffic through 172.17.xxx.xxx. You can read more about how I found that netmask here.

    This gives us all the information we need to write a rule. If you are publishing the container on a different port, you can check for the port number and protocol by doing the following:

    1. Find the ID of you container docker container ls
    2. Find the Port of your container docker container port {id}