From 47cbbb1619ace4013856843ef8f7d68279c74faa Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Sun, 22 Nov 2020 00:16:06 +0000 Subject: Add documentation, fix tiny privdrop bug --- doc/index.html | 7 +- doc/libsbearssl/index.html | 131 +++++++++++++++++++------- doc/libstls/index.html | 112 +++++++++++++++------- doc/s6-tlsc-io.html | 217 +++++++++++++++++++++++++++++++++++++++++++ doc/s6-tlsc.html | 197 +++++++++------------------------------ doc/s6-tlsclient.html | 18 ++-- doc/s6-tlsd-io.html | 212 ++++++++++++++++++++++++++++++++++++++++++ doc/s6-tlsd.html | 193 ++++++++------------------------------ doc/s6-tlsserver.html | 11 ++- doc/s6-ucspitlsc.html | 178 +++++++++++++++++++++++++++++++++++ doc/s6-ucspitlsd.html | 168 +++++++++++++++++++++++++++++++++ doc/tls-overview.html | 142 ++++++++++++++++++++++++++++ src/sbearssl/sbearssl_drop.c | 4 +- src/stls/stls_drop.c | 4 +- 14 files changed, 1199 insertions(+), 395 deletions(-) create mode 100644 doc/s6-tlsc-io.html create mode 100644 doc/s6-tlsd-io.html create mode 100644 doc/s6-ucspitlsc.html create mode 100644 doc/s6-ucspitlsd.html create mode 100644 doc/tls-overview.html diff --git a/doc/index.html b/doc/index.html index 049ed70..f402ab3 100644 --- a/doc/index.html +++ b/doc/index.html @@ -139,10 +139,15 @@ relevant page.

UCSPI tools for secure communication (TLS protocol) over TCP

TCP access control

diff --git a/doc/libsbearssl/index.html b/doc/libsbearssl/index.html index 1579b2d..656c724 100644 --- a/doc/libsbearssl/index.html +++ b/doc/libsbearssl/index.html @@ -470,33 +470,44 @@ because *t does not represent a valid time. i.e. a tai_t plus nanoseconds (which are simply ignored).

+

void sbearssl_drop ()

-

Running the TLS/SSL engine (both clients and servers)

+

+ If the process is running as root, then this function drops its privileges +(else it does nothing). +The gid to drop to is read from the TLS_GID environment variable; the uid to +drop to is read from the TLS_UID environment variable. If those variables +are not given, then the uid, or gid, or both, are not changed. If they +contain something else than numerical uid/gids, the process exits 111 with +an error message. +

+ +

Running the TLS/SSL engine (internal function for both clients and servers)

-

int sbearssl_run (br_ssl_engine_context *ctx, int *fds, pid_t pid, unsigned int verbosity, uint32_t options, tain_t const *tto)

+

void sbearssl_run (br_ssl_engine_context *ctx, int *fds, tain_t const *tto, uint32_t options, unsigned int verbosity, sbearssl_handshake_cb_t_ref cb, sbearssl_handshake_cb_context_t *cbarg)

This function runs a full-duplex TLS/SSL engine, reading/writing clear text from/to two file descriptors, and writing/reading ciphertext to/from two other file descriptors, until the connection is closed both ways (either with a SSL close, or -with EOF) or a given subprocess dies. +with EOF). It does not return.

sbearssl_run will make the process die with an appropriate error message if it encounters an unrecoverable error. If there were no problems and the -SSL/TLS connection closed cleanly, it returns -1. If the application -subprocess dies early, sbearssl_run returns the wstat -for that subprocess, i.e. the integer containing the information about -its exit code or crash signal. No matter how sbearssl_run returns, -the first four descriptors in fds are closed, but the -selfpipe is untouched and the caller should free ctx itself. +SSL/TLS connection closed cleanly, the process exits 0.

-

int sbearssl_s6tlsc (char const *const *argv, char const *const *envp, tain_t const *tto, uint32_t preoptions, uint32_t options, uid_t uid, gid_t gid, unsigned int verbosity, char const *servername, int *sfd)

+

Initializing and running the engine

+ +

void sbearssl_client_init_and_run (int *fds, tain_t const *tto, uint32_t preoptions, uint32_t options, unsigned int verbosity, char const *servername, sbearssl_handshake_cb_t_ref cb, unsigned int notif)

+ +

