1lws-acme-client Plugin 2====================== 3 4## Introduction 5 6lws-acme-client is a protcol plugin for libwebsockets that implements an 7ACME client able to communicate with let's encrypt and other certificate 8providers. 9 10It implements `tls-sni-01` challenge, and is able to provision tls certificates 11"from thin air" that are accepted by all the major browsers. It also manages 12re-requesting the certificate when it only has two weeks left to run. 13 14It works with both the OpenSSL and mbedTLS backends. 15 16## Overview for use 17 18You need to: 19 20 - Provide name resolution to the IP with your server, ie, myserver.com needs to 21 resolve to the IP that hosts your server 22 23 - Enable port forwarding / external firewall access to your port, usually 443 24 25 - Enable the "lws-acme-client" plugin on the vhosts you want it to manage 26 certs for 27 28 - Add per-vhost options describing what should be in the certificate 29 30After that the plugin will sort everything else out. 31 32## Example lwsws setup 33 34``` 35 "vhosts": [ { 36 "name": "home.warmcat.com", 37 "port": "443", 38 "host-ssl-cert": "/etc/lwsws/acme/home.warmcat.com.crt.pem", 39 "host-ssl-key": "/etc/lwsws/acme/home.warmcat.com.key.pem", 40 "ignore-missing-cert": "1", 41 "access-log": "/var/log/lwsws/test-access-log", 42 "ws-protocols": [{ 43 "lws-acme-client": { 44 "auth-path": "/etc/lwsws/acme/auth.jwk", 45 "cert-path": "/etc/lwsws/acme/home.warmcat.com.crt.pem", 46 "key-path": "/etc/lwsws/acme/home.warmcat.com.key.pem", 47 "directory-url": "https://acme-staging.api.letsencrypt.org/directory", 48 "country": "TW", 49 "state": "Taipei", 50 "locality": "Xiaobitan", 51 "organization": "Crash Barrier Ltd", 52 "common-name": "home.warmcat.com", 53 "email": "andy@warmcat.com" 54 }, 55 ... 56``` 57 58## Required PVOs 59 60Notice that the `"host-ssl-cert"` and `"host-ssl-key"` entries have the same 61meaning as usual, they point to your certificate and private key. However 62because the ACME plugin can provision these, you should also mark the vhost with 63`"ignore-missing-cert" : "1"`, so lwsws will ignore what will initially be 64missing certificate / keys on that vhost, and will set about creating the 65necessary certs and keys instead of erroring out. 66 67You must make sure the directories mentioned here exist, lws doesn't create them 68for you. They should be 0700 root:root, even if you drop lws privileges. 69 70If you are implementing support in code, this corresponds to making sure the 71vhost creating `info.options` has the `LWS_SERVER_OPTION_IGNORE_MISSING_CERT` 72bit set. 73 74Similarly, in code, the each of the per-vhost options shown above can be 75provided in a linked-list of structs at vhost creation time. See 76`./test-apps/test-server-v2.0.c` for example code for providing pvos. 77 78### auth-path 79 80This is where the plugin will store the auth keys it generated. 81 82### cert-path 83 84Where the plugin will store the certificate file. Should match `host-ssl-cert` 85that the vhost wants to use. 86 87The path should include at least one 0700 root:root directory. 88 89### key-path 90 91Where the plugin will store the certificate keys. Again it should match 92`host-ssl-key` the vhost is trying to use. 93 94The path should include at least one 0700 root:root directory. 95 96### directory-url 97 98This defines the URL of the certification server you will get your 99certificates from. For let's encrypt, they have a "practice" one 100 101 - `https://acme-staging.api.letsencrypt.org/directory` 102 103and they have a "real" one 104 105 - `https://acme-v01.api.letsencrypt.org/directory` 106 107the main difference is the CA certificate for the real one is in most browsers 108already, but the staging one's CA certificate isn't. The staging server will 109also let you abuse it more in terms of repeated testing etc. 110 111It's recommended you confirm expected operation with the staging directory-url, 112and then switch to the "real" URL. 113 114### common-name 115 116Your server DNS name, like "libwebsockets.org". The remote ACME server will 117use this to find your server to perform the SNI challenges. 118 119### email 120 121The contact email address for the certificate. 122 123## Optional PVOs 124 125These are not included in the cert by letsencrypt 126 127### country 128 129Two-letter country code for the certificate 130 131### state 132 133State "or province" for the certificate 134 135### locality 136 137Locality for the certificate 138 139### organization 140 141Your company name 142 143## Security / Key storage considerations 144 145The `lws-acme-client` plugin is able to provision and update your certificate 146and keys in an entirely root-only storage environment, even though lws runs 147as a different uid / gid with no privileges to access the storage dir. 148 149It does this by opening and holding two WRONLY fds on "update paths" inside the 150root directory structure for each cert and key it manages; these are the normal 151cert and key paths with `.upd` appended. If during the time the server is up 152the certs become within two weeks of expiry, the `lws-acme-client` plugin will 153negotiate new certs and write them to the file descriptors. 154 155Next time the server starts, if it sees `.upd` cert and keys, it will back up 156the old ones and copy them into place as the new ones, before dropping privs. 157 158To also handle the long-uptime server case, lws will update the vhost with the 159new certs using in-memory temporary copies of the cert and key after updating 160the cert. 161 162In this way the cert and key live in root-only storage but the vhost is kept up 163to date dynamically with any cert changes as well. 164 165## Multiple vhosts using same cert 166 167In the case you have multiple vhosts using of the same cert, just attach 168the `lws-acme-client` plugin to one instance. When the cert updates, all the 169vhosts are informed and vhosts using the same filepath to access the cert will 170be able to update their cert. 171 172## Implementation point 173 174You will need to remove the auth keys when switching from OpenSSL to 175mbedTLS. They will be regenerated automatically. It's the file at this 176path: 177 178``` 179"auth-path": "/etc/lwsws/acme/auth.jwk", 180``` 181