15.9.23

How loadBalancerSourceRanges work in kube proxy and why they dont work in windows the same way

 

This issue came up recently, upstream https://github.com/kubernetes/kubernetes/issues/120033 

The question was: Why doesnt the windows kube proxy filter IPs based on loadBalancerSourceRanges? 


....The reason is bc HNS Loadbalancer is not a Firewall but the IPTables proxy IS a firewall.... So, the way you can sorta do "Firewall like things" in the iptables kube proxy is not going to work in other kube proxy implementations that relay on pure loadbalancing technologies that arent capable of packet filtering.....  

So... I THINK maybe you could implement loadbalancerSourceRanges in windows if you programmed windows firewall API...  i.e. w/ https://github.com/inetaf/wf ?


How this works in kube proxy iptables.......

First the kube proxy makes a firewall chain The HNS Loadbalancer for windows to my knowledge isnt able to make "firewalls" though.  i.e. it cant filter packets... 

loadBalancerTrafficChain := externalTrafficChain
fwChain := svcInfo.firewallChainName
usesFWChain := hasEndpoints && len(svcInfo.LoadBalancerVIPStrings()) > 0 && len(svcInfo.LoadBalancerSourceRanges()) > 0
if usesFWChain {
activeNATChains[fwChain] = true
loadBalancerTrafficChain = fwChain
}

Then we write rules that whiltelist this traffic...

// firewall filter based on each source range
allowFromNode := false
for _, src := range svcInfo.LoadBalancerSourceRanges() {
// 1) allow traffic from IP's matching this CIDR
natRules.Write(args, "-s", src, "-j", string(externalTrafficChain))
_, cidr, err := netutils.ParseCIDRSloppy(src)
if err != nil {
klog.ErrorS(err, "Error parsing CIDR in LoadBalancerSourceRanges, dropping it", "cidr", cidr)
} else if cidr.Contains(proxier.nodeIP) {
// 2) also allow traffic that is coming from a node
allowFromNode = true
}
}

And if those rules arent reached, the packet is dropped by this rules...


// Capture load-balancer ingress.
for _, lbip := range svcInfo.LoadBalancerVIPStrings() {
if hasEndpoints {
natRules.Write(
"-A", string(kubeServicesChain),
"-m", "comment", "--comment", fmt.Sprintf(`"%s loadbalancer IP"`, svcPortNameString),
"-m", protocol, "-p", protocol,
"-d", lbip,
"--dport", strconv.Itoa(svcInfo.Port()),
"-j", string(loadBalancerTrafficChain))

}
if usesFWChain {
filterRules.Write(
"-A", string(kubeProxyFirewallChain),
"-m", "comment", "--comment", fmt.Sprintf(`"%s traffic not accepted by %s"`, svcPortNameString, svcInfo.firewallChainName),
"-m", protocol, "-p", protocol,
"-d", lbip,
"--dport", strconv.Itoa(svcInfo.Port()),
"-j", "DROP")
}
}

No comments:

Post a Comment