🔐 Free SSL, Free Wildcard SSL, and Fully Automated HTTPS for node.js, issued by Let's Encrypt v2 via ACME https://git.rootprojects.org/root/greenlock.js
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

668 lines
23 KiB

пре 4 година
# New Documentation & [v4 Migration Guide](https://git.rootprojects.org/root/greenlock.js/src/branch/master/MIGRATION_GUIDE.md)
пре 5 година
пре 5 година
We're still working on the full documentation for this new version,
so please be patient.
To start, check out the
пре 4 година
[Migration Guide](https://git.rootprojects.org/root/greenlock.js/src/branch/master/MIGRATION_GUIDE.md).
пре 5 година
!["Greenlock Logo"](https://git.rootprojects.org/root/greenlock.js/raw/branch/master/logo/greenlock-1063x250.png 'Greenlock lock logo and work mark')
!["Greenlock Function"](https://git.rootprojects.org/root/greenlock.js/raw/branch/master/logo/from-not-secure-to-secure-url-bar.png 'from url bar showing not secure to url bar showing secure')
# [Greenlock](https://git.rootprojects.org/root/greenlock.js) is Let's Encrypt for JavaScript
| Built by [Root](https://rootprojects.org) for [Hub](https://rootprojects.org/hub/)
Greenlock™ is an Automated Certificate Management Environement 🔐.
пре 5 година
| **Greenlock** | [Greenlock Express](https://git.rootprojects.org/root/greenlock-express.js) | [ACME.js](https://git.rootprojects.org/root/acme.js) |
пре 5 година
It uses **Let's Encrypt** to generate Free SSL Certificates, including **Wildcard** SSL.
It supports **Automated Renewal** of certs for Fully Automated HTTPS.
It's written in plain JavaScript and works in Node, Browsers, and WebPack.
the easiest way to integrate Let's Encrypt into your projects, products, and infrastructure.
пре 5 година
пре 5 година
- [x] **Wildcard** Certificates
- [x] **IoT** Environments
- [x] **Enterprise** and **On-Prem**
- [x] **Private** Networks
- [x] **Localhost** Development
- [x] **Web Hosting** Providers
- [x] **Commercial** support
We've built it simple enough for Hobbyists, and robust enough for the Enterprise.
пре 5 година
<!--
пре 5 година
# Localhost Development
<details>
<summary>HTTPS on Localhost</summary>
TODO
</details>
# WebServer with Automatic HTTPS
<details>
<summary>Learn more about the Greenlock Web Server</summary>
TODO
</details>
# Commandline
<details>
<summary>Learn more about the Greenlock CLI</summary>
TODO
</details>
пре 5 година
-->
пре 5 година
# Quick Start
Greenlock is fully-automated, **SSL Certificate Manager** for IoT, Web Hosting, and Enterprise On-Prem, Edge, and Hybrid Cloud.
(though we started building it for [Home Servers](https://rootprojects.org/hub/))
You can use it for one-off certificates, like `certbot`,
but it is _much_ more powerful than that.
By setting just a few callbacks to let it know where it should store private keys and certificates,
it will automatically renew any certificate that you add to it, as long as the process is running.
Certificates are renewed every 45 days by default, and renewal checks will happen several times a day.
<details>
<summary>1. Configure</summary>
```js
'use strict';
var pkg = require('./package.json');
var Greenlock = require('greenlock');
var greenlock = Greenlock.create({
packageRoot: __dirname,
configDir: "./greenlock.d/",
пре 5 година
packageAgent: pkg.name + '/' + pkg.version,
maintainerEmail: pkg.author,
staging: true,
notify: function(event, details) {
if ('error' === event) {
// `details` is an error object in this case
console.error(details);
}
}
});
greenlock.manager
.defaults({
agreeToTerms: true,
subscriberEmail: 'webhosting@example.com'
})
.then(function(fullConfig) {
// ...
});
```
</details>
<details>
<summary>2. Add Domains</summary>
The `subject` (primary domain on certificate) will be the id,
so it's very important that the order of the given domains
be deterministic.
```js
var altnames = ['example.com', 'www.example.com'];
greenlock
.add({
subject: altnames[0],
altnames: altnames
})
.then(function() {
// saved config to db (or file system)
});
```
Issuance and renewal will start immediately, and run continually.
</details>
<details>
<summary>3. Test for Success</summary>
The `store` callbacks will be called every any of your certificates
are renewed.
However, you can do a quick one-off check with `get`.
It will return a certificate immediately (if available),
or wait for the renewal to complete (or for it to fail again).
```js
greenlock
.get({ servername: subject })
.then(function(pems) {
if (pems && pems.privkey && pems.cert && pems.chain) {
console.info('Success');
}
//console.log(pems);
})
.catch(function(e) {
console.error('Big bad error:', e.code);
console.error(e);
});
```
</details>
пре 5 година
# JavaScript API
пре 5 година
пре 5 година
<!--
пре 5 година
<details>
<summary>Greenlock API (shared among JS implementations)</summary>
пре 5 година
-->
пре 5 година
пре 5 година
<details>
пре 4 година
<summary>Greenlock.create({ configDir, packageAgent, maintainerEmail, staging })</summary>
пре 5 година
пре 5 година
## Greenlock.create()
пре 5 година
Creates an instance of greenlock with _environment_-level values.
пре 5 година
пре 5 година
```js
пре 5 година
var pkg = require('./package.json');
пре 5 година
var gl = Greenlock.create({
configDir: './greenlock.d/',
пре 4 година
пре 5 година
// Staging for testing environments
staging: true,
пре 5 година
пре 5 година
// This should be the contact who receives critical bug and security notifications
// Optionally, you may receive other (very few) updates, such as important new features
пре 5 година
maintainerEmail: 'jon@example.com',
пре 4 година
пре 5 година
// for an RFC 8555 / RFC 7231 ACME client user agent
packageAgent: pkg.name + '/' pkg.version
пре 5 година
});
```
| Parameter | Description |
| --------------- | ------------------------------------------------------------------------------------ |
пре 4 година
| configDir | the directory to use for file-based plugins |
пре 5 година
| maintainerEmail | the developer contact for critical bug and security notifications |
| packageAgent | if you publish your package for others to use, `require('./package.json').name` here |
пре 5 година
| staging | use the Let's Encrypt staging URL instead of the production URL |
| directoryUrl | for use with other (not Let's Encrypt) ACME services, and the Pebble test server |
пре 5 година
<!--
| maintainerUpdates | (default: false) receive occasional non-critical notifications |
maintainerUpdates: true // default: false
-->
пре 5 година
пре 5 година
</details>
<details>
<summary>Greenlock#manager.defaults()</summary>
пре 5 година
## Greenlock#manager.defaults()
пре 5 година
Acts as a getter when given no arguments.
Otherwise sets default, site-wide values as described below.
пре 5 година
```js
greenlock.manager.defaults({
пре 5 година
// The "Let's Encrypt Subscriber" (often the same as the maintainer)
// NOT the end customer (except where that is also the maintainer)
subscriberEmail: 'jon@example.com',
agreeToTerms: true
пре 5 година
challenges: {
"http-01": {
module: "acme-http-01-webroot",
webroot: "/path/to/webroot"
}
}
пре 5 година
});
```
пре 5 година
| Parameter | Description |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| agreeToTerms | (default: false) either 'true' or a function that presents the Terms of Service and returns it once accepted |
| challenges['http-01'] | provide an http-01 challenge module |
| challenges['dns-01'] | provide a dns-01 challenge module |
| challenges['tls-alpn-01'] | provide a tls-alpn-01 challenge module |
| challenges[type].module | the name of your challenge module |
| challenges[type].xxxx | module-specific options |
| renewOffset | **leave the default** Other than for testing, leave this at the default of 45 days before expiration date (`'-45d'`) . Can also be set like `5w`, meaning 5 weeks after issue date |
| servername | the default servername to use for non-sni requests (many IoT clients) |
| subscriberEmail | the contact who agrees to the Let's Encrypt Subscriber Agreement and the Greenlock Terms of Service<br>this contact receives renewal failure notifications |
| store | override the default storage module |
| store.module | the name of your storage module |
| store.xxxx | options specific to your storage module |
пре 5 година
пре 5 година
<!--
| serverId | an arbitrary name to distinguish this server within a cluster of servers |
-->
пре 5 година
пре 5 година
</details>
пре 5 година
<details>
<summary>Greenlock#add({ subject, altnames })</summary>
пре 5 година
## Greenlock#add()
пре 5 година
пре 5 година
Greenlock is a **Automated Certificate Management Environment**.
пре 5 година
Once you add a "site", it will begin to automatically renew, immediately.
The certificates will provided to the `store` callbacks as soon as they are ready, and whenever they renew.
Failure to renew will be reported to the `notify` callback.
You can also retrieve them one-off with `get`.
пре 5 година
```js
gl.add({
пре 5 година
subject: 'example.com',
altnames: ['example.com', 'www.example.com', 'exampleapi.com']
пре 5 година
});
пре 5 година
```
пре 5 година
| Parameter | Description |
| --------------- | -------------------------------------------------------------------------------------------- |
| subject | the first domain on, and identifier of the certificate |
| altnames | first domain, plus additional domains<br>note: the order should always be the same |
| subscriberEmail | if different from the default (i.e. multi-tenant, whitelabel) |
| challenges | (same as main config) use if this site needs to use non-default http-01 or dns-01 validation |
пре 5 година
пре 5 година
</details>
<details>
<summary>Greenlock#get({ servername })</summary>
пре 5 година
## Greenlock#get()
пре 5 година
**Disclaimer**: This is only intended for testing, demos, and SNICallback
(in [Greenlock Express](https://git.rootprojects.org/root/greenlock-express.js)).
Greenlock is intended to be left running to allow it to fetech and renew certifictates automatically.
It is intended that you use the `store` callbacks to new certificates instantly as soon as they renew.
This also protects you from accidentally stampeding the Let's Encrypt API with hundreds (or thousands)
of certificate requests.
- [Store Callback Documentation](https://git.rootprojects.org/root/greenlock-store-test.js)
```js
return greenlock.get({ servername }).then(function(site) {
пре 5 година
if (!site) {
console.log(servername + ' was not found in any site config');
return;
}
var privkey = site.pems.privkey;
var fullchain = site.pems.cert + '\n' + site.pems.chain + '\n';
console.log(privkey);
console.log(fullchain);
});
```
пре 5 година
| Parameter | Description |
| ---------- | ------------------------------------------------------------- |
| servername | any altname listed on the certificate (including the subject) |
</details>
<details>
пре 5 година
<summary>Greenlock#renew({ renewBefore })</summary>
пре 5 година
## Greenlock#renew()
пре 5 година
This will renew only domains that have reached their `renewAt` or are within the befault `renewOffset`.
пре 5 година
**Note**: This runs at regular intervals, multiple times a day, in the background.
You are not required to call it. If you implement the `store` callbacks, the certificates
will automatically be saved (and if you don't implement them, they all get saved to disk).
пре 5 година
```js
return greenlock.renew({}).then(function(results) {
пре 5 година
results.forEach(function(site) {
if (site.error) {
console.error(site.subject, site.error);
return;
}
console.log('Renewed certificate for', site.subject, site.altnames);
});
пре 5 година
});
пре 5 година
```
пре 5 година
| Parameter | Type | Description |
| ----------- | ---- | ------------------------------------------------------------------------------- |
| (optional) | | ALL parameters are optional, but some should be paired |
| force | bool | force silly options, such as tiny durations |
| renewBefore | ms | Check domains that are scheduled to renew before the given date in milliseconds |
пре 5 година
<!--
пре 5 година
| issuedBefore | ms | Check domains issued before the given date in milliseconds |
| expiresBefore | ms | Check domains that expire before the given date in milliseconds |
пре 5 година
-->
</details>
пре 5 година
<details>
<summary>Greenlock#remove({ subject })</summary>
## Greenlock#manager.remove()
To stop certificates from being renewed, you must remove them.
If you are implementing your own `manager` callbacks, I recommend that you mark them as deleted
(i.e. `deleted_at` in your database) rather than actually removing them. Just in case.
```js
gl.remove({
subject: 'example.com'
}).then(function(siteConfig) {
// save the old site config elsewhere, just in case you need it again
});
```
| Parameter | Description |
| --------- | ------------------------------------------------------ |
| subject | the first domain on, and identifier of the certificate |
</details>
пре 5 година
<details>
<summary>Events</summary>
Most of the events bubble from ACME.js.
See https://git.rootprojects.org/root/acme.js#api-overview
_TODO_: document the greenlock-specific events.
</details>
пре 5 година
<!--
пре 5 година
<details>
<summary>Node.js</summary>
пре 5 година
-->
# Install
Greenlock comes with reasonable defaults but when you install it,
you should also install any plugins that you need.
пре 5 година
пре 5 година
```bash
пре 4 година
npm install --save @root/greenlock@v4
npm install --save @greenlock/manager
пре 5 година
npm install --save greenlock-store-fs
npm install --save acme-http-01-standalone
пре 5 година
```
пре 5 година
пре 5 година
<!--
пре 5 година
TODO
</details>
<details>
<summary>Express.js</summary>
пре 5 година
пре 5 година
```js
'use strict';
var Greenlock = require(@root/greenlock-express);
var greenlock = Greenlock.create({
// for security and critical bug notices
maintainerEmail: 'jon@example.com'
// for
maintainerNewsletter: true
});
пре 5 година
```
пре 5 година
</details>
пре 5 година
пре 5 година
<details>
<summary>WebPack</summary>
TODO
</details>
пре 5 година
пре 5 година
<details>
<summary>VanillaJS for Browsers</summary>
TODO
</details>
пре 5 година
-->
пре 5 година
# Easy to Customize
<!-- greenlock-manager-test => greenlock-manager-custom -->
<!--
- [greenlock.js/examples/](https://git.rootprojects.org/root/greenlock.js/src/branch/master/examples)
-->
<details>
<summary>SSL Cert & Domain Management</summary>
пре 5 година
пре 5 година
## SSL Certificate & Domain Management
пре 5 година
Full Docs: https://git.rootprojects.org/root/greenlock-manager-test.js
This is what keeps the mapping of domains <-> certificates.
In many cases it will interact with the same database as the Key & Cert Store, and probably the code as well.
- set({ subject, altnames, renewAt })
пре 5 година
- find({ servernames, renewBefore })
пре 5 година
```js
// should return a list of site configs:
[
{
subject: 'example.com',
altnames: ['example.com', 'exampleapi.com'],
renewAt: 1575197231760
},
{
subject: '*.example.com',
altnames: ['*.example.com'],
renewAt: 1575197231760,
challenges: {
'dns-01': {
module: 'acme-dns-01-dnsimple',
apikey: 'xxxx'
}
}
}
];
```
- remove({ subject })
- defaults() (both getter and setter)
```json
{
"subscriberEmail": "jane@example.com",
"agreeToTerms": true,
"challenges": {
"http-01": {
"module": "acme-http-01-standalone"
}
}
}
```
</details>
<details>
<summary>Key & Cert Storage</summary>
пре 5 година
пре 5 година
## Key and Certificate Store
пре 5 година
Full Docs: https://git.rootprojects.org/root/greenlock-store-test.js
This set of callbacks update your service with new certificates and keypairs.
пре 5 година
### Account Keys (JWK)
пре 5 година
(though typically you only have one account key - because you only have one subscriber email)
- accounts.setKeypair({ email, keypair })
- accounts.checkKeypair({ email })
пре 5 година
### Certificate Keys (JWK + PEM)
пре 5 година
(typically you have one for each set of domains, and each load balancer)
- certificates.setKeypair({ subject, keypair })
- certificates.checkKeypair({ subject })
(these are fine to implement the same as above, swapping subject/email)
пре 5 година
### Certificate PEMs
пре 5 година
- certificates.set({ subject, pems })
- certificates.check({ subject })
</details>
<details>
<summary>ACME HTTP-01 Challenges</summary>
пре 5 година
пре 5 година
## ACME Challenge HTTP-01 Strategies
пре 5 година
Full Docs: https://git.rootprojects.org/root/acme-http-01-test.js
This validation and authorization strategy is done over plain HTTP on Port 80.
These are used to set files containing tokens that Let's Encrypt will fetch from each domain
before authorizing a certificate.
**NOT for Wildcards**.
- init({ request })
- set({ challenge: { type, token, keyAuthorization, challengeUrl } })
- get({ challenge: { type, token } })
- remove({ challenge: { type, token } })
<!--
TODO: getAcmeHttp01Challenge
-->
</details>
<details>
<summary>ACME DNS-01 Challenges</summary>
пре 5 година
пре 5 година
## ACME Challenge DNS-01 Strategies
пре 5 година
Full Docs https://git.rootprojects.org/root/acme-dns-01-test.js
This validation and authorization strategy is done over DNS on UDP and TCP ports 53.
**For Wildcards**
These are used to set TXT records containing tokens that Let's Encrypt will fetch for
each domain before authorizing a certificate.
- init({ request })
- zones()
- set({ challenge: { type, dnsZone, dnsPrefix, dnsHost, keyAuthorizationDigest } })
- get({ challenge: { type, dnsZone, dnsPrefix, dnsHost } })
- remove({ challenge: { type, dnsZone, dnsPrefix, dnsHost } })
</details>
пре 5 година
<details>
<summary>Notes on HTTP-01 &amp; DNS-01 Integrations</summary>
пре 5 година
## Notes on HTTP-01 &amp; DNS-01 Integrations
пре 5 година
For Public Web Servers running on a VPS, the **default HTTP-01 challenge plugin**
пре 5 година
will work just fine, for most people.
пре 5 година
пре 5 година
However, for environments that cannot be verified via public HTTP, such as
пре 5 година
пре 5 година
- **Wildcard Certificates**
- **IoT Environments**
- **Enterprise On-Prem**
- **Private Networks**
Greenlock provides an easy way to integrate Let's Encrypt with your existing services
пре 5 година
through a variety of **DNS-01** challenges.
### Why not use dns01 for everything?
пре 5 година
Typically file propagation is faster and more reliably than DNS propagation.
Therefore, http-01 will be preferred to dns-01 except when wildcards or **private domains** are in use.
http-01 will only be supplied as a defaut if no other challenge is provided.
</details>
# Ready-made Integrations
Greenlock Express integrates between Let's Encrypt's ACME Challenges and many popular services.
| Type | Service | Plugin |
| ----------- | ----------------------------------------------------------------------------------- | ------------------------ |
| dns-01 | CloudFlare | acme-dns-01-cloudflare |
| dns-01 | [Digital Ocean](https://git.rootprojects.org/root/acme-dns-01-digitalocean.js) | acme-dns-01-digitalocean |
| dns-01 | [DNSimple](https://git.rootprojects.org/root/acme-dns-01-dnsimple.js) | acme-dns-01-dnsimple |
| dns-01 | [DuckDNS](https://git.rootprojects.org/root/acme-dns-01-duckdns.js) | acme-dns-01-duckdns |
| http-01 | File System / [Web Root](https://git.rootprojects.org/root/acme-http-01-webroot.js) | acme-http-01-webroot |
| dns-01 | [GoDaddy](https://git.rootprojects.org/root/acme-dns-01-godaddy.js) | acme-dns-01-godaddy |
| dns-01 | [Gandi](https://git.rootprojects.org/root/acme-dns-01-gandi.js) | acme-dns-01-gandi |
| dns-01 | [NameCheap](https://git.rootprojects.org/root/acme-dns-01-namecheap.js) | acme-dns-01-namecheap |
| dns-01 | [Name&#46;com](https://git.rootprojects.org/root/acme-dns-01-namedotcom.js) | acme-dns-01-namedotcom |
| dns-01 | Route53 (AWS) | acme-dns-01-route53 |
| http-01 | S3 (AWS, Digital Ocean, Scaleway) | acme-http-01-s3 |
| dns-01 | [Vultr](https://git.rootprojects.org/root/acme-dns-01-vultr.js) | acme-dns-01-vultr |
| dns-01 | [Build your own](https://git.rootprojects.org/root/acme-dns-01-test.js) | acme-dns-01-test |
| http-01 | [Build your own](https://git.rootprojects.org/root/acme-http-01-test.js) | acme-http-01-test |
| tls-alpn-01 | [Contact us](mailto:support@therootcompany.com) | - |
Search `acme-http-01-` or `acme-dns-01-` on npm to find more.
пре 5 година
пре 5 година
# Commercial Support
Do you need...
- training?
- specific features?
- different integrations?
- bugfixes, on _your_ timeline?
- custom code, built by experts?
- commercial support and licensing?
You're welcome to [contact us](mailto:aj@therootcompany.com) in regards to IoT, On-Prem,
Enterprise, and Internal installations, integrations, and deployments.
We have both commercial support and commercial licensing available.
We also offer consulting for all-things-ACME and Let's Encrypt.
# Legal &amp; Rules of the Road
Greenlock&trade; is a [trademark](https://rootprojects.org/legal/#trademark) of AJ ONeal
The rule of thumb is "attribute, but don't confuse". For example:
> Built with [Greenlock Express](https://git.rootprojects.org/root/greenlock.js) (a [Root](https://rootprojects.org) project).
Please [contact us](mailto:aj@therootcompany.com) if you have any questions in regards to our trademark,
attribution, and/or visible source policies. We want to build great software and a great community.
[Greenlock&trade;](https://git.rootprojects.org/root/greenlock.js) |
MPL-2.0 |
[Terms of Use](https://therootcompany.com/legal/#terms) |
[Privacy Policy](https://therootcompany.com/legal/#privacy)