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

Support HAProxy proxy protocol for broker and proxy #8686

Merged
merged 4 commits into from
Nov 30, 2020

Conversation

codelipenghui
Copy link
Contributor

Motivation

Currently, if enable the proxy in the pulsar cluster and client connect to the cluster through the proxy, when we get topic stats, the consumer address and producer address are not the real client address. This PR fix this problem by leverage HAProxy proxy protocol since this is a more general approach. more details about the proxy protocol see
https://www.haproxy.com/blog/haproxy/proxy-protocol/
https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html
http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

Modifications

Allow enable proxy protocol on proxy or broker.

Verifying this change

Tests added

Does this pull request potentially affect one of the following parts:

If yes was chosen, please highlight the changes

  • Dependencies (does it add or upgrade a dependency): (no)
  • The public API: (no)
  • The schema: (no)
  • The default values of configurations: (no)
  • The wire protocol: (no)
  • The rest endpoints: (no)
  • The admin cli options: (no)
  • Anything that affects deployment: (no)

Documentation

  • Does this pull request introduce a new feature? (yes)

@codelipenghui codelipenghui self-assigned this Nov 24, 2020
@codelipenghui codelipenghui added this to the 2.8.0 milestone Nov 24, 2020
@codelipenghui codelipenghui added the doc-required Your PR changes impact docs and you will update later. label Nov 24, 2020
@@ -169,6 +171,11 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws E

@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(haProxyMessage);
Copy link
Member

Choose a reason for hiding this comment

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

remove this?

@eolivelli
Copy link
Contributor

@diegosalvi you have recently implemented this feature on EmailSuccess, can you please take a look?

conf/broker.conf Outdated
@@ -55,6 +55,9 @@ advertisedAddress=
# The Default value is absent, the broker uses the first listener as the internal listener.
# internalListenerName=

# Enable or disable the proxy protocol.
proxyProtocolEnabled=false
Copy link
Contributor

Choose a reason for hiding this comment

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

This naming can be confusing since we already have a "proxy" for Pulsar protocol

Copy link
Contributor Author

@codelipenghui codelipenghui Nov 25, 2020

Choose a reason for hiding this comment

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

How about change to haProxyProtocolEnabled?

Copy link
Member

Choose a reason for hiding this comment

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

haProxyProtocol looks much better than proxyProtocol.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, sounds good.

@codelipenghui
Copy link
Contributor Author

/pulsarbot run-failure-checks

});
}