+ This function initializes a TLS context for a client-side connection, +then runs the TLS engine via a call to sbearssl_run(). The +function does not return. +If the context cannot be initialized, the process exits 96 with an +appropriate error message. +

+ +

+ If the CADIR environment variable is set, then it must contain +the path of a directory containing the hashed names of the public +certificates identifying the trust anchors. Else, if the CAFILE +environment variable is set, then it must contain the path to a PEM file +containing all the certificates for the trust anchors. Else, the process +exits 100 with an error message. +

- This function implements s6-tlsc on top of BearSSL. -It has no other practical purpose; you're better off directly invoking -s6-tlsc. + The arguments are as follows:

-

int sbearssl_s6tlsd (char const *const *argv, char const *const *envp, tain_t const *tto, uint32_t preoptions, uint32_t options, uid_t uid, gid_t gid, unsigned int verbosity)

+ + +

void sbearssl_server_init_and_run (int *fds, tain_t const *tto, uint32_t preoptions, uint32_t options, unsigned int verbosity, sbearssl_handshake_cb_t_ref cb, unsigned int notif)

- This function implements s6-tlsd on top of BearSSL. -It has no other practical purpose; you're better off directly invoking -s6-tlsd. + Same as the previous function, but on the server side. No servername +argument is required. The CERTFILE and KEYFILE environment +variables are mandatory, they point to the server's certificate and private +key. It is only necessary to set CADIR or CAFILE when bit +0 of preoptions is set (this functionality is supported server-side), +in which case client authentication will be +requested, and a list of trust anchors (read from either the directory +in CADIR or the PEM file in CAFILE) will be used to verify +the client certificate.

diff --git a/doc/libstls/index.html b/doc/libstls/index.html index fcd839a..f81396c 100644 --- a/doc/libstls/index.html +++ b/doc/libstls/index.html @@ -52,30 +52,97 @@ sysdeps directory.

Programming

-

Running the TLS/SSL engine

+

Utilities

-

int stls_run (struct tls *ctx, int *fds, pid_t pid, unsigned int verbosity, uint32_t options, tain_t const *tto)

+

void stls_drop ()

+ +

+ If the process is running as root, then this function drops its privileges +(else it does nothing). +The gid to drop to is read from the TLS_GID environment variable; the uid to +drop to is read from the TLS_UID environment variable. If those variables +are not given, then the uid, or gid, or both, are not changed. If they +contain something else than numerical uid/gids, the process exits 111 with +an error message. +

+ +

Initializing the TLS engine

+ +

struct tls *stls_client_init_and_handshake (int const *fds, uint32_t preoptions, char const *servername)

+ +

+ This function initializes a TLS context for a client-side connection, +then performs a TLS handshake. +It then returns a non-null pointer to a struct tls context for the +application to pass to the stls_run function when it wants to +run the engine. +If the context cannot be initialized or the handshake cannot be performed, +the process exits (96 for configuration issues, 97 for context and handshake +issues) with an appropriate error message. +

+ +

+ If the CADIR environment variable is set, then it must contain +the path of a directory containing the hashed names of the public +certificates identifying the trust anchors. Else, if the CAFILE +environment variable is set, then it must contain the path to a PEM file +containing all the certificates for the trust anchors. Else, the process +exits 100 with an error message. +

+ +

+ The arguments are as follows: +

+ +
    +
  • fds : an array of 4 file descriptors, that are in this +order: the fd reading from the application (cleartext), the fd writing to the +application (cleartext), the fd reading from the network, the fd writing to +the network.
  • +
  • preoptions : a bitfield. +
      +
    • Bit 0: if clear, no client authentication is performed. If set, +the CERTFILE and KEYFILE environment variables are read, +they must contain the path to a valid client certificate and private key +(else the process exits 96); this certificate is then provided to the +server for client authentication.
    • +
  • +
  • servername : the server name used for SNI. If NULL, then +no SNI is performed, which may be a security risk.
  • +
+ +

struct tls *stls_server_init_and_handshake (int const *fds, uint32_t preoptions)

+ +

+ Same as the previous function, but on the server side. No servername +argument is required. The CERTFILE and KEYFILE environment +variables are mandatory, they point to the server's certificate and private +key. It is only necessary to set CADIR or CAFILE when bit +0 of preoptions is set, in which case client authentication will be +requested, and a list of trust anchors (read from either the directory +in CADIR or the PEM file in CAFILE) will be used to verify +the client certificate. +

