The s6-tlsd program
s6-tlsd is a program that performs the server side of
a TLS or SSL connection over an existing TCP connection, then execs
into an application. It is meant to make network communications
secure even for applications that do not natively support
s6-networking does not include
cryptographic software. All the crypto used in s6-tlsd
is provided by the chosen SSL backend:
LibreSSL, depending on
the options given when configuring s6-networking.
s6-tlsd [ -S | -s ] [ -Y | -y ] [ -Z | -z ] [ -v verbosity ] [ -K kimeout ] [ -k snilevel ] [ -- ] prog...
- s6-tlsd expects to have an open TCP connection it
can talk to on its stdin (for reading) and stdout
- It spawns a s6-tlsd-io
child process that will be the server-side of a TLS connection,
perform the handshake (expecting a TLS client on the other side
of the network) and maintain the TLS tunnel.
- When notified by s6-tlsd-io
that the handshake has completed, s6-tlsd execs into
- 100: wrong usage.
- 111: system call failed.
If everything goes smoothly, s6-tlsd does not exit, but execs
into prog... instead.
s6-tlsd does not expect to have any particular
environment variables, but it spawns a
s6-tlsd-io program that does.
So it should pay attention to the following variables:
- KEYFILE and CERTFILE. Also (or alternatively),
if the -k option is given: a series of
KEYFILE:x and CERTFILE:x variables,
for every x in the set of server names
- (if the -y or -Y option has been given) CADIR or CAFILE
- TLS_UID and TLS_GID
By default, prog... is run with all these
variables unset: CADIR, CAFILE,
KEYFILE, CERTFILE, KEYFILE:x and CERTFILE:x for
every x, TLS_UID and TLS_GID. They're passed to
the s6-tlsd-io child but
not to prog...;
the -Z option keeps them accessible in prog... as well.
However, prog... is run with the following additional
- SSL_PROTOCOL contains the protocol version:
TLSv1, TLSv1.1, TLSv1.2...
- SSL_CIPHER contains the name of the cipher
- SSL_TLS_SNI_SERVERNAME contains the required SNI
server name, if any. It is removed from the environment if no SNI
has been sent by the client.
- SSL_PEER_CERT_HASH contains the hash of the peer's
End Entity certificate, prefixed by the name of the hash and a colon
- SSL_PEER_CERT_SUBJECT contains the decoded subjectDN
of the peer's End Entity certificate, i.e. identifying information.
What is traditionally called the "name" of the certificate is the
CN field in that data.
- More similar environment variables containing information
about the connection may be added in the future.
- -v verbosity : Be more or less
verbose. Default for verbosity is 1. 0 is quiet, 2 is
verbose, more than 2 is debug output. This option currently has
- -Z : do not clean the environment of
the variables used by s6-tlsd-io
before execing prog....
- -z : clean the environment of
the variables used by s6-tlsd-io
before execing prog.... This is the default.
- -S : send a close_notify alert
and break the connection when prog sends EOF.
- -s : transmit EOF by half-closing the TCP
connection without using close_notify. This is the default.
- -Y : Request an optional client certificate.
- -y : Request a mandatory client certificate.
The default, with neither the -Y nor the -y option,
is not to request a client certificate at all.
- -K kimeout : if the peer fails
to send data for kimeout milliseconds during the handshake,
close the connection. The default is 0, which means infinite timeout
(never kill the connection).
- -k snilevel : support alternative
certificate chains for SNI. If snilevel is nonzero, private
key file names are read from every environment variable of the form
KEYFILE:x, where x is a server name that
the client may require, and a corresponding certificate chain for the name
x should exist in the file named after the contents of the
CERTFILE:x environment variable. If snilevel
is 2 or more, only those files are read, and the generic
KEYFILE and CERTFILE variables are ignored.
If snilevel is 0, or if the option is not given, which is the
default, KEYFILE and CERTFILE are the only private
key / certificate chain pair that are loaded, no other environment
variable is read for keypairs.
- The goal of the s6-tlsd interface (and its
client-side companion s6-tlsc) is to
make it so that if you have a client, run by the command line
client... that speaks a cleartext protocol to a server
run by the command line server..., then if the server
has the proper private key and certificate, and the client has
the proper list of trust anchors, you can just change the
client command line to s6-tlsc client... and the
server command line to s6-tlsd server...
without changing the client or the server themselves, and the
communication between them will be secure.