kerryjiang / SuperSocket

SuperSocket is a light weight, cross platform and extensible socket server application framework.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Proxy Protocol Support

alberk8 opened this issue · comments

Is it possible to add ProxyProtocol support for SuperSocket?. Thank you.

Do you mean this?
https://github.com/SuperSocket/SuperSocket.ProxyServer

This one is still based on SuperSocket 1.6.*. I will spend some time to upgrade it to SuperSocket 2.0.

Do you mean this? https://github.com/SuperSocket/SuperSocket.ProxyServer

This one is still based on SuperSocket 1.6.*. I will spend some time to upgrade it to SuperSocket 2.0.

I think is different. The proxy protocol is more from Reverse Proxy Server. A good example is if the SuperSocket docker is sitting behind Traefik then I get the IP of traefik and not the client remote IP. With Proxy Protocol where the Reverse Proxy server will add data related to the remote IP much like Http X-Forwarded-For but at the packet level.

https://developers.cloudflare.com/spectrum/how-to/enable-proxy-protocol/
https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

commented

I also asked a similar question before. I used Haproxy reverse proxy, so the client IP becomes the IP of the reverse proxy. Haproxy supports the send-proxy protocol and can be parsed from the send-proxy protocol. To the source IP, does SuperSocket 2.0 support it?

I also asked a similar question before. I used Haproxy reverse proxy, so the client IP becomes the IP of the reverse proxy. Haproxy supports the send-proxy protocol and can be parsed from the send-proxy protocol. To the source IP, does SuperSocket 2.0 support it?

No at the moment because SuperSocket does not not process the Proxy Protocol if that is switched on in the Reverse Proxy server.

It's on the way:
49df1f2

I tried to adding EnabledProxyProtocol into appsettings and it does not seems to work what else do I need to do? Thank you.

Update: The latest myget nuget seems to fix the issue.

Yes, haven't pushed the latest package to nuget.

Please help me confirm if this feature can work. I will push a new version to nuget ASAP.

@alberk8

I have tested and it looks like the Server EndPoint IP is in reverse order. The Server Endpoint should read 192.168.2.15
The Client IP 172.27.0.3 is the IP of the SuperSocket Docker Container and supersocket is behind the Traefik Proxy Server.

We also need to better define the IP source and target differentiation

.UsePackageHandler(async (session, package) =>
{
  Console.WriteLine($"Server EndPioint {((IPEndPoint)session.RemoteEndPoint).Address.ToString()} Client EndPoint {((IPEndPoint)session.Connection.RemoteEndPoint).Address.ToString()} ");
}

Server EndPioint 15.2.168.192 Client EndPoint 172.27.0.3

Try this instead.

.UsePackageHandler(async (session, package) =>
{
  Console.WriteLine($"Server EndPioint {((IPEndPoint)session.LocalEndPoint).Address.ToString()} Client EndPoint {((IPEndPoint)session.RemoteEndPoint).Address.ToString()} ");
}

If you want to access the original destination endpoint, you can use the statement below:

session.Connection.ProxyInfo.DestinationIPAddress;

or

session.Connection.ProxyInfo.DestinationEndPoint;

I have tested and it looks like the Server EndPoint IP is in reverse order. The Server Endpoint should read 192.168.2.15 The Client IP 172.27.0.3 is the IP of the SuperSocket Docker Container and supersocket is behind the Traefik Proxy Server.

We also need to better define the IP source and target differentiation

.UsePackageHandler(async (session, package) =>
{
  Console.WriteLine($"Server EndPioint {((IPEndPoint)session.RemoteEndPoint).Address.ToString()} Client EndPoint {((IPEndPoint)session.Connection.RemoteEndPoint).Address.ToString()} ");
}

Server EndPioint 15.2.168.192 Client EndPoint 172.27.0.3

15.2.168.192 was read as original client ip, 172.27.0.3 was read as proxy server's ip.

That means the addresses (at least ipv4) are read in reverse order.

Yes the IP for the ProxyInfo is in reverse order

.UsePackageHandler(async (session, package) =>
{
   Console.WriteLine($"Server EndPioint {((IPEndPoint)session.RemoteEndPoint).Address.ToString()} Client EndPoint {((IPEndPoint)session.Connection.RemoteEndPoint).Address.ToString()} ");
  Console.WriteLine($"Proxy Info Source: {session.Connection.ProxyInfo.SourceIPAddress.ToString()} Destination: {session.Connection.ProxyInfo.SourceIPAddress.ToString()}");
}

Server EndPioint 15.2.168.192 Client EndPoint 172.20.0.3
Proxy Info Source: 15.2.168.192 Destination: 15.2.168.192

Pushed one fix.

I am using Proxy Protocol Version 2 and you code looks right according to Proxy Protocol specs. The reverse proxy I am using is traefik v3.1.1, Have you tested with Proxy protocol with any other Reverse proxy server?

Update:
I tried this Aspnet with ProxyProtocol example and it looks ok. I think you need to check for endianess

Pushed one fix.

Tested and now the IPV4 is the correct order. I looked at your code again, I think you need to reverse the IPV6 also (I have not tested that yet).

There is one thing I notice is that the session.Connection.ProxyInfo.SourceIPAddress and session.Connection.ProxyInfo.SourceIPAddress are exactly identical. I will dig in further once I get more time.

Probably reversing bytes for ipv6 is not necessary because original bytes are taken directly. But I will do further confirming.

Do you mean ProxyInfo.SourceIPAddress and ProxyInfo.DestinationIPAddress are same?

Probably reversing bytes for ipv6 is not necessary because original bytes are taken directly. But I will do further confirming.

Do you mean ProxyInfo.SourceIPAddress and ProxyInfo.DestinationIPAddress are same?

The IPV6 address from the ProxyProtocol is in BigEndian format so on a little endian platform it will look reverse if the reversing is not done.

yes both source and destination IP are the same.

I am working on more unit tests and already noticed the problem of ipv6.

One more thing. if I call the session.Connection.ProxyInfo.SourceIPAddress when the enableProxyProtocol is not set it will throw a null reference. Can this not throw?