+ +

Running the TLS engine

+ +

void stls_run (struct tls *ctx, int *fds, unsigned int verbosity, uint32_t options, tain_t const *tto)

This function runs a full-duplex TLS/SSL engine, reading/writing clear text from/to two file descriptors, and writing/reading ciphertext to/from two other file descriptors, until the connection is closed both ways (either with a SSL close, or -with EOF) or a given subprocess dies. +with EOF). It does not return.

  • ctx is a pointer to a fully initialized context, connected to fds[2] and fds[3]. The TLS handshake must already be completed.
  • -
  • fds is an array of 5 file descriptors, in this +
  • fds is an array of 4 file descriptors, in this order: fd reading clear text, fd writing clear text, fd reading -ciphertext, fd writing ciphertext, selfpipe.
  • -
  • pid is the pid of the application subprocess. -When a SIGCHLD is detected on the selfpipe, the newly deceased -process is reaped, and if it was pid, then the function -returns as soon as it doesn't have anything left to write to -the network peer.
  • +ciphertext, fd writing ciphertext.
  • verbosity defines the engine's verbosity: the higher the more verbose. This parameter is currently ignored.
  • options is a bitfield. @@ -106,29 +173,8 @@ if you don't want the engine to ever timeout.
  • stls_run will make the process die with an appropriate error -message if it encounters an unrecoverable error. If there were no problems and the -SSL/TLS connection closed cleanly, it returns -1. If the application -subprocess dies early, stls_run returns the wstat -for that subprocess, i.e. the integer containing the information about -its exit code or crash signal. No matter how stls_run returns, -the first four descriptors in fds are closed, but the -selfpipe is untouched and the caller should free ctx itself. -

    - -

    int stls_s6tlsc (char const *const *argv, char const *const *envp, tain_t const *tto, uint32_t preoptions, uint32_t options, uid_t uid, gid_t gid, unsigned int verbosity, char const *servername, int *sfd)

    - -

    - This function implements s6-tlsc on top of LibreSSL. -It has no other practical purpose; you're better off directly invoking -s6-tlsc. -

    - -

    int stls_s6tlsd (char const *const *argv, char const *const *envp, tain_t const *tto, uint32_t preoptions, uint32_t options, uid_t uid, gid_t gid, unsigned int verbosity)

    - -

    - This function implements s6-tlsd on top of LibreSSL. -It has no other practical purpose; you're better off directly invoking -s6-tlsd. +message and exit code if it encounters an unrecoverable error. If there were +no problems and the SSL/TLS connection closed cleanly, the process exits 0.

    diff --git a/doc/s6-tlsc-io.html b/doc/s6-tlsc-io.html new file mode 100644 index 0000000..2f02841 --- /dev/null +++ b/doc/s6-tlsc-io.html @@ -0,0 +1,217 @@ + + + + + + s6-networking: the s6-tlsc-io program + + + + + + +

    +s6-networking
    +Software
    +skarnet.org +

    + +

    The s6-tlsc-io program

    + +

    +s6-tlsc-io is a program that establishes a TLS or SSL +client connection over an existing TCP connection, then +communicates with an existing local program over already +established pipes. It is the only client-side program in +s6-networking that performs cryptography. +

    + +

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

    + +

    Interface

    + +
    +     s6-tlsc-io [ -S | -s ] [ -Y | -y ] [ -v verbosity ] [ -K kimeout ] [ -k servername ] [ -d notif ] [ -- ] fdr fdw
    +
    + +
      +
    • s6-tlsc-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 initiates a TLS handshake over the network connection, +expecting a TLS server on the other side.
    • +
    • 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-tlsc-io exits.
    • +
    + +

    Exit codes

    + +
      +
    • 0: the connection terminated normally. +
    • 96: error while configuring the TLS context - for instance, invalid trust anchor set.
    • +
    • 97: error while setting up the TLS client engine.
    • +
    • 98: TLS error while running the engine.
    • +
    • 100: wrong usage.
    • +
    • 111: system call failed.
    • +
    + +

    Protocol version and parameters

    + +

    + During the TLS handshake, s6-tlsc-io 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-io to adapt to as many servers +as possible, that's why it adopts a liberal approach to protocol +versions. +

    + +

    Environment variables

    + +

    + s6-tlsc-io 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: +

    + +
      +
    • for CADIR: a directory where trust anchors +(i.e. root or intermediate CA certificates) can be found, +one per file, DER- or PEM-encoded.
    • +
    • for CAFILE: a file containing the whole set +of trust anchors, PEM-encoded.
    • +
    + +

    + If you are using client certificates, s6-tlsc-io 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. +

    + +

    + If s6-tlsc-io 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-io +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 chainloading way of doing it. +

    + +

    Server name determination for SNI

    + +

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

    + +

    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_notify alert, 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 the +close_notify, it must discard all the incoming +records that are not a close_notify from 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 tranmission, and that +is the default for s6-tlsc-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. +

    + +

    s6-tlsc-io options

    + +
      +
    • -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 +no effect.
    • +
    • -S : send a close_notify alert +and break the connection when receiving a local EOF.
    • +
    • -s : transmit EOF by half-closing the TCP +connection without using close_notify. This is the default.
    • +
    • -Y : Do not send a client certificate. This is the default.
    • +
    • -y : Send a client certificate.
    • +
    • -k servername : use Server Name +Indication, and send servername. The default is not to +use SNI, which may be a security risk.
    • +
    • -K kimeout : close the connection +if kimeout milliseconds elapse without any data being +received from either side. The default is 0, which means +infinite timeout (never kill the connection).
    • +
    • -d notif : 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 +a SSL_PROTOCOL=protocol string +and a SSL_CIPHER=cipher string, 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.
    • +
    + + + diff --git a/doc/s6-tlsc.html b/doc/s6-tlsc.html index 1237460..c2e7521 100644 --- a/doc/s6-tlsc.html +++ b/doc/s6-tlsc.html @@ -20,21 +20,12 @@

    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 +client connection over an existing TCP connection, then execs +into 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. -

    -

    Interface

    @@ -45,60 +36,25 @@ the options given when configuring s6-networking.
      
  • s6-tlsc expects to have an open TCP connection it can talk to on its (by default) descriptors 6 (for reading) and 7 (for writing).
  • -
  • It spawns prog... as a child process, -interposing itself between it and the network.
  • -
  • It initiates a TLS/SSL handshake over the -network connection, expecting a TLS/SSL server on the other -side.
  • -
  • It manages the encryption/decryption of all the -messages between prog and the server. -prog speaks plaintext, but only ciphertext is sent -on the network.
  • -
  • When prog exits, s6-tlsc exits. +
  • It spawns a s6-tlsc-io +child process that will initiate the TLS connection, perform the +handshake (expecting a TLS server on the other side of the +network) and maintain the TLS tunnel.
  • +
  • When notified by s6-tlsc-io +that the handshake has completed, s6-tlsc execs into +prog....

