From 6b69a6a23a8b63f0b11d93dd7bbc44e06fde5a7a Mon Sep 17 00:00:00 2001 From: Boris Djurdjevic Date: Fri, 25 Oct 2019 08:45:25 +0200 Subject: [PATCH] Fix connection resets during firewall sync For very busy tcp connections there is a small possibility to receive a TCP RST during the iptables sync. A default `REJECT` rule is chronologically added before the allow-`RELATED,ESTABLISHED` rule for ingress and egress connections. In between of the creation of these two rules a connection reset can happen for already established connections. This commits swaps the order of rule insertion. --- .../netpol/network_policy_controller.go | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/pkg/controllers/netpol/network_policy_controller.go b/pkg/controllers/netpol/network_policy_controller.go index f5b458305e..554158d86d 100644 --- a/pkg/controllers/netpol/network_policy_controller.go +++ b/pkg/controllers/netpol/network_policy_controller.go @@ -748,6 +748,20 @@ func (npc *NetworkPolicyController) syncPodFirewallChains(version string) (map[s } } + // ensure statefull firewall, that permits return traffic for the traffic originated by the pod + comment = "rule for stateful firewall for pod" + args = []string{"-m", "comment", "--comment", comment, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"} + exists, err = iptablesCmdHandler.Exists("filter", podFwChainName, args...) + if err != nil { + return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) + } + if !exists { + err := iptablesCmdHandler.Insert("filter", podFwChainName, 1, args...) + if err != nil { + return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) + } + } + // ensure there is rule in filter table and FORWARD chain to jump to pod specific firewall chain // this rule applies to the traffic getting routed (coming for other node pods) comment = "rule to jump traffic destined to POD name:" + pod.name + " namespace: " + pod.namespace + @@ -803,20 +817,6 @@ func (npc *NetworkPolicyController) syncPodFirewallChains(version string) (map[s if err != nil { return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) } - - // ensure statefull firewall, that permits return traffic for the traffic originated by the pod - comment = "rule for stateful firewall for pod" - args = []string{"-m", "comment", "--comment", comment, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"} - exists, err = iptablesCmdHandler.Exists("filter", podFwChainName, args...) - if err != nil { - return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) - } - if !exists { - err := iptablesCmdHandler.Insert("filter", podFwChainName, 1, args...) - if err != nil { - return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) - } - } } // loop through the pods running on the node which egress network policies to be applied @@ -859,12 +859,26 @@ func (npc *NetworkPolicyController) syncPodFirewallChains(version string) (map[s } } + // ensure statefull firewall, that permits return traffic for the traffic originated by the pod + comment := "rule for stateful firewall for pod" + args := []string{"-m", "comment", "--comment", comment, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"} + exists, err := iptablesCmdHandler.Exists("filter", podFwChainName, args...) + if err != nil { + return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) + } + if !exists { + err := iptablesCmdHandler.Insert("filter", podFwChainName, 1, args...) + if err != nil { + return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) + } + } + // ensure there is rule in filter table and FORWARD chain to jump to pod specific firewall chain // this rule applies to the traffic getting routed (coming for other node pods) - comment := "rule to jump traffic from POD name:" + pod.name + " namespace: " + pod.namespace + + comment = "rule to jump traffic from POD name:" + pod.name + " namespace: " + pod.namespace + " to chain " + podFwChainName - args := []string{"-m", "comment", "--comment", comment, "-s", pod.ip, "-j", podFwChainName} - exists, err := iptablesCmdHandler.Exists("filter", "FORWARD", args...) + args = []string{"-m", "comment", "--comment", comment, "-s", pod.ip, "-j", podFwChainName} + exists, err = iptablesCmdHandler.Exists("filter", "FORWARD", args...) if err != nil { return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) } @@ -901,20 +915,6 @@ func (npc *NetworkPolicyController) syncPodFirewallChains(version string) (map[s if err != nil { return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) } - - // ensure statefull firewall, that permits return traffic for the traffic originated by the pod - comment = "rule for stateful firewall for pod" - args = []string{"-m", "comment", "--comment", comment, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"} - exists, err = iptablesCmdHandler.Exists("filter", podFwChainName, args...) - if err != nil { - return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) - } - if !exists { - err := iptablesCmdHandler.Insert("filter", podFwChainName, 1, args...) - if err != nil { - return nil, fmt.Errorf("Failed to run iptables command: %s", err.Error()) - } - } } return activePodFwChains, nil