smcp
smcp

Reputation: 169

Docker ports visible on interface even if UFW has denied access

I have a digital ocean droplet which I created using docker-machine with ubuntu-18-04-x64 image. I deploy three containers to it using docker-compose, one of which is an nginx which has ports 80 and 8080 forwarded to 0.0.0.0 and thus listening on all interfaces.

  nginx:
image: noumena/nrg-vpp/nginx:latest
ports:
- "80:80"
- "8080:8080"
depends_on:
- engine
- api

The firewall is configured to block all traffic on eth0 (DO public interface), except 2376 for docker, and open ports 22, 80, 8080 on eth1 (DO private interface).

22/tcp on eth1             ALLOW       Anywhere
8080/tcp on eth1           ALLOW       Anywhere
80/tcp on eth1             ALLOW       Anywhere
2376/tcp on eth0           ALLOW       Anywhere
Anywhere on eth0           DENY        Anywhere
Anywhere on eth1           DENY        Anywhere
22/tcp (v6) on eth1        ALLOW       Anywhere (v6)
8080/tcp (v6) on eth1      ALLOW       Anywhere (v6)
80/tcp (v6) on eth1        ALLOW       Anywhere (v6)
2376/tcp (v6) on eth0      ALLOW       Anywhere (v6)
Anywhere (v6) on eth0      DENY        Anywhere (v6)
Anywhere (v6) on eth1      DENY        Anywhere (v6)

However the ports forwarded by docker (80,8080) are still visible on eth0, any other port is not visible on eth 0 (e.g. 22)

17:10 $ telnet public-ip 22 
Trying x.x.x.x... 
telnet: connect to address x.x.x.x: Operation timed out 
telnet: Unable to connect to remote host 

17:16 $ telnet public-ip 80 
Trying x.x.x.x... 
Connected to x.x.x.x. 
Escape character is '^]'. 
^] 
telnet> Connection closed. 

17:17 $ telnet public-ip 8080 
Trying x.x.x.x...  
Connected to x.x.x.x.
Escape character is '^]'. 
^] 
telnet> Connection closed.

Why on earth would these ports be open? Does the forwarding happen before the firewall is involved?

I've fixed the acute problem by restricting the containers to only listen on the private-ip, but this is annoying as it requires extra logic to query the droplet for its private-ip and the docker-compose file becomes a template. It would be a lot simpler if I could rely on the firewall to keep the forwarded ports closed.

Has anyone come across this type of behaviour before? I would really like to understand what is happening.

Upvotes: 2

Views: 5149

Answers (1)

pwes
pwes

Reputation: 2040

This is due to the way Docker handles network. In short, exposing a port from the container you instruct Docker to put ACCEPT rules for the specific ports before the firewall (at least for UFW) has a chance to apply its own rules.

The main, most sensible issue on GitHub that tracks this behavior seems to be #22054. Depending on your exact firewall configuration (UFW?), one of the comments (especially the newer once, since around 2017) might hold an solution for you.

See also this answer to similar question on ServerFault, which is from the same person as one of successful advices on #22054 issue.

Upvotes: 3

Related Questions