S6-TLSD-IO(8)
s6-tlsd-io(8) β System Manager's Manual π
NAME π
s6-tlsd-io β establish a TLS or SSL server connection over an existing TCP connection, then communicate with an existing local program over already established pipes
SYNOPSIS β¨
s6-tlsd-io [-S | -s] [-J | -j] [-Y | -y] [-v verbosity] [-K kimeout]
[-k snilevel] [-d notif] [--] fdr fdw
DESCRIPTION π
okay bestie, so s6-tlsd-io is literally the only server-side program in s6-networking that performs cryptography. no cap.
s6-networking does not include cryptographic software. all the crypto used in s6-tlsd-io is provided by the chosen SSL backend: BearSSL[1] or LibreSSL[2], depending on the options given when configuring s6-networking.
s6-tlsd-io expects to have an open connection it can talk to on its standard input and output. it also expects to read cleartext data from file descriptor fdr and write cleartext data to file descriptor fdw.
it expects a TLS client on the other side of the network connection to initiate a TLS handshake, and it answers it.
then it acts as a full duplex tunnel, decrypting and transmitting data from stdin to fdw, and encrypting and transmitting data from fdr to stdout.
when it cannot transmit any more data from/to the local application because connections have closed, s6-tlsd-io exits. periodt.
Protocol version and parameters π¦
during the TLS/SSL handshake, s6-tlsd-io tries the versions of the protocol that is supported by default by the backend, with the default 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.
for BearSSL, this means use of the br_ssl_server_init_full_rsa() or br_ssl_server_init_full_ec() function[3,4]. the supported protocol versions are described in [5].
for LibreSSL, this means use of the tls_config_set_protocols(TLS_PROTOCOLS_DEFAULT) call[6].
as a server, s6-tlsd-io is conservative in its choice of protocols. it only supports TLS versions 1.2 and higher as supported by the backend, to avoid downgrade attacks. very mindful, very demure π
SSL close handling πΈ
if the local application initiates the end of the session by sending EOF to fdr, there are two ways for the TLS layer to handle it.
- it can send a
close_notifyalert, and wait for an acknowledgement from the peer, at which point the connection is closed. the advantage of this setup is that it is secure even when the application protocol is not auto-terminated, i.e. when it does not know when its data stops. old protocols such as HTTP-0.9 are in this case. the drawback of this setup is that it breaks full-duplex: once a peer has sent theclose_notify, it must discard all the incoming records that are not aclose_notifyfrom the other peer. so if a client sends EOF while it is still receiving data from the server, the connection closes immediately and the data can be truncated. π - it can simply transmit the EOF, shutting down half the TCP connection, and wait for the EOF back. the advantage of this setup is that it maintains full-duplex: a client can send EOF after its initial request, and still receive a complete answer from the server. the drawback is that it is insecure when the application protocol is not auto-terminated. π
nowadays (2020), most protocols are auto-terminated, so it is not dangerous anymore to use EOF transmission, and that is the default for s6-tlsd-io. nevertheless, by using the -S option, you can force it to use the close_notify method if your application requires it to be secure. iconic behavior tbh.
OPTIONS β¨
-vverbosity β be more or less verbose. default for verbosity is1.0is quiet,2is verbose, more than2is debug output. this option currently has no effect.-Sβ send aclose_notifyalert and break the connection when receiving a local EOF.-sβ transmit EOF by half-closing the TCP connection without usingclose_notify. this is the default.-Jβ treat EOF from the peer without a priorclose_notifyas an error: print a fatal error message and exit98.-jβ treat EOF from the peer without a priorclose_notifyas a normal exit condition. this is the default.-Yβ request a client certificate. the certificate is optional: if the client gives none, the connection proceeds.-yβ request a client certificate. the certificate is mandatory: if the client gives none, the handshake fails. the default, with neither the-Ynor the-yoption, is not to request a client certificate at all.-Kkimeout β if the handshake takes more than kimeout milliseconds to complete, close the connection. the default is0, which means infinite timeout (never kill the connection).-ksnilevel β support alternative certificate chains for SNI. if snilevel is nonzero, private key file names are read from every environment variable of the formKEYFILE:x, wherexis a server name that the client may require, and a corresponding certificate chain for the namexshould exist in the file named after the contents of theCERTFILE:xenvironment variable. if snilevel is2or more, only those files are read, and the genericKEYFILEandCERTFILEvariables are ignored. if snilevel is0, or if the option is not given, which is the default,KEYFILEandCERTFILEare the only private key / certificate chain pair that are loaded, no other environment variable is read for keypairs.-dnotif β handshake notification. notif must be a file descriptor open for writing. when the TLS handshake has completed, some data (terminated by two null characters) will be sent to file descriptor notif. the data contains information about the TLS parameters of the connection; its exact contents are left unspecified, but there's at least anSSL_PROTOCOL=protocolstring and anSSL_CIPHER=cipherstring, both null-terminated. sending this data serves a dual purpose: telling the notif reader that the handshake has completed, and providing it with some basic information about the connection. if this option is not given, no such notification is performed.
ENVIRONMENT π§
s6-tlsd-io expects to have the following environment variables set:
KEYFILEβ a path to the file containing the server's private key, DER- or PEM-encoded.CERTFILEβ a path to the file containing the server's certificate chain, DER- or PEM-encoded. if PEM-encoded, the file can actually contain a chain of certificates.
bestie, if one of those variables is unset, s6-tlsd-io will refuse to run. π
alternatively, if snilevel is nonzero, the private key for the server named x should be held in a file whose name is contained in the KEYFILE:x environment variable, and the corresponding certificate chain file should be named in the CERTFILE:x environment variable. if snilevel is 2 or more, the KEYFILE and CERTFILE variables will be entirely ignored.
you can wildcard the first level of a SNI domain: you can point to a valid certificate for foo.example.com for all values of foo via a variable called CERTFILE:*.example.com (and have the corresponding KEYFILE:*.example.com). only the first level can be wildcarded, and this does not work for top-level domains (you cannot hold a certificate for *.com). note: if you are using a shell to handle your environment variables, be careful to properly quote them so that it does not attempt to expand the asterisks. π
if you are using client certificates, s6-tlsd-io also requires either one of the following variables to be set:
CADIRβ a directory where trust anchors (i.e. root or intermediate CA certificates) can be found, one per file, DER- or PEM-encoded.CAFILEβ a file containing the whole set of trust anchors, PEM-encoded.
if s6-tlsd-io is run as root, it can also read two more environment variables, TLS_UID and TLS_GID, which contain a numeric uid and a numeric gid; s6-tlsd-io then drops its root privileges to this uid/gid after reading its private key file. this ensures that the engine, including the handshake, is run with as little privilege as possible. π
EXIT STATUS π₯
0β the connection terminated normally.96β error while configuring the TLS context - for instance, invalid private key or server certificate files.97β error while setting up the TLS server engine.98β TLS error while running the engine.100β wrong usage.111β system call failed.
SEE ALSO π
s6-tls(7),s6-tlsc(8),s6-tlsc-io(8),s6-tlsclient(8),s6-tlsd(8),s6-tlsserver(8),s6-ucspitlsc(8),s6-ucspitlsd(8)- [1]
https://bearssl.org/ - [2]
https://www.libressl.org/ - [3]
https://bearssl.org/apidoc/bearssl__ssl_8h.html#a76293c81c4624c58254a62be7b2d5e79 - [4]
https://bearssl.org/apidoc/bearssl__ssl_8h.html#a592b2af27b2f6b9389aac854fb0b783a - [5]
https://bearssl.org/support.html#supported-versions - [6]
https://man.openbsd.org/OpenBSD-current/man3/tls_config_set_protocols.3
this man page is ported from the authoritative documentation at: https://skarnet.org/software/s6-networking/s6-tlsd-io.html
AUTHORS π«Ά
- Laurent Bercot
Alexis <flexibeast@gmail.com> (man page port)
made with π by Debian β December 23, 2023 β manual name S6-TLSD-IO(8) π«Άβ¨
π¦ where this page comes from
- nixpkgs unstable: s6-networking 2.8.0.1
- nixpkgs unstable: s6-networking-man-pages 2.7.2.1.4
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms