diff --git a/README.md b/README.md index 56399ae..a584b92 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,29 @@ Automatic [Let's Encrypt](https://letsencrypt.org) HTTPS Certificates for node.j **See Also** -* See the node-letsencrypt [Examples](https://github.com/Daplie/node-letsencrypt/tree/master/examples) * [Let's Encrypt in (exactly) 90 seconds with Caddy](https://daplie.com/articles/lets-encrypt-in-literally-90-seconds/) * [lego](https://github.com/xenolf/lego): Let's Encrypt for golang +STOP +==== + +**These aren't the droids you're looking for.** + +This is a low-level library for implementing CLIs, +system tools, and abstracting storage backends (file vs db, etc). +This is not the thing to use in your webserver directly. + +Are you planning to use one of these? + + * `express` + * `hapi` + * `connect` + * `koa` + * raw `https` + * raw `spdy` + +### Use [letsencrypt-express](https://github.com/Daplie/letsencrypt-express) instead! + Install ======= @@ -128,203 +147,6 @@ le.register({ // and either rene **However**, due to the nature of what this library does, it has a few more "moving parts" than what makes sense to show in a minimal snippet. -Examples -======== - -The simplest example of setting up a webserver appropriately is probably `letsencrypt-cli` (~120 lines of code): - -* [letsencrypt-cli//lib/standalone.js](https://github.com/Daplie/node-letsencrypt-cli/blob/master/lib/standalone.js) - -Similary, `letsencrypt-cli`'s usage of `le.register()` is fairly simple (~75 lines of code): - -* [letsencrypt-cli/bin/letsencrypt.js](https://github.com/Daplie/node-letsencrypt-cli/blob/master/bin/letsencrypt.js) - -### One-Time Registration - -Register a 90-day certificate manually, on a whim - -**Note**: We've been running a fast development cycle and this example may be out of date. -The API *shouldn't* have changed much but, we probably need to come back and update it. - -#### Snippets - -[`commandline-minimal`](https://github.com/Daplie/node-letsencrypt/blob/master/examples/commandline-minimal.js): - -**Part 1: the Let's Encrypt client**: -```javascript -'use strict'; - -var LE = require('letsencrypt'); -var config = require('./config-minimal'); - -// Note: you should make this special dir in your product and leave it empty -config.le.webrootPath = __dirname + '/../tests/acme-challenge'; -config.le.server = LE.stagingServer; - - -// -// Manual Registration -// -var le = LE.create(config.backend, config.le); -le.register({ - agreeTos: true -, domains: ['example.com'] // CHANGE TO YOUR DOMAIN -, email: 'user@email.com' // CHANGE TO YOUR EMAIL -}, function (err) { - if (err) { - console.error('[Error]: node-letsencrypt/examples/standalone'); - console.error(err.stack); - } else { - console.log('success'); - } - - plainServer.close(); - tlsServer.close(); -}); -``` - -**Part 2: Express Web Server**: -```javascript -// -// Express App -// -var app = require('express')(); -app.use('/', le.middleware()); // TODO le.middleware was moved to letsencrypt-express, we need to update the docs here - - -// -// HTTP & HTTPS servers -// (required for domain validation) -// -var plainServer = require('http').createServer(app).listen(config.plainPort, function () { - console.log('Listening http', this.address()); -}); - -var tlsServer = require('https').createServer({ - key: config.tlsKey -, cert: config.tlsCert -, SNICallback: le.sniCallback -}, app).listen(config.tlsPort, function () { - console.log('Listening http', this.address()); -}); -``` - -#### Runnable Demo - -* [commandline (standalone with "webroot")](https://github.com/Daplie/node-letsencrypt/blob/master/examples/commandline.js) - -```bash -# manual standalone registration via commandline -# (runs against testing server on tls port 5001) -node examples/commandline.js example.com,www.example.com user@example.net agree -``` - -### Express - -Fully Automatic HTTPS with ExpressJS using Free SSL certificates from Let's Encrypt - -#### Snippets - -* [Minimal ExpressJS Example](https://github.com/Daplie/node-letsencrypt/blob/master/examples/express-minimal.js) - -```javascript -'use strict'; - -var LE = require('letsencrypt'); -var config = require('./config-minimal'); - -// Note: you should make this special dir in your product and leave it empty -config.le.webrootPath = __dirname + '/../tests/acme-challenge'; -config.le.server = LE.stagingServer; - -// -// Automatically Register / Renew Domains -// -var le = LE.create(config.backend, config.le, { - sniRegisterCallback: function (args, expiredCert, cb) { - // Security: check that this is actually a subdomain we allow - // (otherwise an attacker can cause you to rate limit against the LE server) - - var hostname = args.domains[0]; - if (!/\.example\.com$/.test(hostname)) { - console.error("bad domain '" + hostname + "', not a subdomain of example.com"); - cb(nul, null); - } - - // agree to the LE TOS for this domain - args.agreeTos = true; - args.email = 'user@example.com'; - - // use the cert even though it's expired - if (expiredCert) { - cb(null, expiredCert); - cb = function () { /*ignore*/ }; - } - - // register / renew the certificate in the background - le.register(args, cb); - } -}); - - -// -// Express App -// -var app = require('express')(); -app.use('/', le.middleware()); - - -// -// HTTP & HTTPS servers -// -require('http').createServer(app).listen(config.plainPort, function () { - console.log('Listening http', this.address()); -}); - -require('https').createServer({ - key: config.tlsKey -, cert: config.tlsCert -, SNICallback: le.sniCallback -}, app).listen(config.tlsPort, function () { - console.log('Listening http', this.address()); -}); -``` - -#### Runnable Example - -* [Full ExpressJS Example](https://github.com/Daplie/node-letsencrypt/blob/master/examples/express.js) - -```bash -# clear out the certificates -rm -rf tests/letsencrypt.* - -# automatic registration and renewal (certs install as you visit the site for the first time) -# (runs against testing server on tls port 5001) -node examples/express.js example.com,www.example.com user@example.net agree -``` - -```bash -# this will take a moment because it won't respond to the tls sni header until it gets the certs -curl https://example.com/ -``` - -### non-root - -If you want to run this as non-root, you can. - -You just have to set node to be allowed to use root ports - -``` -# node -sudo setcap cap_net_bind_service=+ep /usr/local/bin/node -``` - -and then make sure to set all of of the following to a directory that your user is permitted to write to - -* `webrootPath` -* `configDir` - - API === @@ -490,6 +312,7 @@ the python client, but it's not necessary) Change History ============== +* v1.4.x I can't remember... but it's better! * v1.1.0 Added letiny-core, removed node-letsencrypt-python * v1.0.2 Works with node-letsencrypt-python * v1.0.0 Thar be dragons diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..714536c --- /dev/null +++ b/examples/README.md @@ -0,0 +1,37 @@ +STOP +==== + +** These aren't the droids you're looking for.** + +You probably don't want to use `node-letsencrypt` directly. + +Instead, look here: + +Webservers +---------- + +For any type of webserver (express, hapi, koa, connect, https, spdy, etc), +you're going to want to take a look at +[letsencrypt-express](https://github.com/Daplie/letsencrypt-express). + + + +CLIs +---- + +For any type of CLI (like what you want to use with bash, fish, zsh, cmd.exe, PowerShell, etc), +you're going to want to take a look at +[letsencrypt-cli](https://github.com/Daplie/letsencrypt-cli). + + + +No, I wanted node-letsencrypt +============================= + +Well, take a look at the API in the main README +and you can also check out the [scraps](https://github.com/Daplie/node-letsencrypt/tree/master/scraps). + +Feel free to create issues for examples that don't work and pull requests if you fix one. + +And please, please, do open an issue. We haven't updated the scrap examples +(hence being moved), but we do have it on the roadmap to bring back some raw API examples. diff --git a/scraps/README.md b/scraps/README.md new file mode 100644 index 0000000..3e27fa8 --- /dev/null +++ b/scraps/README.md @@ -0,0 +1,202 @@ +Scraps +====== + +These are examples that we might come back and update (and would love help updating), +but they are more likely to cause confusion than success for the casual googled-it-and-got-here-er. + +Probably Outdated Examples +======== + +The simplest example of setting up a webserver appropriately is probably `letsencrypt-cli` (~120 lines of code): + +* [letsencrypt-cli//lib/standalone.js](https://github.com/Daplie/node-letsencrypt-cli/blob/master/lib/standalone.js) + +Similary, `letsencrypt-cli`'s usage of `le.register()` is fairly simple (~75 lines of code): + +* [letsencrypt-cli/bin/letsencrypt.js](https://github.com/Daplie/node-letsencrypt-cli/blob/master/bin/letsencrypt.js) + +### One-Time Registration + +Register a 90-day certificate manually, on a whim + +**Note**: We've been running a fast development cycle and this example may be out of date. +The API *shouldn't* have changed much but, we probably need to come back and update it. + +#### Snippets + +[`commandline-minimal`](https://github.com/Daplie/node-letsencrypt/blob/master/examples/commandline-minimal.js): + +**Part 1: the Let's Encrypt client**: +```javascript +'use strict'; + +var LE = require('letsencrypt'); +var config = require('./config-minimal'); + +// Note: you should make this special dir in your product and leave it empty +config.le.webrootPath = __dirname + '/../tests/acme-challenge'; +config.le.server = LE.stagingServer; + + +// +// Manual Registration +// +var le = LE.create(config.backend, config.le); +le.register({ + agreeTos: true +, domains: ['example.com'] // CHANGE TO YOUR DOMAIN +, email: 'user@email.com' // CHANGE TO YOUR EMAIL +}, function (err) { + if (err) { + console.error('[Error]: node-letsencrypt/examples/standalone'); + console.error(err.stack); + } else { + console.log('success'); + } + + plainServer.close(); + tlsServer.close(); +}); +``` + +**Part 2: Express Web Server**: +```javascript +// +// Express App +// +var app = require('express')(); +app.use('/', le.middleware()); // TODO le.middleware was moved to letsencrypt-express, we need to update the docs here + + +// +// HTTP & HTTPS servers +// (required for domain validation) +// +var plainServer = require('http').createServer(app).listen(config.plainPort, function () { + console.log('Listening http', this.address()); +}); + +var tlsServer = require('https').createServer({ + key: config.tlsKey +, cert: config.tlsCert +, SNICallback: le.sniCallback +}, app).listen(config.tlsPort, function () { + console.log('Listening http', this.address()); +}); +``` + +#### Runnable Demo + +* [commandline (standalone with "webroot")](https://github.com/Daplie/node-letsencrypt/blob/master/examples/commandline.js) + +```bash +# manual standalone registration via commandline +# (runs against testing server on tls port 5001) +node examples/commandline.js example.com,www.example.com user@example.net agree +``` + +### Express + +Fully Automatic HTTPS with ExpressJS using Free SSL certificates from Let's Encrypt + +#### Snippets + +* [Minimal ExpressJS Example](https://github.com/Daplie/node-letsencrypt/blob/master/examples/express-minimal.js) + +```javascript +'use strict'; + +var LE = require('letsencrypt'); +var config = require('./config-minimal'); + +// Note: you should make this special dir in your product and leave it empty +config.le.webrootPath = __dirname + '/../tests/acme-challenge'; +config.le.server = LE.stagingServer; + +// +// Automatically Register / Renew Domains +// +var le = LE.create(config.backend, config.le, { + sniRegisterCallback: function (args, expiredCert, cb) { + // Security: check that this is actually a subdomain we allow + // (otherwise an attacker can cause you to rate limit against the LE server) + + var hostname = args.domains[0]; + if (!/\.example\.com$/.test(hostname)) { + console.error("bad domain '" + hostname + "', not a subdomain of example.com"); + cb(nul, null); + } + + // agree to the LE TOS for this domain + args.agreeTos = true; + args.email = 'user@example.com'; + + // use the cert even though it's expired + if (expiredCert) { + cb(null, expiredCert); + cb = function () { /*ignore*/ }; + } + + // register / renew the certificate in the background + le.register(args, cb); + } +}); + + +// +// Express App +// +var app = require('express')(); +app.use('/', le.middleware()); + + +// +// HTTP & HTTPS servers +// +require('http').createServer(app).listen(config.plainPort, function () { + console.log('Listening http', this.address()); +}); + +require('https').createServer({ + key: config.tlsKey +, cert: config.tlsCert +, SNICallback: le.sniCallback +}, app).listen(config.tlsPort, function () { + console.log('Listening http', this.address()); +}); +``` + +#### Runnable Example + +* [Full ExpressJS Example](https://github.com/Daplie/node-letsencrypt/blob/master/examples/express.js) + +```bash +# clear out the certificates +rm -rf tests/letsencrypt.* + +# automatic registration and renewal (certs install as you visit the site for the first time) +# (runs against testing server on tls port 5001) +node examples/express.js example.com,www.example.com user@example.net agree +``` + +```bash +# this will take a moment because it won't respond to the tls sni header until it gets the certs +curl https://example.com/ +``` + +### non-root + +If you want to run this as non-root, you can. + +You just have to set node to be allowed to use root ports + +``` +# node +sudo setcap cap_net_bind_service=+ep /usr/local/bin/node +``` + +and then make sure to set all of of the following to a directory that your user is permitted to write to + +* `webrootPath` +* `configDir` + diff --git a/examples/commandline-minimal.js b/scraps/commandline-minimal.js similarity index 100% rename from examples/commandline-minimal.js rename to scraps/commandline-minimal.js diff --git a/examples/commandline.js b/scraps/commandline.js similarity index 100% rename from examples/commandline.js rename to scraps/commandline.js diff --git a/examples/config-minimal.js b/scraps/config-minimal.js similarity index 100% rename from examples/config-minimal.js rename to scraps/config-minimal.js diff --git a/examples/express-minimal.js b/scraps/express-minimal.js similarity index 100% rename from examples/express-minimal.js rename to scraps/express-minimal.js diff --git a/examples/express.js b/scraps/express.js similarity index 100% rename from examples/express.js rename to scraps/express.js diff --git a/examples/private-key-json-to-account-id.js b/scraps/private-key-json-to-account-id.js similarity index 100% rename from examples/private-key-json-to-account-id.js rename to scraps/private-key-json-to-account-id.js diff --git a/examples/renewal-example.com.conf b/scraps/renewal-example.com.conf similarity index 100% rename from examples/renewal-example.com.conf rename to scraps/renewal-example.com.conf diff --git a/examples/ursa.js b/scraps/ursa.js similarity index 100% rename from examples/ursa.js rename to scraps/ursa.js