feat: add Makefile and README.md for Step-CA Docker stack setup
This commit is contained in:
288
README.md
Normal file
288
README.md
Normal file
@@ -0,0 +1,288 @@
|
||||
# Step-CA Docker Stack
|
||||
|
||||
A Docker Compose setup for deploying [Smallstep CA](https://smallstep.com/certificates/) (step-ca) with PostgreSQL backend support for certificate management and PKI infrastructure.
|
||||
|
||||
## Features
|
||||
|
||||
- **Automated Initialization**: Automatic step-ca setup with optional SSH and ACME support
|
||||
- **PostgreSQL Backend**: Uses PostgreSQL as the primary database (replacing the default Badger)
|
||||
- **Health Checks**: Built-in health checks for PostgreSQL service
|
||||
- **Customizable Configuration**: Full environment variable support for customization
|
||||
- **Docker Build**: Custom Dockerfile with jq for JSON manipulation
|
||||
- **Remote Management**: Support for remote management capabilities
|
||||
- **Admin Provisioner**: Built-in JWK admin provisioner for certificate issuance
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker
|
||||
- Docker Compose
|
||||
- Basic knowledge of step-ca and PKI concepts
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Clone and Setup
|
||||
|
||||
```bash
|
||||
cd /path/to/step-ca
|
||||
cp .env.example .env
|
||||
# Edit .env with your specific configuration
|
||||
```
|
||||
|
||||
### 2. Configure Environment
|
||||
|
||||
Edit `.env` file with your desired configuration:
|
||||
|
||||
```env
|
||||
# PostgreSQL Configuration
|
||||
POSTGRES_PASSWORD=your_secure_password
|
||||
|
||||
# Step-CA Configuration
|
||||
STEP_CA_IP=192.168.1.100
|
||||
STEP_CA_PORT=9000
|
||||
STEP_CA_NAME=My Internal CA
|
||||
STEP_CA_ISSUER=CN=My Internal CA, O=MyOrg, C=US
|
||||
STEP_CA_DNS_NAMES=ca.example.com,ca.internal,pki.local
|
||||
STEP_CA_PROVISIONER=admin-provisioner
|
||||
STEP_CA_ADMIN_SUBJECT=admin@example.com
|
||||
STEP_CA_SSH=true
|
||||
STEP_CA_ACME=true
|
||||
STEP_CA_REMOTE_MANAGEMENT=true
|
||||
|
||||
# DNS Configuration
|
||||
DNS_1=8.8.8.8
|
||||
DNS_2=8.8.4.4
|
||||
DNS_SEARCH_1=example.com
|
||||
DNS_SEARCH_2=internal.local
|
||||
```
|
||||
|
||||
### 3. Initialize Secrets
|
||||
|
||||
Create the required secret files. These are mounted as Docker secrets at `/run/secrets/` inside containers:
|
||||
|
||||
```bash
|
||||
mkdir -p secrets
|
||||
|
||||
echo "your_secure_password" > secrets/postgres_password.txt
|
||||
|
||||
echo "your_ca_password" > secrets/step_pwd.txt
|
||||
|
||||
chmod 600 secrets/*.txt
|
||||
```
|
||||
|
||||
**Important**: These secrets are automatically mounted by Docker Compose:
|
||||
- `secrets/postgres_password.txt` → `/run/secrets/postgres_password`
|
||||
- `secrets/step_pwd.txt` → `/run/secrets/password`
|
||||
|
||||
or just `make configure`
|
||||
|
||||
### 4. Start the Stack
|
||||
|
||||
```bash
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
### 5. Verify Deployment
|
||||
|
||||
```bash
|
||||
docker-compose logs -f step-ca
|
||||
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
All configuration is managed through the `.env` file. Key variables:
|
||||
|
||||
| Variable | Description | Default | Example |
|
||||
|----------|-------------|---------|---------|
|
||||
| `POSTGRES_PASSWORD` | PostgreSQL password | - | `secure_pass_123` |
|
||||
| `STEP_CA_IP` | IP address for CA service | `127.0.0.1` | `192.168.1.100` |
|
||||
| `STEP_CA_PORT` | Port for CA service | `9000` | `9000` |
|
||||
| `STEP_CA_NAME` | CA name | `Default CA` | `Company Internal CA` |
|
||||
| `STEP_CA_ISSUER` | CA issuer certificate DN | - | `CN=My CA, O=Org, C=US` |
|
||||
| `STEP_CA_DNS_NAMES` | DNS names for CA cert | `localhost,ca.local` | `ca.example.com,ca.internal` |
|
||||
| `STEP_CA_PROVISIONER` | Provisioner name | `admin` | `admin-provisioner` |
|
||||
| `STEP_CA_ADMIN_SUBJECT` | Admin email address | `admin@example.com` | `ca-admin@company.com` |
|
||||
| `STEP_CA_SSH` | Enable SSH support | `true` | `true` or `false` |
|
||||
| `STEP_CA_ACME` | Enable ACME support | `true` | `true` or `false` |
|
||||
| `STEP_CA_REMOTE_MANAGEMENT` | Enable remote management | `true` | `true` or `false` |
|
||||
| `DNS_1`, `DNS_2` | DNS servers | `8.8.8.8`, `8.8.4.4` | `1.1.1.1`, `1.0.0.1` |
|
||||
| `DNS_SEARCH_1-3` | DNS search domains | `localhost,local,internal` | `example.com,internal.local` |
|
||||
|
||||
## Service Details
|
||||
|
||||
### PostgreSQL Service
|
||||
- **Image**: `postgres:16-alpine`
|
||||
- **Database**: `stepca`
|
||||
- **User**: `stepca`
|
||||
- **Health Check**: PostgreSQL readiness probe every 10 seconds
|
||||
- **Persistent Storage**: `postgres-data` volume
|
||||
|
||||
### Step-CA Service
|
||||
- **Build**: Custom image based on `smallstep/step-ca`
|
||||
- **Port**: Configurable via `STEP_CA_PORT` (default: 9000)
|
||||
- **Database Migration**: Automatic transition from Badger to PostgreSQL
|
||||
- **Persistent Storage**: `stepca-data` volume for certificates and configuration
|
||||
|
||||
## Initialization Flow
|
||||
|
||||
1. **First Run**: If `ca.json` doesn't exist:
|
||||
- Step-ca performs automated initialization with Badger database
|
||||
- Uses Docker secret from `/run/secrets/password` for key encryption
|
||||
- Generates root, intermediate, and SSH certificates
|
||||
- Creates admin provisioner
|
||||
|
||||
2. **PostgreSQL Migration**:
|
||||
- Configuration is migrated from Badger to PostgreSQL
|
||||
- Database connection details are stored in `ca.json`
|
||||
- Marker file created to prevent re-initialization
|
||||
|
||||
3. **Subsequent Runs**:
|
||||
- Step-ca starts directly with PostgreSQL backend
|
||||
- Uses the same Docker secret for decrypting keys
|
||||
- No re-initialization occurs (marker file prevents this)
|
||||
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
step-ca/
|
||||
├── compose.yaml # Docker Compose configuration
|
||||
├── Dockerfile # Custom Docker image build
|
||||
├── init.sh # Initialization script
|
||||
├── .env.example # Environment variables template
|
||||
├── .gitignore # Git ignore rules
|
||||
├── config/
|
||||
│ └── ca.json # Step-ca configuration (generated)
|
||||
├── secrets/
|
||||
│ ├── postgres_password.txt
|
||||
│ └── step_pwd.txt
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Access Step-CA Admin Interface
|
||||
|
||||
Once the container is running, you can interact with step-ca:
|
||||
|
||||
```bash
|
||||
# Enter the container
|
||||
docker-compose exec step-ca sh
|
||||
|
||||
# List certificates
|
||||
step certificate list
|
||||
|
||||
# Get CA fingerprint
|
||||
step certificate fingerprint /home/step/certs/root_ca.crt
|
||||
```
|
||||
|
||||
### Request a Certificate via JWK Provisioner
|
||||
|
||||
```bash
|
||||
# From inside the container, using the mounted Docker secret
|
||||
docker-compose exec step-ca sh -c \
|
||||
'step ca certificate --provisioner=admin --provisioner-password-file=/run/secrets/password \
|
||||
"my-service.example.com" /tmp/cert.pem /tmp/key.pem'
|
||||
|
||||
# Or from the host with your CA password
|
||||
step ca certificate --provisioner=admin \
|
||||
"my-service.example.com" cert.pem key.pem
|
||||
```
|
||||
|
||||
### ACME Client Setup
|
||||
|
||||
If ACME is enabled, configure your ACME client:
|
||||
|
||||
```
|
||||
CA URL: https://ca.example.com:9000
|
||||
Directory: https://ca.example.com:9000/acme/acme/directory
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### PostgreSQL Connection Fails
|
||||
|
||||
```bash
|
||||
# Check PostgreSQL logs
|
||||
docker-compose logs postgres
|
||||
|
||||
# Verify database exists
|
||||
docker-compose exec postgres psql -U stepca -d stepca -c "\dt"
|
||||
```
|
||||
|
||||
### Step-CA Won't Start
|
||||
|
||||
```bash
|
||||
# Check step-ca logs
|
||||
docker-compose logs step-ca
|
||||
|
||||
# Verify configuration
|
||||
docker-compose exec step-ca cat /home/step/config/ca.json
|
||||
```
|
||||
|
||||
### Remove and Reset
|
||||
|
||||
To completely reset the environment:
|
||||
|
||||
```bash
|
||||
# Stop and remove containers
|
||||
docker-compose down
|
||||
|
||||
# Remove data volumes
|
||||
docker volume rm ca-stepca-data ca-postgres-data
|
||||
|
||||
# Restart fresh
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- **Secret Management**: Store passwords in `secrets/` directory and add to `.gitignore`
|
||||
- **Network**: Use internal Docker network for PostgreSQL communication
|
||||
- **Firewall**: Restrict access to port 9000 from trusted networks only
|
||||
- **TLS**: Ensure step-ca certificates are properly validated by clients
|
||||
- **Backups**: Regularly backup the `stepca-data` and `postgres-data` volumes
|
||||
|
||||
## Ports and Networks
|
||||
|
||||
- **Step-CA Port**: 9000 (configurable)
|
||||
- **PostgreSQL Port**: 5432 (internal only)
|
||||
- **Network**: `ca-internal` (internal Docker bridge)
|
||||
|
||||
## Debugging
|
||||
|
||||
Enable verbose logging by modifying the init script:
|
||||
|
||||
```bash
|
||||
# Add to init.sh
|
||||
set -x # Enable debug output
|
||||
```
|
||||
|
||||
View real-time logs:
|
||||
|
||||
```bash
|
||||
docker-compose logs -f step-ca
|
||||
docker-compose logs -f postgres
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Step-CA Documentation](https://smallstep.com/docs/step-ca)
|
||||
- [Step CLI Reference](https://smallstep.com/docs/step-cli)
|
||||
- [Docker Compose Documentation](https://docs.docker.com/compose/)
|
||||
- [PostgreSQL Documentation](https://www.postgresql.org/docs/)
|
||||
|
||||
## Support
|
||||
|
||||
For issues with step-ca, refer to:
|
||||
- [Step-CA GitHub](https://github.com/smallstep/certificates)
|
||||
- [Step Community Discord](https://u.step.sm/discord)
|
||||
- [Step Community Discussions](https://github.com/smallstep/certificates/discussions)
|
||||
|
||||
## License
|
||||
|
||||
This Docker Compose stack follows the licensing of Smallstep and individual components.
|
||||
Reference in New Issue
Block a user