diff --git a/scraps/README.md b/scraps/README.md deleted file mode 100644 index 3e27fa8..0000000 --- a/scraps/README.md +++ /dev/null @@ -1,202 +0,0 @@ -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/scraps/commandline-minimal.js b/scraps/commandline-minimal.js deleted file mode 100644 index 61d3cb8..0000000 --- a/scraps/commandline-minimal.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - -var LE = require('../'); -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.le); -le.register({ - agreeTos: true -, domains: [process.argv[3] || 'example.com'] // CHANGE TO YOUR DOMAIN -, email: process.argv[2] || 'user@example.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(); -}); - - -// -// Express App -// -var app = require('express')(); -app.use('/', le.middleware()); - - -// -// 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()); -}); diff --git a/scraps/commandline.js b/scraps/commandline.js deleted file mode 100644 index 47604d0..0000000 --- a/scraps/commandline.js +++ /dev/null @@ -1,87 +0,0 @@ -'use strict'; - -var conf = { - domains: process.argv[2] -, email: process.argv[3] -, agree: process.argv[4] -}; -var port = 80; -var tlsPort = 5001; - -if (!conf.domains || !conf.email || !conf.agree) { - console.error("Usage: letsencrypt agree"); - console.error("Example: letsencrypt example.com,www.example.com user@example.com agree"); - return; -} - -var LE = require('../'); -var path = require('path'); -// backend-specific defaults will be passed through -// Note: Since agreeTos is a legal agreement, I would suggest not accepting it by default -var bkDefaults = { - webrootPath: path.join(__dirname, '..', 'tests', 'acme-challenge') -, fullchainTpl: '/live/:hostname/fullchain.pem' -, privkeyTpl: '/live/:hostname/privkey.pem' -, configDir: path.join(__dirname, '..', 'tests', 'letsencrypt.config') -, server: LE.stagingServer - -// backend-specific -, logsDir: path.join(__dirname, '..', 'tests', 'letsencrypt.logs') -, workDir: path.join(__dirname, '..', 'tests', 'letsencrypt.work') -}; - -var le = LE.create(bkDefaults, { -/* - setChallenge: function (hostnames, key, value, cb) { - // the python backend needs fs.watch implemented - // before this would work (and even then it would be difficult) - } -, getChallenge: function (hostnames, key, cb) { - // - } -, sniRegisterCallback: function (args, certInfo, cb) { - - } -, registrationFailureCallback: function (args, certInfo, cb) { - what do to when a backgrounded registration fails - } -*/ -}); - -var localCerts = require('localhost.daplie.com-certificates'); -var express = require('express'); -var app = express(); - -app.use('/', le.middleware()); - -var server = require('http').createServer(); -server.on('request', app); -server.listen(port, function () { - console.log('Listening http', server.address()); -}); - -var tlsServer = require('https').createServer({ - key: localCerts.key -, cert: localCerts.cert -, SNICallback: le.sniCallback -}); -tlsServer.on('request', app); -tlsServer.listen(tlsPort, function () { - console.log('Listening http', tlsServer.address()); -}); - -le.register({ - agreeTos: 'agree' === conf.agree -, domains: conf.domains.split(',') -, email: conf.email -}, function (err) { - if (err) { - console.error('[Error]: node-letsencrypt/examples/standalone'); - console.error(err.stack); - } else { - console.log('success'); - } - - server.close(); - tlsServer.close(); -}); diff --git a/scraps/config-minimal.js b/scraps/config-minimal.js deleted file mode 100644 index 454119f..0000000 --- a/scraps/config-minimal.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict'; - -var path = require('path'); - -var config = { - - plainPort: 80 -, tlsPort: 5001 // 5001 for testing, normally 443 -, tlsKey: require('localhost.daplie.com-certificates').key -, tlsCert: require('localhost.daplie.com-certificates').cert - - -, le: { - webrootPath: path.join(__dirname, '..', 'tests', 'acme-challenge') - , fullchainTpl: '/live/:hostname/fullchain.pem' - , privkeyTpl: '/live/:hostname/privkey.pem' - , configDir: path.join(__dirname, '..', 'tests', 'letsencrypt.config') - - // these are specific to the python client and won't be needed with the purejs library - , logsDir: path.join(__dirname, '..', 'tests', 'letsencrypt.logs') - , workDir: path.join(__dirname, '..', 'tests', 'letsencrypt.work') - } - -}; - -module.exports = config; diff --git a/scraps/express-minimal.js b/scraps/express-minimal.js deleted file mode 100644 index 4e3cdba..0000000 --- a/scraps/express-minimal.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict'; - -var LE = require('../'); -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; - -var le = LE.create(config.le, { - sniRegisterCallback: function (args, expiredCert, cb) { - // In theory you should never get an expired certificate because - // the certificates automatically renew in the background starting - // about a week before they expire. - // (the default behavior is to randomly stagger renewals) - // so in this case we'll just return the expired certificate - if (expiredCert) { return cb(null, expiredCert); } - - // If we get here that means this domain hasn't been registered yet - // Security Warning: you should either manually register domains - // and return null here or check that the sni header isn't being - // spoofed and this is actually a domain you own before registering - // - // cb(null, null); - - var hostname = args.domains[0]; - console.log("[TODO] check that '" + hostname + "' is one I expect"); - - args.agreeTos = true; - args.email = 'user@example.com'; - - 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()); -}); diff --git a/scraps/express.js b/scraps/express.js deleted file mode 100644 index 356d583..0000000 --- a/scraps/express.js +++ /dev/null @@ -1,87 +0,0 @@ -'use strict'; - -var conf = { - domains: (process.argv[2]||'').split(',') -, email: process.argv[3] -, agree: 'agree' === process.argv[4] -}; -var port = 80; -var tlsPort = 5001; - -if (!conf.domains || !conf.email || !conf.agree) { - console.error("Usage: node examples/express agree"); - console.error("Example: node examples/express example.com,www.example.com user@example.com agree"); - return; -} - -var LE = require('../'); -var path = require('path'); -// backend-specific defaults will be passed through -// Note: Since agreeTos is a legal agreement, I would suggest not accepting it by default -var bkDefaults = { - webrootPath: path.join(__dirname, '..', 'tests', 'acme-challenge') -, fullchainTpl: '/live/:hostname/fullchain.pem' -, privkeyTpl: '/live/:hostname/privkey.pem' -, configDir: path.join(__dirname, '..', 'tests', 'letsencrypt.config') -, server: LE.stagingServer -}; - -var le = LE.create(LEP, bkDefaults, { - sniRegisterCallback: function (args, certInfo, cb) { - var allowedDomains = conf.domains; // require('../tests/config').allowedDomains; - - // let the renewal take place in the background - if (certInfo && certInfo.context) { - cb(null, certInfo); - return; - } - - // verify that these are domains we allow to register on our server - if (args.domains.length && args.domains.every(function (hostname) { - hostname = hostname.toLowerCase(); - return (-1 !== allowedDomains.indexOf(hostname)); - })) { - // wait for registration before responding - args.agreeTos = conf.agree; - args.email = conf.email; // you'd want to lookup which user has this email - le.register(args, cb); - } else { - // I don't know where this error goes (SNICallback)... but at least we put it somewhere - cb(new Error("SNI came in for (an) unrecognized domain(s): '" + args.domains + "'")); - } - } -/* -, setChallenge: function (hostnames, key, value, cb) { - // the python backend needs fs.watch implemented - // before this would work (and even then it would be difficult) - } -, getChallenge: function (hostnames, key, cb) { - // - } -, registrationFailureCallback: function (args, certInfo, cb) { - what do to when a backgrounded registration fails - } -*/ -}); - -var localCerts = require('localhost.daplie.com-certificates'); -var express = require('express'); -var app = express(); - -app.use('/', le.middleware()); - -var server = require('http').createServer(); -server.on('request', app); -server.listen(port, function () { - console.log('Listening http', server.address()); -}); - -var tlsServer = require('https').createServer({ - key: localCerts.key -, cert: localCerts.cert -, SNICallback: le.sniCallback -}); -tlsServer.on('request', app); -tlsServer.listen(tlsPort, function () { - console.log('Listening http', tlsServer.address()); -}); diff --git a/scraps/private-key-json-to-account-id.js b/scraps/private-key-json-to-account-id.js deleted file mode 100644 index 3ccd686..0000000 --- a/scraps/private-key-json-to-account-id.js +++ /dev/null @@ -1,80 +0,0 @@ -'use strict'; - -var fs = require('fs'); -var crypto = require('crypto'); -var ursa = require('ursa'); - -// Here are all the places you can discover the account id: -// -// letsencrypt/account.py -// -// /etc/letsencrypt/accounts/{{ server }}/directory/{{ accountId }}/private_key.json -// /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/f4c33502df3789849f617944253b35ae/private_key.json -// -// /etc/letsencrypt/renewal/{{ hostname }}.conf -// /etc/letsencrypt/renewal/example.com.conf -// -// Note: each domain has its own private key - -function fromPrivateKeyUrsa(priv, cb) { - var pub = priv.toPublicPem(); - var accountId = crypto.createHash('md5').update(pub).digest('hex'); - - cb(null, accountId); -} - -function fromAccountPrivateKey(pkj, cb) { - Object.keys(pkj).forEach(function (key) { - pkj[key] = new Buffer(pkj[key], 'base64'); - }); - - var priv = ursa.createPrivateKeyFromComponents( - pkj.n // modulus - , pkj.e // exponent - , pkj.p - , pkj.q - , pkj.dp - , pkj.dq - , pkj.qi - , pkj.d - ); - - fromPrivateKeyUrsa(priv, cb); -} - -function fromAccountPrivateKeyFile(privateKeyPath, cb) { - // Read ACME account key - fs.readFile(privateKeyPath, 'utf8', function (err, privkeyJson) { - var pkj; - - if (err) { - cb(err); - return; - } - - try { - pkj = JSON.parse(privkeyJson); - } catch(e) { - cb(e); - return; - } - - fromAccountPrivateKey(pkj, cb); - }); -} - -function bogusAccountId(cb) { - var priv = ursa.generatePrivateKey(2048, 65537); - - fromPrivateKeyUrsa(priv, cb); -} - -module.exports.bogusAccountId = bogusAccountId; -module.exports.fromAccountPrivateKey = fromAccountPrivateKey; - -module.exports.bogusAccountId(function (err, id) { - console.log('Random Account Id', id); -}); -module.exports.fromAccountPrivateKey('/etc/letsencrypt/live/example.com/privkey.pem', function (err, id) { - console.log(id); -}); diff --git a/scraps/renewal-example.com.conf b/scraps/renewal-example.com.conf deleted file mode 100644 index 4ed27fa..0000000 --- a/scraps/renewal-example.com.conf +++ /dev/null @@ -1,62 +0,0 @@ -cert = /etc/letsencrypt/live/example.com/cert.pem -privkey = /etc/letsencrypt/live/example.com/privkey.pem -chain = /etc/letsencrypt/live/example.com/chain.pem -fullchain = /etc/letsencrypt/live/example.com/fullchain.pem - -# Options and defaults used in the renewal process -[renewalparams] -apache_enmod = a2enmod -no_verify_ssl = False -ifaces = None -apache_dismod = a2dismod -register_unsafely_without_email = False -uir = None -installer = none -config_dir = /etc/letsencrypt -text_mode = False -func = -prepare = False -work_dir = /var/lib/letsencrypt -tos = True -init = False -http01_port = 80 -duplicate = False -key_path = None -nginx = False -fullchain_path = /home/user/letsencrypt/chain.pem -email = user@example.com -csr = None -agree_dev_preview = None -redirect = None -verbose_count = -3 -config_file = None -renew_by_default = False -hsts = False -authenticator = webroot -domains = example.com, -rsa_key_size = 2048 -checkpoints = 1 -manual_test_mode = False -apache = False -cert_path = /home/user/letsencrypt/cert.pem -webroot_path = /srv/www/example.com/, -strict_permissions = False -apache_server_root = /etc/apache2 -account = f4c33502df3789849f617944253b35ae -manual_public_ip_logging_ok = False -chain_path = /home/user/letsencrypt/chain.pem -standalone = False -manual = False -server = https://acme-v01.api.letsencrypt.org/directory -standalone_supported_challenges = "http-01,tls-sni-01" -webroot = True -apache_init_script = None -user_agent = None -apache_ctl = apache2ctl -apache_le_vhost_ext = -le-ssl.conf -debug = False -tls_sni_01_port = 443 -logs_dir = /var/log/letsencrypt -configurator = None -[[webroot_map]] -example.com = /srv/www/example.com/ diff --git a/scraps/ursa.js b/scraps/ursa.js deleted file mode 100644 index 519e8cd..0000000 --- a/scraps/ursa.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict'; - -var LE = require('../'); -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.le); -le.backend.registerAsync({ - agreeTos: true -, domains: ['example.com'] // CHANGE TO YOUR DOMAIN -, email: 'user@example.com' // CHANGE TO YOUR EMAIL -}, function (err, body) { - if (err) { - console.error('[Error]: node-letsencrypt/examples/ursa'); - console.error(err.stack); - } else { - console.log('success', body); - } - - plainServer.close(); - tlsServer.close(); -}).then(function () {}, function (err) { - console.error(err.stack); -}); - -// -// Express App -// -var app = require('express')(); -app.use('/', le.middleware()); - - -// -// 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()); -});