Restrict Docker exposed port from only specific IP adresses

13,042

Solution 1

I had the same problem. I solved it with this rules :

iptables -I DOCKER-USER -i <your_interface_name> -j DROP
iptables -I DOCKER-USER -i <your_interface_name> -s <your_first_ip> -j ACCEPT
iptables -I DOCKER-USER -i <your_interface_name> -s <your_second_ip> -j ACCEPT

Care, DOCKER-USER is a chain which will not be deleted when service docker restart

You should be able to add your port flag, but i'm not an expert and it is not my needs.

Solution 2

Your policy is whitelist, it's better to create a user custom chain handle this alone.

For example, I have a redis container, I want it only serve for specific IPs:

$ docker run -d -p 6379:6379 redis:2.8

After started redis container, the iptables looks like this:

$ iptables -t filter -nL
Chain DOCKER (1 references)
target     prot opt source               destination
ACCEPT  tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:6379

Create our custom chain:

$ iptables -N CUSTOM_REDIS
$ iptables -A CUSTOM_REDIS -p tcp --dport 6379 --source 172.31.101.37 --destination 172.17.0.2 -j ACCEPT
$ iptables -A CUSTOM_REDIS -p tcp --dport 6379 --source 172.31.101.38 --destination 172.17.0.2 -j ACCEPT
$ iptables -A CUSTOM_REDIS -p tcp --dport 6379 --source 0.0.0.0/0 --destination 172.17.0.2 -j DROP

Replace the original rule with custom chain:

$ iptables -R DOCKER 1 -p tcp --source 0.0.0.0/0 --destination 172.17.0.2 --dport 6379 -j CUSTOM_REDIS

Now my redis can only access by ip: 172.31.101.37 and 172.31.101.38.

Note:

  • 172.17.0.2 is the ip of redis container

Solution 3

From the docker guide here:

Docker’s forward rules permit all external source IPs by default. To allow only a specific IP or network to access the containers, insert a negated rule at the top of the DOCKER filter chain. For example, to restrict external access such that only source IP 8.8.8.8 can access the containers, the following rule could be added:

$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP

In your case since you want to allow multiple IP addresses I think something like this should work:

iptables -I DOCKER -s EXTERNAL_IP_1 -p tcp --dport PORT_X -j ACCEPT
iptables -I DOCKER -s EXTERNAL_IP_2 -p tcp --dport PORT_X -j ACCEPT
iptables -I DOCKER -s EXTERNAL_IP_3 -p tcp --dport PORT_X -j ACCEPT
iptables -I DOCKER -p tcp --dport PORT_X -j REJECT --reject-with icmp-port-unreachable

Solution 4

You may also want to prevent access from docker directly, using the specific IP you want to listen, like -p 1.2.3.4:6379:6379/tcp syntax, that way the container will listen only on that IP and interface.

If you use that IP as private IPs, you can avoid completely the iptables because you restricted access only from local/private network.

Share:
13,042
Sony
Author by

Sony

Updated on June 23, 2022

Comments

  • Sony
    Sony almost 2 years

    How to restrict a container's port exposed by Docker from only a list of IPs? Only this list of IP would be able to access this port.

    I tried that:

    iptables -I DOCKER -p tcp --dport PORT_X -j REJECT --reject-with icmp-port-unreachable
    iptables -I DOCKER -p tcp --dport PORT_X --source EXTERNAL_IP_1 --destination HOST_IP_1 -j ACCEPT
    iptables -I DOCKER -p tcp --dport PORT_X --source EXTERNAL_IP_2 --destination HOST_IP_1 -j ACCEPT
    iptables -I DOCKER -p tcp --dport PORT_X --source EXTERNAL_IP_3 --destination HOST_IP_1 -j ACCEPT