Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 1946696: iptables: add filter on node local traffic #489

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 11 additions & 21 deletions go-controller/pkg/node/gateway_iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,31 +137,21 @@ func getLegacySharedGatewayInitRules(chain string, proto iptables.Protocol) []ip
}
}

func getNodePortIPTRules(svcPort kapi.ServicePort, nodeIP *net.IPNet, targetIP string, targetPort int32) []iptRule {
func getNodePortIPTRules(svcPort kapi.ServicePort, targetIP string, targetPort int32) []iptRule {
var protocol iptables.Protocol
if utilnet.IsIPv6String(targetIP) {
protocol = iptables.ProtocolIPv6
} else {
protocol = iptables.ProtocolIPv4
}
var natArgs []string
if nodeIP != nil {
natArgs = []string{
"-p", string(svcPort.Protocol),
"-d", nodeIP.IP.String(),
"--dport", fmt.Sprintf("%d", svcPort.NodePort),
"-j", "DNAT",
"--to-destination", util.JoinHostPortInt32(targetIP, targetPort),
}
} else {
natArgs = []string{
"-p", string(svcPort.Protocol),
"--dport", fmt.Sprintf("%d", svcPort.NodePort),
"-j", "DNAT",
"--to-destination", util.JoinHostPortInt32(targetIP, targetPort),
}
natArgs := []string{
"-p", string(svcPort.Protocol),
"-m", "addrtype",
"--dst-type", "LOCAL",
"--dport", fmt.Sprintf("%d", svcPort.NodePort),
"-j", "DNAT",
"--to-destination", util.JoinHostPortInt32(targetIP, targetPort),
}

return []iptRule{
{
table: "nat",
Expand Down Expand Up @@ -324,7 +314,7 @@ func recreateIPTRules(table, chain string, keepIPTRules []iptRule) {
// only incoming traffic on that IP will be accepted for NodePort rules; otherwise incoming traffic on the NodePort
// on all IPs will be accepted. If gatewayIP is "", then NodePort traffic will be DNAT'ed to the service port on
// the service's ClusterIP. Otherwise, it will be DNAT'ed to the NodePort on the gatewayIP.
func getGatewayIPTRules(service *kapi.Service, gatewayIP string, nodeIP *net.IPNet) []iptRule {
func getGatewayIPTRules(service *kapi.Service, gatewayIP string) []iptRule {
rules := make([]iptRule, 0)
for _, svcPort := range service.Spec.Ports {
if util.ServiceTypeHasNodePort(service) {
Expand All @@ -339,9 +329,9 @@ func getGatewayIPTRules(service *kapi.Service, gatewayIP string, nodeIP *net.IPN
continue
}
if gatewayIP == "" {
rules = append(rules, getNodePortIPTRules(svcPort, nodeIP, service.Spec.ClusterIP, svcPort.Port)...)
rules = append(rules, getNodePortIPTRules(svcPort, service.Spec.ClusterIP, svcPort.Port)...)
} else {
rules = append(rules, getNodePortIPTRules(svcPort, nodeIP, gatewayIP, svcPort.NodePort)...)
rules = append(rules, getNodePortIPTRules(svcPort, gatewayIP, svcPort.NodePort)...)
}
}
for _, externalIP := range service.Spec.ExternalIPs {
Expand Down
6 changes: 3 additions & 3 deletions go-controller/pkg/node/gateway_localnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (l *localPortWatcher) addService(svc *kapi.Service) error {

if port.NodePort > 0 {
if gatewayIP != "" {
iptRules = append(iptRules, getNodePortIPTRules(port, nil, ip, port.Port)...)
iptRules = append(iptRules, getNodePortIPTRules(port, ip, port.Port)...)
klog.V(5).Infof("Will add iptables rule for NodePort: %v and "+
"protocol: %v", port.NodePort, port.Protocol)
} else {
Expand Down Expand Up @@ -283,7 +283,7 @@ func (l *localPortWatcher) deleteService(svc *kapi.Service) error {
iptRules = append(iptRules, getLoadBalancerIPTRules(svc, port, ip, port.Port)...)
if port.NodePort > 0 {
if gatewayIP != "" {
iptRules = append(iptRules, getNodePortIPTRules(port, nil, ip, port.Port)...)
iptRules = append(iptRules, getNodePortIPTRules(port, ip, port.Port)...)
klog.V(5).Infof("Will delete iptables rule for NodePort: %v and "+
"protocol: %v", port.NodePort, port.Protocol)
}
Expand Down Expand Up @@ -359,7 +359,7 @@ func (l *localPortWatcher) SyncServices(serviceInterface []interface{}) {
gatewayIP = l.gatewayIPv6
}
if gatewayIP != "" {
keepIPTRules = append(keepIPTRules, getGatewayIPTRules(svc, gatewayIP, nil)...)
keepIPTRules = append(keepIPTRules, getGatewayIPTRules(svc, gatewayIP)...)
}
keepRoutes = append(keepRoutes, svc.Spec.ExternalIPs...)
}
Expand Down
8 changes: 4 additions & 4 deletions go-controller/pkg/node/gateway_localnet_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ var _ = Describe("Node Operations", func() {
expectedTables := map[string]util.FakeTable{
"nat": {
"OVN-KUBE-NODEPORT": []string{
fmt.Sprintf("-p %s --dport %v -j DNAT --to-destination %s:%v", service.Spec.Ports[0].Protocol, service.Spec.Ports[0].NodePort, service.Spec.ClusterIP, service.Spec.Ports[0].Port),
fmt.Sprintf("-p %s -m addrtype --dst-type LOCAL --dport %v -j DNAT --to-destination %s:%v", service.Spec.Ports[0].Protocol, service.Spec.Ports[0].NodePort, service.Spec.ClusterIP, service.Spec.Ports[0].Port),
},
},
}
Expand Down Expand Up @@ -442,7 +442,7 @@ var _ = Describe("Node Operations", func() {
expectedTables4 := map[string]util.FakeTable{
"nat": {
"OVN-KUBE-NODEPORT": []string{
fmt.Sprintf("-p %s --dport %v -j DNAT --to-destination %s:%v", service.Spec.Ports[0].Protocol, service.Spec.Ports[0].NodePort, service.Spec.ClusterIPs[0], service.Spec.Ports[0].Port),
fmt.Sprintf("-p %s -m addrtype --dst-type LOCAL --dport %v -j DNAT --to-destination %s:%v", service.Spec.Ports[0].Protocol, service.Spec.Ports[0].NodePort, service.Spec.ClusterIPs[0], service.Spec.Ports[0].Port),
},
},
}
Expand All @@ -454,7 +454,7 @@ var _ = Describe("Node Operations", func() {
expectedTables6 := map[string]util.FakeTable{
"nat": {
"OVN-KUBE-NODEPORT": []string{
fmt.Sprintf("-p %s --dport %v -j DNAT --to-destination [%s]:%v", service.Spec.Ports[0].Protocol, service.Spec.Ports[0].NodePort, service.Spec.ClusterIPs[1], service.Spec.Ports[0].Port),
fmt.Sprintf("-p %s -m addrtype --dst-type LOCAL --dport %v -j DNAT --to-destination [%s]:%v", service.Spec.Ports[0].Protocol, service.Spec.Ports[0].NodePort, service.Spec.ClusterIPs[1], service.Spec.Ports[0].Port),
},
},
}
Expand Down Expand Up @@ -684,7 +684,7 @@ var _ = Describe("Node Operations", func() {
expectedTables := map[string]util.FakeTable{
"nat": {
"OVN-KUBE-NODEPORT": []string{
fmt.Sprintf("-p %s --dport %v -j DNAT --to-destination %s:%v", service.Spec.Ports[0].Protocol, nodePort, service.Spec.ClusterIP, service.Spec.Ports[0].Port),
fmt.Sprintf("-p %s -m addrtype --dst-type LOCAL --dport %v -j DNAT --to-destination %s:%v", service.Spec.Ports[0].Protocol, nodePort, service.Spec.ClusterIP, service.Spec.Ports[0].Port),
},
},
}
Expand Down
14 changes: 6 additions & 8 deletions go-controller/pkg/node/gateway_shared_intf.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ type nodePortWatcher struct {
ofportPhys string
ofportPatch string
gwBridge string
nodeIP *net.IPNet
}

// AddService handles configuring shared gateway bridge flows to steer External IP, Node Port, Ingress LB traffic into OVN
Expand Down Expand Up @@ -119,7 +118,7 @@ func (npw *nodePortWatcher) AddService(service *kapi.Service) {
}
}

addSharedGatewayIptRules(service, npw.nodeIP)
addSharedGatewayIptRules(service)
}

func (npw *nodePortWatcher) UpdateService(old, new *kapi.Service) {
Expand Down Expand Up @@ -206,7 +205,7 @@ func (npw *nodePortWatcher) DeleteService(service *kapi.Service) {
}
}

delSharedGatewayIptRules(service, npw.nodeIP)
delSharedGatewayIptRules(service)
}

func (npw *nodePortWatcher) SyncServices(services []interface{}) {
Expand Down Expand Up @@ -250,7 +249,7 @@ func (npw *nodePortWatcher) SyncServices(services []interface{}) {
}
}

syncSharedGatewayIptRules(services, npw.nodeIP)
syncSharedGatewayIptRules(services)

stdout, stderr, err := util.RunOVSOfctl("dump-flows",
npw.gwBridge)
Expand Down Expand Up @@ -518,7 +517,7 @@ func newSharedGateway(nodeName string, subnets []*net.IPNet, gwNextHops []net.IP
klog.Info("Creating new shared gateway")
gw := &gateway{}

bridgeName, uplinkName, macAddress, ips, err := gatewayInitInternal(
bridgeName, uplinkName, macAddress, _, err := gatewayInitInternal(
nodeName, gwIntf, subnets, gwNextHops, nodeAnnotator)
if err != nil {
return nil, err
Expand All @@ -545,7 +544,7 @@ func newSharedGateway(nodeName string, subnets []*net.IPNet, gwNextHops []net.IP

if config.Gateway.NodeportEnable {
klog.Info("Creating Shared Gateway Node Port Watcher")
gw.nodePortWatcher, err = newNodePortWatcher(patchPort, bridgeName, uplinkName, ips[0])
gw.nodePortWatcher, err = newNodePortWatcher(patchPort, bridgeName, uplinkName)
if err != nil {
return err
}
Expand All @@ -557,7 +556,7 @@ func newSharedGateway(nodeName string, subnets []*net.IPNet, gwNextHops []net.IP
return gw, nil
}

func newNodePortWatcher(patchPort, gwBridge, gwIntf string, nodeIP *net.IPNet) (*nodePortWatcher, error) {
func newNodePortWatcher(patchPort, gwBridge, gwIntf string) (*nodePortWatcher, error) {
// Get ofport of patchPort
ofportPatch, stderr, err := util.RunOVSVsctl("--if-exists", "get",
"interface", patchPort, "ofport")
Expand Down Expand Up @@ -587,7 +586,6 @@ func newNodePortWatcher(patchPort, gwBridge, gwIntf string, nodeIP *net.IPNet) (
ofportPhys: ofportPhys,
ofportPatch: ofportPatch,
gwBridge: gwBridge,
nodeIP: nodeIP,
}
return npw, nil
}
Expand Down
12 changes: 6 additions & 6 deletions go-controller/pkg/node/gateway_shared_intf_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,29 +93,29 @@ func setupLocalNodeAccessBridge(nodeName string, subnets []*net.IPNet) error {
return nil
}

func addSharedGatewayIptRules(service *kapi.Service, nodeIP *net.IPNet) {
rules := getGatewayIPTRules(service, "", nodeIP)
func addSharedGatewayIptRules(service *kapi.Service) {
rules := getGatewayIPTRules(service, "")
if err := addIptRules(rules); err != nil {
klog.Errorf("Failed to add iptables rules for service %s/%s: %v", service.Namespace, service.Name, err)
}
}

func delSharedGatewayIptRules(service *kapi.Service, nodeIP *net.IPNet) {
rules := getGatewayIPTRules(service, "", nodeIP)
func delSharedGatewayIptRules(service *kapi.Service) {
rules := getGatewayIPTRules(service, "")
if err := delIptRules(rules); err != nil {
klog.Errorf("Failed to delete iptables rules for service %s/%s: %v", service.Namespace, service.Name, err)
}
}

func syncSharedGatewayIptRules(services []interface{}, nodeIP *net.IPNet) {
func syncSharedGatewayIptRules(services []interface{}) {
keepIPTRules := []iptRule{}
for _, service := range services {
svc, ok := service.(*kapi.Service)
if !ok {
klog.Errorf("Spurious object in syncSharedGatewayIptRules: %v", service)
continue
}
keepIPTRules = append(keepIPTRules, getGatewayIPTRules(svc, "", nodeIP)...)
keepIPTRules = append(keepIPTRules, getGatewayIPTRules(svc, "")...)
}
for _, chain := range []string{iptableNodePortChain, iptableExternalIPChain} {
recreateIPTRules("nat", chain, keepIPTRules)
Expand Down