Reputation: 169
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
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