diff --git a/app/kumactl/cmd/completion/testdata/bash.golden b/app/kumactl/cmd/completion/testdata/bash.golden index 2177e53e6f93..2879a5a475cd 100644 --- a/app/kumactl/cmd/completion/testdata/bash.golden +++ b/app/kumactl/cmd/completion/testdata/bash.golden @@ -2401,6 +2401,9 @@ _kumactl_install_transparent-proxy() flags+=("--redirect-dns-port=") two_word_flags+=("--redirect-dns-port") local_nonpersistent_flags+=("--redirect-dns-port=") + flags+=("--redirect-dns-upstream-target-chain=") + two_word_flags+=("--redirect-dns-upstream-target-chain") + local_nonpersistent_flags+=("--redirect-dns-upstream-target-chain=") flags+=("--redirect-inbound") local_nonpersistent_flags+=("--redirect-inbound") flags+=("--redirect-inbound-port=") diff --git a/app/kumactl/cmd/completion/testdata/zsh.golden b/app/kumactl/cmd/completion/testdata/zsh.golden index 3cbcdfbe1406..927d90f275a2 100644 --- a/app/kumactl/cmd/completion/testdata/zsh.golden +++ b/app/kumactl/cmd/completion/testdata/zsh.golden @@ -977,6 +977,7 @@ function _kumactl_install_transparent-proxy { '--modify-resolv-conf[skip modifying the host `/etc/resolv.conf`]' \ '--redirect-dns[redirect the DNS requests to a specified port]' \ '--redirect-dns-port[the port where the DNS agent is listening]:' \ + '--redirect-dns-upstream-target-chain[(optional) the iptables chain where the upstream DNS requests should be directed to. Use with care.]:' \ '--redirect-inbound[redirect the inbound traffic to the Envoy. Should be disabled for Gateway data plane proxies.]' \ '--redirect-inbound-port[inbound port redirected to Envoy, as specified in dataplane'\''s `networking.transparentProxying.redirectPortInbound`]:' \ '--redirect-inbound-port-v6[IPv6 inbound port redirected to Envoy, as specified in dataplane'\''s `networking.transparentProxying.redirectPortInboundV6`]:' \ diff --git a/app/kumactl/cmd/install/install_transparent_proxy.go b/app/kumactl/cmd/install/install_transparent_proxy.go index 6a03294c68e9..a403e11b68a0 100644 --- a/app/kumactl/cmd/install/install_transparent_proxy.go +++ b/app/kumactl/cmd/install/install_transparent_proxy.go @@ -20,42 +20,44 @@ import ( ) type transparenProxyArgs struct { - DryRun bool - ModifyIptables bool - RedirectPortOutBound string - RedirectInbound bool - RedirectPortInBound string - RedirectPortInBoundV6 string - ExcludeInboundPorts string - ExcludeOutboundPorts string - UID string - User string - RedirectDNS bool - AgentDNSListenerPort string - ModifyResolvConf bool - StoreFirewalld bool - KumaCpIP net.IP + DryRun bool + ModifyIptables bool + RedirectPortOutBound string + RedirectInbound bool + RedirectPortInBound string + RedirectPortInBoundV6 string + ExcludeInboundPorts string + ExcludeOutboundPorts string + UID string + User string + RedirectDNS bool + AgentDNSListenerPort string + DNSUpstreamTargetChain string + ModifyResolvConf bool + StoreFirewalld bool + KumaCpIP net.IP } var defaultCpIP = net.IPv4(0, 0, 0, 0) func newInstallTransparentProxy() *cobra.Command { args := transparenProxyArgs{ - DryRun: false, - ModifyIptables: true, - RedirectPortOutBound: "15001", - RedirectInbound: true, - RedirectPortInBound: "15006", - RedirectPortInBoundV6: "15010", - ExcludeInboundPorts: "", - ExcludeOutboundPorts: "", - UID: "", - User: "", - RedirectDNS: false, - AgentDNSListenerPort: "15053", - ModifyResolvConf: false, - StoreFirewalld: false, - KumaCpIP: defaultCpIP, + DryRun: false, + ModifyIptables: true, + RedirectPortOutBound: "15001", + RedirectInbound: true, + RedirectPortInBound: "15006", + RedirectPortInBoundV6: "15010", + ExcludeInboundPorts: "", + ExcludeOutboundPorts: "", + UID: "", + User: "", + RedirectDNS: false, + AgentDNSListenerPort: "15053", + DNSUpstreamTargetChain: "RETURN", + ModifyResolvConf: false, + StoreFirewalld: false, + KumaCpIP: defaultCpIP, } cmd := &cobra.Command{ Use: "transparent-proxy", @@ -158,6 +160,7 @@ runuser -u 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 the DNS requests to a specified port") 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. Use with care.") cmd.Flags().BoolVar(&args.ModifyResolvConf, "modify-resolv-conf", args.ModifyResolvConf, "skip modifying the host `/etc/resolv.conf`") cmd.Flags().BoolVar(&args.StoreFirewalld, "store-firewalld", args.StoreFirewalld, "store the iptables changes with firewalld") cmd.Flags().IPVar(&args.KumaCpIP, "kuma-cp-ip", args.KumaCpIP, "the IP address of the Kuma CP which exposes the DNS service on port 53.") @@ -190,17 +193,18 @@ func modifyIpTables(cmd *cobra.Command, args *transparenProxyArgs) error { _, _ = cmd.OutOrStdout().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.")) } output, err := tp.Setup(&config.TransparentProxyConfig{ - DryRun: args.DryRun, - RedirectPortOutBound: args.RedirectPortOutBound, - RedirectInBound: args.RedirectInbound, - RedirectPortInBound: args.RedirectPortInBound, - RedirectPortInBoundV6: args.RedirectPortInBoundV6, - ExcludeInboundPorts: args.ExcludeInboundPorts, - ExcludeOutboundPorts: args.ExcludeOutboundPorts, - UID: uid, - GID: gid, - RedirectDNS: args.RedirectDNS, - AgentDNSListenerPort: args.AgentDNSListenerPort, + DryRun: args.DryRun, + RedirectPortOutBound: args.RedirectPortOutBound, + RedirectInBound: args.RedirectInbound, + RedirectPortInBound: args.RedirectPortInBound, + RedirectPortInBoundV6: args.RedirectPortInBoundV6, + ExcludeInboundPorts: args.ExcludeInboundPorts, + ExcludeOutboundPorts: args.ExcludeOutboundPorts, + UID: uid, + GID: gid, + RedirectDNS: args.RedirectDNS, + AgentDNSListenerPort: args.AgentDNSListenerPort, + DNSUpstreamTargetChain: args.DNSUpstreamTargetChain, }) if err != nil { return errors.Wrap(err, "failed to setup transparent proxy") diff --git a/app/kumactl/cmd/install/install_transparent_proxy_test.go b/app/kumactl/cmd/install/install_transparent_proxy_test.go index 20318da3079c..91191525843a 100644 --- a/app/kumactl/cmd/install/install_transparent_proxy_test.go +++ b/app/kumactl/cmd/install/install_transparent_proxy_test.go @@ -76,6 +76,7 @@ var _ = Describe("kumactl install tracing", func() { "--kuma-cp-ip", "1.2.3.4", "--redirect-dns", "--redirect-dns-port", "12345", + "--redirect-dns-upstream-target-chain", "DOCKER_OUTPUT", }, goldenFile: "install-transparent-proxy.dns.golden.txt", }), diff --git a/app/kumactl/cmd/install/testdata/install-transparent-proxy.dns.golden.txt b/app/kumactl/cmd/install/testdata/install-transparent-proxy.dns.golden.txt index 542ed2b9894d..9690e66afa7e 100644 --- a/app/kumactl/cmd/install/testdata/install-transparent-proxy.dns.golden.txt +++ b/app/kumactl/cmd/install/testdata/install-transparent-proxy.dns.golden.txt @@ -11,14 +11,14 @@ -A OUTPUT -p tcp -j (.*)_OUTPUT -A (.*)_OUTPUT -o lo -s 127.0.0.6/32 -j RETURN -A (.*)_OUTPUT -o lo ! -d 127.0.0.1/32 -p tcp ! --dport 53 -m owner --uid-owner 0 -j (.*)_IN_REDIRECT --A (.*)_OUTPUT -o lo -p tcp ! --dport 53 -m owner ! --uid-owner 0 -j RETURN +-A (.*)_OUTPUT -o lo -p tcp ! --dport 53 -m owner ! --uid-owner 0 -j DOCKER_OUTPUT -A (.*)_OUTPUT -m owner --uid-owner 0 -j RETURN -A (.*)_OUTPUT -o lo ! -d 127.0.0.1/32 -m owner --gid-owner 0 -j (.*)_IN_REDIRECT --A (.*)_OUTPUT -o lo -p tcp ! --dport 53 -m owner ! --gid-owner 0 -j RETURN +-A (.*)_OUTPUT -o lo -p tcp ! --dport 53 -m owner ! --gid-owner 0 -j DOCKER_OUTPUT -A (.*)_OUTPUT -m owner --gid-owner 0 -j RETURN -A (.*)_OUTPUT -p tcp --dport 53 -d (.*) -j REDIRECT --to-ports 12345 -A (.*)_OUTPUT -d 127.0.0.1/32 -j RETURN -A (.*)_OUTPUT -j (.*)_REDIRECT --A OUTPUT -p udp --dport 53 -m owner --uid-owner 0 -j RETURN --A OUTPUT -p udp --dport 53 -m owner --gid-owner 0 -j RETURN --A OUTPUT -p udp --dport 53 -d (.*) -j REDIRECT --to-port 12345 +-I OUTPUT 1 -p udp --dport 53 -m owner --uid-owner 0 -j DOCKER_OUTPUT +-I OUTPUT 2 -p udp --dport 53 -m owner --gid-owner 0 -j DOCKER_OUTPUT +-I OUTPUT 3 -p udp --dport 53 -d (.*) -j REDIRECT --to-port 12345 diff --git a/pkg/transparentproxy/config/config.go b/pkg/transparentproxy/config/config.go index 63a5f72cf005..cbb79b6e910a 100644 --- a/pkg/transparentproxy/config/config.go +++ b/pkg/transparentproxy/config/config.go @@ -1,15 +1,16 @@ package config type TransparentProxyConfig struct { - DryRun bool - RedirectPortOutBound string - RedirectInBound bool - RedirectPortInBound string - RedirectPortInBoundV6 string - ExcludeInboundPorts string - ExcludeOutboundPorts string - UID string - GID string - RedirectDNS bool - AgentDNSListenerPort string + DryRun bool + RedirectPortOutBound string + RedirectInBound bool + RedirectPortInBound string + RedirectPortInBoundV6 string + ExcludeInboundPorts string + ExcludeOutboundPorts string + UID string + GID string + RedirectDNS bool + AgentDNSListenerPort string + DNSUpstreamTargetChain string } diff --git a/pkg/transparentproxy/istio/istio.go b/pkg/transparentproxy/istio/istio.go index bfc1ddd998c7..4cde9c0495a8 100644 --- a/pkg/transparentproxy/istio/istio.go +++ b/pkg/transparentproxy/istio/istio.go @@ -43,6 +43,7 @@ func (tp *IstioTransparentProxy) Setup(cfg *config.TransparentProxyConfig) (stri viper.Set(constants.RunValidation, false) viper.Set(constants.RedirectDNS, cfg.RedirectDNS) viper.Set(constants.AgentDNSListenerPort, cfg.AgentDNSListenerPort) + viper.Set(constants.DNSUpstreamTargetChain, cfg.DNSUpstreamTargetChain) tp.redirectStdOutStdErr() defer func() { @@ -65,6 +66,7 @@ func (tp *IstioTransparentProxy) Setup(cfg *config.TransparentProxyConfig) (stri func (tp *IstioTransparentProxy) Cleanup(dryRun bool) (string, error) { viper.Set(constants.DryRun, dryRun) + viper.Set(constants.DNSUpstreamTargetChain, "") tp.redirectStdOutStdErr() defer func() { diff --git a/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/cmd/cleanup.go b/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/cmd/cleanup.go index 5844f2dfad4f..c58ed36de64b 100644 --- a/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/cmd/cleanup.go +++ b/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/cmd/cleanup.go @@ -41,6 +41,7 @@ func removeOldChains(cfg *config.Config, ext dep.Dependencies, cmd string) { if redirectDNS { common.HandleDNSUDP(common.DeleteOps, builder.NewIptablesBuilder(), ext, cmd, cfg.AgentDNSListenerPort, + cfg.DNSUpstreamTargetChain, cfg.ProxyUID, cfg.ProxyGID, cfg.DNSServersV4) } diff --git a/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/cmd/root.go b/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/cmd/root.go index 26e7a8ee5896..01bd8d9d39d8 100644 --- a/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/cmd/root.go +++ b/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/cmd/root.go @@ -51,11 +51,12 @@ var rootCmd = &cobra.Command{ func constructConfig() *config.Config { cfg := &config.Config{ - DryRun: viper.GetBool(constants.DryRun), - ProxyUID: viper.GetString(constants.ProxyUID), - ProxyGID: viper.GetString(constants.ProxyGID), - RedirectDNS: viper.GetBool(constants.RedirectDNS), - AgentDNSListenerPort: viper.GetString(constants.AgentDNSListenerPort), + DryRun: viper.GetBool(constants.DryRun), + ProxyUID: viper.GetString(constants.ProxyUID), + ProxyGID: viper.GetString(constants.ProxyGID), + RedirectDNS: viper.GetBool(constants.RedirectDNS), + AgentDNSListenerPort: viper.GetString(constants.AgentDNSListenerPort), + DNSUpstreamTargetChain: viper.GetString(constants.DNSUpstreamTargetChain), } // TODO: Make this more configurable, maybe with an allowlist of users to be captured for output instead of a denylist. @@ -120,6 +121,11 @@ func bindFlags(cmd *cobra.Command, args []string) { handleError(err) } viper.SetDefault(constants.AgentDNSListenerPort, constants.IstioAgentDNSListenerPort) + + if err := viper.BindPFlag(constants.DNSUpstreamTargetChain, cmd.Flags().Lookup(constants.DNSUpstreamTargetChain)); err != nil { + handleError(err) + } + viper.SetDefault(constants.DNSUpstreamTargetChain, constants.RETURN) } // https://github.com/spf13/viper/issues/233. diff --git a/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/config/config.go b/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/config/config.go index 426387d3a91c..1103b405cfbc 100644 --- a/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/config/config.go +++ b/pkg/transparentproxy/istio/tools/istio-clean-iptables/pkg/config/config.go @@ -22,13 +22,14 @@ import ( // Command line options // nolint: maligned type Config struct { - DryRun bool `json:"DRY_RUN"` - ProxyUID string `json:"PROXY_UID"` - ProxyGID string `json:"PROXY_GID"` - RedirectDNS bool `json:"REDIRECT_DNS"` - DNSServersV4 []string `json:"DNS_SERVERS_V4"` - DNSServersV6 []string `json:"DNS_SERVERS_V6"` - AgentDNSListenerPort string `json:"AGENT_DNS_LISTENER_PORT"` + DryRun bool `json:"DRY_RUN"` + ProxyUID string `json:"PROXY_UID"` + ProxyGID string `json:"PROXY_GID"` + RedirectDNS bool `json:"REDIRECT_DNS"` + DNSServersV4 []string `json:"DNS_SERVERS_V4"` + DNSServersV6 []string `json:"DNS_SERVERS_V6"` + AgentDNSListenerPort string `json:"AGENT_DNS_LISTENER_PORT"` + DNSUpstreamTargetChain string `json:"DNS_UPSTREAM_TARGET_CHAIN"` } func (c *Config) String() string { @@ -48,5 +49,6 @@ func (c *Config) Print() { fmt.Printf("DNS_CAPTURE=%t\n", c.RedirectDNS) fmt.Printf("DNS_SERVERS=%s,%s\n", c.DNSServersV4, c.DNSServersV6) fmt.Printf("AGENT_DNS_LISTENER_PORT=%s\n", c.AgentDNSListenerPort) + fmt.Printf("DNS_UPSTREAM_TARGET_CHAIN=%s\n", c.DNSUpstreamTargetChain) fmt.Println("") } diff --git a/pkg/transparentproxy/istio/tools/istio-iptables/pkg/cmd/root.go b/pkg/transparentproxy/istio/tools/istio-iptables/pkg/cmd/root.go index f12694db7f82..2b9d7c9a07f7 100644 --- a/pkg/transparentproxy/istio/tools/istio-iptables/pkg/cmd/root.go +++ b/pkg/transparentproxy/istio/tools/istio-iptables/pkg/cmd/root.go @@ -100,6 +100,7 @@ func constructConfig() *config.Config { RunValidation: viper.GetBool(constants.RunValidation), RedirectDNS: viper.GetBool(constants.RedirectDNS), AgentDNSListenerPort: viper.GetString(constants.AgentDNSListenerPort), + DNSUpstreamTargetChain: viper.GetString(constants.DNSUpstreamTargetChain), } // TODO: Make this more configurable, maybe with an allowlist of users to be captured for output instead of a denylist. @@ -312,6 +313,11 @@ func bindFlags(cmd *cobra.Command, args []string) { handleError(err) } viper.SetDefault(constants.AgentDNSListenerPort, constants.IstioAgentDNSListenerPort) + + if err := viper.BindPFlag(constants.DNSUpstreamTargetChain, cmd.Flags().Lookup(constants.DNSUpstreamTargetChain)); err != nil { + handleError(err) + } + viper.SetDefault(constants.DNSUpstreamTargetChain, constants.RETURN) } // https://github.com/spf13/viper/issues/233. diff --git a/pkg/transparentproxy/istio/tools/istio-iptables/pkg/cmd/run.go b/pkg/transparentproxy/istio/tools/istio-iptables/pkg/cmd/run.go index f79e9e2deabf..dde5c7a78d16 100644 --- a/pkg/transparentproxy/istio/tools/istio-iptables/pkg/cmd/run.go +++ b/pkg/transparentproxy/istio/tools/istio-iptables/pkg/cmd/run.go @@ -444,7 +444,7 @@ func (iptConfigurator *IptablesConfigurator) run() { // Instead, we just have: // app => istio-agent => dns server iptConfigurator.iptables.AppendRuleV4(constants.ISTIOOUTPUT, constants.NAT, "-o", "lo", "!", "-d", "127.0.0.1/32", - "-p", "tcp", "!", "--dport", "53", + "-p", constants.TCP, "!", "--dport", "53", "-m", "owner", "--uid-owner", uid, "-j", constants.ISTIOINREDIRECT) } else { iptConfigurator.iptables.AppendRuleV4(constants.ISTIOOUTPUT, constants.NAT, "-o", "lo", "!", "-d", "127.0.0.1/32", @@ -461,9 +461,9 @@ func (iptConfigurator *IptablesConfigurator) run() { // handle this case, we exclude port 53 from this rule. Note: We cannot just move the // port 53 redirection rule further up the list, as we will want to avoid capturing // DNS requests from the proxy UID/GID - iptConfigurator.iptables.AppendRuleV4(constants.ISTIOOUTPUT, constants.NAT, "-o", "lo", "-p", "tcp", + iptConfigurator.iptables.AppendRuleV4(constants.ISTIOOUTPUT, constants.NAT, "-o", "lo", "-p", constants.TCP, "!", "--dport", "53", - "-m", "owner", "!", "--uid-owner", uid, "-j", constants.RETURN) + "-m", "owner", "!", "--uid-owner", uid, "-j", iptConfigurator.cfg.DNSUpstreamTargetChain) } else { iptConfigurator.iptables.AppendRuleV4(constants.ISTIOOUTPUT, constants.NAT, "-o", "lo", "-m", "owner", "!", "--uid-owner", uid, "-j", constants.RETURN) } @@ -490,9 +490,9 @@ func (iptConfigurator *IptablesConfigurator) run() { // handle this case, we exclude port 53 from this rule. Note: We cannot just move the // port 53 redirection rule further up the list, as we will want to avoid capturing // DNS requests from the proxy UID/GID - iptConfigurator.iptables.AppendRuleV4(constants.ISTIOOUTPUT, constants.NAT, "-o", "lo", "-p", "tcp", + iptConfigurator.iptables.AppendRuleV4(constants.ISTIOOUTPUT, constants.NAT, "-o", "lo", "-p", constants.TCP, "!", "--dport", "53", - "-m", "owner", "!", "--gid-owner", gid, "-j", constants.RETURN) + "-m", "owner", "!", "--gid-owner", gid, "-j", iptConfigurator.cfg.DNSUpstreamTargetChain) } else { iptConfigurator.iptables.AppendRuleV4(constants.ISTIOOUTPUT, constants.NAT, "-o", "lo", "-m", "owner", "!", "--gid-owner", gid, "-j", constants.RETURN) } @@ -553,6 +553,7 @@ func (iptConfigurator *IptablesConfigurator) run() { HandleDNSUDP( AppendOps, iptConfigurator.iptables, iptConfigurator.ext, "", iptConfigurator.cfg.AgentDNSListenerPort, + iptConfigurator.cfg.DNSUpstreamTargetChain, iptConfigurator.cfg.ProxyUID, iptConfigurator.cfg.ProxyGID, iptConfigurator.cfg.DNSServersV4) @@ -560,6 +561,7 @@ func (iptConfigurator *IptablesConfigurator) run() { HandleDNSUDPv6( AppendOps, iptConfigurator.iptables, iptConfigurator.ext, "", iptConfigurator.cfg.AgentDNSListenerPort, + iptConfigurator.cfg.DNSUpstreamTargetChain, iptConfigurator.cfg.ProxyUID, iptConfigurator.cfg.ProxyGID, iptConfigurator.cfg.DNSServersV6) } @@ -583,23 +585,24 @@ func (iptConfigurator *IptablesConfigurator) run() { // This helps the creation logic of DNS UDP rules in sync with the deletion. func HandleDNSUDP( ops Ops, iptables *builder.IptablesBuilderImpl, ext dep.Dependencies, - cmd, agentDNSListenerPort, proxyUID, proxyGID string, dnsServersV4 []string) { + cmd, agentDNSListenerPort, dnsUpstreamTargetChain, proxyUID, proxyGID string, dnsServersV4 []string) { const paramIdxRaw = 4 var raw []string opsStr := opsToString[ops] table := constants.NAT chain := constants.OUTPUT + rulePosition := 1 // Make sure that upstream DNS requests from agent/envoy dont get captured. - // TODO: add ip6 as well for _, uid := range split(proxyUID) { raw = []string{ "-t", table, opsStr, chain, - "-p", "udp", "--dport", "53", "-m", "owner", "--uid-owner", uid, "-j", constants.RETURN, + "-p", "udp", "--dport", "53", "-m", "owner", "--uid-owner", uid, "-j", dnsUpstreamTargetChain, } switch ops { case AppendOps: - iptables.AppendRuleV4(chain, table, raw[paramIdxRaw:]...) + iptables.InsertRuleV4(chain, table, rulePosition, raw[paramIdxRaw:]...) + rulePosition++ case DeleteOps: ext.RunQuietlyAndIgnore(cmd, raw...) } @@ -607,11 +610,12 @@ func HandleDNSUDP( for _, gid := range split(proxyGID) { raw = []string{ "-t", table, opsStr, chain, - "-p", "udp", "--dport", "53", "-m", "owner", "--gid-owner", gid, "-j", constants.RETURN, + "-p", "udp", "--dport", "53", "-m", "owner", "--gid-owner", gid, "-j", dnsUpstreamTargetChain, } switch ops { case AppendOps: - iptables.AppendRuleV4(chain, table, raw[paramIdxRaw:]...) + iptables.InsertRuleV4(chain, table, rulePosition, raw[paramIdxRaw:]...) + rulePosition++ case DeleteOps: ext.RunQuietlyAndIgnore(cmd, raw...) } @@ -632,7 +636,8 @@ func HandleDNSUDP( } switch ops { case AppendOps: - iptables.AppendRuleV4(chain, table, raw[paramIdxRaw:]...) + iptables.InsertRuleV4(chain, table, rulePosition, raw[paramIdxRaw:]...) + rulePosition++ case DeleteOps: ext.RunQuietlyAndIgnore(cmd, raw...) } @@ -645,23 +650,24 @@ func HandleDNSUDP( // This helps the creation logic of DNS UDP rules in sync with the deletion. func HandleDNSUDPv6( ops Ops, iptables *builder.IptablesBuilderImpl, ext dep.Dependencies, - cmd, agentDNSListenerPort, proxyUID, proxyGID string, dnsServersV6 []string) { + cmd, agentDNSListenerPort, dnsUpstreamTargetChain, proxyUID, proxyGID string, dnsServersV6 []string) { const paramIdxRaw = 4 var raw []string opsStr := opsToString[ops] table := constants.NAT chain := constants.OUTPUT + rulePosition := 1 // Make sure that upstream DNS requests from agent/envoy dont get captured. - // TODO: add ip6 as well for _, uid := range split(proxyUID) { raw = []string{ "-t", table, opsStr, chain, - "-p", "udp", "--dport", "53", "-m", "owner", "--uid-owner", uid, "-j", constants.RETURN, + "-p", "udp", "--dport", "53", "-m", "owner", "--uid-owner", uid, "-j", dnsUpstreamTargetChain, } switch ops { case AppendOps: - iptables.AppendRuleV4(chain, table, raw[paramIdxRaw:]...) + iptables.InsertRuleV6(chain, table, rulePosition, raw[paramIdxRaw:]...) + rulePosition++ case DeleteOps: ext.RunQuietlyAndIgnore(cmd, raw...) } @@ -669,11 +675,12 @@ func HandleDNSUDPv6( for _, gid := range split(proxyGID) { raw = []string{ "-t", table, opsStr, chain, - "-p", constants.UDP, "--dport", "53", "-m", "owner", "--gid-owner", gid, "-j", constants.RETURN, + "-p", constants.UDP, "--dport", "53", "-m", "owner", "--gid-owner", gid, "-j", dnsUpstreamTargetChain, } switch ops { case AppendOps: - iptables.AppendRuleV6(chain, table, raw[paramIdxRaw:]...) + iptables.InsertRuleV6(chain, table, rulePosition, raw[paramIdxRaw:]...) + rulePosition++ case DeleteOps: ext.RunQuietlyAndIgnore(cmd, raw...) } @@ -694,7 +701,8 @@ func HandleDNSUDPv6( } switch ops { case AppendOps: - iptables.AppendRuleV6(chain, table, raw[paramIdxRaw:]...) + iptables.InsertRuleV6(chain, table, rulePosition, raw[paramIdxRaw:]...) + rulePosition++ case DeleteOps: ext.RunQuietlyAndIgnore(cmd, raw...) } diff --git a/pkg/transparentproxy/istio/tools/istio-iptables/pkg/config/config.go b/pkg/transparentproxy/istio/tools/istio-iptables/pkg/config/config.go index f8c921f66d37..741d9061e1a2 100644 --- a/pkg/transparentproxy/istio/tools/istio-iptables/pkg/config/config.go +++ b/pkg/transparentproxy/istio/tools/istio-iptables/pkg/config/config.go @@ -50,6 +50,7 @@ type Config struct { DNSServersV4 []string `json:"DNS_SERVERS_V4"` DNSServersV6 []string `json:"DNS_SERVERS_V6"` AgentDNSListenerPort string `json:"AGENT_DNS_LISTENER_PORT"` + DNSUpstreamTargetChain string `json:"DNS_UPSTREAM_TARGET_CHAIN"` } func (c *Config) String() string { @@ -83,5 +84,6 @@ func (c *Config) Print() { fmt.Printf("DNS_CAPTURE=%t\n", c.RedirectDNS) fmt.Printf("DNS_SERVERS=%s,%s\n", c.DNSServersV4, c.DNSServersV6) fmt.Printf("AGENT_DNS_LISTENER_PORT=%s\n", c.AgentDNSListenerPort) + fmt.Printf("DNS_UPSTREAM_TARGET_CHAIN=%s\n", c.DNSUpstreamTargetChain) fmt.Println("") } diff --git a/pkg/transparentproxy/istio/tools/istio-iptables/pkg/constants/constants.go b/pkg/transparentproxy/istio/tools/istio-iptables/pkg/constants/constants.go index 173ff4eee5ba..43c6f4c677d0 100644 --- a/pkg/transparentproxy/istio/tools/istio-iptables/pkg/constants/constants.go +++ b/pkg/transparentproxy/istio/tools/istio-iptables/pkg/constants/constants.go @@ -90,6 +90,7 @@ const ( ProbeTimeout = "probe-timeout" RedirectDNS = "redirect-dns" AgentDNSListenerPort = "agent-dns-listener-port" + DNSUpstreamTargetChain = "dns-upstream-target-chain" ) const ( @@ -129,7 +130,7 @@ const ( ValidationErrorCode = 126 ) -// DNS ports +// DNS ports and others const ( EnvoyDNSListenerPort = "15013" IstioAgentDNSListenerPort = "15053"