v3.0.0: update for greenlock v2.7+
This commit is contained in:
parent
0285cf74ab
commit
498c8e53b3
52
LICENSE
52
LICENSE
|
@ -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.
|
||||
|
|
73
README.md
73
README.md
|
@ -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
|
||||
|
|
53
index.js
53
index.js
|
@ -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.");
|
||||
cb(null);
|
||||
//});
|
||||
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);
|
||||
};
|
||||
|
|
21
package.json
21
package.json
|
@ -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)",
|
||||
|
|
Loading…
Reference in New Issue