Skip to content

Commit 0cf4f28

Browse files
committed
Use container secrets securely
* 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 0cf4f28

File tree

4 files changed

+113
-3
lines changed

4 files changed

+113
-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](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: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ function generate_password () {
3232
set -o pipefail
3333
}
3434

35+
function set_password_files () {
36+
local FILE_PATH=$1
37+
38+
ln -sf "${FILE_PATH}" "${STEPPATH}/password"
39+
ln -sf "${FILE_PATH}" "${STEPPATH}/provisioner_password"
40+
}
41+
3542
# Initialize a CA if not already initialized
3643
function step_ca_init () {
3744
DOCKER_STEPCA_INIT_PROVISIONER_NAME="${DOCKER_STEPCA_INIT_PROVISIONER_NAME:-admin}"
@@ -46,9 +53,8 @@ function step_ca_init () {
4653
--provisioner-password-file "${STEPPATH}/provisioner_password"
4754
--address "${DOCKER_STEPCA_INIT_ADDRESS}"
4855
)
49-
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"
56+
if [ -f "${DOCKER_STEPCA_INIT_PASSWORD_FILE}" ]; then
57+
set_password_files "${DOCKER_STEPCA_INIT_PASSWORD_FILE}"
5258
elif [ -n "${DOCKER_STEPCA_INIT_PASSWORD}" ]; then
5359
echo "${DOCKER_STEPCA_INIT_PASSWORD}" > "${STEPPATH}/password"
5460
echo "${DOCKER_STEPCA_INIT_PASSWORD}" > "${STEPPATH}/provisioner_password"
@@ -86,4 +92,8 @@ if [ ! -f "${STEPPATH}/config/ca.json" ]; then
8692
init_if_possible
8793
fi
8894

95+
if [ -f "${DOCKER_STEPCA_PASSWORD_FILE}" ]; then
96+
set_password_files "${DOCKER_STEPCA_PASSWORD_FILE}"
97+
fi
98+
8999
exec "${@}"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
PodmanArgs=--memory 50m --cpus 0.25
13+
PidsLimit=100
14+
DropCapability=ALL
15+
NoNewPrivileges=true
16+
AutoUpdate=registry
17+
ContainerName=stepca
18+
Environment=TZ="UTC"
19+
Environment="DOCKER_STEPCA_INIT_NAME=Example CA"
20+
Environment=DOCKER_STEPCA_INIT_DNS_NAMES=ca.custom.domain,10.89.0.10,localhost,127.0.0.1
21+
Environment=DOCKER_STEPCA_INIT_PROVISIONER_NAME=admin@custom.domain
22+
Environment=DOCKER_STEPCA_INIT_SSH=true
23+
Environment=DOCKER_STEPCA_INIT_ACME=true
24+
Environment=DOCKER_STEPCA_INIT_PASSWORD_FILE=/run/secrets/stepca
25+
HostName=stepca
26+
Image=docker.io/smallstep/step-ca
27+
PublishPort=10.89.0.10:9000:9000/tcp
28+
PublishPort=127.0.0.1:9000:9000/tcp
29+
Secret=source=stepca,type=mount,uid=1000,gid=1000,mode=400
30+
Volume=/path/to/volumes/stepca/config:/home/step:Z
31+
DNS=10.89.0.1
32+
DNSOption=~custom.domain
33+
ReloadSignal=SIGHUP
34+
# Use systemd restart policy
35+
HealthOnFailure=kill
36+
HealthStartPeriod=90s
37+
HealthStartupCmd=sleep 5
38+
HealthCmd=step ca health
39+
HealthInterval=30m
40+
HealthRetries=3
41+
HealthTimeout=20s
42+
43+
[Service]
44+
Restart=always
45+
# Extend Timeout for image pulls
46+
TimeoutStartSec=900
47+
48+
[Install]
49+
WantedBy=default.target
50+
```

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+
- [examples/podman/stepca.container.md](https://github.com/smallstep/certificates/tree/master/examples/podman/stepca.container.md)
9+
10+
```
11+
iface=wt0 # running over Netbird VPN
12+
ctr=stepca
13+
ip=$(ip -f inet addr show $iface | sed -En -e 's/.*inet ([0-9.]+).*/\1/p')
14+
repo=docker.io/smallstep/step-ca
15+
# TPM supported image
16+
# repo=docker.io/smallstep/step-ca:hsm
17+
ca="My CA"
18+
email="admin@custom.domain"
19+
dns="ca.custom.domain,$ip,localhost,127.0.0.1"
20+
volume="${HOME}/volumes/$ctr/config}"
21+
22+
###############
23+
# auto config #
24+
###############
25+
26+
bytes=8192
27+
mkdir -p $volume
28+
openssl rand -hex $bytes | podman secret create --replace $ctr -
29+
30+
podman run -d --replace \
31+
--name $ctr \
32+
--hostname $ctr \
33+
--secret source=$ctr,type=mount,uid=1000,gid=1000,mode=400 \
34+
--env "DOCKER_STEPCA_INIT_NAME=$ca" \
35+
--env "DOCKER_STEPCA_INIT_DNS_NAMES=$dns" \
36+
--env "DOCKER_STEPCA_INIT_PROVISIONER_NAME=$email" \
37+
--env "DOCKER_STEPCA_INIT_SSH=true" \
38+
--env "DOCKER_STEPCA_INIT_ACME=true" \
39+
--env "DOCKER_STEPCA_PASSWORD_FILE=/run/secrets/$ctr" \
40+
--cap-drop ALL \
41+
--restart always \
42+
--label "io.containers.autoupdate=registry" \
43+
-v $volume:/home/step:Z \
44+
$repo
45+
```
46+
47+
* Running the container with `--privileged` should only be needed to [configure a TPM](https://smallstep.com/blog/trusted-platform-modules-tpms/).

0 commit comments

Comments
 (0)