Skip to content

Lack of proxy-protocol support prevents use of Kestrel with HAproxy in TCP mode #28526

Open
@ststeiger

Description

@ststeiger

One of the advantages of using haproxy over nginx is, that you don't need nginx-PLUS (commercial offering) if you want to add SNI-hosts dynamically.
Another advantages of using HAproxy over nginx is that HAproxy can do SSL/TLS-passthrough forwarding.
Meaning HAproxy then doesn't need the ssl certificate etc, which is great, because then I only need to configure the SSL-key on Kestrel - especially if the SSL/TLS certificate changes at runtime (LetsEncrypt).

A further advantage is, that a TCP-level-proxy will not be limited by a proxy-pipeline, e.g. interfering with HTTP 1.1/2.0.

Now, I have multiple sites running on the same IP.
The way to do this with HAproxy is sni-header inspection.
But because Kestrel does not support the proxy protocol, it's impossible to get the client's IP .

GoLang has support for that since at least 4 years...
By breaking the ability to get the client's IP, you're breaking the ability to geolocate - which breaks the ability to adapt content to a user's region ...

When an intermediary service such as a proxy server or load balancer forwards an HTTP request, it appends the source address of the connection to the request’s "Forwarded" header in order to provide this information to subsequent intermediaries and to the back-end service to which the request is ultimately forwarded. However, if the connection is encrypted, intermediaries cannot modify the "Forwarded" header. In this case, the HTTP header will not accurately communicate the original source address when the request is forwarded.

To solve this problem, some load balancers encapsulate HTTP requests using the PROXY protocol as an alternative to simply forwarding HTTP. Encapsulation enables the load balancer to add information to the request without modifying the forwarded request itself. In particular, this means that the load balancer can communicate the source address even when forwarding an encrypted connection.

If Kestrel could be configured to accept PROXY-protocol connections, it could decapsulate the HTTP request.
Since Kestrel is the route termination, it could decrypt the request, and update the "Forwarded" HTTP header (and related HTTP headers) appending any source address that is communicated using the PROXY protocol.

e.g.

frontend https
    bind :443
    mode tcp
    option tcplog
    tcp-request inspect-delay 5s
    tcp-request content accept if { req.ssl_hello_type 1 }

    use_backend awx_example_com if { req_ssl_sni -i awx.example.com }
    use_backend goren_example_com if { req_ssl_sni -i goren.example.com }
    use_backend tower_example_com if { req_ssl_sni -i tower.example.com }

backend awx_example_com
    server awx 192.168.101.182:5001 send-proxy-v2

backend goren_example_com
    server goren 192.168.101.182:5002 send-proxy-v2

backend tower_example_com
    server tower 192.168.101.182:443 se5003nd-proxy-v2

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsenhancementThis issue represents an ask for new feature or an enhancement to an existing onefeature-kestrelpartner-impact

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions