Docker ignores iptable rules when using “-p :

前端 未结 5 925
广开言路
广开言路 2021-01-31 22:10

Just realized a few days ago that Docker seems to bypass my iptable rules. I am not incredible experienced with Docker nor iptables. Tried a lot of different things the last day

5条回答
  •  后悔当初
    2021-01-31 22:35

    Given: Debian stretch, docker 18.06, and a docker process created via

    docker run ... -p 5678:1234 ...
    

    Required: Access to the docker container restricted to multiple external subnetworks.

    Solution: (using some example subnetworks)

    iptables -I DOCKER-USER                  -p tcp --dport 1234 -j REJECT
    iptables -I DOCKER-USER -s 18.204.0.0/16 -p tcp --dport 1234 -j RETURN
    iptables -I DOCKER-USER -s 34.192.0.0/16 -p tcp --dport 1234 -j RETURN
    iptables -I DOCKER-USER -s 35.153.0.0/16 -p tcp --dport 1234 -j RETURN
    iptables -I DOCKER-USER -s 13.56.63.0/24 -p tcp --dport 1234 -j RETURN
    

    Persist the changed rules using iptables-save:

    iptables-save > /etc/iptables/rules.v4
    

    Result:

    iptables -L DOCKER-USER -n -v --line-numbers
    
    Chain DOCKER-USER (1 references)
    pkts bytes target     prot opt in     out     source               destination
    0     0 RETURN     tcp  --  *      *       13.56.63.0/24        0.0.0.0/0            tcp dpt:1234
    0     0 RETURN     tcp  --  *      *       35.153.0.0/16        0.0.0.0/0            tcp dpt:1234
    0     0 RETURN     tcp  --  *      *       34.192.0.0/16        0.0.0.0/0            tcp dpt:1234
    0     0 RETURN     tcp  --  *      *       18.204.0.0/16        0.0.0.0/0            tcp dpt:1234
    0     0 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:1234 reject-with icmp-port-unreachable
    

    Background 1: Rules

    All rules are added to the chain DOCKER-USER as recommended by the current docker documentation.

    The first rule targets REJECT and will end up as the last rule, since the other rules are added on top (option -I without a position number corresponds to adding a rule at position 1). All packages with destination port 1234 reaching this rule will be rejected.

    The other rules target RETURN, i.e. a package with destination port 1234 and source IP from one of the given subnetworks will be returned to the calling chain, which is the FORWARD chain.

    iptables -L FORWARD -n -v
    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts bytes target     prot opt in     out     source               destination
    16471 4568K DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    16413 4565K DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    7173 2060K ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    45  2340 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0
    

    From the FORWARD chain, it will be processed by the DOCKER chain, where it is forwarded as desired to the docker container:

    iptables -L DOCKER -n -v
    Chain DOCKER (1 references)
    pkts bytes target     prot opt in     out     source               destination
    45  2340 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.2           tcp dpt:1234
    

    Background 2: Port value

    We don't use the external port value 5678 in the forward rule, because the destination port is changed via a rule automatically created by docker and applied before the forward chain is executed. See top section of /etc/iptables/rules.v4:

    -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
    ...
    -A DOCKER ! -i docker0 -p tcp -m tcp --dport 5678 -j DNAT --to-destination 172.17.0.2:1234
    

提交回复
热议问题