shithub: tlssrv.sni

ref: 27c94cd34892ffd8443bfb596e69704624b30595
dir: /README/

View raw version
A variant of tlssrv(8) supporting the Server Name Identifier (SNI)
extension.  With this extension it is possible to use multiple SSL
certificates with a single IP address.

# Example Setup

The easiest way to fetch and renew a **TLS** certificate on
[9front](http://9front.org) is via
[acmed(8)](http://man.9front.org/8/acmed). We are going to
create two SSL certificates, that is mux.9lab.org and
mux.bytelabs.org, for the same IP address.

Initially an account key must be generated:

```
% ramfs -p ; cd /tmp
% auth/rsagen -t \
    'service=acme role=sign hash=sha256 acct=igor@9lab.org' \
    >account.key
% auth/rsa2jwk account.key \
    >/sys/lib/tls/acmed/igor@9lab.org.pub
```

The `account.key` must be loaded into
[factotum(4)](http://man.9front.org/4/factotum); however, it is best
to store it in [secstore(1)](http://man.9front.org/1/secstore) instead
of storing it unencrypted on the file system:

```
% auth/secstore -g factotum
secstore password:
% cat account.key >> factotum
% auth/secstore -p factotum
secstore password:
% read -m factotum > /mnt/factotum/ctl
```

Please consult the [secstore(1)](http://man.9front.org/1/secstore) man
page as well as the excellent [9front FQA secstore
documentation](http://fqa.9front.org/fqa8.html#8.4.7) if the above
doesn't make sense or doesn't work for you.

Next, generate [rsa(8)](http://man.9front.org/8/rsa) key (i.e.
`certificate.key`) and certificate signing request (i.e.
`mux.9lab.org.csr`, `mux.bytelabs.org`) files:

```
% auth/rsagen -t 'service=tls role=client owner=*' \
    >certificate.key
% auth/rsa2csr 'CN=mux.9lab.org' certificate.key \
    >/sys/lib/tls/acmed/mux.9lab.org.csr
% auth/rsa2csr 'CN=mux.bytelabs.org' certificate.key \
    >/sys/lib/tls/acmed/mux.bytelabs.org.csr
```

Again, you are urged to store the
[rsa(8)](http://man.9front.org/8/rsa) key in
[secstore(1)](http://man.9front.org/1/secstore):

```
% auth/secstore -g factotum
secstore password:
% cat certificate.key >> factotum
% auth/secstore -p factotum
secstore password:
% read -m factotum > /mnt/factotum/ctl
```

See [rsa(8)](http://man.9front.org/8/rsa) and
[tlssrv(8)](http://man.9front.org/8/tlssrv) for more examples on how
to use RSA keys.

Finally, the certificate for your domain can now be fetched.  This
requires [webfs(4)](http://man.9front.org/4/webfs) to be mounted as
the [ACME
protocol](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment)
uses HTTP to talk to the provider.

```
% webfs
% auth/acmed igor@9lab.org /sys/lib/tls/acmed/mux.9lab.org.csr \
    >/sys/lib/tls/acmed/mux.9lab.org.crt
% auth/acmed igor@9lab.org /sys/lib/tls/acmed/mux.bytelabs.org.csr \
    >/sys/lib/tls/acmed/mux.bytelabs.org.crt
```

The above incantation is also used to *renew* the certificate.

Let's display the certificate:

```
% auth/pemdecode 'CERTIFICATE' /sys/lib/tls/acmed/mux.9lab.org.crt | auth/x5092pub
key proto=rsa size=2048 ek=… n=… subject=mux.9lab.org
```

At last, to [listen(8)](http://man.9front.org/8/listen) on https port
443 for requests modify the file `/bin/service/tcp443` as follows:

```
% cat /bin/service/tcp443
#!/bin/rc
exec /bin/tlssrv -c/sys/lib/tls/acmed/mux.9lab.org.crt -ltcp80 -r`{cat $3/remote} /bin/tcp80 `{cat $3/remote}>>[2]/sys/log/tcp80
```

# Caveats

A main or fallback certificate can be specified to tlssrv(8)
via the `-c` option. If an SNI is provided we try to find it
as follows:

```
  snprint(path, sizeof(path), "/sys/lib/tls/acmed/%s.crt", c->serverName);
```

That means the certificate has to be present in the `/sys/lib/tls/acmed/`
folder with the name `SNI.crt` where SNI is the the server name indicator
provided by the client.

It is not yet possible to override the path to certificates.