From 214540c8238bd7941c772ae9d3bc5444f8fa507b Mon Sep 17 00:00:00 2001 From: Dennis Adjei-Baah Date: Thu, 15 Nov 2018 13:56:45 -0800 Subject: [PATCH] Add new iptable rule to for outbound traffic (#1863) When requests from a pod send requests to itself, the proxy properly redirects traffic from the originating container in the pod through the outbound listener of the proxy. Once the request ends on the inbound side of the proxy, it skips the proxy and calls the original container that made the request. This can cause problems for containers that serve HTTP as the proxy naively tries to initiate an HTTP/2 connection to the destination of a request. (See #1585 for a concrete example) This PR adds a new iptable rule, coupled with a proxy [change](https://github.com/linkerd/linkerd2-proxy/pull/122) ensure that requests from a that occur in the aforementioned scenario, always redirect to the inbound listener of the proxy first. fixes #1585 Signed-off-by: Dennis Adjei-Baah --- bin/docker-build-proxy | 2 +- proxy-init/iptables/iptables.go | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/bin/docker-build-proxy b/bin/docker-build-proxy index 1acc2111d..3e01d5c80 100755 --- a/bin/docker-build-proxy +++ b/bin/docker-build-proxy @@ -14,6 +14,6 @@ rootdir="$( cd $bindir/.. && pwd )" . $bindir/_tag.sh # Default to a pinned commit SHA of the proxy. -PROXY_VERSION="${PROXY_VERSION:-5e0a15b}" +PROXY_VERSION="${PROXY_VERSION:-21887e5}" docker_build proxy "$(head_root_tag)" $rootdir/Dockerfile-proxy --build-arg PROXY_VERSION=$PROXY_VERSION diff --git a/proxy-init/iptables/iptables.go b/proxy-init/iptables/iptables.go index a4a4d4ea8..e484df237 100644 --- a/proxy-init/iptables/iptables.go +++ b/proxy-init/iptables/iptables.go @@ -73,14 +73,17 @@ func formatComment(text string) string { func addOutgoingTrafficRules(commands []*exec.Cmd, firewallConfiguration FirewallConfiguration) []*exec.Cmd { outputChainName := "PROXY_INIT_OUTPUT" + redirectChainName := "PROXY_INIT_REDIRECT" executeCommand(firewallConfiguration, makeFlushChain(outputChainName)) executeCommand(firewallConfiguration, makeDeleteChain(outputChainName)) commands = append(commands, makeCreateNewChain(outputChainName, "redirect-common-chain")) - // Ingore traffic from the proxy + // Ignore traffic from the proxy if firewallConfiguration.ProxyUid > 0 { log.Printf("Ignoring uid %d", firewallConfiguration.ProxyUid) + // Redirect calls originating from the proxy destined for an app container e.g. app -> proxy(outbound) -> proxy(inbound) -> app + commands = append(commands, makeRedirectChainForOutgoingTraffic(outputChainName, redirectChainName, firewallConfiguration.ProxyUid,"redirect-non-loopback-local-traffic")) commands = append(commands, makeIgnoreUserId(outputChainName, firewallConfiguration.ProxyUid, "ignore-proxy-user-id")) } else { log.Println("Not ignoring any uid") @@ -241,6 +244,19 @@ func makeJumpFromChainToAnotherForAllProtocols(chainName string, targetChain str "--comment", formatComment(comment)) } +func makeRedirectChainForOutgoingTraffic(chainName string, redirectChainName string, uid int, comment string) *exec.Cmd { + return exec.Command("iptables", + "-t", "nat", + "-A", chainName, + "-m", "owner", + "--uid-owner",strconv.Itoa(uid), + "-o", "lo", + "!", "-d 127.0.0.1/32", + "-j", redirectChainName, + "-m", "comment", + "--comment", formatComment(comment)) +} + func makeShowAllRules() *exec.Cmd { return exec.Command("iptables", "-t", "nat", "-vnL") }