A file-based certificate store for greenlock that supports wildcards.
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:
- [x] single domains
- [x] multiple domains (SANs, AltNames)
- [x] wildcards
- [x] private / localhost domains
Global config:
``js`
greenlock.manager.defaults({
store: {
module: "greenlock-store-fs",
basePath: "~/.config/greenlock"
}
});
Per-site config:
`js`
greenlock.add({
subject: "example.com",
altnames: ["example.com", "www.example.com"],
store: {
module: "greenlock-store-fs",
basePath: "~/.config/greenlock"
}
});
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
You DO NOT NEED TO KNOW these details.
They're provided for the sake of understanding what happens "under the hood"
to help you make better choices "in the seat".
| 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 |
`js`
accounts.setKeypair = async function({
env,
basePath,
directoryUrl,
email,
account
}) {
var id = account.id || email;
var serverDir = directoryUrl.replace("https://", "");
};
`js
accounts.checkKeypair = async function({
env,
basePath,
directoryUrl,
email,
account
}) {
var id = account.id || email;
var serverDir = directoryUrl.replace("https://", "");
return {
privateKeyPem,
privateKeyJwk
};
};
`
`js`
certificate.setKeypair = async function({
env,
basePath,
directoryUrl,
subject,
certificate
}) {
var id = account.id || email;
env = env || directoryUrl.replace("https://", "");
};
`js
certificate.checkKeypair = async function({
env,
basePath,
directoryUrl,
subject,
certificate
}) {
var id = account.id || email;
env = env || directoryUrl.replace("https://", "");
return {
privateKeyPem,
privateKeyJwk
};
};
`
`js`
certificate.set = async function({
env,
basePath,
directoryUrl,
subject,
certificate,
pems
}) {
var id = account.id || email;
env = env || directoryUrl.replace("https://", "");
};
`js
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
};
};
``