Updated documentation.
This commit is contained in:
196
README.md
196
README.md
@@ -2,22 +2,23 @@
|
|||||||
|
|
||||||
This repository contains a simple CLI tool for managing a Certificate Authority (CA).
|
This repository contains a simple CLI tool for managing a Certificate Authority (CA).
|
||||||
|
|
||||||
It has been designed to be as easy to use as possible and provides a basic set of CA features:
|
It is designed to be easy to use and provides a basic set of CA features:
|
||||||
|
|
||||||
- Create a CA and a self-signed CA certificate
|
- Create a CA and a self-signed CA certificate
|
||||||
- Create and sign a few most common types of certificates:
|
- Create and sign common types of certificates:
|
||||||
- Server certificate
|
- Server certificate
|
||||||
- Client certificate
|
- Client certificate
|
||||||
- Code signing certificate
|
- Code signing certificate
|
||||||
- Email certificate
|
- Email certificate
|
||||||
- Sign a CSR to create a certificate
|
|
||||||
- Revoke a certificate
|
- Revoke a certificate
|
||||||
- List issued certificates
|
- List issued certificates
|
||||||
- Create a CRL (Certificate Revocation List)
|
- Create a CRL (Certificate Revocation List)
|
||||||
|
|
||||||
|
> **NOTE:** Certificate types can be combined (e.g. `server,client`).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The tool is designed to be used from the command line. It has a simple command structure:
|
The tool is used from the command line. It has a simple command structure:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
lab-ca <command> [options]
|
lab-ca <command> [options]
|
||||||
@@ -25,23 +26,26 @@ lab-ca <command> [options]
|
|||||||
|
|
||||||
The main commands available are:
|
The main commands available are:
|
||||||
|
|
||||||
- `initca` — Initialize a new CA and create a self-signed CA certificate.
|
- `initca` — Initialize a new CA and create a self-signed CA certificate and key.
|
||||||
- `issue` — Issue a new certificate signed by the CA.
|
- `issue` — Issue a new certificate signed by the CA (single certificate, command-line options).
|
||||||
- `provision` — Provision multiple certificates from a batch file (HCL) in one go.
|
- `provision` — Provision multiple certificates from a batch file (HCL) in one go.
|
||||||
- `revoke` — Revoke a certificate by name or serial number.
|
- `revoke` — Revoke a certificate by name or serial number.
|
||||||
- `crl` — Generate a Certificate Revocation List (CRL) from revoked certificates.
|
- `crl` — Generate a Certificate Revocation List (CRL) from revoked certificates.
|
||||||
|
- `list` — List issued certificates (optionally including revoked).
|
||||||
- `version` — Show version information for the tool.
|
- `version` — Show version information for the tool.
|
||||||
|
|
||||||
Run the command with `-h` or `--help` or without any arguments to see the usage information. Each command has its own set of options, arguments, and a help message.
|
Run the command with `-h` or `--help` or without any arguments to see usage information. Each command has its own set of options, arguments, and a help message.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### CA Initialization
|
### CA Initialization
|
||||||
|
|
||||||
Create a new CA configuration file:
|
Create a new CA configuration file (HCL):
|
||||||
|
|
||||||
```
|
```hcl
|
||||||
ca "example_ca" {
|
ca "example_ca" {
|
||||||
name = "Example CA"
|
name = "Example CA"
|
||||||
country = "PL"
|
country = "US"
|
||||||
organization = "ACME Corp"
|
organization = "ACME Corp"
|
||||||
key_size = 4096
|
key_size = 4096
|
||||||
validity = "10y"
|
validity = "10y"
|
||||||
@@ -49,72 +53,178 @@ ca "example_ca" {
|
|||||||
paths {
|
paths {
|
||||||
certificates = "certs"
|
certificates = "certs"
|
||||||
private_keys = "private"
|
private_keys = "private"
|
||||||
|
state_file = "ca_state.json"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> **NOTE:** `lab-ca` uses HCL (HashiCorp Configuration Language) for configuration files. You can find more information about HCL [here](https://github.com/hashicorp/hcl).
|
- The `ca` block's label is used as a logical name for the CA and for the default state file name.
|
||||||
|
- The `paths` block defines where certificates, private keys, and the CA state file are stored.
|
||||||
|
- On Linux/macOS, the private keys directory is created with `0700` permissions.
|
||||||
|
- The command does not encrypt private keys. Do not use in production.
|
||||||
|
|
||||||
The `ca` block's label has no function, but may be used to identify the CA in the future.
|
---
|
||||||
|
|
||||||
The following attributes are available:
|
### Listing Certificates
|
||||||
|
|
||||||
- `name` - the name of the CA
|
List all issued (non-revoked) certificates:
|
||||||
- `country` - the country of the CA
|
|
||||||
- `organization` - the organization of the CA
|
|
||||||
- `organizational_unit` - the organizational unit of the CA (optional)
|
|
||||||
- `locality` - the locality of the CA (optional)
|
|
||||||
- `province` - the province of the CA (optional)
|
|
||||||
- `email` - the email address of the CA (optional)
|
|
||||||
- `key_size` - the size of the CA key in bits (default: 4096)
|
|
||||||
- `validity` - the validity period of the CA certificate (default: 10 years)
|
|
||||||
- `paths` - paths to store certificates and private keys
|
|
||||||
|
|
||||||
The `paths` block defines where the command will store the generated certificates and private keys. On Linux and macOS, the directory specified for private keys will be created with `0700` permissions. However, the command does not check if the directory has correct permissions, so you should ensure that the directory is not accessible by other users. On Windows, both directories will be created with the default ACL for the current user. You have to secure the private keys directory yourself.
|
```bash
|
||||||
|
lab-ca list
|
||||||
|
```
|
||||||
|
|
||||||
> **NOTE:** The command does not encrypt private keys. It is not designed to be used in a production environment.
|
To include revoked certificates:
|
||||||
|
|
||||||
## Certificate Issuance and Provisioning
|
```bash
|
||||||
|
lab-ca list --revoked
|
||||||
|
```
|
||||||
|
|
||||||
To issue a new certificate, you can use the `issue` command and specify the certificate definition on the command line, or use the `provision` command to provide a file with multiple certificate definitions for batch processing.
|
---
|
||||||
|
|
||||||
The definition file also uses HCL syntax. Here is an example of a certificate definition file:
|
### Issuing a Certificate
|
||||||
|
|
||||||
|
Issue a new certificate from the command line:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lab-ca issue --name <name> [--subject <subject>] [--type <type>] [--validity <period>] [--san <SAN> ...] [--overwrite] [--dry-run] [--verbose]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `--name` (required): Name for the certificate and key files (used as subject if `--subject` is omitted)
|
||||||
|
- `--subject`: Subject Common Name or full DN (optional, defaults to `--name`)
|
||||||
|
- `--type`: Certificate type: `client`, `server`, `code-signing`, `email` (comma-separated for multiple usages; default: `server`)
|
||||||
|
- `--validity`: Validity period (e.g. `2y`, `6m`, `30d`; default: `1y`)
|
||||||
|
- `--san`: Subject Alternative Name (repeatable; e.g. `dns:example.com`, `ip:1.2.3.4`, `email:user@example.com`)
|
||||||
|
- `--overwrite`: Allow overwriting existing files
|
||||||
|
- `--dry-run`: Validate and show what would be created, but do not write files
|
||||||
|
- `--verbose`: Print detailed information
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Provisioning Certificates (Batch)
|
||||||
|
|
||||||
|
Provision multiple certificates from a batch file (HCL):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lab-ca provision --file <certificates.hcl> [--overwrite] [--verbose]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Example HCL Provisioning File
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
defaults {
|
defaults {
|
||||||
subject = "{{ .Name }}.example.org"
|
subject = "{{ .Name }}.example.org"
|
||||||
type = "server"
|
type = "server,client"
|
||||||
validity = "1y"
|
validity = "1y"
|
||||||
san = ["DNS:{{ .Name }}.example.org"]
|
san = ["DNS:{{ .Name }}.example.org"]
|
||||||
}
|
}
|
||||||
|
|
||||||
variables = {
|
variables = {
|
||||||
Domain = "example.net"
|
Domain = "example.net"
|
||||||
Country = "EX"
|
Country = "EX"
|
||||||
}
|
}
|
||||||
|
|
||||||
certificate "service1" {
|
certificate "service1" {
|
||||||
# from default: subject = "{{ .Name }}.example.org"
|
# from default: subject = "{{ .Name }}.example.org"
|
||||||
# from default: type = "server"
|
# from default: type = "server,client"
|
||||||
# from default: validity = "1y"
|
# from default: validity = "1y"
|
||||||
# from default: san = ["DNS:{{ .Name }}.example.org"]
|
# from default: san = ["DNS:service1.example.org"]
|
||||||
}
|
}
|
||||||
|
|
||||||
certificate "service2" {
|
certificate "service2" {
|
||||||
subject = "{{ .Name }}.example.net"
|
subject = "{{ .Name }}.{{ .Domain }}" # result: service2.example.net
|
||||||
# from default: type = "server"
|
san = ["DNS:{{ .Name }}.{{ .Domain }}"] # result: [ "DNS:service2.example.net" ]
|
||||||
# from default: validity = "1y"
|
|
||||||
san = ["DNS:{{ .Name }}.example.net"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
certificate "service3" {}
|
certificate "service3" {}
|
||||||
|
|
||||||
certificate "service4" {
|
certificate "user1" {
|
||||||
subject = "{{ .Name }}.{{ .Domain }}"
|
subject = "CN=User One,emailAddress=user1@example.org,O=Example,C=US"
|
||||||
san = ["DNS:{{ .Name }}.{{ .Domain }}"]
|
type = "client,email"
|
||||||
|
validity = "1y"
|
||||||
|
san = ["email:user1@example.net"]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Values specified in the `defaults` block will be used for all certificates unless overridden in individual certificate definitions. Go-style template syntax is also supported, so you can use `{{ .Name }}` to refer to the certificate name, and variables from the `variables` map can be used in templates as well.
|
- The `defaults` block provides default values for all certificates unless overridden.
|
||||||
|
- The `variables` map can be used in Go template expressions in any field.
|
||||||
|
- Each `certificate` block defines a certificate to be issued. The block label is available as `{{ .Name }}` in templates.
|
||||||
|
- Fields:
|
||||||
|
- `subject`: Subject string (can be a template)
|
||||||
|
- `type`: Comma-separated usages (server, client, code-signing, email)
|
||||||
|
- `validity`: Validity period (e.g. `1y`, `6m`, `30d`)
|
||||||
|
- `san`: List of SANs (e.g. `DNS:...`, `IP:...`, `email:...`)
|
||||||
|
|
||||||
You can use DNS or IP SANs for server certificates (`server` and `server-only`), and email SANs for email certificates (`email`). The command will check if the SAN is valid based on the type of certificate.
|
---
|
||||||
|
|
||||||
|
### Revoking a Certificate
|
||||||
|
|
||||||
|
Revoke a certificate by name or serial number:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lab-ca revoke --name <name> [--reason <reason>]
|
||||||
|
lab-ca revoke --serial <serial> [--reason <reason>]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `--reason` can be one of: `unspecified`, `keyCompromise`, `caCompromise`, `affiliationChanged`, `superseded`, `cessationOfOperation`, `certificateHold`, `removeFromCRL` (default: `cessationOfOperation`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Generating a CRL
|
||||||
|
|
||||||
|
Generate a Certificate Revocation List (CRL) from revoked certificates:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lab-ca crl [--crl-file <path>] [--validity-days <days>]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `--crl-file`: Output path for CRL file (default: `crl.pem`)
|
||||||
|
- `--validity-days`: CRL validity in days (default: 30)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Version
|
||||||
|
|
||||||
|
Show version information:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lab-ca version
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration and Templates
|
||||||
|
|
||||||
|
- All configuration and provisioning files use HCL (HashiCorp Configuration Language).
|
||||||
|
- Go template syntax is supported in `subject`, `san`, and other string fields. The following variables are available:
|
||||||
|
- `.Name`: The certificate name (from the block label)
|
||||||
|
- Any key from the `variables` map
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
subject = "{{ .Name }}.{{ .Domain }}"
|
||||||
|
san = ["DNS:{{ .Name }}.{{ .Domain }}"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Certificate Types and SANs
|
||||||
|
|
||||||
|
- `server`: For server certificates. SANs should be DNS or IP.
|
||||||
|
- `client`: For client certificates. SANs can be email or DNS.
|
||||||
|
- `email`: For S/MIME/email certificates. SANs should be email.
|
||||||
|
- `code-signing`: For code signing certificates.
|
||||||
|
|
||||||
|
The tool checks that SANs are valid for the selected certificate type(s). Certificate usage can be combined (e.g. `server,client`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example: Real-World Provisioning File
|
||||||
|
|
||||||
|
See `examples/example-certificates.hcl` for a more advanced provisioning file with templates and variables.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The tool does not encrypt private keys. Protect your private keys directory.
|
||||||
|
- Not intended for production use.
|
||||||
|
- For more information about HCL, see: https://github.com/hashicorp/hcl
|
||||||
|
Reference in New Issue
Block a user