Files
lab-ca/README.md

241 lines
6.8 KiB
Markdown

# Lab CA
This repository contains a simple CLI tool for managing a Certificate Authority (CA).
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 and sign common types of certificates:
- Server certificate
- Client certificate
- Code signing certificate
- Email certificate
- Revoke a certificate
- List issued certificates
- Create a CRL (Certificate Revocation List)
> **NOTE:** Certificate types can be combined (e.g. `server,client`).
## Usage
The tool is used from the command line. It has a simple command structure:
```bash
lab-ca <command> [options]
```
The main commands available are:
- `initca` — Initialize a new CA and create a self-signed CA certificate and key.
- `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.
- `revoke` — Revoke a certificate by name or serial number.
- `crl` — Generate a Certificate Revocation List (CRL) from revoked certificates.
- `list` — List issued certificates (optionally including revoked).
- `version` — Show version information for the tool.
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
Create a new CA configuration file (HCL):
```hcl
ca "example_ca" {
name = "Example CA"
country = "US"
organization = "ACME Corp"
key_size = 4096
validity = "10y"
paths {
certificates = "certs"
private_keys = "private"
state_file = "ca_state.json"
}
}
```
- 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.
---
### Listing Certificates
List all issued (non-revoked) certificates:
```bash
lab-ca list
```
To include revoked certificates:
```bash
lab-ca list --revoked
```
---
### 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
defaults {
subject = "{{ .Name }}.example.org"
type = "server,client"
validity = "1y"
san = ["DNS:{{ .Name }}.example.org"]
}
variables = {
Domain = "example.net"
Country = "EX"
}
certificate "service1" {
# from default: subject = "{{ .Name }}.example.org"
# from default: type = "server,client"
# from default: validity = "1y"
# from default: san = ["DNS:service1.example.org"]
}
certificate "service2" {
subject = "{{ .Name }}.{{ .Domain }}" # result: service2.example.net
san = ["DNS:{{ .Name }}.{{ .Domain }}"] # result: [ "DNS:service2.example.net" ]
}
certificate "service3" {}
certificate "user1" {
subject = "CN=User One,emailAddress=user1@example.org,O=Example,C=US"
type = "client,email"
validity = "1y"
san = ["email:user1@example.net"]
}
```
- 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:...`)
---
### 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.
## Building the Tool
The repository includes a `build.sh` script to build the CLI tool. It updates the version in `version.go` and builds the binary.
To ignore changes made to `version.go` in Git, you can run:
```bash
git update-index --assume-unchanged version.go
```
---
## 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