Score:1

Linux netfilter NAT based on SNI?

cn flag

I am trying to do SNI proxying to a subnet on a router while keeping the src IP.

Background: I have a router doing DNAT to do port-forwarding for many application ports, and it is connected to a subnet (using a VPN actually) with different backends. For protocols that do NOT have something like HTTP Host or TLS SNI that can be routed to different IPs based on the request, I simply uses DNAT with TCP port filter, and they are working well.

For TLS, I am using SNIProxy to multiplex the incoming connections to different servers, based on TLS SNI. It works pretty well, but SINProxy sends the TLS packets from the router itself, discarding src addresses. This breaks some backend services that rely on the src IP.

Thus, I am wondering if it is possible for netfilter to filter the traffic using TLS SNI (optionally with external modules) and route them using DNAT (instead of just dropping). If that is not possible, are there any alternatives?

By the way, I do not want to deploy full HTTP (or any L5 servers) on my router because:

  1. I have to decrypt the traffic and proxy them to the backend. This is a huge overhead.
  2. I do not want to deploy TLS certificates on routers due to the complexity in management.

Thanks very much for any helpful response in advance.

Score:2
se flag

Thus, I am wondering if it is possible for netfilter to filter the traffic using TLS SNI (optionally with external modules)

This is not possible. NAT must be done starting with the first packet of the connection, i.e. the TCP SYN which initiates the TCP handshake. But the SNI is only in the ClientHello of the TLS handshake, which is send only after the TCP handshake is done. In other words: the information needed for NAT are not yet available at the time they are needed.

If that is not possible, are there any alternatives?

haproxy can terminate the TCP connection and then forward the data based on the SNI in the ClientHello - without terminating TLS at the proxy. It can then forward the original source IP of the client inside the TCP connection using the PROXY protocol (basically a header at the beginning of the forwarded connection). If the upstream server does not understand PROXY protocol itself one can use software like mmproxy to SNAT the connection from haproxy so that it shows the original source IP.

Score:1
cl flag
A.B

In theory, using -j NFQUEUE to have userspace alter the first packet and do NAT you could imagine doing something like this. In practice you can't because you need to have received a full ClientHello message with SNI extension to guess the new destination address, and since the first TCP packet will be empty, or with UDP, DTLS will require a few rounds anyway, it's then too late to NAT a flow now managed by conntrack.

You need a proxy. But the proxy can be made transparent or you can use the PROXY protocol with backend applications supporting it (though they have to support using together the PROXY protocol plus TLS).

For example haproxy running on the gateway can do either: it's the project that proposed the PROXY protocol, and it can also use Linux tproxy target for transparent (transparent both with source and destination) proxying.

Here's a link I found to a github gist offering both choices: Leverage HAProxy to transparently route requests to web services identified by host name. Here are a few lines about transparent proxy configuration, to be used along the linux kernel tproxy documentation (also in the same gist):

The HAProxy server configuration would look like the following. It works for both the TCP and HTTP modes.

server app1-tls 192.0.2.10:3001 source * usesrc client weight 0
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.