瀏覽代碼

libnet/d/bridge: Allow IPv6 ICC from any IP address

IPv6 ipt rules are exactly the same as IPv4 rules, although both
protocol don't use the same networking model. This has bad consequences,
for instance: 1. the current v6 rules disallow Neighbor
Solication/Advertisement ; 2. multicast addresses can't be used ; 3.
link-local addresses are blocked too.

To solve this, this commit changes the following rules:

```
-A DOCKER-ISOLATION-STAGE-1 ! -s fdf1:a844:380c:b247::/64 -o br-21502e5b2c6c -j DROP
-A DOCKER-ISOLATION-STAGE-1 ! -d fdf1:a844:380c:b247::/64 -i br-21502e5b2c6c -j DROP
```

into:

```
-A DOCKER-ISOLATION-STAGE-1 ! -s fdf1:a844:380c:b247::/64 ! -i br-21502e5b2c6c   -o br-21502e5b2c6c -j DROP
-A DOCKER-ISOLATION-STAGE-1 ! -d fdf1:a844:380c:b247::/64   -i br-21502e5b2c6c ! -o br-21502e5b2c6c -j DROP
```

These rules only limit the traffic ingressing/egressing the bridge, but
not traffic between veth on the same bridge.

Note that, the Kernel takes care of dropping invalid IPv6 packets, eg.
loopback spoofing, thus these rules don't need to be more specific.

Solve #45460.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
(cherry picked from commit da9e44a620db39307f5548a1451be9c434c5b34d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Albin Kerouanton 2 年之前
父節點
當前提交
b7d1e98ae7
共有 1 個文件被更改,包括 15 次插入8 次删除
  1. 15 8
      libnetwork/drivers/bridge/setup_ip_tables.go

+ 15 - 8
libnetwork/drivers/bridge/setup_ip_tables.go

@@ -397,15 +397,21 @@ func removeIPChains(version iptables.IPVersion) {
 }
 }
 
 
 func setupInternalNetworkRules(bridgeIface string, addr *net.IPNet, icc, insert bool) error {
 func setupInternalNetworkRules(bridgeIface string, addr *net.IPNet, icc, insert bool) error {
-	var (
-		inDropRule  = iptRule{table: iptables.Filter, chain: IsolationChain1, args: []string{"-i", bridgeIface, "!", "-d", addr.String(), "-j", "DROP"}}
-		outDropRule = iptRule{table: iptables.Filter, chain: IsolationChain1, args: []string{"-o", bridgeIface, "!", "-s", addr.String(), "-j", "DROP"}}
-	)
-
-	version := iptables.IPv4
-
-	if addr.IP.To4() == nil {
+	var version iptables.IPVersion
+	var inDropRule, outDropRule iptRule
+
+	if addr.IP.To4() != nil {
+		version = iptables.IPv4
+		inDropRule = iptRule{table: iptables.Filter, chain: IsolationChain1, args: []string{
+			"-i", bridgeIface, "!", "-d", addr.String(), "-j", "DROP"}}
+		outDropRule = iptRule{table: iptables.Filter, chain: IsolationChain1, args: []string{
+			"-o", bridgeIface, "!", "-s", addr.String(), "-j", "DROP"}}
+	} else {
 		version = iptables.IPv6
 		version = iptables.IPv6
+		inDropRule = iptRule{table: iptables.Filter, chain: IsolationChain1, args: []string{
+			"-i", bridgeIface, "!", "-o", bridgeIface, "!", "-d", addr.String(), "-j", "DROP"}}
+		outDropRule = iptRule{table: iptables.Filter, chain: IsolationChain1, args: []string{
+			"!", "-i", bridgeIface, "-o", bridgeIface, "!", "-s", addr.String(), "-j", "DROP"}}
 	}
 	}
 
 
 	if err := programChainRule(version, inDropRule, "DROP INCOMING", insert); err != nil {
 	if err := programChainRule(version, inDropRule, "DROP INCOMING", insert); err != nil {
@@ -414,6 +420,7 @@ func setupInternalNetworkRules(bridgeIface string, addr *net.IPNet, icc, insert
 	if err := programChainRule(version, outDropRule, "DROP OUTGOING", insert); err != nil {
 	if err := programChainRule(version, outDropRule, "DROP OUTGOING", insert); err != nil {
 		return err
 		return err
 	}
 	}
+
 	// Set Inter Container Communication.
 	// Set Inter Container Communication.
 	return setIcc(version, bridgeIface, icc, insert)
 	return setIcc(version, bridgeIface, icc, insert)
 }
 }