From 4a1fbc7c385bd9c1b4cc5b2d172e2e5190646878 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Fri, 3 May 2019 18:40:59 +0530 Subject: [PATCH 1/2] lazily add iptables rule to drop egress traffic from the pods only if network policies are applied does not address #3464 but just avoids the issue atleast for those who dont use network policies --- npc/controller.go | 22 +++++++++++++++++++--- prog/weave-npc/main.go | 1 - 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/npc/controller.go b/npc/controller.go index e8425993..27dd1a15 100644 --- a/npc/controller.go +++ b/npc/controller.go @@ -3,6 +3,8 @@ package npc import ( "sync" + goiptables "github.com/coreos/go-iptables/iptables" + "github.com/pkg/errors" coreapi "k8s.io/api/core/v1" extnapi "k8s.io/api/extensions/v1beta1" @@ -35,8 +37,9 @@ type controller struct { ipt iptables.Interface ips ipset.Interface - nss map[string]*ns // ns name -> ns struct - nsSelectors *selectorSet // selector string -> nsSelector + nss map[string]*ns // ns name -> ns struct + nsSelectors *selectorSet // selector string -> nsSelector + defaultEgressDrop bool } func New(nodeName string, ipt iptables.Interface, ips ipset.Interface) NetworkPolicyController { @@ -121,11 +124,24 @@ func (npc *controller) AddNetworkPolicy(obj interface{}) error { npc.Lock() defer npc.Unlock() + // lazily add default rule to drop egress traffic only when network policies are applied + if !npc.defaultEgressDrop { + npc.defaultEgressDrop = true + ipt, err := goiptables.New() + if err != nil { + common.Log.Fatalf("Failed to create iptables handler %v", err.Error()) + } + if err := ipt.Append(TableFilter, EgressChain, + "-m", "mark", "!", "--mark", EgressMark, "-j", "DROP"); err != nil { + common.Log.Errorf("Failed to add iptable rule to drop egress traffic from the pods by default due to %s", err.Error()) + npc.defaultEgressDrop = false + } + } + nsName, err := nsName(obj) if err != nil { return err } - common.Log.Infof("EVENT AddNetworkPolicy %s", js(obj)) return npc.withNS(nsName, func(ns *ns) error { return errors.Wrap(ns.addNetworkPolicy(obj), "add network policy") diff --git a/prog/weave-npc/main.go b/prog/weave-npc/main.go index a7407a3f..3944cb88 100644 --- a/prog/weave-npc/main.go +++ b/prog/weave-npc/main.go @@ -183,7 +183,6 @@ func createBaseRules(ipt *iptables.IPTables, ips ipset.Interface) error { {"-m", "state", "--state", "NEW", "-j", string(npc.EgressDefaultChain)}, {"-m", "state", "--state", "NEW", "-m", "mark", "!", "--mark", npc.EgressMark, "-j", string(npc.EgressCustomChain)}, {"-m", "state", "--state", "NEW", "-m", "mark", "!", "--mark", npc.EgressMark, "-j", "NFLOG", "--nflog-group", "86"}, - {"-m", "mark", "!", "--mark", npc.EgressMark, "-j", "DROP"}, }...) if err := net.AddChainWithRules(ipt, npc.TableFilter, npc.EgressChain, ruleSpecs); err != nil { return err From ea2084d871817fdea410198e5e3d79994f7735b1 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Mon, 6 May 2019 16:27:38 +0530 Subject: [PATCH 2/2] return from further processign networkpolicy if base rule failed to gets created --- npc/controller.go | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/npc/controller.go b/npc/controller.go index 27dd1a15..eef4af7f 100644 --- a/npc/controller.go +++ b/npc/controller.go @@ -1,10 +1,9 @@ package npc import ( + "fmt" "sync" - goiptables "github.com/coreos/go-iptables/iptables" - "github.com/pkg/errors" coreapi "k8s.io/api/core/v1" extnapi "k8s.io/api/extensions/v1beta1" @@ -39,7 +38,7 @@ type controller struct { nss map[string]*ns // ns name -> ns struct nsSelectors *selectorSet // selector string -> nsSelector - defaultEgressDrop bool + defaultEgressDrop bool // flag to track if base iptable rule to drop egress traffic is added or not } func New(nodeName string, ipt iptables.Interface, ips ipset.Interface) NetworkPolicyController { @@ -126,15 +125,17 @@ func (npc *controller) AddNetworkPolicy(obj interface{}) error { // lazily add default rule to drop egress traffic only when network policies are applied if !npc.defaultEgressDrop { - npc.defaultEgressDrop = true - ipt, err := goiptables.New() + egressNetworkPolicy, err := isEgressNetworkPolicy(obj) if err != nil { - common.Log.Fatalf("Failed to create iptables handler %v", err.Error()) + return err } - if err := ipt.Append(TableFilter, EgressChain, - "-m", "mark", "!", "--mark", EgressMark, "-j", "DROP"); err != nil { - common.Log.Errorf("Failed to add iptable rule to drop egress traffic from the pods by default due to %s", err.Error()) - npc.defaultEgressDrop = false + if egressNetworkPolicy { + npc.defaultEgressDrop = true + if err := npc.ipt.Append(TableFilter, EgressChain, + "-m", "mark", "!", "--mark", EgressMark, "-j", "DROP"); err != nil { + npc.defaultEgressDrop = false + return fmt.Errorf("Failed to add iptable rule to drop egress traffic from the pods by default due to %s", err.Error()) + } } } @@ -218,3 +219,20 @@ func nsName(obj interface{}) (string, error) { return "", errInvalidNetworkPolicyObjType } + +func isEgressNetworkPolicy(obj interface{}) (bool, error) { + if policy, ok := obj.(*networkingv1.NetworkPolicy); ok { + if len(policy.Spec.PolicyTypes) > 0 { + for _, policyType := range policy.Spec.PolicyTypes { + if policyType == networkingv1.PolicyTypeEgress { + return true, nil + } + } + } + if policy.Spec.Egress != nil { + return true, nil + } + return false, nil + } + return false, errInvalidNetworkPolicyObjType +}