There is a server with Ubuntu 20. It has Docker installed, and several containers are running. The reverseproxy
is a Nginx that should take traffic on 80 and 443, and route it to the containers. It works perfectly. But now I wanted to block all traffic (apart from 80, 443 and ssh) with ufw.
Somehow traffic on http ports 3000, 3001, 8081, 15672 (ports published by containers) still gets through.
Why? How to block all traffic using ufw?
ufw configuration
www@broowqh:~$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
9000 ALLOW IN Anywhere
3001 DENY IN Anywhere
3001/tcp DENY IN Anywhere
3001/udp DENY IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
9000 (v6) ALLOW IN Anywhere (v6)
3001 (v6) DENY IN Anywhere (v6)
3001/tcp (v6) DENY IN Anywhere (v6)
3001/udp (v6) DENY IN Anywhere (v6)
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48709042d67f nginx:1.23-alpine "/docker-entrypoint.…" 10 hours ago Up 10 hours. 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp. reverseproxy
401d6576b3e0 adminer:4.8.1 "entrypoint.sh docke…" 10 hours ago Up 10 hours. 0.0.0.0:8081->8080/tcp, :::8081->8080/tcp adminer
c47966cae717 postgres:14.1-alpine "docker-entrypoint.s…" 10 hours ago Up 10 hours. 5432/tcp db
1c3709a07fb0 www:current "docker-entrypoint.s…" 15 hours ago Up 10 hours. 0.0.0.0:3001->3001/tcp, :::3001->3001/tcp www
db252e2833bc postgrest/postgrest:v10.0.0 "/bin/postgrest" 18 hours ago Up 10 hours. 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp api
68396bebcaa8 rabbitmq:3.9.13-management-alpine "docker-entrypoint.s…" 19 hours ago Up 10 hours. 0.0.0.0:5672->5672/tcp, 0.0.0.0:15672->15672/tcp broker
Nginx configuration
upstream www {
server www:3001;
}
upstream api {
server api:3000;
}
upstream adminer {
server adminer:8080;
}
upstream rabbit {
server broker:15672;
}
server {
listen 80;
listen [::]:80;
server_name example.com
location / {
return 301 https://example.com$request_uri;
}
}
server {
listen 443 default_server ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/live/smartplaylist.me/example.crt;
ssl_certificate_key /etc/nginx/ssl/live/smartplaylist.me/example.key;
location /adminer/ {
proxy_pass http://adminer/;
}
location /rabbit/ {
proxy_pass http://rabbit/;
}
location /api/ {
proxy_pass http://api/;
}
location / {
proxy_pass http://www/;
}
}
CodePudding user response:
Docker bypass the UFW rules and the published ports can be accessed from outside. You can publish the port onto a specific interface, e.g. 127.0.0.1:8080:80
which would publish the port 8080 on the host's loopback interface (127.0.0.1) to connect to a container's port 80, and that loopback interface is not externally accessible.
With UFW you are modifying the INPUT rules, but docker adds it rules in PREROUTING
table, that mean you can't put filter rules at INPUT
chain because it will never match and bypass all.