Exit codes

    -
  • 96: error while configuring the TLS/SSL context - for instance, invalid trust anchor set.
  • -
  • 97: error while setting up the TLS/SSL client engine.
  • -
  • 98: TLS/SSL error while running the engine.
  • 100: wrong usage.
  • 111: system call failed.

- 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. + If everything goes smoothly, s6-tlsc does not exit, but execs +into prog... instead.

Environment variables

@@ -106,110 +62,44 @@ versions.

Read

- 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: + s6-tlsc does not expect to have any particular +environment variables, but it spawns a +s6-tlsc-io program that does. +So it should pay attention to the following variables:

    -
  • for CADIR: a directory where trust anchors -(i.e. root or intermediate CA certificates) can be found, -one per file, DER- or PEM-encoded.
  • -
  • for CAFILE: a file containing the whole set -of trust anchors, PEM-encoded.
  • +
  • CADIR or CAFILE
  • +
  • (if the -y option has been given) CERTFILE and KEYFILE
  • +
  • TLS_UID and TLS_GID
-

- 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. -

- -

- 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. -

-

Written

- 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. + 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-tlsc-io child but +not to prog.... +The -Z option prevents that behaviour.

- 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. + However, prog... is run with the following additional +environment variables:

    -
  • It can send a close_notify alert, 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 the -close_notify, it must discard all the incoming -records that are not a close_notify from 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.
  • +
  • SSL_PROTOCOL contains the protocol version: +TLSv1, TLSv1.1, TLSv1.2...
  • +
  • SSL_CIPHER contains the name of the cipher +used.
  • +
  • More similar environment variables containing information +about the connection may be added in the future.
-

- Nowadays (2017), most protocols are auto-terminated, so -it is not dangerous anymore to use EOF tranmission, and that -is the default for 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

