UFW alternatives?
If UFW cant do a simple job to setup security rules docker or not, then we should leave it in the past as it deserves. We live in a containerized world, so UFW is like useless at this point
So my question to you reading this is.
What are the alternatives to UFW? that will work with docker so we can leave UFW alone
Thanks for contributing
The idea that "UFW is faulty" or "UFW can’t secure Docker" is fundamentally flawed. The problem isn’t UFW - it’s a misunderstanding of how Docker networking works.
Docker doesn’t magically "open ports". What actually happens is that people put ports: XXXX:XXXX in their docker-compose.yml, and that publishes the port directly to the host. That’s a deliberate choice, not a failure of UFW.
YES, docker by default is capable of modifying the iptable rules... but it does not just open ports "because".
Its's like telling UFW "open port XXXX" and then complaining "why do you not protect that port?!"
The correct approach is simple: don’t open ports you don’t need. Instead, run your services on a shared Docker network and expose only standard entry points (e.g., 80/443) through a reverse proxy like Nginx Proxy Manager. And, of course, protect your host with UFW. You will not find a Firewall that stops Docker from breaking it, if people tell docker do break it.
For example:
services:
your-service:
# Avoid exposing ports like this:
# ports:
# - "2283:2283"
networks:
shared_network:
ipv4_address: 192.168.96.3
networks:
shared_network:
external: true
Then configure your proxy container:
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: npm_proxy
restart: unless-stopped
ports:
- "0.0.0.0:80:80"
- "0.0.0.0:443:443"
networks:
shared_network:
ipv4_address: 192.168.96.2
networks:
shared_network:
name: shared_network
driver: bridge
ipam:
config:
- subnet: 192.168.96.0/21
Now you forward requests from Nginx Proxy Manager to 192.168.96.3:2283 internally, and you control access with DNS and firewall rules on just 80/443.
This works just as well on a LAN as on the public internet. The bottom line: UFW is not the problem - misuse of Docker networking is.
As such I believe the question does not have to be "what is the alternative to UFW", rather, "How can we educate people to use Docker in a more safe way".
Thank you very much @smileBeda for this helpful comment. I know have a better understanding of all this.
@smileBeda The fact that Docker implicitly binds to 0.0.0.0 by default is insane. I don’t know a single other development tool that binds to 0.0.0.0 by default rather than 127.0.0.1 and then behind the hood silently tweaks the firewall to remove any safeguards.
The solution is to explicitly specify the interface every time you expose ports in Docker:
services:
your-service:
ports:
- "127.0.0.1:2283:2283"
This should be the default, not 0.0.0.0.
But overall I agree that it’s not the fault of ufw, the problem is that Docker fiddles with it in non-intuitive ways without people knowing.
You're right about that!
It just underlined that the issue isn't UFW, and you're totally right about Docker by default - not only by practice - doing things in an aggressive (and wrong) way.
So perhaps the efforts also should toward a change of how docker works per se, not just education of how to use it.
This is interesting discussion and I appreciate the insights.
What I want is a simple way to govern the publicly exposed ports on a standalone docker host. I previously used the off-host firewall provided by my VPS provider, but now I'm running on bare-metal and don't have that, so I need to do it on-host. I thought I could use UFW for this purpose, but ended up here when I realized it wasn't working.
Yes I can just be careful about publishing ports, and only publish them to specific interfaces, but those definitions are scattered around so they're harder to audit at a glance.
@smileBeda's solution comes the closest I think, and then force all exposed services through Traefik.