The s6-tlsc program

s6-tlsc is a program that establishes a TLS or SSL client connection over an existing TCP connection, then spawns an application. It is meant to make network communications secure even for applications that do not natively support TLS/SSL.

s6-networking does not include cryptographic software. All the crypto used in s6-tlsc is provided by the chosen SSL backend: BearSSL or LibreSSL, depending on the options given when configuring s6-networking.


     s6-tlsc [ -S | -s ] [ -Y | -y ] [ -Z | -z ] [ -v verbosity ] [ -K kimeout ] [ -k servername ] [ -6 rfd ] [ -7 wfd ] [ -- ] prog...

Exit codes

If the TLS/SSL connection closes cleanly, s6-tlsc waits for prog to exit, then exits with an approximation of prog's exit code.

Protocol version and parameters

During the TLS/SSL handshake, s6-tlsc tries every version of the protocol that is supported by the backend, with all supported algorithms and cipher suites; the backend normally ensures that the most secure combination is tried first, with slow degradation until the client and the server agree.

As a client, it is better for s6-tlsc to adapt to as many servers as possible, that's why it adopts a liberal approach to protocol versions.

Environment variables


s6-tlsc expects to have one of the CADIR or CAFILE environment variables set. It will refuse to run if both are unset. If both are set, CADIR has priority. The value of that variable is:

If you are using client certificates, s6-tlsc also reads two more environment variables: KEYFILE contains the path to a file containing the private key, DER- or PEM-encoded; and CERTFILE contains the path to a file containing the client certificate, DER- or PEM-encoded. Please note that for now, support for client certificates is experimental, and only works with the LibreSSL backend (BearSSL does not support client certificates yet).

If s6-tlsc is run as root, it can also read two other environment variables, TLS_UID and TLS_GID, which contain a numeric uid and a numeric gid; s6-tlsc then drops its root privileges to this uid/gid after spawning prog.... This ensures that the TLS/engine and the application run with different privileges. Note that prog... should drop its own root privileges by its own means: the s6-applyuidgid program is a way of doing it.


Unless the -Z option has been given to s6-tlsc, prog... is run with all the TLS/SSL variables unset: CADIR, CAFILE, KEYFILE, CERTFILE, TLS_UID and TLS_GID. The goal is for s6-tlsc to be, by default, as invisible as possible.

Server name determination for SNI

The -k servername option is important to s6-tlsc: it tells it to send servername as the name to require a certificate for. Not setting this option allows s6-tlsc to proceed without SNI, which may be a security risk.

The s6-tlsclient program can automatically craft a -k option for s6-tlsc if the host argument that is given to it is a host name. But if you're invoking s6-tlsc directly, do not forget to give it this option.

SSL close handling

If prog initiates the end of the session by sending EOF, there are two ways for the TLS/SSL layer to handle it.

Nowadays (2016), most protocols are auto-terminated, so it is not dangerous anymore to use EOF tranmission, and that is the default fo s6-tlsc. Nevertheless, by using the -S option, you can force it to use the close_notify method if your application requires it to be secure.

s6-tlsc options