From 483bf629dbe6ab98a4256c61f9c3c917cb2081fb Mon Sep 17 00:00:00 2001 From: tydra-wang Date: Wed, 25 May 2022 23:19:34 +0800 Subject: [PATCH] Feature: yurthub supports setting ipv6 dummy if ip --- cmd/yurthub/app/options/options.go | 41 +++++++++++++++++++++--------- cmd/yurthub/app/start.go | 2 +- pkg/util/ip/ip.go | 16 ++++++++++++ pkg/util/ip/ip_test.go | 16 ++++++++++++ pkg/yurthub/network/iptables.go | 24 +++++++++-------- 5 files changed, 76 insertions(+), 23 deletions(-) diff --git a/cmd/yurthub/app/options/options.go b/cmd/yurthub/app/options/options.go index cee8d1d10a6..5ec07e4cc82 100644 --- a/cmd/yurthub/app/options/options.go +++ b/cmd/yurthub/app/options/options.go @@ -23,6 +23,8 @@ import ( "time" "github.com/spf13/pflag" + "k8s.io/klog/v2" + utilnet "k8s.io/utils/net" "github.com/openyurtio/openyurt/pkg/projectinfo" "github.com/openyurtio/openyurt/pkg/yurthub/storage/disk" @@ -30,8 +32,10 @@ import ( ) const ( - DummyIfCIDR = "169.254.0.0/16" - ExclusiveCIDR = "169.254.31.0/24" + DefaultDummyIfIP4 = "169.254.2.1" + DefaultDummyIfIP6 = "fd00::2:1" + DummyIfCIDR4 = "169.254.0.0/16" + ExclusiveCIDR = "169.254.31.0/24" ) // YurtHubOptions is the main settings for the yurthub @@ -90,7 +94,6 @@ func NewYurtHubOptions() *YurtHubOptions { EnableProfiling: true, EnableDummyIf: true, EnableIptables: true, - HubAgentDummyIfIP: "169.254.2.1", HubAgentDummyIfName: fmt.Sprintf("%s-dummy0", projectinfo.GetHubName()), DiskCachePath: disk.CacheBaseDir, AccessServerThroughHub: true, @@ -103,8 +106,8 @@ func NewYurtHubOptions() *YurtHubOptions { return o } -// ValidateOptions validates YurtHubOptions -func ValidateOptions(options *YurtHubOptions) error { +// Validate validates YurtHubOptions +func (options *YurtHubOptions) Validate() error { if len(options.NodeName) == 0 { return fmt.Errorf("node name is empty") } @@ -125,7 +128,7 @@ func ValidateOptions(options *YurtHubOptions) error { return fmt.Errorf("working mode %s is not supported", options.WorkingMode) } - if err := verifyDummyIP(options.HubAgentDummyIfIP); err != nil { + if err := options.verifyDummyIP(); err != nil { return fmt.Errorf("dummy ip %s is not invalid, %w", options.HubAgentDummyIfIP, err) } @@ -168,21 +171,35 @@ func (o *YurtHubOptions) AddFlags(fs *pflag.FlagSet) { fs.BoolVar(&o.EnableNodePool, "enable-node-pool", o.EnableNodePool, "enable list/watch nodepools resource or not for filters(only used for testing)") } -// verifyDummyIP verify the specified ip is valid or not -func verifyDummyIP(dummyIP string) error { - //169.254.2.1/32 +// verifyDummyIP verify the specified ip is valid or not and set the default ip if empty +func (o *YurtHubOptions) verifyDummyIP() error { + if o.HubAgentDummyIfIP == "" { + if utilnet.IsIPv6String(o.YurtHubHost) { + o.HubAgentDummyIfIP = DefaultDummyIfIP6 + } else { + o.HubAgentDummyIfIP = DefaultDummyIfIP4 + } + klog.Infof("dummy ip not set, will use %s as default", o.HubAgentDummyIfIP) + return nil + } + + dummyIP := o.HubAgentDummyIfIP dip := net.ParseIP(dummyIP) if dip == nil { return fmt.Errorf("dummy ip %s is invalid", dummyIP) } - _, dummyIfIPNet, err := net.ParseCIDR(DummyIfCIDR) + if utilnet.IsIPv6(dip) { + return nil + } + + _, dummyIfIPNet, err := net.ParseCIDR(DummyIfCIDR4) if err != nil { - return fmt.Errorf("cidr(%s) is invalid, %w", DummyIfCIDR, err) + return fmt.Errorf("cidr(%s) is invalid, %w", DummyIfCIDR4, err) } if !dummyIfIPNet.Contains(dip) { - return fmt.Errorf("dummy ip %s is not in cidr(%s)", dummyIP, DummyIfCIDR) + return fmt.Errorf("dummy ip %s is not in cidr(%s)", dummyIP, DummyIfCIDR4) } _, exclusiveIPNet, err := net.ParseCIDR(ExclusiveCIDR) diff --git a/cmd/yurthub/app/start.go b/cmd/yurthub/app/start.go index 23c4838afd7..21f1053d678 100644 --- a/cmd/yurthub/app/start.go +++ b/cmd/yurthub/app/start.go @@ -59,7 +59,7 @@ func NewCmdStartYurtHub(stopCh <-chan struct{}) *cobra.Command { cmd.Flags().VisitAll(func(flag *pflag.Flag) { klog.V(1).Infof("FLAG: --%s=%q", flag.Name, flag.Value) }) - if err := options.ValidateOptions(yurtHubOptions); err != nil { + if err := yurtHubOptions.Validate(); err != nil { klog.Fatalf("validate options: %v", err) } diff --git a/pkg/util/ip/ip.go b/pkg/util/ip/ip.go index 2703c6e690b..2d1c9b239a5 100644 --- a/pkg/util/ip/ip.go +++ b/pkg/util/ip/ip.go @@ -1,3 +1,19 @@ +/* +Copyright 2021 The OpenYurt Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package ip import ( diff --git a/pkg/util/ip/ip_test.go b/pkg/util/ip/ip_test.go index 527d6f4caf3..efcef4195d3 100644 --- a/pkg/util/ip/ip_test.go +++ b/pkg/util/ip/ip_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2021 The OpenYurt Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package ip import ( diff --git a/pkg/yurthub/network/iptables.go b/pkg/yurthub/network/iptables.go index 379c69ffbc6..0c5a8519125 100644 --- a/pkg/yurthub/network/iptables.go +++ b/pkg/yurthub/network/iptables.go @@ -22,6 +22,7 @@ import ( utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/klog/v2" "k8s.io/utils/exec" + utilnet "k8s.io/utils/net" "github.com/openyurtio/openyurt/pkg/util/iptables" ) @@ -40,6 +41,9 @@ type IptablesManager struct { func NewIptablesManager(dummyIfIP, dummyIfPort string) *IptablesManager { protocol := iptables.ProtocolIpv4 + if utilnet.IsIPv6String(dummyIfIP) { + protocol = iptables.ProtocolIpv6 + } execer := exec.New() iptInterface := iptables.New(execer, protocol) @@ -63,16 +67,16 @@ func makeupIptablesRules(ifIP, ifPort string) []iptablesRule { {iptables.Prepend, iptables.Table("raw"), iptables.ChainOutput, []string{"-p", "tcp", "--sport", ifPort, "-s", ifIP, "-j", "NOTRACK"}}, // accept traffic from 169.254.2.1:10261 {iptables.Prepend, iptables.TableFilter, iptables.ChainOutput, []string{"-p", "tcp", "--sport", ifPort, "-s", ifIP, "-j", "ACCEPT"}}, - // skip connection track for traffic from container to 127.0.0.1:10261 - {iptables.Prepend, iptables.Table("raw"), iptables.ChainPrerouting, []string{"-p", "tcp", "--dport", ifPort, "--destination", "127.0.0.1", "-j", "NOTRACK"}}, - // skip connection track for traffic from host network to 127.0.0.1:10261 - {iptables.Prepend, iptables.Table("raw"), iptables.ChainOutput, []string{"-p", "tcp", "--dport", ifPort, "--destination", "127.0.0.1", "-j", "NOTRACK"}}, - // accept traffic to 127.0.0.1:10261 - {iptables.Prepend, iptables.TableFilter, iptables.ChainInput, []string{"-p", "tcp", "--dport", ifPort, "--destination", "127.0.0.1", "-j", "ACCEPT"}}, - // skip connection track for traffic from 127.0.0.1:10261 - {iptables.Prepend, iptables.Table("raw"), iptables.ChainOutput, []string{"-p", "tcp", "--sport", ifPort, "-s", "127.0.0.1", "-j", "NOTRACK"}}, - // accept traffic from 127.0.0.1:10261 - {iptables.Prepend, iptables.TableFilter, iptables.ChainOutput, []string{"-p", "tcp", "--sport", ifPort, "-s", "127.0.0.1", "-j", "ACCEPT"}}, + // skip connection track for traffic from container to localhost:10261 + {iptables.Prepend, iptables.Table("raw"), iptables.ChainPrerouting, []string{"-p", "tcp", "--dport", ifPort, "--destination", "localhost", "-j", "NOTRACK"}}, + // skip connection track for traffic from host network to localhost:10261 + {iptables.Prepend, iptables.Table("raw"), iptables.ChainOutput, []string{"-p", "tcp", "--dport", ifPort, "--destination", "localhost", "-j", "NOTRACK"}}, + // accept traffic to localhost:10261 + {iptables.Prepend, iptables.TableFilter, iptables.ChainInput, []string{"-p", "tcp", "--dport", ifPort, "--destination", "localhost", "-j", "ACCEPT"}}, + // skip connection track for traffic from localhost:10261 + {iptables.Prepend, iptables.Table("raw"), iptables.ChainOutput, []string{"-p", "tcp", "--sport", ifPort, "-s", "localhost", "-j", "NOTRACK"}}, + // accept traffic from localhost:10261 + {iptables.Prepend, iptables.TableFilter, iptables.ChainOutput, []string{"-p", "tcp", "--sport", ifPort, "-s", "localhost", "-j", "ACCEPT"}}, } }