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