2

I want to create a firewall to Docker container that allows only some IPs and rejects others.

The default setting was like this:

$ sudo iptables --list
Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

As documented on the Docker document, this allows all incoming IPs. So I'm modifying this. I ran the following commands:

sudo iptables -D DOCKER-USER -j RETURN
sudo iptables -A DOCKER-USER -s xx.xx.xx.xx,yy.yy.yy.yy -j ACCEPT
sudo iptables -A DOCKER-USER -j DROP

This should have worked, my expected result is that if I try to access to the server from the zz.zz.zz.zz IP, it will be rejected, but from xx.xx.xx.xx, it will be passed.

But the result now is, whether I'm accessing from xx.xx.xx.xx (or yy.yy.yy.yy) or zz.zz.zz.zz, the page told me "Failed to connect". So apparently it's being dropped.

I have no idea what is happening, what is cause of this problem. Thanks for your help.

1
  • You should follow the manual: docs.docker.com/network/iptables . While they don't explain why, they tell to add negated rules that drop and specify the interface. My guess is that this chain is used multiple times (from INPUT, FORWARD and OUTPUT), and while your rules accept packets originating from xx.xx.xx.xx, they won't then accept replies to them.
    – A.B
    May 14, 2021 at 1:51

2 Answers 2

2

So, basically the issue was because I was skipping to pass an -i (--in-interface) option to specify input network interface name.

Why I skipped? Well, I guess because:

  • The docker official document mentioning the -i option with the obscure value ext_if. As the first reason of this error, I didn't (couldn't) understand what this ext_if means after some googling and such.
  • sudo iptables --list shows nothing about the -i (or -o) specified values. So I thought the option is not that important anyway and totally ignoreable. (you can list with the option with -v option e.g. sudo iptables --list DOCKER-USER -v)

Thanks to the comment @A.B said, I took a look one time again the same document entirely, and tried all the stuff from zero to last, and found the solve.

So, at last the set of commands that I ran and solved the issue is as follows.

$ docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nameOfContainer # check the docker container's local ip e.g. 172.17.0.3

# assumes the docker container ip is 172.17.0.3, 
# the "internal" docker container port (e.g. "443" for "0.0.0.0:8122->443/tcp") you want to filter is 443, 
# the network interface (you can check with e.g. `ip addr`) is wlp2s0.

sudo iptables -I DOCKER-USER -i wlp2s0 -p tcp -m tcp --dport 443 -d 172.17.0.3 -j DROP
sudo iptables -I DOCKER-USER -i wlp2s0 -p tcp -m tcp --dport 443 -d 172.17.0.3 -s xx.xx.xx.xx -j ACCEPT
sudo iptables -I DOCKER-USER -i wlp2s0 -p tcp -m tcp --dport 443 -d 172.17.0.3 -s yy.yy.yy.0/24 -j ACCEPT

So the list result be like:

$ sudo iptables --list DOCKER-USER -v
[sudo] password for user: 
Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination
   10   704 ACCEPT     tcp  --  wlp2s0 any     yy.yy.yy.0.static.xtom.com/24  172.17.0.3           tcp dpt:https
   20  1900 ACCEPT     tcp  --  wlp2s0 any     xx-xx-xx-xx.oo.oo.vectant.ne.jp  172.17.0.3           tcp dpt:https
   30  1760 DROP       tcp  --  wlp2s0 any     anywhere             172.17.0.3           tcp dpt:https
 145K   60M RETURN     all  --  any    any     anywhere             anywhere
1
  • Running ip addr will list all your interfaces. Your external interface is often the second one listed, after lo. wlp2s0 is common for Wi-Fi, and eth0 for cables. Oct 5, 2022 at 23:10
0

Edit the rule set and replace "RETURN" with "FORWARD" while you determine the default policy.

Reference: https://www.linuxtopia.org/Linux_Firewall_iptables/x4604.html

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .