s6-networking: the s6-tlsclient program
Keywords: s6-networking s6-tlsclient tlsclient tls ssl ucspi tcp inet network tcp/ip client

s6-networking
Software
skarnet.org

# The `s6-tlsclient` program

`s6-tlsclient` is an UCSPI client tool for TLS/SSL connections over INET domain sockets. It establishes a TCP connection to a server and a TLS transport over it, then executes into a program.

## Interface

         s6-tlsclient [ options ] [ -- ] host port prog...

- s6-tlsclient rewrites itself into a command line involving:
  - s6-tcpclient, which establishes a TCP connection to host host port port.
  - s6-tlsc, which establishes a TLS transport (client-side) over that connection.
  - prog..., your client program, which is executed into by s6-tlsc once the s6-tlsc-io child it has spawned has set up the TLS connection and performed the handshake.
- prog... is run with the same pid as s6-tlsclient.

prog is expected to read from its peer on descriptor 6 and write to its peer on descriptor 7. Since there will be a s6-tlsc-io program between prog and the network to perform the TLS encryption/decryption, those descriptors will not be a network socket - they will be pipes.

## Server name determination for SNI

If the `-H` option is not given to `s6-tlsclient`, then host will be used as the server name to verify. You can use the `-k` option to override this default. Please note that if you use the `-H` option and do not provide a server name via `-k`, SNI will not be used, which may be a security risk.

## Environment variables

### Read

The following variables should be set before invoking `s6-tlsclient`, because they will be used by s6-tlsc-io:

- CADIR
- CAFILE (alternative to CADIR)
- KEYFILE (if you're using a client certificate)
- CERTFILE (if you're using a client certificate)
- TLS_UID and TLS_GID (if you run `s6-tlsclient` as root)

Setting either CADIR or CAFILE is mandatory.

### Written

prog... is run with the following variables added to, or removed from, its environment by s6-tcpclient:

- PROTO
- TCPREMOTEIP
- TCPREMOTEPORT
- TCPREMOTEHOST
- TCPLOCALHOST
- TCPREMOTEINFO

Unless the `-Z` option is given to `s6-tlsclient`, the CADIR, CAFILE, KEYFILE, CERTFILE, TLS_UID and TLS_GID variables will not appear in prog's environment.

## Options

`s6-tlsclient` accepts a myriad of options, all of which are passed as is to the correct executable. Not giving any options will generally work: the defaults are sensible.

### Options passed as is to s6-tcpclient

- `-q`, `-Q`, `-v` : be quiet, normally verbose, or verbose
- `-4`, `-6` : stick to IPv4 or IPv6 addresses
- `-d`, `-D` : enable or disable Nagle's algorithm
- `-r`, `-R` : enable or disable IDENT lookup
- `-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
- `-n`, `-N` : qualify the host or not when resolving it
- `-t timeout` : global timeout on the connection attempt
- `-i localip`, `-p localport` : force local socket parameters
- `-T timeoutconn` : configurable connection timeouts

### Options passed as is to s6-tlsc

- `-Z`, `-z` : keep or remove the s6-tlsc-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` : don't send, or send, a client certificate
- `-k servername` : use SNI and provide a server name
- `-K kimeout` : set a timeout for the TLS handshake

## Example

`CADIR=/etc/ssl/certs s6-tlsclient skarnet.org 443 s6-ioconnect`

This will open a connection to the skarnet.org web server over TLS and verify its certificate via the trust anchors listed in the `/etc/ssl/certs` directory. It will then branch your terminal to it: try typing `GET / HTTP/1.0` then hitting return twice.