logo
0
0
WeChat Login
AJ ONeal<aj@therootcompany.com>
doc: note change of --ip-domain to --ip-domains

tlsrouter

A TLS Reverse Proxy for SNI and ALPN routing.

Supports both static and dynamic TLS routing.

go run ./cmd/tlsrouter/ \ --config ~/.config/tlsrouter/backends.csv \ --vault ~/.config/tlsrouter/secrets.tsv \ --ip-domains vm.example.com \ --networks 192.168.1.0/24 \ --bind 0.0.0.0 \ --port 443

Configured backends are loaded statically, while URLs like https://tls-192-168-1-100.vm.example.com are dynamically proxied - provided that the ip domain and ip-as-subdomain addresses match the allowed domain and networks.

DNS Authorization

Sites are configured through DNS.

CNAME (for subdomains)

Both http/1.1 and ssh (terminated) can be enabled by setting a CNAME to the direct IP domain:

# terminates https to 3080 CNAME site-a.whatever.com tls-192-168-1-100.vm.example.net 300 # proxies non-terminated to 443 CNAME site-a.whatever.com tcp-192-168-1-100.vm.example.net 300

If you'd like to use a CNAME for convenience for multiple records, use cname.<ip-domain>, such as cname.vm.example.net.

CNAME sites.whatever.com cname.vm.example.net 300

Note: all ports in the table below are public and you should bind to localhost or use a firewall if you wish to run things on those ports privately.

A + SRV (for apex domains)

A whatever.com 123.1.2.3 300 SRV _http._tcp.whatever.com 10 3080 tls-10-11-1-123.a.bnna.net 300 10 SRV _ssh._tcp.whatever.com 10 22 tls-10-11-1-123.a.bnna.net 300 10

Note: ports must be selected according to the table below. Arbitrary ports are not allowed for security reasons (anyone can set records on their domain to your IP address).

SRV (to enable more protocols)

Whether using CNAME or A records, SRV records will enable additional proxying.

SRV _h2._tcp.whatever.com 10 443 tcp-10-11-1-123.a.bnna.net 300 10 SRV _postgresql._tcp.whatever.com 10 3080 tls-10-11-1-123.a.bnna.net 300 10

ALPN names can be translated to service names in one of two ways:

  1. replace all . (periods) with -, and replace / with _
  2. drop anything after / and replace all . (periods) with -

For example: http and http_1-1 are both valid for http/1.1

Note: ports must be selected according to the table below. Arbitrary ports are not allowed for security reasons (anyone can set records on their domain to your IP address).

Dynamic IP URL Mapping

The URL pattern is There are two URL patterns:

  • <layer4>-<ipv4-octets>-<ip-domain>
  • tls-192-168-1-100.example.com (Handles / Terminates TLS)
  • tcp-192-168-1-100.example.com (Raw TCP Passthrough / Non-Terminating)

ALL TRAFFIC uses port 443 externally.

If the Raw TCP URL is used, then the Raw Port will be used - proxied traffic will remain encrypted.

If the Terminating URL is used, then the Decrypted Port will be used.

Why non-standard ports? So that unencrypted services, which may have been intended for private networking, aren't exposed to the Internet by default.

ALPNRaw PortDecrypted PortComment
http/1.144330803080 to be familiar, but non-default like 3000, 8080, and 80
ssh4432222sshd can't handle sclient tls directly, hence 44322 for tls
---------special protocols
acme-tls/1443-for ACME / Let's Encrypt TLS SNI ALPN challenges
h2443-proper HTTP/2 requires raw passthrough and has no plain port
h2c-3080plain HTTP/2, for testing/debugging
---------10,000 is added to the default ports below
coap568415683IoT, plain port is 5683
dicom276210104biomedical imaging, plain port is 104
dot85310053dns-over-tls, normal plain port is 53 (udp and tcp)
ftp99010021normal plain port is 21, but it's more complicated than that
imap99310143normal plain port is 143
irc669716667normal plain port is 6667
managesieve419014190for mail filtering, plain is also 4190
mqtt888311883normal plain port is 1883
nntp56310119for News Servers, plain port is 119
ntske/1446010123for NTP, normal plain port is 123
pop399510110normal plain port is 110
postgresql543215432Postgres 17+ supports direct TLS
tds/8.0143311433MS SQL 2025+ supports direct TLS
radius/1.0208312083legacy TLS optional
radius/1.1208312083direct TLS required
sip506115060normal plain port is 5060 (or 5080)
smb1044510445Either use requires tunneling (native SMB TLS requires QUIC)
webrtc4431008010080 to be familiar, but not 18080, 8080, 8081, or 9000
c-webrtc44310080"
xmpp-client522315222client-to-server communication, default 5222 (plain)
xmpp-server527015269server-to-server communication, default 5269 (plain)

For all registered ALPNs, see https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml.

Excluded:

  • co is UDP-only
  • doq DNS over QUIC is UDP-only
  • http/0.9, http/1.0 superseded by http/1.1
  • h3 HTTP over QUIC is UDP-only
  • nnsp has no port designation (and isn't actually referenced in the RFC)
  • spdy/* superseded by h2
  • stun.turn has more complex implications that I'm ready to consider
  • stun.nat-discovery (same)
  • sunrpc probably not relevant