192 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # [greenlock-store-fs](https://git.rootprojects.org/root/greenlock-store-fs.js) | A [Root](https://rootprojects.org) project
 | |
| 
 | |
| 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
 | |
| 
 | |
| # Usage
 | |
| 
 | |
| **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"
 | |
|     }
 | |
| });
 | |
| ```
 | |
| 
 | |
| # 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
 | |
| ```
 | |
| 
 | |
| # Internal Implementation Details
 | |
| 
 | |
| 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
 | |
| 
 | |
| | 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 |
 | |
| 
 | |
| ### Account Keypair
 | |
| 
 | |
| ```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
 | |
|     };
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### Certificate Keypair
 | |
| 
 | |
| ```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
 | |
|     };
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### Certificate PEMs
 | |
| 
 | |
| ```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
 | |
|     };
 | |
| };
 | |
| ```
 |