v3.0.0: update for greenlock v2.7+

This commit is contained in:
AJ ONeal 2019-04-02 20:59:11 -06:00
parent 0285cf74ab
commit 498c8e53b3
4 changed files with 121 additions and 78 deletions

52
LICENSE
View File

@ -1,21 +1,41 @@
Copyright 2016-2019 AJ ONeal
This is open source software; you can redistribute it and/or modify it under the
terms of either:
a) the "MIT License"
b) the "Apache-2.0 License"
MIT License
Copyright (c) 2016 Daplie, Inc
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Apache-2.0 License Summary
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,5 +1,4 @@
le-challenge-dns
================
# le-challenge-dns
| A [Root](https://rootprojects.org) Project
| [greenlock.js](https://git.coolaj86.com/coolaj86/greenlock.js) (library)
@ -21,19 +20,19 @@ press [enter] to continue the process.
_acme-challenge.example.com TXT xxxxxxxxxxxxxxxx TTL 60
```
Install
-------
## Install
```bash
npm install --save le-challenge-dns@2.x
npm install --save le-challenge-dns@3.x
```
Usage
-----
If you have `greenlock@v2.6` or lower, you'll need the old `le-challenge-dns@3.x` instead.
## Usage
The challenge can be set globally like this:
```bash
```js
var leChallengeDns = require('le-challenge-dns').create({
debug: false
});
@ -41,21 +40,37 @@ var leChallengeDns = require('le-challenge-dns').create({
var Greenlock = require('greenlock');
Greenlock.create({
server: LE.stagingServerUrl // Change to LE.productionServerUrl in production
, challengeType: 'dns-01'
...
, challenges: {
'dns-01': leChallengeDns
}
, approveDomains: [ 'example.com' ]
, approveDomains: [ 'example.com', '*.example.com' ]
});
```
In can also be set in the `approveDomains` callback instead, like this:
```
```js
function approveDomains(opts, certs, cb) {
opts.challenges = { 'dns-01': leChallengeDns };
...
opts.subject = 'example.com'
opts.domains = [ 'example.com', '*.example.com' ];
cb(null, { options: opts, certs: certs });
}
```
If you didn't make the dns challenge globally available in the main greenlock config,
you can make it locally available here:
```js
function approveDomains(opts, certs, cb) {
...
if (!opts.challenges) { opts.challenges = {}; }
opts.challenges['dns-01'] = leChallengeDns;
opts.challenges['http-01'] = ...
cb(null, { options: opts, certs: certs });
}
```
@ -63,19 +78,33 @@ function approveDomains(opts, certs, cb) {
NOTE: If you request a certificate with 6 domains listed,
it will require 6 individual challenges.
Exposed Methods
---------------
## Exposed Methods
For ACME Challenge:
* `set(opts, domain, challange, keyAuthorization, done)`
* `get(defaults, domain, challenge, done)`
* `remove(defaults, domain, challenge, done)`
* `set(opts, done)`
* `remove(opts, done)`
Note: `get()` is a no-op for `dns-01`.
The options object has whatever options were set in `approveDomains()` as well as the `challenge`:
```js
{ challenge: {
identifier: { type: 'dns', value: 'example.com'
, wildcard: true
, altname: '*.example.com'
, type: 'dns-01'
, token: 'xxxxxx'
, keyAuthorization: 'xxxxxx.abc123'
, dnsHost: '_acme-challenge.example.com'
, dnsAuthorization: 'abc123'
, expires: '1970-01-01T00:00:00Z'
}
}
```
Note: There's no `get()` because it's the DNS server, not the Greenlock server, that answers the requests.
(though I suppose you could implement it if you happen to run your DNS and webserver together... kinda weird though)
For greenlock.js internals:
* `getOptions()` returns the internal defaults merged with the user-supplied options
* `loopback(defaults, domain, challange, done)` performs a dns lookup of the txt record
* `test(opts, domain, challange, keyAuthorization, done)` runs set, loopback, remove, loopback
* `options` stores the internal defaults merged with the user-supplied options

View File

@ -4,48 +4,44 @@ var Challenge = module.exports;
Challenge.create = function (defaults) {
return {
getOptions: function () {
return defaults || {};
}
options: defaults
, set: Challenge.set
, get: Challenge.get
, remove: Challenge.remove
, loopback: Challenge.loopback
, test: Challenge.test
};
};
// Show the user the token and key and wait for them to be ready to continue
Challenge.set = function (args, domain, challenge, keyAuthorization, cb) {
var keyAuthDigest = require('crypto').createHash('sha256').update(keyAuthorization||'').digest('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/g, '')
;
var challengeDomain = domain;
Challenge.set = function (args, cb) {
if (!args.challenge) {
console.error("please update to greenlock v2.7+");
process.exit();
}
var opts = args.challenge;
if (this.leDnsResponse) {
this.leDnsResponse(challenge, keyAuthorization, keyAuthDigest, challengeDomain, domain)
this.leDnsResponse(opts.token, opts.keyAuthorization, opts.dnsAuthorization, opts.dnsHost, opts.altname)
.then(function (/*successMessage*/) {
cb(null);
});
} else {
console.info("");
console.info("Challenge for '" + domain + "'");
console.info("Challenge for '" + opts.altname + "'");
console.info("");
console.info("We now present (for you copy-and-paste pleasure) your ACME Challenge");
console.info("public Challenge and secret KeyAuthorization and Digest, in that order, respectively:");
console.info(challenge);
console.info(keyAuthorization);
console.info(keyAuthDigest);
console.info("");
console.info(challengeDomain + "\tTXT " + keyAuthDigest + "\tTTL 60");
console.info(opts.dnsHost + "\tTXT " + opts.dnsAuthorization + "\tTTL 60");
console.info("");
console.info(JSON.stringify({
domain: domain
, challenge: challenge
, keyAuthorization: keyAuthorization
, keyAuthDigest: keyAuthDigest
identifier: opts.identifier
, wildcard: opts.wildcard
, altname: opts.altname
, type: opts.type
, token: opts.token
, keyAuthorization: opts.keyAuthorization
, dnsHost: opts.dnsHost
, dnsAuthorization: opts.dnsAuthorization
, expires: opts.expires
}, null, ' ').replace(/^/gm, '\t'));
console.info("");
console.info("hit enter to continue...");
@ -58,13 +54,14 @@ Challenge.set = function (args, domain, challenge, keyAuthorization, cb) {
};
// nothing to do here, that's why it's manual
Challenge.get = function (defaults, domain, challenge, cb) {
Challenge.get = function (defaults, cb) {
// defaults.challenge
cb(null);
};
// might as well tell the user that whatever they were setting up has been checked
Challenge.remove = function (args, domain, challenge, cb) {
console.info("Challenge for '" + domain + "' complete. You may remove it.");
Challenge.remove = function (args, cb) {
console.info("Challenge complete. You may remove the DNS-01 challenge record:");
console.info("\t" + args.challenge.altname + "\tTXT\t" + args.challenge.dnsAuthorization);
cb(null);
//});
};

View File

@ -1,7 +1,7 @@
{
"name": "le-challenge-dns",
"version": "2.3.2",
"description": "A manual (interactive CLI) dns-based strategy for node-letsencrypt for setting, retrieving, and clearing ACME DNS-01 challenges issued by the ACME server",
"version": "3.0.0",
"description": "A manual (interactive CLI) dns-based strategy for Greenlock / Let's Encrypt / ACME DNS-01 challenges",
"main": "index.js",
"scripts": {
"test": "node test.js"
@ -11,21 +11,18 @@
"url": "git+https://git.coolaj86.com/coolaj86/le-challenge-dns.js.git"
},
"keywords": [
"le",
"Let's Encrypt",
"Greenlock",
"ACME",
"dns-01",
"wildcard",
"wildcards",
"letsencrypt",
"le-challenge",
"le-challenge-",
"le-challenge-dns",
"manual",
"interactive",
"cli",
"acme",
"Let's Encrypt v2",
"LetsEncrypt",
"challenge",
"dns",
"cluster",
"ephemeral"
"challenge"
],
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
"license": "(MIT OR Apache-2.0)",