+

Options

  • -v verbosity : Be more or less @@ -217,10 +107,11 @@ verbose. Default for verbosity is 1. 0 is quiet, 2 is verbose, more than 2 is debug output. This option currently has no effect.
  • -Z : do not clean the environment of -s6-tlsc-related variables before spawning prog....
  • +the variables used by s6-tlsc-io +before execing prog....
  • -z : clean the environment of -s6-tlsc-related variables before spawning prog.... -This is the default.
  • +the variables used by s6-tlsc-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 @@ -234,20 +125,20 @@ use SNI, which may be a security risk.
  • if kimeout milliseconds elapse without any data being received from either side. The default is 0, which means infinite timeout (never kill the connection). -
  • -6 rfd : expect an open file -descriptor numbered rfd to read network (ciphertext) +
  • -6 fdr : expect an open file +descriptor numbered fdr to read network (ciphertext) data from. Make sure prog also reads its data -from its own fd rfd. Default is 6.
  • -
  • -7 wfd : expect an open file -descriptor numbered wfd to write network (ciphertext) +from its own fd fdr. Default is 6.
  • +
  • -7 fdw : expect an open file +descriptor numbered fdw to write network (ciphertext) data to. Make sure prog also writes its data to -its own fd wfd. Default is 7.
  • +its own fd fdw. Default is 7.

