robbertkl / docker-ipv6nat

Extend Docker with IPv6 NAT, similar to IPv4
MIT License
662 stars 48 forks source link

Internal network rules for IPv6 not working? #58

Closed chris42 closed 4 years ago

chris42 commented 4 years ago

Hi there, i just moved a few container into a new internal network (created with --internal) and would have expected to see the isolation rules to be created analog to IPv4 IPv4

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DROP       all  -- !192.168.5.0/24       anywhere            
DROP       all  --  anywhere            !192.168.5.0/24      
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere 

However the ip6tables show no such rule? IPv6

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DROP       all      anywhere             anywhere            
DROP       all      anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all      anywhere             anywhere            
RETURN     all      anywhere             anywhere   
chris42 commented 4 years ago

Huh, no one has this problem as well?

robbertkl commented 4 years ago

@bephinix, do you have an idea?

bephinix commented 4 years ago

@chris42 Can you post your output for iptables -nvL and ip6tables -nvL?

I am running Docker-IPv6NAT Version 0.4.2 and created an internal network:

sudo docker network create \
    -d bridge \
    --ipv6 \
    --subnet 172.30.123.0/24 \
    --subnet fddd:0:0:123::/64 \
    --internal \
    -o "com.docker.network.bridge.enable_icc=true" \
    -o "com.docker.network.bridge.enable_ip_masquerade=false" \
    -o "com.docker.network.bridge.name=dckrTest" \
    dckrTest

IPv4 Tables Docker

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      dckrTest !172.30.123.0/24      0.0.0.0/0           
    0     0 DROP       all  --  dckrTest *       0.0.0.0/0           !172.30.123.0/24     
13474  787K DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
6201K  145G RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
13487  788K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
6201K  145G RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

IPv6 Tables Docker

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all      !dckrTest dckrTest  ::/0                 ::/0                
    0     0 DROP       all      dckrTest !dckrTest  ::/0                 ::/0                
    0     0 DOCKER-ISOLATION-STAGE-2  all      docker0 !docker0  ::/0                 ::/0                
    0     0 RETURN     all      *      *       ::/0                 ::/0                

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all      *      docker0  ::/0                 ::/0                
    0     0 RETURN     all      *      *       ::/0                 ::/0                

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all      *      *       ::/0                 ::/0

It seems, that the IPv4 rules are slightly different than the IPv6 rules, but they act the same. We can fix this but it seems not critical to me.

bephinix commented 4 years ago
if network.internal {
    return &Ruleset{
        // internal: drop traffic to docker network from foreign subnet
        // notice: rule is different from IPv4 counterpart because NDP should not be blocked
        NewPrependRule(TableFilter, ChainDockerIsolation1,
            "!", "-s", network.subnet.String(),
            "-o", network.bridge,
            "-j", "DROP"),
        // internal: drop traffic from docker network to foreign subnet
        // notice: rule is different from IPv4 counterpart because NDP should not be blocked
        NewPrependRule(TableFilter, ChainDockerIsolation1,
            "!", "-d", network.subnet.String(),
            "-i", network.bridge,
            "-j", "DROP"),
        // ICC
        NewRule(TableFilter, ChainForward,
            "-i", network.bridge,
            "-o", network.bridge,
            "-j", iccAction),
    }
}

@robbertkl @chris42

Update: This difference is intended, because we should not block NDP traffic.
This would break the internal IPv6 network.

chris42 commented 4 years ago

Ok, -nvL shows something there.

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 DROP       all  --  *      br-6399b9d7ef02 !192.168.5.0/24       0.0.0.0/0           
    0     0 DROP       all  --  br-6399b9d7ef02 *       0.0.0.0/0           !192.168.5.0/24      
1144K 1121M DOCKER-ISOLATION-STAGE-2  all  --  br-08e6fee45fc7 !br-08e6fee45fc7  0.0.0.0/0            0.0.0.0/0           
3227K 1497M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 DROP       all  --  *      br-08e6fee45fc7  0.0.0.0/0            0.0.0.0/0           
1144K 1121M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

ipv6:

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-ISOLATION-STAGE-2  all      docker0 !docker0  ::/0                 ::/0                
    0     0 DROP       all      !br-6399b9d7ef02 br-6399b9d7ef02  ::/0                 ::/0                
    0     0 DROP       all      br-6399b9d7ef02 !br-6399b9d7ef02  ::/0                 ::/0                
 560K  693M DOCKER-ISOLATION-STAGE-2  all      br-08e6fee45fc7 !br-08e6fee45fc7  ::/0                 ::/0                
1964K 1111M RETURN     all      *      *       ::/0                 ::/0                

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all      *      docker0  ::/0                 ::/0                
    0     0 DROP       all      *      br-08e6fee45fc7  ::/0                 ::/0                
 560K  693M RETURN     all      *      *       ::/0                 ::/0

Ah, you are blocking the interface, not the iprange as it is done in ipv4?!

bephinix commented 4 years ago

@chris42 Correct. You cannot use IPv6 subnets, because this will block NDP and link local address which leads to a non functional network.

robbertkl commented 4 years ago

Thanks for clearing that up @bephinix! I guess this one can be closed as it's functioning as intended?

bephinix commented 4 years ago

@robbertkl That's correct. :rocket:

chris42 commented 4 years ago

Ok, Thanks!