The s6-ucspitlsd program
s6-ucspitlsd is a server-side program that establishes
communication channels according to the UCSPI-TLS protocol,
then execs into an application. Later, if the application sends
a command, a TLS tunnel will be started and the application will
be able to use it instead of communicating with the network via
The point of this protocol, and this program, is to make it easy
to implement commands like SMTP's STARTTLS without embedding a
TLS stack in the server itself.
s6-ucspitlsd [ -S | -s ] [ -Y | -y ] [ -Z | -z ] [ -v verbosity ] [ -K kimeout ] [ -- ] prog...
- s6-ucspitlsd expects to have an open TCP connection it
can talk to on its stdin and stdout.
- It forks and establishes communication channels between
the parent and the child. The parent executes into
prog...; the child remains and waits for a
- At any time, prog... can send a command to its
control socket provided by s6-ucspitlsd, following the
protocol. Then the s6-ucspitlsd child will exec into a
process that will initialize the TLS connection, perform the
handshake (expecting a TLS client on the other side of the
network) and maintain a TLS tunnel. prog can
use that TLS tunnel instead of talking directly to the
- 100: wrong usage.
- 111: system call failed.
Normally the parent s6-ucspitlsd process execs into prog...
and the child process execs into s6-tlsd-io.
If the parent dies or closes its control socket before sending a
command to start TLS, the child exits 0.
s6-ucspitlsd 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:
- CERTFILE and KEYFILE
- (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, TLS_UID and TLS_GID. They're passed to
the s6-tlsd-io child but
not to prog....
The -Z option prevents that behaviour.
However, prog... is run with the following additional
environment variables, following the UCSPI-TLS protocol:
- SSLCTLFD contains the file descriptor number of
the control socket.
- SSLREADFD contains the file descriptor number of
the pipe used to read data from the TLS tunnel after it
has been activated.
- SSLWRITEFD contains the file descriptor number of
the pipe used to write data to the TLS tunnel after it
has been activated.
Since prog is exec'ed before the TLS handshake takes
place, it cannot get information about the TLS connection via
environment variables. However, if it starts the TLS connection
via a Y command (as opposed to a y command),
it will receive this information as a string sent over the
- -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-tlsc-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 : Require an optional client certificate.
- -y : Require a mandatory client certificate.
The default, with neither the -Y nor the -y option,
is not to require a client certificate at all.
- -K kimeout : close the connection if
the handshake takes more than kimeout milliseconds to complete.
The default is 0, which means infinite timeout: let the handshake complete
at its own pace, no matter how slow.
- It only makes sense to run s6-ucspitlsd if its application
program prog knows and understands the
protocol for opportunistic TLS. If it does not, you will not
be able to secure your connection, and what you need is a regular
immediate TLS program instead, which means