Notes

    -
  • The goal of the s6-tlsc interface (and its +
  • The goal of the s6-tlsc interface (and its server-side companion s6-tlsd) is to make it so that if you have a client, run by the command line client... that speaks a cleartext protocol to a server diff --git a/doc/s6-tlsclient.html b/doc/s6-tlsclient.html index 2553637..fc357a7 100644 --- a/doc/s6-tlsclient.html +++ b/doc/s6-tlsclient.html @@ -40,22 +40,20 @@ involving: 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 run as a -child of s6-tlsc.
  • +
  • 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.
-
  • It runs until the connection closes.
  • -
  • It exits either with a s6-tlsc -error code (and error message), or with an -approximation -of prog's exit code.
  • +
  • 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 +Since there will be a s6-tlsc-io program between prog and the network to perform -the SSL encryption/decryption, those descriptors will not +the TLS encryption/decryption, those descriptors will not be a network socket - they will be pipes.

    @@ -79,7 +77,7 @@ used, which may be a security risk.

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

      diff --git a/doc/s6-tlsd-io.html b/doc/s6-tlsd-io.html new file mode 100644 index 0000000..6aad7dc --- /dev/null +++ b/doc/s6-tlsd-io.html @@ -0,0 +1,212 @@ + + + + + + s6-networking: the s6-tlsc-io program + + + + + + +

      +s6-networking
      +Software
      +skarnet.org +

      + +

      The s6-tlsc-io program

      + +

      +s6-tlsd-io is a program that establishes a TLS or SSL +server connection over an existing TCP connection, then +communicates with an existing local program over already +established pipes. It is the only server-side program in +s6-networking that performs cryptography. +

      + +

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

      + +

      Interface

      + +
      +     s6-tlsd-io [ -S | -s ] [ -Y | -y ] [ -v verbosity ] [ -K kimeout ] [ -d notif ] [ -- ] fdr fdw
      +
      + +
        +
      • 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.
      • +
      + +

      Exit codes

      + +
        +
      • 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.
      • +
      + +

      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. +

      + + + +

      + As a server, s6-tlsd-io can be conservative in its +choice of protocols. It is currently not very conservative +when using the BearSSL backend; it could become more so in +the future, by defining a custom server profile that supports +only TLS-1.2 but with several algorithms and cipher suites. +

      + +

      Environment variables

      + +

      + 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, DER- or PEM-encoded. +If PEM-encoded, the file can actually contain a chain +of certificates.
      • +
      + +

      + If one of those variables is unset, s6-tlsd-io +will refuse to run. +

      + +

      + If you are using client certificats, 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. +

      + +

      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_notify alert, 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 the +close_notify, it must discard all the incoming +records that are not a close_notify from 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 tranmission, 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. +

      + +

      s6-tlsd-io options

      + +
        +
      • -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 +no effect.
      • +
      • -S : send a close_notify alert +and break the connection when receiving a local EOF.
      • +
      • -s : transmit EOF by half-closing the TCP +connection without using close_notify. This is the default.
      • +
      • -Y : Do not send a client certificate. This is the default.
      • +
      • -y : Send a client certificate.
      • +
      • -K kimeout : close the connection +if kimeout milliseconds elapse without any data being +received from either side. The default is 0, which means +infinite timeout (never kill the connection).
      • +
      • -d notif : 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 +a SSL_PROTOCOL=protocol string +and a SSL_CIPHER=cipher string, 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.
      • +
      + + + diff --git a/doc/s6-tlsd.html b/doc/s6-tlsd.html index 36125d2..beeedda 100644 --- a/doc/s6-tlsd.html +++ b/doc/s6-tlsd.html @@ -20,8 +20,8 @@

      s6-tlsd is a program that performs the server side of -a TLS or SSL connection over an existing TCP connection, then spawns -an application. It is meant to make network communications +a TLS or SSL connection over an existing TCP connection, then execs +into an application. It is meant to make network communications secure even for applications that do not natively support TLS/SSL.

      @@ -45,69 +45,25 @@ the options given when configuring s6-networking.
    • s6-tlsd expects to have an open TCP connection it can talk to on its stdin (for reading) and stdout (for writing).
    • -
    • It spawns prog... as a child process, -interposing itself between it and the network. -In other words: prog still reads cleartext -on its stdin and writes cleartext on its stdout, but -those will actually be pipes to s6-tlsd, which -will read ciphertext from its own stdin (the network) -and write ciphertext to its own stdout (the network).
    • -
    • It initiates the server side of a TLS/SSL handshake -over the network connection, expecting a TLS/SSL client on -the other side.
    • -
    • It manages the encryption/decryption of all the -messages between prog and the client. -prog speaks plaintext, but only ciphertext is sent -on the network.
    • -
    • When prog exits, s6-tlsd exits. +
    • It spawns a s6-tlsd-io +child process that will be the server-side of a TLS connection, +perform the handshake (expecting a TLS client on the other side +of the network) and maintain the TLS tunnel.
    • +
    • When notified by s6-tlsd-io +that the handshake has completed, s6-tlsd execs into +prog....

    Exit codes

      -
    • 96: error while configuring the TLS/SSL context - for instance, invalid -private key or server certificate files.
    • -
    • 97: error while setting up the TLS/SSL client engine.
    • -
    • 98: TLS/SSL error while running the engine.
    • 100: wrong usage.
    • 111: system call failed.

    - If the TLS/SSL connection closes cleanly, s6-tlsd -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-tlsd 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. -

    - - - -

    - As a server, s6-tlsd can be conservative in its -choice of protocols. It is currently not very conservative -when using the BearSSL backend; it could become more so in -the future, by defining a custom server profile that supports -only TLS-1.2 but with several algorithms and cipher suites. + If everything goes smoothly, s6-tlsd does not exit, but execs +into prog... instead.

    Environment variables

    @@ -115,120 +71,44 @@ only TLS-1.2 but with several algorithms and cipher suites.

    Read

    - s6-tlsd 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, DER- or PEM-encoded. -If PEM-encoded, the file can actually contain a chain -of certificates.
    • -
    - -

    - If one of those variables is unset, s6-tlsd -will refuse to run. -

    - -

    - If you are using client certificats, s6-tlsd -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 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 -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. If the s6-tlsd -invocation actually comes from a -s6-tlsserver command line, -and privilege-dropping options (-G, -g, --u or -U) have been given to -s6-tlsserver, then -s6-applyuidgid -directly follows s6-tlsd on the command line, in order -to also drop the child's privileges before executing the application. -The point of that setup is: + s6-tlsd 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:

      -
    • To read the private key file as root
    • -
    • To run the application as a non-root user
    • -
    • To run s6-tlsd as a different non-root user
    • -
    • That way, even if s6-tlsd, the application, or both, -get compromised, the private key is still secure.
    • +
    • KEYFILE and CERTFILE
    • +
    • (if the -y or -Y option has been given) CADIR or CAFILE
    • +
    • TLS_UID and TLS_GID

    Written

    - Unless the -Z option has been given to -s6-tlsd, prog... is run with all the -TLS/SSL variables unset: CADIR, CAFILE, -KEYFILE, CERTFILE, TLS_UID and TLS_GID. The goal is -for s6-tlsd to be, by default, as invisible -as possible. + 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.

    -

    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. + However, prog... is run with the following additional +environment variables:

      -
    • It can send a close_notify alert, 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 the -close_notify, it must discard all the incoming -records that are not a close_notify from 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.
    • +
    • SSL_PROTOCOL contains the protocol version: +TLSv1, TLSv1.1, TLSv1.2...
    • +
    • SSL_CIPHER contains the name of the cipher +used.
    • +
    • More similar environment variables containing information +about the connection may be added in the future.
    -

    - Nowadays (2017), most protocols are auto-terminated, so -it is not dangerous anymore to use EOF tranmission, and that -is the default for s6-tlsd. 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-tlsd options

    +

    Options

    • -v verbosity : Be more or less @@ -236,10 +116,11 @@ verbose. Default for verbosity is 1. 0 is quiet, 2 is verbose, more than 2 is debug output. This option currently has no effect.
    • -Z : do not clean the environment of -s6-tlsd-related variables before spawning prog....
    • +the variables used by s6-tlsd-io +before execing prog....
    • -z : clean the environment of -s6-tlsd-related variables before spawning prog.... -This is the default.
    • +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 diff --git a/doc/s6-tlsserver.html b/doc/s6-tlsserver.html index a87fbb7..04d9951 100644 --- a/doc/s6-tlsserver.html +++ b/doc/s6-tlsserver.html @@ -21,7 +21,7 @@

      s6-tlsserver is an UCSPI server tool for -TLS/SSL connections over INET domain sockets. It acts as a TCP superserver +TLS/SSL connections over INET domain sockets. It acts as a TCP super-server that listens to connections, accepts them, and for each connection, establishes a TLS transport over it, then executes into a program.

      @@ -49,12 +49,13 @@ than what you originally wrote. This is normal and healthy.
    • which performs TCP access control and various operations on the TCP connection.
    • s6-tlsd, which establishes -a TLS transport (server-side) over a connection.
    • +a TLS transport (server-side) over a connection, via a +s6-tlsd-io child process.
    • (if applicable) s6-applyuidgid, which drops root privileges.
    • -
    • prog..., your client program, which is run as a -child of s6-tlsd.
    • +
    • prog..., your client program, which is run with the +same pid as s6-tlsd.
  • It runs until it is killed by a signal.
  • @@ -62,7 +63,7 @@ child of s6-tlsd.

    prog is expected to read from its peer on its standard input and write to its peer on its standard output. -Since there will be a s6-tlsd +Since there will be a s6-tlsd-io program between prog and the network to perform the SSL encryption/decryption, those descriptors will not be a network socket - they will be pipes. diff --git a/doc/s6-ucspitlsc.html b/doc/s6-ucspitlsc.html new file mode 100644 index 0000000..4c1d2be --- /dev/null +++ b/doc/s6-ucspitlsc.html @@ -0,0 +1,178 @@ + + + + + + s6-networking: the s6-ucspitlsc program + + + + + + +

    +s6-networking
    +Software
    +skarnet.org +

    + +

    The s6-ucspitlsc program

    + +

    +s6-ucspitlsc is a client-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 +cleartext. +

    + +

    + 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 client itself. +

    + +

    Interface

    + +
    +     s6-ucspitlsc [ -S | -s ] [ -Y | -y ] [ -Z | -z ] [ -v verbosity ] [ -K kimeout ] [ -k servername ] [ -6 rfd ] [ -7 wfd ] [ -- ] prog...
    +
    + +
      +
    • s6-ucspitlsc expects to have an open TCP connection it +can talk to on its (by default) descriptors 6 (for reading) +and 7 (for writing).
    • +
    • It forks and establishes communication channels between +the parent and the child. The parent executes into +prog...; the child remains and waits for a +command.
    • +
    • At any time, prog... can send a command to its +control socket provided by s6-ucspitlsc, following the +UCSPI-TLS +protocol. Then the s6-ucspitlsc child will exec into a +s6-tlsc-io +process that will initiate the TLS connection, perform the +handshake (expecting a TLS server on the other side of the +network) and maintain a TLS tunnel. prog can +use that TLS tunnel instead of talking directly to the +network.
    • +
    + +

    Exit codes

    + +
      +
    • 100: wrong usage.
    • +
    • 111: system call failed.
    • +
    + +

    + Normally the parent s6-ucspitlsc process execs into prog... +and the child process execs into s6-tlsc-io. +If the parent dies or closes its control socket before sending a +command to start TLS, the child exits 0. +

    + +

    Environment variables

    + +

    Read

    + +

    + s6-ucspitlsc does not expect to have any particular +environment variables, but it spawns a +s6-tlsc-io program that does. +So it should pay attention to the following variables: +

    + +
      +
    • CADIR or CAFILE
    • +
    • (if the -y option has been given) CERTFILE and KEYFILE
    • +
    • TLS_UID and TLS_GID +
    + +

    Written

    + +

    + 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-tlsc-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 +control socket. +

    + +

    Options

    + +
      +
    • -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 +no effect.
    • +
    • -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-tlsc-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 : Do not send a client certificate. This is the default.
    • +
    • -y : Send a client certificate.
    • +
    • -k servername : use Server Name +Indication, and send servername. The default is not to +use SNI, which may be a security risk.
    • +
    • -K kimeout : close the connection +if kimeout milliseconds elapse without any data being +received from either side. The default is 0, which means +infinite timeout (never kill the connection).
    • +
    • -6 fdr : expect an open file +descriptor numbered fdr to read network (ciphertext) +data from. Make sure prog also reads its data +from its own fd fdr. Default is 6.
    • +
    • -7 fdw : expect an open file +descriptor numbered fdw to write network (ciphertext) +data to. Make sure prog also writes its data to +its own fd fdw. Default is 7.
    • +
    + +

    Notes

    + +
      +
    • It only makes sense to run s6-ucspitlsc if its application +program prog knows and understands the +UCSPI-TLS +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 +s6-tlsc.
    • +
    + + + diff --git a/doc/s6-ucspitlsd.html b/doc/s6-ucspitlsd.html new file mode 100644 index 0000000..51372e2 --- /dev/null +++ b/doc/s6-ucspitlsd.html @@ -0,0 +1,168 @@ + + + + + + s6-networking: the s6-ucspitlsd program + + + + + + +

    +s6-networking
    +Software
    +skarnet.org +

    + +

    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 +cleartext. +

    + +

    + 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. +

    + +

    Interface

    + +
    +     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 +command.
    • +
    • At any time, prog... can send a command to its +control socket provided by s6-ucspitlsd, following the +UCSPI-TLS +protocol. Then the s6-ucspitlsd child will exec into a +s6-tlsd-io +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 +network.
    • +
    + +

    Exit codes

    + +
      +
    • 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. +

    + +

    Environment variables

    + +

    Read

    + +

    + 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 +
    + +

    Written

    + +

    + 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 +control socket. +

    + +

    Options

    + +
      +
    • -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 +no effect.
    • +
    • -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 kimeout milliseconds elapse without any data being +received from either side. The default is 0, which means +infinite timeout (never kill the connection).
    • +
    + +

    Notes

    + +
      +
    • It only makes sense to run s6-ucspitlsd if its application +program prog knows and understands the +UCSPI-TLS +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 +s6-tlsd.
    • +
    + + + diff --git a/doc/tls-overview.html b/doc/tls-overview.html new file mode 100644 index 0000000..4ba3f69 --- /dev/null +++ b/doc/tls-overview.html @@ -0,0 +1,142 @@ + + + + + + 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

    + + + + + diff --git a/src/sbearssl/sbearssl_drop.c b/src/sbearssl/sbearssl_drop.c index 2d826af..31e5f49 100644 --- a/src/sbearssl/sbearssl_drop.c +++ b/src/sbearssl/sbearssl_drop.c @@ -12,8 +12,8 @@ void sbearssl_drop (void) { if (!getuid()) { - uid_t uid ; - gid_t gid ; + uid_t uid = 0 ; + gid_t gid = 0 ; char const *x = getenv("TLS_UID") ; if (x && !uid0_scan(x, &uid)) strerr_dieinvalid(100, "TLS_UID") ; x = getenv("TLS_GID") ; diff --git a/src/stls/stls_drop.c b/src/stls/stls_drop.c index d1e6831..7fc1bc5 100644 --- a/src/stls/stls_drop.c +++ b/src/stls/stls_drop.c @@ -12,8 +12,8 @@ void stls_drop (void) { if (!getuid()) { - uid_t uid ; - gid_t gid ; + uid_t uid = 0 ; + gid_t gid = 0 ; char const *x = getenv("TLS_UID") ; if (x && !uid0_scan(x, &uid)) strerr_dieinvalid(100, "TLS_UID") ; x = getenv("TLS_GID") ; -- cgit v1.2.3