I have a service running (docker registry) on my debian server at port 5000. I would like to restrict access to that to specific IP, so I've created a file with rules (1.2.3.4 is my trusted IP)
*filter
-A INPUT -p tcp --dport 5000 --source 1.2.3.4 -j ACCEPT
-A INPUT -p tcp --dport 5000 -j DROP
COMMIT
then i've used a command to apply these rules to iptables
sudo iptables-restore < myfile
so the result of command sudo iptables -L is:
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 1.2.3.4 anywhere tcp dpt:5000
DROP tcp -- anywhere anywhere tcp dpt:5000
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Then i'm checking if port 5000 is reachable from internet (from my another server)
nc -zv 5.6.7.8 5000
and the result is [... 5000 (?) open] My question is why ? These rules are so straightforward, why can i access service that is at port 5000 ? Even if I keep just one rule (-A INPUT -p tcp --dport 5000 -j DROP), I can still access to that port.
Edit 1: @A.B you're right. Now I can see also docker's rules.
sudo iptables-save -c
# Generated by xtables-save v1.8.2 on Thu Feb 13 15:21:42 2020
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:DOCKER - [0:0]
[39755:1536013] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
[40:2500] -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
[0:0] -A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 5000 -j MASQUERADE
[0:0] -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
[0:0] -A DOCKER -i docker0 -j RETURN
[33:1824] -A DOCKER ! -i docker0 -p tcp -m tcp --dport 5000 -j DNAT --to-destination 172.17.0.2:5000
COMMIT
# Completed on Thu Feb 13 15:21:42 2020
# Generated by xtables-save v1.8.2 on Thu Feb 13 15:21:42 2020
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:DOCKER-USER - [0:0]
[0:0] -A DOCKER-USER -p tcp -m tcp --dport 5000 -j DROP
COMMIT
# Completed on Thu Feb 13 15:21:42 2020
So now the question is how to add DROP rule to nat table? I've added a rule according to docker docs
sudo iptables -t nat -N DOCKER-USER
sudo iptables -t nat -I DOCKER-USER -p tcp -m tcp --dport 5000 -j RETURN
but no effect.
Edit2: Finally! I've found an answer here: https://unix.stackexchange.com/questions/462706/block-docker-port-and-access-it-to-few-ip-addresses
This solves the problem.
-I FORWARD 1 -d 172.17.0.2 -p tcp --dport 5000 -j DROP