ref: a8a35ee8f3dd514407206a3b09578bb66f06f097
dir: /README/
# Tlssrv(8) with Server Name Indication (SNI) support A variant of tlssrv(8) supporting the [Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) extension. With this extension it is possible to use *multiple* SSL certificates with a *single* IP address. # Installation ``` % git/clone git://shithub.us/igor/tlssrv.sni % cd tlssrv.sni % mk install ``` # 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 request 4 SSL certificates, that is `9lab.org`, `mux.9lab.org`, `bytelabs.org`, and `mux.bytelabs.org`, backed by the same IP address. Initially an account key must be generated (see [acmed(8)](http://man.9front.org/8/acmed): ``` % 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 [secstore(1)](http://man.9front.org/1/secstore) 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 a [rsa(8)](http://man.9front.org/8/rsa) key (i.e. `certificate.key`) and store it in [secstore(1)](http://man.9front.org/1/secstore): ``` % auth/rsagen -t 'service=tls role=client owner=*' \ >certificate.key % 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. Now it is time to create certificate signing request (i.e. `mux.9lab.org.csr`) files: ``` % auth/rsa2csr 'CN=9lab.org' certificate.key \ >/sys/lib/tls/acmed/9lab.org.csr % auth/rsa2csr 'CN=mux.9lab.org' certificate.key \ >/sys/lib/tls/acmed/mux.9lab.org.csr % auth/rsa2csr 'CN=bytelabs.org' certificate.key \ >/sys/lib/tls/acmed/bytelabs.org.csr % auth/rsa2csr 'CN=mux.bytelabs.org' certificate.key \ >/sys/lib/tls/acmed/mux.bytelabs.org.csr ``` Finally, the certificates for your domains can 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/9lab.org.csr \ >/sys/lib/tls/acmed/9lab.org.crt % 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/bytelabs.org.csr \ >/sys/lib/tls/acmed/bytelabs.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* certificates. The following is handy to display a 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/9lab.org.crt -ltcp80 -r`{cat $3/remote} /bin/tcp80 `{cat $3/remote}>>[2]/sys/log/tcp80 ``` If you already have `/bin/service/tcp443` with a certificate setup you do not need any additional steps to enable SNI to work other than ensuring your certificates are in the appropriate folder `/sys/lib/tls/acmed/` using the right suffix (see Caveats section). # Caveats A main or fallback certificate can be specified to tlssrv(8) via the `-c` option. If a Server Name Identifier SNI is provided, we attempt to load its certificate from: ``` snprint(path, sizeof(path), "/sys/lib/tls/acmed/%s.crt", c->serverName); ``` That means the certificate has to be present in `/sys/lib/tls/acmed/` with the name `SNI.crt`, where SNI is the the server name indicator provided by the client.