2019-04-16 05:45:12 +00:00
|
|
|
# [greenlock-store-fs](https://git.rootprojects.org/root/greenlock-store-fs.js) | A [Root](https://rootprojects.org) project
|
2019-04-08 06:14:28 +00:00
|
|
|
|
|
|
|
A keypair and certificate storage strategy for Greenlock v2.7+ (and v3).
|
|
|
|
The (much simpler) successor to le-store-certbot.
|
|
|
|
|
|
|
|
Works with all ACME (Let's Encrypt) SSL certificate sytles:
|
2019-11-02 18:38:12 +00:00
|
|
|
|
|
|
|
- [x] single domains
|
|
|
|
- [x] multiple domains (SANs, AltNames)
|
|
|
|
- [x] wildcards
|
|
|
|
- [x] private / localhost domains
|
2019-04-01 07:56:41 +00:00
|
|
|
|
|
|
|
# Usage
|
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
**Global** config:
|
|
|
|
|
2019-04-01 07:56:41 +00:00
|
|
|
```js
|
2019-11-02 19:26:08 +00:00
|
|
|
greenlock.manager.defaults({
|
|
|
|
store: {
|
|
|
|
module: "greenlock-store-fs",
|
|
|
|
basePath: "~/.config/greenlock"
|
|
|
|
}
|
2019-04-01 07:56:41 +00:00
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
**Per-site** config:
|
2019-04-01 07:56:41 +00:00
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
```js
|
|
|
|
greenlock.add({
|
|
|
|
subject: "example.com",
|
|
|
|
altnames: ["example.com", "www.example.com"],
|
|
|
|
store: {
|
|
|
|
module: "greenlock-store-fs",
|
|
|
|
basePath: "~/.config/greenlock"
|
|
|
|
}
|
|
|
|
});
|
2019-04-01 07:56:41 +00:00
|
|
|
```
|
2019-11-02 19:26:08 +00:00
|
|
|
|
|
|
|
# File System
|
|
|
|
|
|
|
|
The default file system layout mirrors that of certbot (python Let's Encrypt implementation) and
|
|
|
|
the prior le-store-certbot in order to make transitioning effortless.
|
|
|
|
|
|
|
|
The default structure looks like this:
|
|
|
|
|
|
|
|
```txt
|
|
|
|
.config
|
|
|
|
└── greenlock
|
|
|
|
├── accounts
|
|
|
|
│ └── acme-staging-v02.api.letsencrypt.org
|
|
|
|
│ └── directory
|
|
|
|
│ └── sites@example.com.json
|
|
|
|
├── staging
|
|
|
|
│ └── (same as live)
|
|
|
|
└── live
|
|
|
|
├── example.com
|
|
|
|
│ ├── bundle.pem
|
|
|
|
│ ├── cert.pem
|
|
|
|
│ ├── chain.pem
|
|
|
|
│ ├── fullchain.pem
|
|
|
|
│ └── privkey.pem
|
|
|
|
└── www.example.com
|
|
|
|
├── bundle.pem
|
|
|
|
├── cert.pem
|
|
|
|
├── chain.pem
|
|
|
|
├── fullchain.pem
|
|
|
|
└── privkey.pem
|
2019-04-01 07:56:41 +00:00
|
|
|
```
|
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
# Internal Implementation Details
|
2019-04-01 07:56:41 +00:00
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
You **DO NOT NEED TO KNOW** these details.
|
2019-04-01 07:56:41 +00:00
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
They're provided for the sake of understanding what happens "under the hood"
|
|
|
|
to help you make better choices "in the seat".
|
2019-04-01 07:56:41 +00:00
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
# Parameters
|
2019-04-01 07:56:41 +00:00
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
| parameters | example | notes |
|
|
|
|
| ----------------- | -------------------------------------------------------- | ---------------- |
|
|
|
|
| `env` | `staging` or `live` | - |
|
|
|
|
| `directoryUrl` | `https://acme-staging-v02.api.letsencrypt.org/directory` | - |
|
|
|
|
| `keypair` | `{ privateKeyPem, privateKeyJwk }` | |
|
|
|
|
| `account` | `{ id: "an-arbitrary-id" }` | account only |
|
|
|
|
| `subscriberEmail` | `webhost@example.com` | account only |
|
|
|
|
| `certificate` | `{ id: "an-arbitrary-id" }` | certificate only |
|
|
|
|
| `subject` | `example.com` | certificate only |
|
|
|
|
| `pems` | `{ privkey, cert, chain, issuedAt, expiresAt }` | certificate only |
|
2019-04-01 07:56:41 +00:00
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
### Account Keypair
|
2019-04-01 07:56:41 +00:00
|
|
|
|
|
|
|
```js
|
2019-11-02 19:26:08 +00:00
|
|
|
accounts.setKeypair = async function({
|
|
|
|
env,
|
|
|
|
basePath,
|
|
|
|
directoryUrl,
|
|
|
|
email,
|
|
|
|
account
|
|
|
|
}) {
|
|
|
|
var id = account.id || email;
|
|
|
|
var serverDir = directoryUrl.replace("https://", "");
|
|
|
|
};
|
|
|
|
```
|
2019-11-02 18:38:12 +00:00
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
```js
|
|
|
|
accounts.checkKeypair = async function({
|
|
|
|
env,
|
|
|
|
basePath,
|
|
|
|
directoryUrl,
|
|
|
|
email,
|
|
|
|
account
|
|
|
|
}) {
|
|
|
|
var id = account.id || email;
|
|
|
|
var serverDir = directoryUrl.replace("https://", "");
|
|
|
|
|
|
|
|
return {
|
|
|
|
privateKeyPem,
|
|
|
|
privateKeyJwk
|
2019-11-02 18:38:12 +00:00
|
|
|
};
|
2019-11-02 19:26:08 +00:00
|
|
|
};
|
2019-04-01 07:56:41 +00:00
|
|
|
```
|
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
### Certificate Keypair
|
2019-04-01 07:56:41 +00:00
|
|
|
|
|
|
|
```js
|
2019-11-02 19:26:08 +00:00
|
|
|
certificate.setKeypair = async function({
|
|
|
|
env,
|
|
|
|
basePath,
|
|
|
|
directoryUrl,
|
|
|
|
subject,
|
|
|
|
certificate
|
|
|
|
}) {
|
|
|
|
var id = account.id || email;
|
|
|
|
env = env || directoryUrl.replace("https://", "");
|
|
|
|
};
|
|
|
|
```
|
2019-04-01 07:56:41 +00:00
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
```js
|
|
|
|
certificate.checkKeypair = async function({
|
|
|
|
env,
|
|
|
|
basePath,
|
|
|
|
directoryUrl,
|
|
|
|
subject,
|
|
|
|
certificate
|
|
|
|
}) {
|
|
|
|
var id = account.id || email;
|
|
|
|
env = env || directoryUrl.replace("https://", "");
|
|
|
|
|
|
|
|
return {
|
|
|
|
privateKeyPem,
|
|
|
|
privateKeyJwk
|
|
|
|
};
|
|
|
|
};
|
2019-04-01 07:56:41 +00:00
|
|
|
```
|
|
|
|
|
2019-11-02 19:26:08 +00:00
|
|
|
### Certificate PEMs
|
|
|
|
|
2019-04-01 07:56:41 +00:00
|
|
|
```js
|
2019-11-02 19:26:08 +00:00
|
|
|
certificate.set = async function({
|
|
|
|
env,
|
|
|
|
basePath,
|
|
|
|
directoryUrl,
|
|
|
|
subject,
|
|
|
|
certificate,
|
|
|
|
pems
|
|
|
|
}) {
|
|
|
|
var id = account.id || email;
|
|
|
|
env = env || directoryUrl.replace("https://", "");
|
|
|
|
};
|
2019-04-01 07:56:41 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
```js
|
2019-11-02 19:26:08 +00:00
|
|
|
certificate.check = async function({
|
|
|
|
env,
|
|
|
|
basePath,
|
|
|
|
directoryUrl,
|
|
|
|
subject,
|
|
|
|
certificate
|
|
|
|
}) {
|
|
|
|
var id = account.id || email;
|
|
|
|
env = env || directoryUrl.replace("https://", "");
|
|
|
|
|
|
|
|
return {
|
|
|
|
privkey,
|
|
|
|
cert,
|
|
|
|
chain,
|
|
|
|
issuedAt,
|
|
|
|
expiresAt
|
|
|
|
};
|
2019-11-02 18:38:12 +00:00
|
|
|
};
|
2019-04-01 07:56:41 +00:00
|
|
|
```
|