dockerdnsportfirewalliptables

Trying to whitelist `DOCKER-USER` ports but it blocks containers from resolving DNS


I have some containers that are bound to the host but I don't want them to be exposed to internet except HTTP ones. So I do:

sudo iptables -F DOCKER-USER
sudo iptables -I DOCKER-USER -i ens3 -p tcp -m multiport --dports 80,443 -j ACCEPT
sudo iptables -A DOCKER-USER -i ens3 -p tcp -j REJECT --reject-with tcp-reset
sudo iptables -A DOCKER-USER -i ens3 -p udp -j REJECT --reject-with icmp-port-unreachable

docker run busybox nslookup google.com # NOT WORKING

Unfortunately, due to the lines about REJECT, containers are unable to resolve DNS. They still are able to reach a remote IP directly but nothing through DNS resolving. Note also it's working with the test:

sudo iptables -F DOCKER-USER
sudo iptables -I DOCKER-USER -i ens3 -p tcp -m multiport --dports 80,443 -j ACCEPT

docker run busybox nslookup google.com # WORKING

I tried to use tcpdump to understand what is going on but I didn't succeed identifying the issue. It seems containers are resolving DNS with a local IP with a dedicated port but I'm not able to identify it. And even if so, would this one is immutable? Or will it change after reboot? (I want my iptables rules to be persistent)

Note: since DNS resolving is being tried on TCP with fallback to UDP from what I understand, having just 1 reject (no matter which one) will work, but that's not a solution.


Solution

  • I finally ended up with the following solution. That's maybe not perfect but I guess I'm missing some knowledge about firewall rules and Docker routing to do something better. Any suggestion would be more than welcome :)

    sudo iptables -F DOCKER-USER
    sudo iptables -A DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j RETURN
    sudo iptables -A DOCKER-USER -i ens3 -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j ACCEPT
    sudo iptables -A DOCKER-USER -i ens3 -p tcp -m conntrack --ctstate NEW -j REJECT --reject-with tcp-reset
    sudo iptables -A DOCKER-USER -i ens3 -p udp -m conntrack --ctstate NEW -j REJECT --reject-with icmp-port-unreachable
    sudo iptables -A DOCKER-USER -j RETURN