s6-networking
Software
skarnet.org
The s6-tlsserver program
s6-tlsserver is an
UCSPI server tool for
TLS/SSL connections over INET domain sockets. It acts as a TCP super-server
that listens to connections, accepts them, and for each connection,
establishes a TLS transport over it, then executes into a program.
Interface
s6-tlsserver [ options ] [ -- ] ip port prog...
- s6-tlsserver rewrites itself into a command line
involving:
- s6-tcpserver, which
listens to TCP connections on IP address ip port port
and forks a command line for every connection. Note that
s6-tcpserver also rewrites
itself into a more complex command line (the final long-lived
process being s6-tcpserverd),
so your end command line may look a lot longer in ps
than what you originally wrote. This is normal and healthy.
- (if applicable) s6-tcpserver-access,
which performs TCP access control and various operations on the
TCP connection.
- s6-tlsd, which establishes
a TLS transport (server-side) over a connection, via an
s6-tlsd-io child process.
- (if applicable)
s6-applyuidgid,
which drops root privileges.
- prog..., your client program, which is run with the
same pid as s6-tlsd.
- It runs until it is killed by a signal.
prog is expected to read from its peer on its
standard input and write to its peer on its standard output.
Since there will be an s6-tlsd-io
program between prog and the network to perform
the SSL encryption/decryption, those descriptors will not
be a network socket - they will be pipes.
Signals
s6-tlsserver reacts to the same signals as
s6-tcpserverd,
which is the long-lived process hanging around.
Environment variables
Read
The following variables should be set before invoking
s6-tlsserver, because they will be used by
every s6-tlsd invocation:
- KEYFILE
- CERTFILE
- TLS_UID and TLS_GID (if you run s6-tlsserver as root)
- CADIR (if you want client certificates)
- CAFILE (if you want client certificates, alternative to CADIR)
Setting both KEYFILE and CERTFILE is mandatory.
Written
prog... is run with the following variables added to,
or removed from, its environment by s6-tcpserverd
and possibly by s6-tcpserver-access:
- PROTO
- TCPREMOTEIP
- TCPREMOTEPORT
- TCPCONNNUM
- TCPLOCALIP
- TCPLOCALPORT
- TCPREMOTEHOST
- TCPLOCALHOST
- TCPREMOTEINFO
Depending on TCP access rules (if the -i or -x
option has been given), it is possible that prog's
environment undergoes more modifications. Also, since
s6-tlsd is always run
after s6-tcpserver-access,
it is possible to set different TLS/SSL parameters (typically
a different KEYFILE and CERTFILE) depending on the client
connection, by writing the correct set of TCP access rules.
Unless the -Z option is given to s6-tlsserver,
the CADIR, CAFILE, KEYFILE, CERTFILE, TLS_UID and TLS_GID
variables will not appear in prog's environment.
Options
s6-tlsserver accepts a myriad of options, all of which are
passed as is to the correct executable. Not giving any options will
generally work, but unless you're running a very public server
(such as a Web server) or base your access control on client
certificates, you probably still want TCP access rules.
Options passed as is to s6-tcpserver
- -q, -Q, -v
- -1
- -c maxconn
- -C localmaxconn
- -b backlog
Options passed as is to s6-tcpserver-access
- The verbosity level, if not default, as -v0 or -v2
- -w, -W : be strict or tolerant with DNS or IDENT resolution errors
- -d, -D : enable or disable Nagle's algorithm
- -r, -R : enable or disable IDENT lookups
- -p, -P : enable or disable paranoid DNS cross-checking
- -H : disable DNS lookups
- -h : consult /etc/hosts before DNS
- -l localname : get the local name from the command line, don't look it up
- -B banner : initial server-side banner
- -t timeout : set a timeout for all the lookups
- -i rulesdir, -x rulesfile : TCP access control
Options passed as is to s6-tlsd
- -Z, -z : keep or remove the s6-tlsd-io-specific
variables from the application's environment
- -S, -s : use close_notify or EOF to signal the end of a TLS connection
- -J, -j : exit nonzero with an error message when the peer fails to close_notify, or ignore it
- -Y, -y : request an optional or a mandatory client certificate
- -K kimeout : set a timeout for the TLS handshake
- -k snilevel : support SNI-based certificate chains
Options passed to s6-applyuidgid
- -u uid, -g gid, -G gidlist : set uid, gid, or supplementary group list
- -U (passed as -Uz) : get the uid, gid and supplementary group list from the UID, GID and GIDLIST variables,
and remove these variables from the application's environment
Example
As root:
env KEYFILE=/etc/ssl/private/mykey.der CERTFILE=/etc/ssl/public/mycert.pem \
TLS_UID=65534 TLS_GID=65534 \
s6-envuidgid www \
s6-tlsserver -U -- 1.2.3.4 443 httpd
This will start a server listening to 1.2.3.4 on TCP port 443,
and for every connection, spawn the httpd program
reading queries on stdin and replying on stdout, as user www,
with a TLS layer protecting the connection, the TLS engine running
as user nobody (65534:65534). The server is
authenticated by the certificate in /etc/ssl/public/mycert.pem
that it sends to the client, and the private key in
/etc/ssl/private/mykey.der that it keeps to itself.