connection: Set the SOL_IP,IP_TRANSPARENT option on listen sockets#2719
connection: Set the SOL_IP,IP_TRANSPARENT option on listen sockets#2719htuch merged 7 commits intoenvoyproxy:masterfrom rlenglet:listen-socket-transparent
Conversation
There was a problem hiding this comment.
I don't think this should be set unconditionally; this should only be done based on some configuration.
|
This seems like it should be configurable per listener. Can you create a PR in https://github.com/envoyproxy/data-plane-api with a proposed modification to LDS configuration? |
|
Will do. Thanks! |
|
Submitted this PR to data-plane-api: envoyproxy/data-plane-api#522. |
There was a problem hiding this comment.
AFAIK, this should be IP_TRANSPARENT for IPv4 and IPV6_TRANSPARENT for IPv6.
There was a problem hiding this comment.
Fixed in upcoming commit.
There was a problem hiding this comment.
Note that this won't work for IPv6 when building using Envoy's Docker image (Ubuntu 16.04.3 with libc6-dev 2.23-0ubuntu10) because IPV6_TRANSPARENT is not defined in that image:
$ ./ci/run_envoy_docker.sh 'grep IPV6_TRANSPARENT /usr/include/x86_64-linux-gnu/bits/in.h'
returns nothing.
On Ubuntu 17.10 with libc6-dev 2.26-0ubuntu2.1, this macro is defined as expected:
$ grep IPV6_TRANSPARENT /usr/include/x86_64-linux-gnu/bits/in.h
#define IPV6_TRANSPARENT 75
There was a problem hiding this comment.
This is still a real error, if configuration requires IP_TRANSPARENT.
There was a problem hiding this comment.
Fixed in upcoming commit.
There was a problem hiding this comment.
I believe this can be moved into if (bind_to_port) { ... }, since as far as I recall, it's useless without bind().
There was a problem hiding this comment.
One could make the same argument about the existing setsockopt(fd_, SOL_SOCKET, SO_REUSEADDR, ...) above. Should I move all setsockopt calls into if (bind_to_port) { ... }?
|
Re: #2659, this is a different, complementary issue. You need first to implement IP_TRANSPARENT in the inbound listen socket anyway, like I do here, so that you get the original source address. Without that, you won't know what address to bind to. |
|
The mac tests timed out. It doesn't seem to be a functional failure. Is that something I should look into? |
…#522) Add a "transparent" option to Listener to set the SOL_IP/IP_TRANSPARENT option on listen sockets, which allows using Envoy with the iptables TPROXY target. Unlike the iptables REDIRECT target, TPROXY allows preserving both the source and destination IP addresses and ports of accepted connections. API changes for: envoyproxy/envoy#2719 Signed-off-by: Romain Lenglet <romain@covalent.io>
Pull a quick-and-dirty implementation of the SOL_IP,IP_TRANSPARENT option setup on listen sockets: https://github.com/rlenglet/envoy/tree/quick-and-dirty-transparent This will be reverted when the proper, clean change is merged upstream into Envoy: envoyproxy/envoy#2719 Signed-off-by: Romain Lenglet <romain@covalent.io>
|
@rlenglet can you merge to resolve conflict? |
There was a problem hiding this comment.
Q: Do we foresee having more options like this in the future? If so should we switch to some type of options struct that gets passed around? That would a avoid having to change every individual callsite and test again in the future potentially. Just throwing it out there.
There was a problem hiding this comment.
I personally don't foresee more options like this. But if we think that could happen, I could use #2734 to implement this internally.
There was a problem hiding this comment.
If we don't foresee more options like this than I wouldn't worry about it.
There was a problem hiding this comment.
I have one more option coming that is similar/related: enabling tcp-fastopen on listening sockets.
There was a problem hiding this comment.
@ggreenway So what is your preference? Should we implement this with #2734?
There was a problem hiding this comment.
question.. how does IP_FREEBIND differ from IP_TRANSPARENT?
There was a problem hiding this comment.
@ggreenway Would it work for you better if I generalized the current option setting code (i.e., #2734 ) to accept multiple option setters, maintain a list of set options and have the call sites call all of them (unless one of them fails)?
There was a problem hiding this comment.
FREEBIND allows binding to an address that isn't configured on any interface on the machine. IP_TRANSPARENT would also allow this, but from inside Envoy should otherwise work the same as a regular listener (whereas transparent is designed around a different use case where the traffic has been redirected to Envoy and has some original destination that is meaningful).
PiotrSikora
left a comment
There was a problem hiding this comment.
Since there are no tests (due to iptables), did anybody other than the author tested that it really works?
Another questions is, how does this interact with SO_ORIGINAL_DST and PROXY protocol?
There was a problem hiding this comment.
Is there a reason why we cannot disable IP_TRANSPARENT for the new listener?
There was a problem hiding this comment.
@PiotrSikora I was thinking that we have an atomicity issue. How do we atomically hand off the socket to the new listener and set/unset the option? That would require that there is a period of time when no thread is accepting on the socket during the handoff. I don't think we have that (?). And that's not desirable, since that would cause connections to be rejected during that period.
There was a problem hiding this comment.
@rlenglet there is always a period of time when no thread is accepting new connections (i.e. when all threads are busy processing active requests), and no connections are rejected because of kernel-maintained backlog queue on the listening socket, so I don't think lack of atomicity is the problem.
Having said that, I'm fine if you want to leave it as-is.
There was a problem hiding this comment.
I'm removing that verification. We know from an accepted socket's option whether it has been TPROXYed or not, so we can safely have a mix of connections with and without TPROXY in the same queue.
|
@PiotrSikora It should have no interaction with |
|
@rlenglet my point was what happens if you use |
|
@rlenglet can you take a look at #2922? I started with some of the pieces in this PR, but there was a bunch of cleanup I did to make it (1) avoid the #ifdef proliferation, (2) add support for upstream as well as listener and (3) work with additional options without boiletplate. I think it might make sense to merge that one first and then this present PR should be much simpler. |
|
@htuch Great! I'll merge from master today. |
…nsparent Signed-off-by: Romain Lenglet <romain@covalent.io>
|
@htuch Please review. I merged from master. |
Pull a quick-and-dirty implementation of the SOL_IP,IP_TRANSPARENT option setup on listen sockets: https://github.com/rlenglet/envoy/tree/quick-and-dirty-transparent This will be reverted when the proper, clean change is merged upstream into Envoy: envoyproxy/envoy#2719 Signed-off-by: Romain Lenglet <romain@covalent.io>
htuch
left a comment
There was a problem hiding this comment.
This looks great, the implementation is ready to ship. Can you add a listener_manager_impl_test similar to what is done for freebind and was done in earlier revisions?
|
Love, love, love how simple this all became. Great work @ggreenway @PiotrSikora @htuch @rlenglet! @rlenglet can we get the doc/release note PR redone before we merge this? Thank you. |
Signed-off-by: Romain Lenglet <romain@covalent.io>
Signed-off-by: Romain Lenglet <romain@covalent.io>
|
@htuch Added tests. Looks clean. |
|
@mattklein123 Here is the release note PR: envoyproxy/data-plane-api#593 |
|
The |
| } | ||
| } | ||
|
|
||
| // Transparent settings have no effect on post-bind behavior. |
There was a problem hiding this comment.
I thought transparent does have an effect on both prebind and postbind?
There was a problem hiding this comment.
Right. I will relax that.
There was a problem hiding this comment.
Added a commit to support setting IP_TRANSPARENT both pre-bind and post-bind.
Signed-off-by: Romain Lenglet <romain@covalent.io>
Signed-off-by: Romain Lenglet <romain@covalent.io>
ggreenway
left a comment
There was a problem hiding this comment.
LGTM; just questioning whether we can remove the v1 support.
| }, | ||
| "drain_type": {"type" : "string", "enum" : ["default", "modify_only"]}, | ||
| "ssl_context" : {"$ref" : "#/definitions/ssl_context"}, | ||
| "transparent" : {"type": "boolean"}, |
There was a problem hiding this comment.
Is the v1 API absolutely required?
There was a problem hiding this comment.
We'll need it for Istio. Cf. istio/istio#4654 (review)
|
Thanks @rlenglet for all your patience here. |
|
@htuch Thanks a lot! |
… (#522) Add a "transparent" option to Listener to set the SOL_IP/IP_TRANSPARENT option on listen sockets, which allows using Envoy with the iptables TPROXY target. Unlike the iptables REDIRECT target, TPROXY allows preserving both the source and destination IP addresses and ports of accepted connections. API changes for: envoyproxy/envoy#2719 Signed-off-by: Romain Lenglet <romain@covalent.io>
connection: Set the SOL_IP,IP_TRANSPARENT option on listen sockets
Implement the "transparent" option in the LDS Listener to set the SOL_IP/IP_TRANSPARENT option on listen sockets, which allows using Envoy with the iptables TPROXY target. Unlike the iptables REDIRECT target, TPROXY allows preserving both the source and destination IP addresses and ports of accepted connections.
Update the OriginalDst filter to restore the original destination IP address of TPROXY connections in addition to REDIRECT connections.
Signed-off-by: Romain Lenglet romain@covalent.io
Signed-off-by: Jarno Rajahalme jarno@covalent.io
Risk Level: Low