diff --git a/app/cni/pkg/cni/injector_linux.go b/app/cni/pkg/cni/injector_linux.go index 30f6de2d7cc5..211819bd907d 100644 --- a/app/cni/pkg/cni/injector_linux.go +++ b/app/cni/pkg/cni/injector_linux.go @@ -69,6 +69,8 @@ func Inject(netns string, logger logr.Logger, intermediateConfig *IntermediateCo } func mapToConfig(intermediateConfig *IntermediateConfig, logWriter *bufio.Writer) (*config.Config, error) { + cfg := config.DefaultConfig() + port, err := convertToUint16("inbound port", intermediateConfig.targetPort) if err != nil { return nil, err @@ -88,20 +90,13 @@ func mapToConfig(intermediateConfig *IntermediateConfig, logWriter *bufio.Writer return nil, err } - cfg := config.Config{ - RuntimeStdout: logWriter, - Owner: config.Owner{ - UID: intermediateConfig.noRedirectUID, - }, - Redirect: config.Redirect{ - Outbound: config.TrafficFlow{ - Enabled: true, - Port: port, - ExcludePorts: excludePorts, - ExcludePortsForUIDs: excludePortsForUIDsParsed, - }, - }, - } + cfg.Verbose = true + cfg.RuntimeStdout = logWriter + cfg.Owner.UID = intermediateConfig.noRedirectUID + cfg.Redirect.Outbound.Enabled = true + cfg.Redirect.Outbound.Port = port + cfg.Redirect.Outbound.ExcludePorts = excludePorts + cfg.Redirect.Outbound.ExcludePortsForUIDs = excludePortsForUIDsParsed isGateway, err := GetEnabled(intermediateConfig.isGateway) if err != nil { @@ -133,12 +128,11 @@ func mapToConfig(intermediateConfig *IntermediateConfig, logWriter *bufio.Writer if err != nil { return nil, err } - cfg.Redirect.Inbound = config.TrafficFlow{ - Enabled: true, - Port: inboundPort, - PortIPv6: inboundPortV6, - ExcludePorts: excludedPorts, - } + + cfg.Redirect.Inbound.Enabled = true + cfg.Redirect.Inbound.Port = inboundPort + cfg.Redirect.Inbound.PortIPv6 = inboundPortV6 + cfg.Redirect.Inbound.ExcludePorts = excludedPorts } useBuiltinDNS, err := GetEnabled(intermediateConfig.builtinDNS) @@ -150,13 +144,13 @@ func mapToConfig(intermediateConfig *IntermediateConfig, logWriter *bufio.Writer if err != nil { return nil, err } - cfg.Redirect.DNS = config.DNS{ - Enabled: true, - Port: builtinDnsPort, - CaptureAll: true, - ConntrackZoneSplit: true, - } + + cfg.Redirect.DNS.Enabled = true + cfg.Redirect.DNS.Port = builtinDnsPort + cfg.Redirect.DNS.CaptureAll = true + cfg.Redirect.DNS.ConntrackZoneSplit = true } + return &cfg, nil } diff --git a/app/kumactl/cmd/install/install_transparent_proxy.go b/app/kumactl/cmd/install/install_transparent_proxy.go index f7b7ac1e78a8..0ad0ea399d27 100644 --- a/app/kumactl/cmd/install/install_transparent_proxy.go +++ b/app/kumactl/cmd/install/install_transparent_proxy.go @@ -7,7 +7,6 @@ import ( "fmt" os_user "os/user" "runtime" - "time" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -19,10 +18,7 @@ import ( ) type transparentProxyArgs struct { - DryRun bool - Verbose bool RedirectPortOutBound string - RedirectInbound bool IpFamilyMode string RedirectPortInBound string RedirectPortInBoundV6 string @@ -33,31 +29,15 @@ type transparentProxyArgs struct { ExcludeOutboundPortsForUIDs []string UID string User string - RedirectDNS bool - RedirectAllDNSTraffic bool AgentDNSListenerPort string - DNSUpstreamTargetChain string - StoreFirewalld bool SkipDNSConntrackZoneSplit bool - EbpfEnabled bool - EbpfProgramsSourcePath string - EbpfInstanceIP string - EbpfBPFFSPath string - EbpfCgroupPath string - EbpfTCAttachIface string - VnetNetworks []string - Wait uint - WaitInterval uint - MaxRetries int - SleepBetweenRetries time.Duration } func newInstallTransparentProxy() *cobra.Command { + cfg := config.DefaultConfig() + args := transparentProxyArgs{ - DryRun: false, - Verbose: false, RedirectPortOutBound: "15001", - RedirectInbound: true, RedirectPortInBound: "15006", // this argument is to be deprecated, it now defaults to the same port with ipv4 (instead of 15010) // before deprecation, the user can still change it as needed @@ -69,23 +49,10 @@ func newInstallTransparentProxy() *cobra.Command { ExcludeOutboundUDPPortsForUIDs: []string{}, UID: "", User: "", - RedirectDNS: false, - RedirectAllDNSTraffic: false, AgentDNSListenerPort: "15053", - DNSUpstreamTargetChain: "", - StoreFirewalld: false, SkipDNSConntrackZoneSplit: false, - EbpfEnabled: false, - EbpfProgramsSourcePath: "/tmp/kuma-ebpf", - EbpfBPFFSPath: "/sys/fs/bpf", - EbpfCgroupPath: "/sys/fs/cgroup", - EbpfTCAttachIface: "", - VnetNetworks: []string{}, - Wait: 5, - WaitInterval: 0, - MaxRetries: 4, - SleepBetweenRetries: 2 * time.Second, } + cmd := &cobra.Command{ Use: "transparent-proxy", Short: "Install Transparent Proxy pre-requisites on the host", @@ -137,8 +104,12 @@ runuser -u kuma-dp -- \ --binary-path /usr/local/bin/envoy `, + PreRun: func(cmd *cobra.Command, _ []string) { + cfg.RuntimeStdout = cmd.OutOrStdout() + cfg.RuntimeStderr = cmd.ErrOrStderr() + }, RunE: func(cmd *cobra.Command, _ []string) error { - if !args.DryRun && runtime.GOOS != "linux" { + if !cfg.DryRun && runtime.GOOS != "linux" { return errors.Errorf("transparent proxy will work only on Linux OSes") } @@ -146,25 +117,25 @@ runuser -u kuma-dp -- \ return errors.Errorf("--kuma-dp-user or --kuma-dp-uid should be supplied") } - if args.RedirectAllDNSTraffic && args.RedirectDNS { + if cfg.Redirect.DNS.CaptureAll && cfg.Redirect.DNS.Enabled { return errors.Errorf("one of --redirect-dns or --redirect-all-dns-traffic should be specified") } - if args.RedirectAllDNSTraffic { - args.RedirectDNS = true + if cfg.Redirect.DNS.CaptureAll { + cfg.Redirect.DNS.Enabled = true } - if args.EbpfEnabled { - if args.EbpfInstanceIP == "" { + if cfg.Ebpf.Enabled { + if cfg.Ebpf.InstanceIP == "" { return errors.Errorf("--ebpf-instance-ip flag has to be specified --ebpf-enabled is provided") } - if args.StoreFirewalld { - _, _ = cmd.ErrOrStderr().Write([]byte("# [WARNING] --store-firewalld will be ignored when --ebpf-enabled is being used\n")) + if cfg.StoreFirewalld { + fmt.Fprintln(cfg.RuntimeStderr, "# [WARNING] --store-firewalld will be ignored when --ebpf-enabled is being used") } if args.SkipDNSConntrackZoneSplit { - _, _ = cmd.ErrOrStderr().Write([]byte("# [WARNING] --skip-dns-conntrack-zone-split will be ignored when --ebpf-enabled is being used\n")) + fmt.Fprintln(cfg.RuntimeStderr, "# [WARNING] --skip-dns-conntrack-zone-split will be ignored when --ebpf-enabled is being used") } } @@ -173,66 +144,82 @@ runuser -u kuma-dp -- \ if args.RedirectPortInBoundV6 != "" && args.RedirectPortInBoundV6 != fmt.Sprintf("%d", defaultCfg.Redirect.Inbound.Port) /* new default value, identical to ipv4 port */ && args.RedirectPortInBoundV6 != fmt.Sprintf("%d", defaultCfg.Redirect.Inbound.PortIPv6) /* old default value, dedicated for ipv6 */ { - _, _ = cmd.ErrOrStderr().Write([]byte("# [WARNING] flag --redirect-inbound-port-v6 is deprecated, use --redirect-inbound-port or --ip-family-mode ipv4 instead\n")) + fmt.Fprintln(cfg.RuntimeStderr, "# [WARNING] flag --redirect-inbound-port-v6 is deprecated, use --redirect-inbound-port or --ip-family-mode ipv4 instead") } if len(args.ExcludeOutboundPorts) > 0 && (len(args.ExcludeOutboundUDPPortsForUIDs) > 0 || len(args.ExcludeOutboundTCPPortsForUIDs) > 0) { return errors.Errorf("--exclude-outbound-ports-for-uids set you can't use --exclude-outbound-tcp-ports-for-uids and --exclude-outbound-udp-ports-for-uids anymore") } if len(args.ExcludeOutboundTCPPortsForUIDs) > 0 { - _, _ = cmd.ErrOrStderr().Write([]byte("# [WARNING] flag --exclude-outbound-tcp-ports-for-uids is deprecated use --exclude-outbound-ports-for-uids instead\n")) + fmt.Fprintln(cfg.RuntimeStderr, "# [WARNING] flag --exclude-outbound-tcp-ports-for-uids is deprecated use --exclude-outbound-ports-for-uids instead") for _, v := range args.ExcludeOutboundTCPPortsForUIDs { args.ExcludeOutboundPortsForUIDs = append(args.ExcludeOutboundPortsForUIDs, fmt.Sprintf("tcp:%s", v)) } } if len(args.ExcludeOutboundUDPPortsForUIDs) > 0 { - _, _ = cmd.ErrOrStderr().Write([]byte("# [WARNING] flag --exclude-outbound-udp-ports-for-uids is deprecated use --exclude-outbound-ports-for-uids instead\n")) + fmt.Fprintln(cfg.RuntimeStderr, "# [WARNING] flag --exclude-outbound-udp-ports-for-uids is deprecated use --exclude-outbound-ports-for-uids instead") for _, v := range args.ExcludeOutboundUDPPortsForUIDs { args.ExcludeOutboundPortsForUIDs = append(args.ExcludeOutboundPortsForUIDs, fmt.Sprintf("udp:%s", v)) } } - if err := configureTransparentProxy(cmd, &args); err != nil { - return err + + if err := parseArgs(&cfg, &args); err != nil { + return errors.Wrap(err, "failed to setup transparent proxy") + } + + output, err := transparentproxy.Setup(cmd.Context(), cfg) + if err != nil { + return errors.Wrap(err, "failed to setup transparent proxy") } - _, _ = cmd.OutOrStdout().Write([]byte("# Transparent proxy set up successfully, you can now run kuma-dp using transparent-proxy.\n")) + if !cfg.Ebpf.Enabled && cfg.StoreFirewalld { + if _, err := firewalld.NewIptablesTranslator(). + WithDryRun(cfg.DryRun). + WithOutput(cfg.RuntimeStdout). + StoreRules(output); err != nil { + return err + } + } + + fmt.Fprintln(cfg.RuntimeStdout, "# Transparent proxy set up successfully, you can now run kuma-dp using transparent-proxy.") + return nil }, } - cmd.Flags().BoolVar(&args.DryRun, "dry-run", args.DryRun, "dry run") - cmd.Flags().BoolVar(&args.Verbose, "verbose", args.Verbose, "verbose") + cmd.Flags().BoolVar(&cfg.DryRun, "dry-run", cfg.DryRun, "dry run") + cmd.Flags().BoolVar(&cfg.Verbose, "verbose", cfg.Verbose, "verbose") cmd.Flags().StringVar(&args.IpFamilyMode, "ip-family-mode", args.IpFamilyMode, "The IP family mode to enable traffic redirection for. Can be 'dualstack' or 'ipv4'") cmd.Flags().StringVar(&args.RedirectPortOutBound, "redirect-outbound-port", args.RedirectPortOutBound, "outbound port redirected to Envoy, as specified in dataplane's `networking.transparentProxying.redirectPortOutbound`") - cmd.Flags().BoolVar(&args.RedirectInbound, "redirect-inbound", args.RedirectInbound, "redirect the inbound traffic to the Envoy. Should be disabled for Gateway data plane proxies.") + cmd.Flags().BoolVar(&cfg.Redirect.Inbound.Enabled, "redirect-inbound", cfg.Redirect.Inbound.Enabled, "redirect the inbound traffic to the Envoy. Should be disabled for Gateway data plane proxies.") cmd.Flags().StringVar(&args.RedirectPortInBound, "redirect-inbound-port", args.RedirectPortInBound, "inbound port redirected to Envoy, as specified in dataplane's `networking.transparentProxying.redirectPortInbound`") cmd.Flags().StringVar(&args.RedirectPortInBoundV6, "redirect-inbound-port-v6", args.RedirectPortInBoundV6, "[DEPRECATED (use --redirect-inbound-port or --ip-family-mode ipv4)] IPv6 inbound port redirected to Envoy, as specified in dataplane's `networking.transparentProxying.redirectPortInboundV6`") cmd.Flags().StringVar(&args.ExcludeInboundPorts, "exclude-inbound-ports", args.ExcludeInboundPorts, "a comma separated list of inbound ports to exclude from redirect to Envoy") cmd.Flags().StringVar(&args.ExcludeOutboundPorts, "exclude-outbound-ports", args.ExcludeOutboundPorts, "a comma separated list of outbound ports to exclude from redirect to Envoy") cmd.Flags().StringVar(&args.User, "kuma-dp-user", args.UID, "the user that will run kuma-dp") cmd.Flags().StringVar(&args.UID, "kuma-dp-uid", args.UID, "the uid of the user that will run kuma-dp") - cmd.Flags().BoolVar(&args.RedirectDNS, "redirect-dns", args.RedirectDNS, "redirect only DNS requests targeted to the servers listed in /etc/resolv.conf to a specified port") - cmd.Flags().BoolVar(&args.RedirectAllDNSTraffic, "redirect-all-dns-traffic", args.RedirectAllDNSTraffic, "redirect all DNS traffic to a specified port, unlike --redirect-dns this will not be limited to the dns servers identified in /etc/resolve.conf") + cmd.Flags().BoolVar(&cfg.Redirect.DNS.Enabled, "redirect-dns", cfg.Redirect.DNS.Enabled, "redirect only DNS requests targeted to the servers listed in /etc/resolv.conf to a specified port") + cmd.Flags().BoolVar(&cfg.Redirect.DNS.CaptureAll, "redirect-all-dns-traffic", cfg.Redirect.DNS.CaptureAll, "redirect all DNS traffic to a specified port, unlike --redirect-dns this will not be limited to the dns servers identified in /etc/resolve.conf") cmd.Flags().StringVar(&args.AgentDNSListenerPort, "redirect-dns-port", args.AgentDNSListenerPort, "the port where the DNS agent is listening") - cmd.Flags().StringVar(&args.DNSUpstreamTargetChain, "redirect-dns-upstream-target-chain", args.DNSUpstreamTargetChain, "(optional) the iptables chain where the upstream DNS requests should be directed to. It is only applied for IP V4. Use with care.") - cmd.Flags().BoolVar(&args.StoreFirewalld, "store-firewalld", args.StoreFirewalld, "store the iptables changes with firewalld") + cmd.Flags().StringVar(&cfg.Redirect.DNS.UpstreamTargetChain, "redirect-dns-upstream-target-chain", cfg.Redirect.DNS.UpstreamTargetChain, "(optional) the iptables chain where the upstream DNS requests should be directed to. It is only applied for IP V4. Use with care.") + cmd.Flags().BoolVar(&cfg.StoreFirewalld, "store-firewalld", cfg.StoreFirewalld, "store the iptables changes with firewalld") cmd.Flags().BoolVar(&args.SkipDNSConntrackZoneSplit, "skip-dns-conntrack-zone-split", args.SkipDNSConntrackZoneSplit, "skip applying conntrack zone splitting iptables rules") // ebpf - cmd.Flags().BoolVar(&args.EbpfEnabled, "ebpf-enabled", args.EbpfEnabled, "use ebpf instead of iptables to install transparent proxy") - cmd.Flags().StringVar(&args.EbpfProgramsSourcePath, "ebpf-programs-source-path", args.EbpfProgramsSourcePath, "path where compiled ebpf programs and other necessary for ebpf mode files can be found") - cmd.Flags().StringVar(&args.EbpfInstanceIP, "ebpf-instance-ip", args.EbpfInstanceIP, "IP address of the instance (pod/vm) where transparent proxy will be installed") - cmd.Flags().StringVar(&args.EbpfBPFFSPath, "ebpf-bpffs-path", args.EbpfBPFFSPath, "the path of the BPF filesystem") - cmd.Flags().StringVar(&args.EbpfCgroupPath, "ebpf-cgroup-path", args.EbpfCgroupPath, "the path of cgroup2") - cmd.Flags().StringVar(&args.EbpfTCAttachIface, "ebpf-tc-attach-iface", args.EbpfTCAttachIface, "name of the interface which TC eBPF programs should be attached to") + cmd.Flags().BoolVar(&cfg.Ebpf.Enabled, "ebpf-enabled", cfg.Ebpf.Enabled, "use ebpf instead of iptables to install transparent proxy") + cmd.Flags().StringVar(&cfg.Ebpf.ProgramsSourcePath, "ebpf-programs-source-path", cfg.Ebpf.ProgramsSourcePath, "path where compiled ebpf programs and other necessary for ebpf mode files can be found") + cmd.Flags().StringVar(&cfg.Ebpf.InstanceIP, "ebpf-instance-ip", cfg.Ebpf.InstanceIP, "IP address of the instance (pod/vm) where transparent proxy will be installed") + cmd.Flags().StringVar(&cfg.Ebpf.BPFFSPath, "ebpf-bpffs-path", cfg.Ebpf.BPFFSPath, "the path of the BPF filesystem") + cmd.Flags().StringVar(&cfg.Ebpf.CgroupPath, "ebpf-cgroup-path", cfg.Ebpf.CgroupPath, "the path of cgroup2") + cmd.Flags().StringVar(&cfg.Ebpf.TCAttachIface, "ebpf-tc-attach-iface", cfg.Ebpf.TCAttachIface, "name of the interface which TC eBPF programs should be attached to") cmd.Flags().StringArrayVar(&args.ExcludeOutboundTCPPortsForUIDs, "exclude-outbound-tcp-ports-for-uids", []string{}, "[DEPRECATED (use --exclude-outbound-ports-for-uids)] tcp outbound ports to exclude for specific uids in a format of ports:uids where ports can be a single value, a list, a range or a combination of all and uid can be a value or a range e.g. 53,3000-5000:106-108 would mean exclude ports 53 and from 3000 to 5000 for uids 106, 107, 108") cmd.Flags().StringArrayVar(&args.ExcludeOutboundUDPPortsForUIDs, "exclude-outbound-udp-ports-for-uids", []string{}, "[DEPRECATED (use --exclude-outbound-ports-for-uids)] udp outbound ports to exclude for specific uids in a format of ports:uids where ports can be a single value, a list, a range or a combination of all and uid can be a value or a range e.g. 53, 3000-5000:106-108 would mean exclude ports 53 and from 3000 to 5000 for uids 106, 107, 108") cmd.Flags().StringArrayVar(&args.ExcludeOutboundPortsForUIDs, "exclude-outbound-ports-for-uids", []string{}, "outbound ports to exclude for specific uids in a format of protocol:ports:uids where protocol and ports can be omitted or have value tcp or udp and ports can be a single value, a list, a range or a combination of all or * and uid can be a value or a range e.g. 53,3000-5000:106-108 would mean exclude ports 53 and from 3000 to 5000 for both TCP and UDP for uids 106, 107, 108") - cmd.Flags().StringArrayVar(&args.VnetNetworks, "vnet", []string{}, "virtual networks in a format of interfaceNameRegex:CIDR split by ':' where interface name doesn't have to be exact name e.g. docker0:172.17.0.0/16, br+:172.18.0.0/16, iface:::1/64") - cmd.Flags().UintVar(&args.Wait, "wait", args.Wait, "specify the amount of time, in seconds, that the application should wait for the xtables exclusive lock before exiting. If the lock is not available within the specified time, the application will exit with an error") - cmd.Flags().UintVar(&args.WaitInterval, "wait-interval", args.WaitInterval, "flag can be used to specify the amount of time, in microseconds, that iptables should wait between each iteration of the lock acquisition loop. This can be useful if the xtables lock is being held by another application for a long time, and you want to reduce the amount of CPU that iptables uses while waiting for the lock") - cmd.Flags().IntVar(&args.MaxRetries, "max-retries", args.MaxRetries, "flag can be used to specify the maximum number of times to retry an installation before giving up") - cmd.Flags().DurationVar(&args.SleepBetweenRetries, "sleep-between-retries", args.SleepBetweenRetries, "flag can be used to specify the amount of time to sleep between retries") + cmd.Flags().StringArrayVar(&cfg.Redirect.VNet.Networks, "vnet", cfg.Redirect.VNet.Networks, "virtual networks in a format of interfaceNameRegex:CIDR split by ':' where interface name doesn't have to be exact name e.g. docker0:172.17.0.0/16, br+:172.18.0.0/16, iface:::1/64") + cmd.Flags().UintVar(&cfg.Wait, "wait", cfg.Wait, "specify the amount of time, in seconds, that the application should wait for the xtables exclusive lock before exiting. If the lock is not available within the specified time, the application will exit with an error") + cmd.Flags().UintVar(&cfg.WaitInterval, "wait-interval", cfg.WaitInterval, "flag can be used to specify the amount of time, in microseconds, that iptables should wait between each iteration of the lock acquisition loop. This can be useful if the xtables lock is being held by another application for a long time, and you want to reduce the amount of CPU that iptables uses while waiting for the lock") + cmd.Flags().IntVar(cfg.Retry.MaxRetries, "max-retries", pointer.Deref(cfg.Retry.MaxRetries), "flag can be used to specify the maximum number of times to retry an installation before giving up") + cmd.Flags().DurationVar(&cfg.Retry.SleepBetweenReties, "sleep-between-retries", cfg.Retry.SleepBetweenReties, "flag can be used to specify the amount of time to sleep between retries") _ = cmd.Flags().MarkDeprecated("redirect-dns-upstream-target-chain", "This flag has no effect anymore. Will be removed in 2.9.x version") @@ -259,15 +246,15 @@ func findUidGid(uid, user string) (string, string, error) { return u.Uid, u.Gid, nil } -func parseArgs(cmd *cobra.Command, args *transparentProxyArgs) (config.Config, error) { +func parseArgs(cfg *config.Config, args *transparentProxyArgs) error { uid, _, err := findUidGid(args.UID, args.User) if err != nil { - return config.Config{}, errors.Wrapf(err, "unable to find the kuma-dp user") + return errors.Wrapf(err, "unable to find the kuma-dp user") } redirectInboundPort, err := transparentproxy.ParseUint16(args.RedirectPortInBound) if err != nil { - return config.Config{}, errors.Wrap(err, "parsing inbound redirect port failed") + return errors.Wrap(err, "parsing inbound redirect port failed") } var redirectInboundPortIPv6 uint16 @@ -275,32 +262,32 @@ func parseArgs(cmd *cobra.Command, args *transparentProxyArgs) (config.Config, e if args.RedirectPortInBoundV6 != "" { redirectInboundPortIPv6, err = transparentproxy.ParseUint16(args.RedirectPortInBoundV6) if err != nil { - return config.Config{}, errors.Wrap(err, "parsing inbound redirect port IPv6 failed") + return errors.Wrap(err, "parsing inbound redirect port IPv6 failed") } } redirectOutboundPort, err := transparentproxy.ParseUint16(args.RedirectPortOutBound) if err != nil { - return config.Config{}, errors.Wrap(err, "parsing outbound redirect port failed") + return errors.Wrap(err, "parsing outbound redirect port failed") } agentDNSListenerPort, err := transparentproxy.ParseUint16(args.AgentDNSListenerPort) if err != nil { - return config.Config{}, errors.Wrap(err, "parsing agent DNS listener port failed") + return errors.Wrap(err, "parsing agent DNS listener port failed") } var excludeInboundPorts []uint16 if args.ExcludeInboundPorts != "" { excludeInboundPorts, err = transparentproxy.SplitPorts(args.ExcludeInboundPorts) if err != nil { - return config.Config{}, errors.Wrap(err, "cannot parse inbound ports to exclude") + return errors.Wrap(err, "cannot parse inbound ports to exclude") } } var excludeOutboundPortsForUids []config.UIDsToPorts if len(args.ExcludeOutboundPortsForUIDs) > 0 { excludeOutboundPortsForUids, err = transparentproxy.ParseExcludePortsForUIDs(args.ExcludeOutboundPortsForUIDs) if err != nil { - return config.Config{}, errors.Wrap(err, "parsing excluded outbound ports for uids failed") + return errors.Wrap(err, "parsing excluded outbound ports for uids failed") } } @@ -308,7 +295,7 @@ func parseArgs(cmd *cobra.Command, args *transparentProxyArgs) (config.Config, e if args.ExcludeOutboundPorts != "" { excludeOutboundPorts, err = transparentproxy.SplitPorts(args.ExcludeOutboundPorts) if err != nil { - return config.Config{}, errors.Wrap(err, "cannot parse outbound ports to exclude") + return errors.Wrap(err, "cannot parse outbound ports to exclude") } } @@ -323,80 +310,24 @@ func parseArgs(cmd *cobra.Command, args *transparentProxyArgs) (config.Config, e ipv6, err = transparentproxy.ShouldEnableIPv6(redirectInboundPortIPv6) if err != nil { - return config.Config{}, errors.Wrap(err, "cannot verify if IPv6 should be enabled") + return errors.Wrap(err, "cannot verify if IPv6 should be enabled") } } - return config.Config{ - Owner: config.Owner{ - UID: uid, - }, - Redirect: config.Redirect{ - NamePrefix: "KUMA_", - Inbound: config.TrafficFlow{ - Enabled: args.RedirectInbound, - Port: redirectInboundPort, - PortIPv6: redirectInboundPortIPv6, - ExcludePorts: excludeInboundPorts, - }, - Outbound: config.TrafficFlow{ - Enabled: true, - Port: redirectOutboundPort, - ExcludePorts: excludeOutboundPorts, - ExcludePortsForUIDs: excludeOutboundPortsForUids, - }, - DNS: config.DNS{ - Enabled: args.RedirectDNS, - CaptureAll: args.RedirectAllDNSTraffic, - Port: agentDNSListenerPort, - UpstreamTargetChain: args.DNSUpstreamTargetChain, - ConntrackZoneSplit: !args.SkipDNSConntrackZoneSplit, - }, - VNet: config.VNet{ - Networks: args.VnetNetworks, - }, - }, - Ebpf: config.Ebpf{ - Enabled: args.EbpfEnabled, - InstanceIP: args.EbpfInstanceIP, - BPFFSPath: args.EbpfBPFFSPath, - CgroupPath: args.EbpfCgroupPath, - TCAttachIface: args.EbpfTCAttachIface, - ProgramsSourcePath: args.EbpfProgramsSourcePath, - }, - RuntimeStdout: cmd.OutOrStdout(), - RuntimeStderr: cmd.ErrOrStderr(), - IPv6: ipv6, - Verbose: args.Verbose, - DryRun: args.DryRun, - Wait: args.Wait, - WaitInterval: args.WaitInterval, - Retry: config.RetryConfig{ - MaxRetries: pointer.To(args.MaxRetries), - SleepBetweenReties: args.SleepBetweenRetries, - }, - }, nil -} + cfg.IPv6 = ipv6 -func configureTransparentProxy(cmd *cobra.Command, args *transparentProxyArgs) error { - cfg, err := parseArgs(cmd, args) - if err != nil { - return errors.Wrap(err, "failed to setup transparent proxy") - } + cfg.Owner.UID = uid - output, err := transparentproxy.Setup(cmd.Context(), cfg) - if err != nil { - return errors.Wrap(err, "failed to setup transparent proxy") - } + cfg.Redirect.Inbound.Port = redirectInboundPort + cfg.Redirect.Inbound.PortIPv6 = redirectInboundPortIPv6 + cfg.Redirect.Inbound.ExcludePorts = excludeInboundPorts - if !args.EbpfEnabled && args.StoreFirewalld { - if _, err := firewalld.NewIptablesTranslator(). - WithDryRun(args.DryRun). - WithOutput(cmd.OutOrStdout()). - StoreRules(output); err != nil { - return err - } - } + cfg.Redirect.Outbound.Port = redirectOutboundPort + cfg.Redirect.Outbound.ExcludePorts = excludeOutboundPorts + cfg.Redirect.Outbound.ExcludePortsForUIDs = excludeOutboundPortsForUids + + cfg.Redirect.DNS.Port = agentDNSListenerPort + cfg.Redirect.DNS.ConntrackZoneSplit = !args.SkipDNSConntrackZoneSplit return nil } diff --git a/pkg/transparentproxy/config/config.go b/pkg/transparentproxy/config/config.go index 1ee5bdba8109..508e93451174 100644 --- a/pkg/transparentproxy/config/config.go +++ b/pkg/transparentproxy/config/config.go @@ -134,6 +134,9 @@ type Config struct { // Retry allows you to configure the number of times that the system should // retry an installation if it fails Retry RetryConfig + // StoreFirewalld when set, configures firewalld to store the generated + // iptables rules. + StoreFirewalld bool } // ShouldDropInvalidPackets is just a convenience function which can be used in @@ -193,11 +196,11 @@ func (c Config) ShouldConntrackZoneSplit(iptablesExecutable string) bool { return true } -func defaultConfig() Config { +func DefaultConfig() Config { return Config{ Owner: Owner{UID: "5678"}, Redirect: Redirect{ - NamePrefix: "", + NamePrefix: "KUMA_", Inbound: TrafficFlow{ Enabled: true, Port: 15006, @@ -218,7 +221,7 @@ func defaultConfig() Config { DNS: DNS{ Port: 15053, Enabled: false, - CaptureAll: true, + CaptureAll: false, ConntrackZoneSplit: true, ResolvConfigPath: "/etc/resolv.conf", }, @@ -228,6 +231,7 @@ func defaultConfig() Config { }, Ebpf: Ebpf{ Enabled: false, + CgroupPath: "/sys/fs/cgroup", BPFFSPath: "/run/kuma/bpf", ProgramsSourcePath: "/tmp/kuma-ebpf", }, @@ -235,7 +239,7 @@ func defaultConfig() Config { IPv6: false, RuntimeStdout: os.Stdout, RuntimeStderr: os.Stderr, - Verbose: true, + Verbose: false, DryRun: false, Log: LogConfig{ Enabled: false, @@ -249,153 +253,3 @@ func defaultConfig() Config { }, } } - -func DefaultConfig() Config { - return defaultConfig() -} - -func MergeConfigWithDefaults(cfg Config) Config { - result := defaultConfig() - - // .Owner - if cfg.Owner.UID != "" { - result.Owner.UID = cfg.Owner.UID - } - - // .Redirect - if cfg.Redirect.NamePrefix != "" { - result.Redirect.NamePrefix = cfg.Redirect.NamePrefix - } - - // .Redirect.Inbound - result.Redirect.Inbound.Enabled = cfg.Redirect.Inbound.Enabled - if cfg.Redirect.Inbound.Port != 0 { - result.Redirect.Inbound.Port = cfg.Redirect.Inbound.Port - } - - if cfg.Redirect.Inbound.PortIPv6 != 0 { - result.Redirect.Inbound.PortIPv6 = cfg.Redirect.Inbound.PortIPv6 - } - - if cfg.Redirect.Inbound.Chain.Name != "" { - result.Redirect.Inbound.Chain.Name = cfg.Redirect.Inbound.Chain.Name - } - - if cfg.Redirect.Inbound.RedirectChain.Name != "" { - result.Redirect.Inbound.RedirectChain.Name = cfg.Redirect.Inbound.RedirectChain.Name - } - - if len(cfg.Redirect.Inbound.ExcludePorts) > 0 { - result.Redirect.Inbound.ExcludePorts = cfg.Redirect.Inbound.ExcludePorts - } - - if len(cfg.Redirect.Inbound.IncludePorts) > 0 { - result.Redirect.Inbound.IncludePorts = cfg.Redirect.Inbound.IncludePorts - } - - // .Redirect.Outbound - result.Redirect.Outbound.Enabled = cfg.Redirect.Outbound.Enabled - if cfg.Redirect.Outbound.Port != 0 { - result.Redirect.Outbound.Port = cfg.Redirect.Outbound.Port - } - - if cfg.Redirect.Outbound.Chain.Name != "" { - result.Redirect.Outbound.Chain.Name = cfg.Redirect.Outbound.Chain.Name - } - - if cfg.Redirect.Outbound.RedirectChain.Name != "" { - result.Redirect.Outbound.RedirectChain.Name = cfg.Redirect.Outbound.RedirectChain.Name - } - - if len(cfg.Redirect.Outbound.ExcludePorts) > 0 { - result.Redirect.Outbound.ExcludePorts = cfg.Redirect.Outbound.ExcludePorts - } - - if len(cfg.Redirect.Outbound.IncludePorts) > 0 { - result.Redirect.Outbound.IncludePorts = cfg.Redirect.Outbound.IncludePorts - } - - if len(cfg.Redirect.Outbound.ExcludePortsForUIDs) > 0 { - result.Redirect.Outbound.ExcludePortsForUIDs = cfg.Redirect.Outbound.ExcludePortsForUIDs - } - - // .Redirect.DNS - result.Redirect.DNS.Enabled = cfg.Redirect.DNS.Enabled - result.Redirect.DNS.ConntrackZoneSplit = cfg.Redirect.DNS.ConntrackZoneSplit - result.Redirect.DNS.CaptureAll = cfg.Redirect.DNS.CaptureAll - if cfg.Redirect.DNS.ResolvConfigPath != "" { - result.Redirect.DNS.ResolvConfigPath = cfg.Redirect.DNS.ResolvConfigPath - } - - if cfg.Redirect.DNS.UpstreamTargetChain != "" { - result.Redirect.DNS.UpstreamTargetChain = cfg.Redirect.DNS.UpstreamTargetChain - } - - if cfg.Redirect.DNS.Port != 0 { - result.Redirect.DNS.Port = cfg.Redirect.DNS.Port - } - - // .Redirect.VNet - if len(cfg.Redirect.VNet.Networks) > 0 { - result.Redirect.VNet.Networks = cfg.Redirect.VNet.Networks - } - - // .Ebpf - result.Ebpf.Enabled = cfg.Ebpf.Enabled - if cfg.Ebpf.InstanceIP != "" { - result.Ebpf.InstanceIP = cfg.Ebpf.InstanceIP - } - - if cfg.Ebpf.BPFFSPath != "" { - result.Ebpf.BPFFSPath = cfg.Ebpf.BPFFSPath - } - - if cfg.Ebpf.ProgramsSourcePath != "" { - result.Ebpf.ProgramsSourcePath = cfg.Ebpf.ProgramsSourcePath - } - - // .DropInvalidPackets - result.DropInvalidPackets = cfg.DropInvalidPackets - - // .IPv6 - result.IPv6 = cfg.IPv6 - - // .RuntimeStdout - if cfg.RuntimeStdout != nil { - result.RuntimeStdout = cfg.RuntimeStdout - } - - // .RuntimeStderr - if cfg.RuntimeStderr != nil { - result.RuntimeStderr = cfg.RuntimeStderr - } - - // .Verbose - result.Verbose = cfg.Verbose - - // .DryRun - result.DryRun = cfg.DryRun - - // .Log - result.Log.Enabled = cfg.Log.Enabled - if cfg.Log.Level != DebugLogLevel { - result.Log.Level = cfg.Log.Level - } - - // .Wait - result.Wait = cfg.Wait - - // .WaitInterval - result.WaitInterval = cfg.WaitInterval - - // .Retry - if cfg.Retry.MaxRetries != nil { - result.Retry.MaxRetries = cfg.Retry.MaxRetries - } - - if cfg.Retry.SleepBetweenReties != 0 { - result.Retry.SleepBetweenReties = cfg.Retry.SleepBetweenReties - } - - return result -} diff --git a/pkg/transparentproxy/iptables/builder/builder.go b/pkg/transparentproxy/iptables/builder/builder.go index f48d36b12ce6..4267f7c2a690 100644 --- a/pkg/transparentproxy/iptables/builder/builder.go +++ b/pkg/transparentproxy/iptables/builder/builder.go @@ -62,8 +62,6 @@ func BuildIPTablesForRestore( ipv6 bool, iptablesExecutablePath string, ) (string, error) { - cfg = config.MergeConfigWithDefaults(cfg) - loopbackIface, err := getLoopback() if err != nil { return "", fmt.Errorf("cannot obtain loopback interface: %s", err) @@ -230,8 +228,6 @@ func (r *restorer) tryRestoreIPTables( } func RestoreIPTables(ctx context.Context, cfg config.Config) (string, error) { - cfg = config.MergeConfigWithDefaults(cfg) - _, _ = cfg.RuntimeStdout.Write([]byte("# kumactl is about to apply the " + "iptables rules that will enable transparent proxying on the machine. " + "The SSH connection may drop. If that happens, just reconnect again.\n"))