Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to make Blockhole blocking on L7 #4

Closed
wants to merge 3 commits into from

Conversation

henrybear327
Copy link
Owner

@henrybear327 henrybear327 commented Apr 23, 2024

Attempt to make Blockhole blocking on L7

Based on Fu Wei's idea [2], we employ blocking on L7 but without using
external tools.

The main idea is to read out X-PeerURLs from the header, since this
is how peer traffic identifies itself to others. As we also know that
all nodes will create direct connections with their peers, so the traffic
blocking will actually happen at all nodes' proxies (contrary to the
current design, where only the proxy of the peer is being blackholed.

However, this way of blocking (by X-PeerURLs from the header) will
miss certain types of traffic to certain endpoints,
e.g. /members, /version, and /raft/probing.

See below for the log extract,
as its header doesn't contain X-PeerURLs information.

  • map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]] /members
  • map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]] /version
  • map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]] /raft/probing

In order to read out X-PeerURLs from the header, we need to terminate
the SSL connection, as we can't drop cleartext traffic (ref [1]). Thus,
a new option e2e.WithSSLTerminationProxy(true) is introduced, which
will change the network flow into

A -- B's SSL termination proxy - B's transparent proxy - B
     ^ newly introduced          ^ in the original codebase

This prototype doesn't address

  • blocking only RX or TX traffic
  • slowness when performing test cleanup
    , and the coding convention needs to be improved as it's still a PoC

References:
[1] etcd-io#15595
[2] etcd-io#17737

@henrybear327 henrybear327 force-pushed the fix/e2e_blackhole_proxy_review branch 2 times, most recently from 4b5895d to 5290dea Compare April 25, 2024 08:16
- map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]] /version
- map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]] /raft/probing
*/
if req, err := http.ReadRequest(bufio.NewReader(bytes.NewBuffer(data))); err != nil {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick question: it's going to read data and marshal into request?

Copy link
Owner Author

@henrybear327 henrybear327 Apr 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my current design no, I only look at the header X-PeerURLs

If there are other fields within the request body that’s worth looking into in your mind, please let me know!

Thank you!

siyuanfoundation and others added 2 commits April 28, 2024 05:50
Shorten the wait time for the open connection to expire to 5s
@henrybear327 henrybear327 force-pushed the fix/e2e_blackhole_proxy_review branch from 5290dea to fab864d Compare April 27, 2024 21:50
Based on Fu Wei's idea, we employ blocking on L7 but without using
external tools.

[Main ideas]
The main idea is
1) utilize the `X-PeerURLs` field from the header, as we know all
traffic to peer will contain this header field.
2) As we also know that all nodes will create direct connections with their
peers, so the traffic blocking will have to happen at all nodes'
proxies, contrary to the current design, where only the proxy of the
peer is being blackholed.

Based on the main ideas, we introduce a SSL termination proxy so we can
obtain the `X-PeerURLs` field from the header.

[Issues]

There are 2 known issues with this approach
1) still leaking some traffic. But the leaked traffic (as discussed
later won't affect the blackhole idea that we would like to achieve (as
stream and pipeline traffic between raft nodes are now properly terminated)
2) we would need to employ SSL termination proxy, which might lead to a
small performance hit

For 1), as this way of blocking (by utilizing `X-PeerURLs` from the
header) will miss certain types of traffic to certain endpoints, as
the traffic to some endpoints doesn't have the `X-PeerURLs` field.
Currently, here are the known ones: /members, /version, and /raft/probing.
As you can see from the log, its header doesn't contain the `X-PeerURLs`
field, but only the following fields:
- map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]] /members
- map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]] /version
- map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]] /raft/probing

For 2) in order to read out `X-PeerURLs` from the header, we need to
terminate the SSL connection, as we can't drop cleartext traffic
(ref [1]). Thus, a new option `e2e.WithSSLTerminationProxy(true)`
is introduced, which will change the network flow into
```
A -- B's SSL termination proxy - B's transparent proxy - B
     ^ newly introduced          ^ in the original codebase
```

[Known improvements required before turning RFC into PR]

The prototype needs to be further improved for code review after
fixing the following issues:
- blocking only RX or TX traffic (as currently a call to `blackholeTX`
or `blackholeRX` will black both TX and RX traffic instead of just
the specified one.
- slowness when performing test cleanup (I think this is related to the
SSL timeout setting, but I haven't looked into it yet)
- coding style improvements

References:
[1] etcd-io#15595
@henrybear327
Copy link
Owner Author

Superseded by etcd-io#17891

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants