feat: add Makefile and README.md for Step-CA Docker stack setup

This commit is contained in:
vorpax
2026-01-20 14:48:34 +00:00
parent 1647327dde
commit f7de687487
2 changed files with 352 additions and 0 deletions

64
Makefile Normal file
View File

@@ -0,0 +1,64 @@
.PHONY: help configure clean
# Colors for output
BLUE := \033[0;34m
GREEN := \033[0;32m
YELLOW := \033[0;33m
RED := \033[0;31m
NC := \033[0m # No Color
help: ## Show this help message
@echo "$(BLUE)Step-CA Docker Stack - Available commands:$(NC)"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " $(GREEN)%-15s$(NC) %s\n", $$1, $$2}'
configure: ## Create secret files from .env if they don't exist
@echo "$(BLUE)Configuring secrets...$(NC)"
@if [ ! -f .env ]; then \
echo "$(RED)Error: .env file not found. Please copy .env.example to .env and configure it.$(NC)"; \
exit 1; \
fi
@mkdir -p secrets
@if [ ! -f secrets/postgres_password.txt ]; then \
echo "$(YELLOW)Creating secrets/postgres_password.txt$(NC)"; \
grep '^POSTGRES_PASSWORD=' .env | cut -d '=' -f2- | tr -d '"' > secrets/postgres_password.txt; \
chmod 600 secrets/postgres_password.txt; \
echo "$(GREEN)✓ Created secrets/postgres_password.txt$(NC)"; \
else \
echo "$(GREEN)✓ secrets/postgres_password.txt already exists$(NC)"; \
fi
@if [ ! -f secrets/step_pwd.txt ]; then \
echo "$(YELLOW)Creating secrets/step_pwd.txt$(NC)"; \
if grep -q '^STEP_CA_PASSWORD=' .env; then \
grep '^STEP_CA_PASSWORD=' .env | cut -d '=' -f2- | tr -d '"' > secrets/step_pwd.txt; \
else \
openssl rand -base64 32 > secrets/step_pwd.txt; \
echo "$(YELLOW)No STEP_CA_PASSWORD in .env, generated random password$(NC)"; \
fi; \
chmod 600 secrets/step_pwd.txt; \
echo "$(GREEN)✓ Created secrets/step_pwd.txt$(NC)"; \
else \
echo "$(GREEN)✓ secrets/step_pwd.txt already exists$(NC)"; \
fi
@echo "$(GREEN)✓ Configuration complete$(NC)"
clean:
docker compose down
@echo "$(RED)WARNING: This will destroy all data (certificates, database)$(NC)"
@read -p "Are you sure? [y/N] " -n 1 -r; \
echo; \
if [[ $$REPLY =~ ^[Yy]$$ ]]; then \
echo "$(BLUE)Removing volumes...$(NC)"; \
docker compose down -v; \
echo "$(GREEN)✓ Volumes removed$(NC)"; \
else \
echo "$(YELLOW)Cancelled$(NC)"; \
fi
exec-ca: ## Execute ash in step-ca container
docker compose exec step-ca sh
exec-db: ## Execute psql in postgres container
docker compose exec postgres psql -U stepca -d stepca
fingerprint: ## Get CA root certificate fingerprint
@docker compose exec step-ca step certificate fingerprint /home/step/certs/root_ca.crt 2>/dev/null || echo "$(RED)CA not initialized yet$(NC)"

288
README.md Normal file
View 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.