aboutsummaryrefslogtreecommitdiffstats
s6-networking: an overview of the tls-related programs

s6-networking
Software
skarnet.org

An overview of the TLS-related programs

The s6-*tls* programs are organized in a way that minimizes the amount of code, and in particular that keeps the crypto code as encapsulated as possible.

They are divided in two sets: client programs, which have client or c in their name, and server programs, which have server or d in their name. The sets are symmetrical: the same functionality is available whether you're interested in using a client or a server.

Of course, they do not have to be used together. You can run a TLS-enabled super-server via s6-tlsserver and it will work with any client speaking the correct TLS-enabled protocol, not only s6-tlsclient.

The core TLS engine: s6-tlsc-io and s6-tlsd-io

  • s6-tlsc-io and s6-tlsd-io are the only programs that actually perform TLS operations; the only ones that are linked against the BearSSL or LibreSSL libraries.
  • They read TLS-related information (where to find my trust anchor list? where to find my server certificate and private key?) from their environment.
  • They assume that their stdin/stdout is talking to the network; they also take two other fds on the command line that they assume are open and talking to the local application - one for reading, one for writing.
  • They establish a TLS tunnel over the network.
  • They maintain full-duplex communication: what they read from the local application is sent to stdout as ciphertext; what they read from stdin is sent to the local application as cleartext.
  • They exit when they cannot transmit any more data.

Other programs in the s6-tls set perform various operations such as Unix file descriptor plumbing in order to provide a specific interface, but they always end up spawning a s6-tlsc-io or s6-tlsd-io child that will handle the actual TLS management for them.

Regular TLSification of a service: s6-tlsc and s6-tlsd

  • The s6-tlsc and s6-tlsd programs are "immediate encryption"-type programs. They assume that the rest of their command line is a UCSPI client or server application, i.e. reads from the network on fd (6 for clients, 0 for servers) and writes to the network on fd (7 for clients, 1 for servers); their goal is to provide this application with transparent encryption.
  • They first spawn a s6-tlsc-io or s6-tlsd-io child to initialize the TLS connection.
  • When the TLS handshake has completed, they exec into the rest of their command line, interposing the s6-tls[cd]-io program in between this application and the network.
  • The application still communicates via cleartext, but the data is transparently encrypted before it goes to the network.
  • The application is only started after the handshake succeeds; the TLS tunnel stays up for the whole lifetime of the application, or until the application closes the fds it uses to communicate with (what it thinks is) the network.

Opportunistic TLS: s6-ucspitlsc and s6-ucspitlsd

  • The s6-ucspitlsc and s6-ucspitlsd programs are "delayed encryption"-type programs. They assume that the rest of their command line is an application that follows the UCSPI-TLS protocol. This is a bit of a misnomer: the aim of this protocol is just to provide an application with a means to ask for TLS encryption at any time.
  • They prepare the necessary communication channels, then fork. The parent execs into the rest of its command line, with the appropriate ucspi-tls environment variables set. The child stays and waits for a command.
  • When the application sends a command to start TLS, the child execs into s6-tlsc-io or s6-tlsd-io, which initializes a TLS connection and performs a handshake.
  • The application then communicates via the fds that have been provided to it via the ucspi-tls protocol. Those fds go through the TLS engine.

High-level client connections and super-servers: s6-tlsclient and s6-tlsserver