diff --git a/net/bridge.go b/net/bridge.go index 713ecf6b..9359fa86 100644 --- a/net/bridge.go +++ b/net/bridge.go @@ -455,6 +455,15 @@ func configureIPTables(config *BridgeConfig) error { return err } } + + if !config.NPC { + // Create a chain for allowing ingress traffic when the bridge is exposed + _ = ipt.NewChain("filter", "WEAVE-EXPOSE") + if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-j", "WEAVE-EXPOSE"); err != nil { + return err + } + } + // Forward from weave to the rest of the world if err = ipt.AppendUnique("filter", "FORWARD", "-i", config.WeaveBridgeName, "!", "-o", config.WeaveBridgeName, "-j", "ACCEPT"); err != nil { return err diff --git a/net/expose.go b/net/expose.go index 7b7454f9..97edecbf 100644 --- a/net/expose.go +++ b/net/expose.go @@ -19,16 +19,31 @@ import ( // * "removeDefaultRoute" - whether to remove a default route installed by the kernel (used only in the AWSVPC mode). // * "npc" - whether is Weave NPC running. func Expose(bridgeName string, ipAddr *net.IPNet, removeDefaultRoute, npc bool) error { + ipt, err := iptables.New() + if err != nil { + return errors.Wrap(err, "iptables.New") + } + cidr := ipAddr.String() + if err := addBridgeIPAddr(bridgeName, ipAddr, removeDefaultRoute); err != nil { return errors.Wrap(err, "addBridgeIPAddr") } - if err := exposeNAT(ipAddr); err != nil { + if err := exposeNAT(ipt, cidr); err != nil { return errors.Wrap(err, "exposeNAT") } if !npc { - // TODO comment why not in npc mode && add filter rules and docs + // Docker 1.13 has changed a default policy of FORWARD chain to DROP + // (https://github.com/moby/moby/pull/28257) which makes containers + // inaccessible from a remote host when the bridge is exposed. + // + // The change breaks e.g. the AWSVPC mode. To overcome this we install + // an explicit rule for accepting forwarded ingress traffic to an + // exposed subnet. + if err := ipt.AppendUnique("filter", "WEAVE-EXPOSE", "-d", cidr, "-j", "ACCEPT"); err != nil { + return errors.Wrap(err, "ipt.AppendUnique") + } } return nil @@ -71,13 +86,7 @@ func addBridgeIPAddr(bridgeName string, addr *net.IPNet, removeDefaultRoute bool return nil } -func exposeNAT(ipnet *net.IPNet) error { - ipt, err := iptables.New() - if err != nil { - return err - } - cidr := ipnet.String() - +func exposeNAT(ipt *iptables.IPTables, cidr string) error { if err := addNatRule(ipt, "-s", cidr, "-d", "224.0.0.0/4", "-j", "RETURN"); err != nil { return err } diff --git a/weave b/weave index 238668de..aaaa4e34 100755 --- a/weave +++ b/weave @@ -508,6 +508,11 @@ destroy_bridge() { run_iptables -t filter -D FORWARD -o $BRIDGE -m state --state NEW -j NFLOG --nflog-group 86 2>/dev/null || true run_iptables -t filter -D FORWARD -o $BRIDGE -j DROP 2>/dev/null || true run_iptables -X WEAVE-NPC >/dev/null 2>&1 || true + + run_iptables -F WEAVE-EXPOSE >/dev/null 2>&1 || true + run_iptables -t filter -D FORWARD -o $BRIDGE -j WEAVE-EXPOSE 2>/dev/null || true + run_iptables -X WEAVE-EXPOSE >/dev/null 2>&1 || true + run_iptables -t nat -F WEAVE >/dev/null 2>&1 || true run_iptables -t nat -D POSTROUTING -j WEAVE >/dev/null 2>&1 || true run_iptables -t nat -D POSTROUTING -o $BRIDGE -j ACCEPT >/dev/null 2>&1 || true @@ -1494,6 +1499,7 @@ case "$COMMAND" in ip addr del dev $BRIDGE $CIDR delete_iptables_rule nat WEAVE -d $CIDR ! -s $CIDR -j MASQUERADE delete_iptables_rule nat WEAVE -s $CIDR ! -d $CIDR -j MASQUERADE + delete_iptables_rule filter WEAVE-EXPOSE -d $CIDR -j ACCEPT when_weave_running delete_dns weave:expose $CIDR fi done