{josuah.net} | {panoramix-labs.fr}
(DIR) • {josuah.net}
(DIR) • {panoramix-labs.fr}
{cv} | {links} | {quotes} | {mail}
(BIN) • {cv}
(DIR) • {links}
(DIR) • {quotes}
━━━━━━━━━
sni-shunt
━━━━━━━━━
(TXT) `git://git.josuah.net/sni-shunt` - {0.3}
(DIR) {sni-shunt(1)} is a small utility to dispatch incoming TLS request to the
apropriate backend according to the TLS Server Name.
(HTM) It is inspired by {calico}, but calico only supports dispatching to UNIX domain
sockets.
How to use it?
──────────────
For instance, to choose the certificate file according to a pattern and then
(HTM) starting the httpd within the connexion, using {s6-networking} for handling TCP
(HTM) and TLS and {httpfile} for handling HTTP:
┊ $ s6-tcpserver :: 443 \
┊ sni-shunt \
┊ -e KEYFILE=/etc/letsencrypt/live/%/privkey.pem \
┊ -e CERTFILE=/etc/letsencrypt/live/%/fullchain.pem \
┊ s6-tlsd \
┊ env UID="$(id -u www)" GID="$(id -g www)" ROOT="/srv/www/htdocs" \
┊ httpfile-httpd
How to get it?
──────────────
No dependency other than libc and cc: the TLS SNI parsing is not so hard, and
built in sni-shunt.
┊ $ git clone git://code.z0.is/sni-shunt
┊ $ cd sni-shunt
┊ $ make PREFIX=/usr/local MANPREFIX=/usr/local/man install
What is it for?
───────────────
TLS clients send the ServerName to the server while connecting to indicate
which certificate the server must send to it. sni-shunt uses this indication to
choose something different depending on the ServerName sent by the client.
This permits to shunt the incoming TLS connexion to a different backend
according to the domain name used to connect, even if it is the same IP
address, without any httpd or other protocol-specific server.
This permits to use tools like [s6-tlsserver]() for multiple certificates by
specifying it which one to use, even though s6-tlsserver support only one.
How does it work?
─────────────────
It expects to be run from {inetd(8)} or an {UCSPI} server program such as {s6-tcpserver}
(HTM) • {inetd(8)}
(HTM) • {UCSPI}
(HTM) • {s6-tcpserver}
o that it has a listenning socket at file descriptor 0 (`STDIN_FILENO`).
Once a client opens a TLS session, it peeks at the first 1024 bytes and parse
the Server Name value (no TLS library needed: rather simple parsing).
If found, it sets `SERVER_NAME` to the string encountered, as well as others
variables according to patterns sent via the `-e` command line flag.
It is transparent to the backend, as the bytes it reads are still considered
(HTM) unread, due to {`MSG_PEEK` of recv(2)} so the back-end is still providing the
TLS implementation. You read it right: the ServerName message is parsed twice.
Any benchmark?
──────────────
*sni-shunt* does not aim high-performance, so no benchmark. But like calico,
it adds very little overhead as it does a very small task and let the TLS
handling to the child program.