Skip to content

Commit 307f599

Browse files
committed
Use container secrets securely
* increases the default password length from 40 to 256 characters * adds a new ENV variable DOCKER_STEPCA_PASSWORD_FILE so the password file location can be changed * adds set_password_files() to entrypoint.sh so /home/step/secrets/password becomes a symlink in containers pointing to DOCKER_STEPCA_INIT_PASSWORD_FILE & also DOCKER_STEPCA_PASSWORD_FILE so file permissions are retained * adds podman example quadlet / run command with a 378,000 character secret * small update to README.md for new podman examples / docker examples Fixes #2270
1 parent 30e79a2 commit 307f599

File tree

5 files changed

+189
-3
lines changed

5 files changed

+189
-3
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ See our installation docs [here](https://smallstep.com/docs/step-ca/installation
136136
[on smallstep.com](https://smallstep.com/docs/step-cli/reference/),
137137
or by running `step help --http=:8080` from the command line
138138
and visiting http://localhost:8080.
139+
* [Examples](https://github.com/smallstep/certificates/tree/master/examples) including
140+
[Podman & Quantum Resistant CA](https://github.com/smallstep/certificates/tree/master/examples/podman) &
141+
[Docker](https://github.com/smallstep/certificates/tree/master/examples/docker)
139142

140143
## Feedback?
141144

docker/entrypoint.sh

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,16 @@ function init_if_possible () {
2727

2828
function generate_password () {
2929
set +o pipefail
30-
< /dev/urandom tr -dc A-Za-z0-9 | head -c40
30+
< /dev/urandom tr -dc A-Za-z0-9 | head -c256
3131
echo
3232
set -o pipefail
3333
}
3434

35+
function set_password_files () {
36+
ln -sf "${DOCKER_STEPCA_INIT_PASSWORD_FILE}" "${STEPPATH}/password"
37+
ln -sf "${DOCKER_STEPCA_INIT_PASSWORD_FILE}" "${STEPPATH}/provisioner_password"
38+
}
39+
3540
# Initialize a CA if not already initialized
3641
function step_ca_init () {
3742
DOCKER_STEPCA_INIT_PROVISIONER_NAME="${DOCKER_STEPCA_INIT_PROVISIONER_NAME:-admin}"
@@ -47,8 +52,7 @@ function step_ca_init () {
4752
--address "${DOCKER_STEPCA_INIT_ADDRESS}"
4853
)
4954
if [ -n "${DOCKER_STEPCA_INIT_PASSWORD_FILE}" ]; then
50-
cat < "${DOCKER_STEPCA_INIT_PASSWORD_FILE}" > "${STEPPATH}/password"
51-
cat < "${DOCKER_STEPCA_INIT_PASSWORD_FILE}" > "${STEPPATH}/provisioner_password"
55+
set_password_files
5256
elif [ -n "${DOCKER_STEPCA_INIT_PASSWORD}" ]; then
5357
echo "${DOCKER_STEPCA_INIT_PASSWORD}" > "${STEPPATH}/password"
5458
echo "${DOCKER_STEPCA_INIT_PASSWORD}" > "${STEPPATH}/provisioner_password"
@@ -86,4 +90,8 @@ if [ ! -f "${STEPPATH}/config/ca.json" ]; then
8690
init_if_possible
8791
fi
8892

93+
if [ -n "${DOCKER_STEPCA_PASSWORD_FILE}" ]; then
94+
set_password_files
95+
fi
96+
8997
exec "${@}"
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
## Example [Quantum Resistant CA](https://angrysysadmins.tech/index.php/2022/09/grassyloki/step-ca-change-certificate-authority-and-intermediate-authority-encryption-type-and-key-size/)
2+
3+
Generates:
4+
5+
* **Root CA** with RSA `16384` bit certificate
6+
* **Intermediate CA** with RSA `8192` bit certificate
7+
* Use [higher container limits](https://github.com/smallstep/certificates/tree/master/examples/podman/stepca.container.md): `1` or `2` cores in testing below is ideal
8+
* `PodmanArgs=--memory 50m --cpus 1`
9+
10+
---
11+
12+
* Get a shell in the container & regenerate certificates
13+
* `podman exec -it container_name /bin/bash`
14+
15+
---
16+
```
17+
export root_bits=16384
18+
export intermediate_bits=8192
19+
```
20+
21+
## ROOT CA
22+
23+
```
24+
step certificate create 'My Root CA' \
25+
$(step path)/certs/root_ca.crt \
26+
$(step path)/secrets/root_ca_key \
27+
--profile root-ca \
28+
--kty RSA --size $root_bits \
29+
--force
30+
```
31+
32+
8192 bits (root CA generation time)
33+
---
34+
* 1 core = 1 min / 21 secs / 50 secs
35+
36+
16384 bits (root CA generation time)
37+
---
38+
* 8 cores = 3 mins / 12 mins
39+
* 3 cores = 14 mins
40+
* 2 cores = 3 mins / 6 mins / 7 mins / 9 mins / 11 mins / 13 mins
41+
* 1.5 cores = 8 mins / 29 mins
42+
* 1 core = 2 mins / 6 mins / 7.5 mins / 15 mins / 16.5 mins
43+
* 0.5 core = 9 mins / 23 mins
44+
45+
## Intermediate CA
46+
47+
```
48+
step certificate create 'My Intermediate CA' \
49+
$(step path)/certs/intermediate_ca.crt \
50+
$(step path)/secrets/intermediate_ca_key \
51+
--profile intermediate-ca \
52+
--ca $(step path)/certs/root_ca.crt \
53+
--ca-key $(step path)/secrets/root_ca_key \
54+
--kty RSA --size $intermediate_bits \
55+
--force
56+
```
57+
58+
8192 bits (intermediate CA generation time)
59+
---
60+
* 2 core = 30 secs
61+
* 1 core = 25 secs
62+
63+
---
64+
65+
* Restart the container & note the new X.509 Root Fingerprint: `podman logs container_name`
66+
* Boostsrap clients
67+
68+
```
69+
port=xxx
70+
71+
step ca bootstrap \
72+
--ca-url https://ca.mydomain.com:$port \
73+
--fingerprint 12345678abcdef12345678abcdef12345678abcdef12345678abcdef12345678 \
74+
--context your_label \
75+
--force
76+
```
77+
78+
---
79+
80+
* Contributed by: [Stuart Cardall](https://github.com/itoffshore)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
## Example [Podman Quadlet container](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html#container-units-container) file
2+
3+
* `~/.config/containers/systemd/stepca.container` (rootless)
4+
* `/etc/containers/systemd/stepca.container` (rootful)
5+
6+
```
7+
[Unit]
8+
Description=Smallstep Certificate Authority
9+
After=network-online.target
10+
11+
[Container]
12+
# default EC root CA / intermediate CA
13+
PodmanArgs=--memory 25m --cpus 0.20
14+
# RSA 16384 / 8192 bit root CA / intermediate CA
15+
# PodmanArgs=--memory 50m --cpus 1
16+
PidsLimit=60
17+
DropCapability=ALL
18+
AutoUpdate=registry
19+
ContainerName=stepca
20+
DropCapability=ALL
21+
Environment=TZ="Europe/London"
22+
Environment="DOCKER_STEPCA_INIT_NAME=Example CA"
23+
Environment=DOCKER_STEPCA_INIT_DNS_NAMES=ca.custom.domain,10.89.0.10,localhost,127.0.0.1
24+
Environment=DOCKER_STEPCA_INIT_PROVISIONER_NAME=admin@custom.domain
25+
Environment=DOCKER_STEPCA_INIT_SSH=true
26+
Environment=DOCKER_STEPCA_INIT_ACME=true
27+
Environment=DOCKER_STEPCA_INIT_PASSWORD_FILE=/run/secrets/stepca
28+
HostName=stepca
29+
PodmanArgs=--privileged
30+
# Alpine image
31+
Image=docker.io/smallstep/step-ca
32+
# Debian image with TPM support
33+
#Image=docker.io/smallstep/step-ca:hsm
34+
PublishPort=10.89.0.10:9000:9000/tcp
35+
PublishPort=127.0.0.1:9000:9000/tcp
36+
Secret=source=stepca,type=mount,uid=1000,gid=1000,mode=400
37+
Volume=/path/to/volumes/stepca/config:/home/step:Z
38+
DNS=10.89.0.1
39+
DNSOption=~custom.domain
40+
41+
[Service]
42+
Restart=always
43+
44+
[Install]
45+
WantedBy=default.target
46+
```
47+
48+
* Contributed by: [Stuart Cardall](https://github.com/itoffshore)

examples/podman/stepca.run.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
## Example creation of a Podman container & secret
2+
3+
* Using a [cryptographically strong secret from `openssl` with an `8192` character `hex` string](https://docs.podman.io/en/latest/markdown/podman-secret-create.1.html#examples)
4+
5+
see also:
6+
7+
- [Create a "quadlet"](https://github.com/containers/podlet)
8+
- [Netbird VPN](https://github.com/netbirdio/netbird)
9+
- [examples/podman/stepca.container.md](https://github.com/smallstep/certificates/tree/master/examples/podman/stepca.container.md)
10+
11+
```
12+
iface=wt0 # running over netbird
13+
ctr=stepca
14+
ip=$(ip -f inet addr show $iface | sed -En -e 's/.*inet ([0-9.]+).*/\1/p')
15+
repo=docker.io/smallstep/step-ca
16+
# TPM supported image
17+
# repo=docker.io/smallstep/step-ca:hsm
18+
dns="ca.custom.domain,$ip,localhost,127.0.0.1"
19+
email="admin@custom.domain"
20+
ca="My CA"
21+
22+
####################
23+
# auto config #
24+
####################
25+
26+
bytes=8096
27+
openssl rand -hex $bytes | podman secret create --replace $ctr -
28+
29+
podman run -d --replace \
30+
--name $ctr \
31+
--hostname $ctr \
32+
--secret source=$ctr,type=mount,uid=1000,gid=1000,mode=400 \
33+
--env "DOCKER_STEPCA_INIT_NAME=$ca" \
34+
--env "DOCKER_STEPCA_INIT_DNS_NAMES=$dns" \
35+
--env "DOCKER_STEPCA_INIT_PROVISIONER_NAME=$email" \
36+
--env "DOCKER_STEPCA_INIT_SSH=true" \
37+
--env "DOCKER_STEPCA_INIT_ACME=true" \
38+
--env "DOCKER_STEPCA_PASSWORD_FILE=/run/secrets/$ctr" \
39+
--cap-drop ALL \
40+
--restart always \
41+
--privileged \
42+
--label "io.containers.autoupdate=registry" \
43+
-v ${HOME}/volumes/$ctr/config:/home/step:Z \
44+
$repo
45+
```
46+
47+
* Contributed by: [Stuart Cardall](https://github.com/itoffshore)

0 commit comments

Comments
 (0)