I built a TLS router that forwards connections based on SNI (Server Name Indication).
-
I built a TLS router that forwards connections based on SNI (Server Name Indication). That means, it accepts TLS connections (like https), checks the desired target hostname, then forwards the encrypted stream to the backend that's configured for the hostname.
It hands off the actual forwarding task to the Linux kernel via eBPF, which makes this a zero-copy operation. As a result, services behind the router are _noticably_ snappier than with the userspace based solutions (that copied the incoming data to userland, copied it from one socket to the other there, back to kernel for further distribution) that I used until now.
Through that, it keeps the client's IP address visible to the client natively instead of fronting everything with the proxy's address.
As a convenience, it can figure out the backend by docker/podman container name, removing the need to "expose" the ports through docker/podman own infrastructure (which is, again, a copy via userspace in some scenarios), including figuring out the new IP address on container restarts.
Other implementations parse out the TLS records manually, trying to get to the SNI data in the ClientHello record with the least amount of effort possible. In contrast, my router uses the Go TLS library, which should make it generally more robust and future proof, given that the library is in use in much more critical scenarios than mine.
It also means that ECH (Encrypted ClientHello) should work to hide the target domain name from the outside world (the router still needs the private key used for ECH to figure out routing, but even with that, it still can't read the data stream itself). That said, I don't have the ECH setup to test it, so that's more of a theoretical option for now.
It runs on my personal infra and makes Jellyfin much snappier, and I'll roll it out to more servers that I maintain as I gain confidence that it's robust enough. Still cleaning up the code, but I'll release it as Free Software sometimes soon.
#freesoftware #Linux #networking -
I built a TLS router that forwards connections based on SNI (Server Name Indication). That means, it accepts TLS connections (like https), checks the desired target hostname, then forwards the encrypted stream to the backend that's configured for the hostname.
It hands off the actual forwarding task to the Linux kernel via eBPF, which makes this a zero-copy operation. As a result, services behind the router are _noticably_ snappier than with the userspace based solutions (that copied the incoming data to userland, copied it from one socket to the other there, back to kernel for further distribution) that I used until now.
Through that, it keeps the client's IP address visible to the client natively instead of fronting everything with the proxy's address.
As a convenience, it can figure out the backend by docker/podman container name, removing the need to "expose" the ports through docker/podman own infrastructure (which is, again, a copy via userspace in some scenarios), including figuring out the new IP address on container restarts.
Other implementations parse out the TLS records manually, trying to get to the SNI data in the ClientHello record with the least amount of effort possible. In contrast, my router uses the Go TLS library, which should make it generally more robust and future proof, given that the library is in use in much more critical scenarios than mine.
It also means that ECH (Encrypted ClientHello) should work to hide the target domain name from the outside world (the router still needs the private key used for ECH to figure out routing, but even with that, it still can't read the data stream itself). That said, I don't have the ECH setup to test it, so that's more of a theoretical option for now.
It runs on my personal infra and makes Jellyfin much snappier, and I'll roll it out to more servers that I maintain as I gain confidence that it's robust enough. Still cleaning up the code, but I'll release it as Free Software sometimes soon.
#freesoftware #Linux #networking@patrick This would replace a bunch of NGINX in my network that are just plain reverse proxies, although it sounds like it would require the backend to also terminate TLS and some of my devices can't do that.
-
R relay@relay.infosec.exchange shared this topic