From 69f5fc9c450a45620fdc9c1a91d4d656efea8a27 Mon Sep 17 00:00:00 2001 From: Ben Schmidt Date: Sun, 9 Oct 2016 23:54:27 +1100 Subject: [PATCH] fix renewal, add --renew-within, reorganise args --- README.md | 47 +++++++++++++++++++++++++--------------------- bin/letsencrypt.js | 17 +++++++++-------- index.js | 33 +++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index b1a96be..5c3a693 100644 --- a/README.md +++ b/README.md @@ -237,24 +237,19 @@ Usage: letsencrypt [OPTIONS] [ARGS] Options: + --server [STRING] ACME Directory Resource URI. (Default is https://acme-v01.api.letsencrypt.org/directory)) + --email EMAIL Email used for registration and recovery contact. (default: null) + --agree-tos BOOLEAN Agree to the Let's Encrypt Subscriber Agreement + --domains URL Domain names to apply. For multiple domains you can enter a comma separated list of domains as a parameter. (default: []) - --duplicate BOOLEAN Allow getting a certificate that duplicates an existing one + --renew-within [NUMBER] Renew certificates this many days before expiry. (default: 7) - --agree-tos BOOLEAN Agree to the Let's Encrypt Subscriber Agreement - - --debug BOOLEAN show traces and logs - - --tls-sni-01-port NUMBER Use TLS-SNI-01 challenge type with this port. - (must be 443 with most production servers) (Boulder allows 5001 in testing mode) - - --http-01-port [NUMBER] Use HTTP-01 challenge type with this port, used for SimpleHttp challenge. (Default is 80) - (must be 80 with most production servers) - - --dns-01 Use DNS-01 challenge type. + --duplicate BOOLEAN Allow getting a certificate that duplicates an existing one/is + an early renewal. --rsa-key-size [NUMBER] Size (in bits) of the RSA key. (Default is 2048) @@ -269,9 +264,26 @@ Options: --domain-key-path STRING Path to privkey.pem to use for domain (default: generate new) + --account-key-path STRING Path to privkey.pem to use for account (default: generate new) + --config-dir STRING Configuration directory. (Default is ~/letsencrypt/etc/) - --server [STRING] ACME Directory Resource URI. (Default is https://acme-v01.api.letsencrypt.org/directory)) + --tls-sni-01-port NUMBER Use TLS-SNI-01 challenge type with this port. + (must be 443 with most production servers) (Boulder allows 5001 in testing mode) + + --http-01-port [NUMBER] Use HTTP-01 challenge type with this port, used for SimpleHttp challenge. (Default is 80) + (must be 80 with most production servers) + + --dns-01 Use DNS-01 challenge type. + + --standalone [BOOLEAN] Obtain certs using a "standalone" webserver. (Default is true) + + --manual [BOOLEAN] Print the token and key to the screen and wait for you to hit enter, + giving you time to copy it somewhere before continuing. (Default is false) + + --webroot BOOLEAN Obtain certs by placing files in a webroot directory. + + --webroot-path STRING public_html / webroot path. --apache BOOLEAN Obtain certs using Apache virtual hosts. @@ -301,14 +313,7 @@ Options: --apache-disable STRING Command to run to disable the site in Apache. (Default is `rm /etc/apache2/sites-enabled/{{{token}}}.conf`) - --standalone [BOOLEAN] Obtain certs using a "standalone" webserver. (Default is true) - - --manual [BOOLEAN] Print the token and key to the screen and wait for you to hit enter, - giving you time to copy it somewhere before continuing. (Default is false) - - --webroot BOOLEAN Obtain certs by placing files in a webroot directory. - - --webroot-path STRING public_html / webroot path. + --debug BOOLEAN show traces and logs -h, --help Display help and usage details ``` diff --git a/bin/letsencrypt.js b/bin/letsencrypt.js index 95dd2e2..6f90851 100755 --- a/bin/letsencrypt.js +++ b/bin/letsencrypt.js @@ -5,14 +5,12 @@ var cli = require('cli'); var mkdirp = require('mkdirp'); cli.parse({ - email: [ false, " Email used for registration and recovery contact. (default: null)", 'email' ] -, domains: [ false, " Domain names to apply. For multiple domains you can enter a comma separated list of domains as a parameter. (default: [])", 'string' ] -, duplicate: [ false, " Allow getting a certificate that duplicates an existing one", 'boolean', false ] + server: [ false, " ACME Directory Resource URI.", 'string', '' ] +, email: [ false, " Email used for registration and recovery contact. (default: null)", 'email' ] , 'agree-tos': [ false, " Agree to the Let's Encrypt Subscriber Agreement", 'boolean', false ] -, debug: [ false, " show traces and logs", 'boolean', false ] -, 'tls-sni-01-port': [ false, " Use TLS-SNI-01 challenge type with this port (only port 443 is valid with most production servers)", 'int' ] -, 'http-01-port': [ false, " Use HTTP-01 challenge type with this port (only port 80 is valid with most production servers) (default: 80)", 'int' ] -, 'dns-01': [ false, " Use DNS-01 challange type", 'boolean', false ] +, domains: [ false, " Domain names to apply. For multiple domains you can enter a comma separated list of domains as a parameter. (default: [])", 'string' ] +, 'renew-within': [ false, " Renew certificates this many days before expiry", 'int', 7 ] +, duplicate: [ false, " Allow getting a certificate that duplicates an existing one/is an early renewal", 'boolean', false ] , 'rsa-key-size': [ false, " Size (in bits) of the RSA key.", 'int', 2048 ] , 'cert-path': [ false, " Path to where new cert.pem is saved", 'string',':configDir/live/:hostname/cert.pem' ] , 'fullchain-path': [ false, " Path to where new fullchain.pem (cert + chain) is saved", 'string', ':configDir/live/:hostname/fullchain.pem' ] @@ -20,7 +18,9 @@ cli.parse({ , 'domain-key-path': [ false, " Path to privkey.pem to use for domain (default: generate new)", 'string' ] , 'account-key-path': [ false, " Path to privkey.pem to use for account (default: generate new)", 'string' ] , 'config-dir': [ false, " Configuration directory.", 'string', '~/letsencrypt/etc/' ] -, server: [ false, " ACME Directory Resource URI.", 'string', '' ] +, 'tls-sni-01-port': [ false, " Use TLS-SNI-01 challenge type with this port (only port 443 is valid with most production servers)", 'int' ] +, 'http-01-port': [ false, " Use HTTP-01 challenge type with this port (only port 80 is valid with most production servers) (default: 80)", 'int' ] +, 'dns-01': [ false, " Use DNS-01 challange type", 'boolean', false ] , standalone: [ false, " Obtain certs using a \"standalone\" webserver.", 'boolean', false ] , manual: [ false, " Print the token and key to the screen and wait for you to hit enter, giving you time to copy it somewhere before continuing (default: false)", 'boolean', false ] , webroot: [ false, " Obtain certs by placing files in a webroot directory.", 'boolean', false ] @@ -36,6 +36,7 @@ cli.parse({ , 'apache-reload': [ false, " Command to run to reload Apache.", 'string' ] , 'apache-disable': [ false, " Command to run to disable the site in Apache.", 'string' ] //, 'standalone-supported-challenges': [ false, " Supported challenges, order preferences are randomly chosen. (default: http-01,tls-sni-01)", 'string', 'http-01,tls-sni-01'] +, debug: [ false, " show traces and logs", 'boolean', false ] , 'work-dir': [ false, "(ignored)", 'string', '~/letsencrypt/var/lib/' ] , 'logs-dir': [ false, "(ignored)", 'string', '~/letsencrypt/var/log/' ] }); diff --git a/index.js b/index.js index 8a984e5..85e0b0c 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,7 @@ 'use strict'; +var DAY = 24 * 60 * 60 * 1000; + var LE = require('letsencrypt'); module.exports.run = function (args) { @@ -73,6 +75,7 @@ module.exports.run = function (args) { , server: args.server , store: leStore , challenges: leChallenges + , renewWithin: args.renewWithin * DAY , duplicate: args.duplicate }); @@ -93,29 +96,41 @@ module.exports.run = function (args) { // Note: can't use args directly as null values will overwrite template values le.register({ - domains: args.domains + debug: args.debug , email: args.email , agreeTos: args.agreeTos - , challengeType: challengeType + , domains: args.domains , rsaKeySize: args.rsaKeySize + , challengeType: challengeType + }).then(function (certs) { + if (!certs._renewing) { + return certs; + } + console.log(""); + console.log("Got certificate(s) for " + certs.altnames.join(', ')); + console.log("\tIssued at " + new Date(certs.issuedAt).toISOString() + ""); + console.log("\tValid until " + new Date(certs.expiresAt).toISOString() + ""); + console.log(""); + console.log("Renewing them now"); + return certs._renewing; }).then(function (certs) { if (servers) { servers.closeServers(); } + console.log(""); + console.log("Got certificate(s) for " + certs.altnames.join(', ')); + console.log("\tIssued at " + new Date(certs.issuedAt).toISOString() + ""); + console.log("\tValid until " + new Date(certs.expiresAt).toISOString() + ""); + console.log(""); + // should get back account, path to certs, pems, etc? console.log('\nCertificates installed at:'); console.log(Object.keys(args).filter(function (key) { return /Path/.test(key); }).map(function (key) { return args[key]; - }).join('\n').replace(/:hostname/, args.domains[0])); - - console.log(""); - console.log("Got certificate(s) for " + certs.altnames.join(', ')); - console.log("\tIssued at " + new Date(certs.issuedAt).toISOString() + ""); - console.log("\tValid until " + new Date(certs.expiresAt).toISOString() + ""); - console.log(""); + }).join('\n').replace(/:hostname/g, args.domains[0])); process.exit(0); }, function (err) {