chaifeng / ufw-docker

To fix the Docker and UFW security flaw without disabling iptables
GNU General Public License v3.0
4.29k stars 368 forks source link

table `nat' is incompatible, use 'nft' tool #114

Open petrprikryl opened 9 months ago

petrprikryl commented 9 months ago

Hi, I have problem starting ufw-docker-agent service in swarm mode on Debian 12 bookworm.

# docker logs -f ufw-docker-agent.i0spp3mykizu77bimo65xwr02.vm1271int13yib48zdufmfydn
iptables v1.8.7 (nf_tables): chain `DOCKER-INGRESS' in table `nat' is incompatible, use 'nft' tool.

I have tried 221002-nf_tables and latest tags with same error.

darklow commented 5 months ago

It would be great to have support to iptables v1.8.7 without downgrade.

Update: following didn't worked after all, docker was failing to create any networks after downgrade:

This downgrade to legacy iptables helped me solve ufw-docker on Ubuntu 22.04.3 which by default now uses iptables v1.8.7: https://unix.stackexchange.com/a/762800

akselerando commented 1 month ago

I was able to get this work by renaming the DOCKER-INGRESS chain to just DOCKER here

I.e. from this:

target_ip_port="$(iptables -t nat -L DOCKER-INGRESS | grep -E "^DNAT\\s+${proto}\\s+.+\\sto:[.0-9]+:${port}\$" | grep -Eo "[.0-9]+:${port}\$")"

to this:

target_ip_port="$(iptables -t nat -L DOCKER | grep -E "^DNAT\\s+${proto}\\s+.+\\sto:[.0-9]+:${port}\$" | grep -Eo "[.0-9]+:${port}\$")"

I am not sure if this is because Docker has changed how they implement their chains, or if my setup is different from the usual setup. I am running Ubuntu 20.04.4 with Docker engine version 26.1.4. My Swarm consists of a single node with a few services that all only have 1 replica for each.

If this is a bug that should be fixed, I can create a pull request with the necessary changes. Is it still valid to check the DOCKER-INGRESS chain? If so, maybe a solution is to first check DOCKER-INGRESS, and then DOCKER? @chaifeng

@petrprikryl Can you try my solution by building the image locally and see if it fixes your problem aswell?

chaifeng commented 1 month ago

Hi @akselerando Thank you for the solution. Is it because of the changes in the latest version of Docker? Or is it an issue that is dependent on the operating system? I tried the latest version of Docker on Debian earlier this year, but I couldn't reproduce this issue. Can you reproduce this issue by making changes to this Vagrantfile? Anyway, YES, I believe it should be considered a bug. We should check the Docker version and other factors to make sure that this script is still compatible with previous versions of Docker and platforms. Thank you in advance for fixing this issue.

akselerando commented 1 month ago

Thank you for a quick reply! I tried to research what has changed, but could not find anything concrete. I will try to reproduce this issue next week:)

akselerando commented 1 month ago

Update:

I've been testing some more and I think i figured out the issue. My case is kind of special in the sense that all services only have a single replica and I am running on a single node. In order to be able to reach some containers from outside the host machine, all services are deployed with the ports opened with mode=host. Because of this, the DOCKER-INGRESS chain is never created.

By changing the mode to the default value, the chain is created as intended.

This probably means that the error i got is just caused by my edge-case of not running any services with the ingress mode. Still, this tool seems to solve my issue with ufw + Docker.

Any thoughts on my use-case @chaifeng ? If this is sort of out-of-scope for this tools, then I understand, but if not, maybe a solution is to first check the DOCKER-INGRESS chain, and if it doesn't find the service there, try the DOCKER chain?

In any case, it would probably be wise to wrap the iptables lookup in some error handling and print an appropriate error if the chain is missing in order to avoid misinterpretation of the error presented in the initial post here.

Let me know what solution you prefer, and I'll create a PR:)

chaifeng commented 1 month ago

Thank you for the update.

It looks that this modification requires using docker inspect command to check the network mode of the service first, and then to determine whether to add the iptables rules to the DOCKER or DOCKER-INGRESS chain. Don't forget to add new unit test cases.