private ByteBuf encodeProxyProtocolMessage(HAProxyMessage msg) {
// Max length of v1 version proxy protocol message is 108
ByteBuf out = Unpooled.buffer(108);
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually maximum record size is 107 by spec:

  • worst case (optional fields set to 0xff) :```

    "PROXY UNKNOWN ffff:f...f:ffff ffff:f...f:ffff 65535 65535\r\n"
    => 5 + 1 + 7 + 1 + 39 + 1 + 39 + 1 + 5 + 1 + 5 + 2 = 107 chars

[...]

The receiver must wait for the CRLF sequence before starting to decode the
addresses in order to ensure they are complete and properly parsed. If the CRLF
sequence is not found in the first 107 characters, the receiver should declare
the line invalid.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm using the netty-haproxy-codec directly. I think netty codec already handled this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -118,6 +119,9 @@ protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("ByteBufPairEncoder", ByteBufPair.ENCODER);
}

if (pulsar.getConfiguration().isHaProxyProtocolEnabled()) {
ch.pipeline().addLast(OptionalProxyProtocolDecoder.NAME, new OptionalProxyProtocolDecoder());
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should have the possibilitiy to require proxy headers instead of handle them as optional.
Specification itself states:

The receiver MUST be configured to only receive the protocol described in this
specification and MUST not try to guess whether the protocol header is present
or not. This means that the protocol explicitly prevents port sharing between
public and private access.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a flag to control if users want to enable the haproxy protocol support. We must provide a way to disable this feature.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure! What I was saying is that there isn't a way to REQUIRE proxy header if pulsar.getConfiguration().isHaProxyProtocolEnabled(). Specs states that is MUST expect a proxy header, it isn't optional. There could be another option to handle optional/mandatory

InetSocketAddress proxyAddress = (InetSocketAddress) inboundChannel.remoteAddress();
String destinationAddress = proxyAddress.getAddress().getHostAddress();
int destinationPort = proxyAddress.getPort();
HAProxyMessage msg = new HAProxyMessage(HAProxyProtocolVersion.V1, HAProxyCommand.PROXY,
Copy link
Contributor

Choose a reason for hiding this comment

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

netty-haproxy can decode binary v2 version too (but doesn't implements encoding).
We could add another encoding method for v2 protocol and let the configurer choose which use.

For the encoding implementation I've done one for subethamail if you want take a peek. It has been done for testing purposes (so it permits some strange behaviour to check various edge cases and "wrong" headers and can surely be simplified): https://github.com/davidmoten/subethasmtp/blob/master/src/test/java/org/subethamail/smtp/internal/proxy/ProxyProtocolV2HandlerTest.java

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not a required for this PR, we can support the proxy set the different protocol version in the following PRs.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good

@sijie sijie merged commit 625627c into apache:master Nov 30, 2020
@sijie
Copy link
Member

sijie commented Nov 30, 2020

/pulsarbot cherry-pick to branch-2.6

@sijie
Copy link
Member

sijie commented Nov 30, 2020

/pulsarbot cherry-pick to branch-2.7

github-actions bot pushed a commit that referenced this pull request Nov 30, 2020
### Motivation

Currently, if enable the proxy in the pulsar cluster and client connect to the cluster through the proxy, when we get topic stats, the consumer address and producer address are not the real client address. This PR fix this problem by leverage HAProxy proxy protocol since this is a more general approach.  more details about the proxy protocol see
https://www.haproxy.com/blog/haproxy/proxy-protocol/
https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html
http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

### Modifications

Allow enable proxy protocol on proxy or broker.

### Verifying this change

Tests added

(cherry picked from commit 625627c)
codelipenghui added a commit that referenced this pull request Dec 2, 2020
### Motivation

Currently, if enable the proxy in the pulsar cluster and client connect to the cluster through the proxy, when we get topic stats, the consumer address and producer address are not the real client address. This PR fix this problem by leverage HAProxy proxy protocol since this is a more general approach.  more details about the proxy protocol see
https://www.haproxy.com/blog/haproxy/proxy-protocol/
https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html
http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

### Modifications

Allow enable proxy protocol on proxy or broker.

### Verifying this change

Tests added

(cherry picked from commit 625627c)
@codelipenghui codelipenghui deleted the penghui/proxy_protocol branch December 2, 2020 09:27
@codelipenghui codelipenghui added the cherry-picked/branch-2.7 Archived: 2.7 is end of life label Dec 2, 2020
@codelipenghui
Copy link
Contributor Author

/pulsarbot cherry-pick to branch-2.6

codelipenghui added a commit that referenced this pull request Dec 3, 2020
Currently, if enable the proxy in the pulsar cluster and client connect to the cluster through the proxy, when we get topic stats, the consumer address and producer address are not the real client address. This PR fix this problem by leverage HAProxy proxy protocol since this is a more general approach.  more details about the proxy protocol see
https://www.haproxy.com/blog/haproxy/proxy-protocol/
https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html
http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

Allow enable proxy protocol on proxy or broker.

Tests added

(cherry picked from commit 625627c)
codelipenghui added a commit to streamnative/pulsar-archived that referenced this pull request Dec 3, 2020
Currently, if enable the proxy in the pulsar cluster and client connect to the cluster through the proxy, when we get topic stats, the consumer address and producer address are not the real client address. This PR fix this problem by leverage HAProxy proxy protocol since this is a more general approach.  more details about the proxy protocol see
https://www.haproxy.com/blog/haproxy/proxy-protocol/
https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html
http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

Allow enable proxy protocol on proxy or broker.

Tests added

(cherry picked from commit 625627c)
(cherry picked from commit 3813062)
@Anonymitaet Anonymitaet removed the doc-required Your PR changes impact docs and you will update later. label Mar 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants