Skip to content

Commit

Permalink
Make SSH keys passed via an eval script, not as a string, to enable s…
Browse files Browse the repository at this point in the history
…toring them in e.g. Secrets Manager
  • Loading branch information
dimikot committed Mar 5, 2024
1 parent 36fe965 commit 76c7b0c
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 19 deletions.
6 changes: 3 additions & 3 deletions docker/.env
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# This key (as well as docker-compose.yml) is only used in tests, so it's safe
# to have it here.
CI_STORAGE_HOST_PRIVATE_KEY_TEST_ONLY="-----BEGIN OPENSSH PRIVATE KEY-----
CI_STORAGE_HOST_PRIVATE_KEY_EVAL_TEST_ONLY="echo '-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBZgbuAsWHfeYshNJacifV30KxJVFKr4/B4WnvxO8x2jAAAAKgm2KyUJtis
lAAAAAtzc2gtZWQyNTUxOQAAACBZgbuAsWHfeYshNJacifV30KxJVFKr4/B4WnvxO8x2jA
AAAECRcPB4jRqJEgNBvFPA6+k5HPT5/ZbXnD2KUyE+oJFfA1mBu4CxYd95iyE0lpyJ9XfQ
rElUUqvj8Hhae/E7zHaMAAAAHmRtaXRyeUBEbWl0cnktTWFjQm9vay1NMS5sb2NhbAECAw
QFBgc=
-----END OPENSSH PRIVATE KEY-----"
CI_STORAGE_HOST_PUBLIC_KEY_TEST_ONLY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFmBu4CxYd95iyE0lpyJ9XfQrElUUqvj8Hhae/E7zHaM"
-----END OPENSSH PRIVATE KEY-----'"
CI_STORAGE_HOST_PUBLIC_KEY_EVAL_TEST_ONLY="echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFmBu4CxYd95iyE0lpyJ9XfQrElUUqvj8Hhae/E7zHaM'"
9 changes: 9 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Self Hosted Runner and ci-storage Host Container

See nested README.md files.

To build the containers and run/test them locally/manually:

```
./compose-up.sh
```
4 changes: 2 additions & 2 deletions docker/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ services:
ports:
- 10022:22
environment:
- CI_STORAGE_HOST_PUBLIC_KEY=${CI_STORAGE_HOST_PUBLIC_KEY_TEST_ONLY?}
- CI_STORAGE_HOST_PUBLIC_KEY_EVAL=${CI_STORAGE_HOST_PUBLIC_KEY_EVAL_TEST_ONLY?}
self-hosted-runner:
build:
context: self-hosted-runner
Expand All @@ -27,4 +27,4 @@ services:
- GH_LABELS=${GH_LABELS:-ci-storage}
- GH_TOKEN
- CI_STORAGE_HOST=${CI_STORAGE_HOST:-host:22}
- CI_STORAGE_HOST_PRIVATE_KEY=${CI_STORAGE_HOST_PRIVATE_KEY_TEST_ONLY?}
- CI_STORAGE_HOST_PRIVATE_KEY_EVAL=${CI_STORAGE_HOST_PRIVATE_KEY_EVAL_TEST_ONLY?}
2 changes: 1 addition & 1 deletion docker/host/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ARG BASE_IMAGE="ubuntu:22.04"

FROM $BASE_IMAGE

ENV CI_STORAGE_HOST_PUBLIC_KEY=""
ENV CI_STORAGE_HOST_PUBLIC_KEY_EVAL=""

ENV DEBIAN_FRONTEND=noninteractive
RUN true \
Expand Down
3 changes: 2 additions & 1 deletion docker/host/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
Build an image from this Dockerfile to launch a simple SSH server with rsync.

- Pre-creates /home/user/ci-storage directory.
- Copies public key in CI_STORAGE_HOST_PUBLIC_KEY to user's authorized_keys.
- Copies public key printed by `CI_STORAGE_HOST_PUBLIC_KEY_EVAL` to user's
authorized_keys.

One "host" container may serve multiple GitHub repositories. Each of them will
have own directory in /home/user/ci-storage (managed by ci-storage tool).
Expand Down
17 changes: 11 additions & 6 deletions docker/host/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@
#
set -u -e

if [[ "${CI_STORAGE_HOST_PUBLIC_KEY:=}" == "" ]]; then
echo "CI_STORAGE_HOST_PUBLIC_KEY must be set to a valid SSH public key."
if [[ "${CI_STORAGE_HOST_PUBLIC_KEY_EVAL:=}" == "" ]]; then
echo "CI_STORAGE_HOST_PUBLIC_KEY_EVAL must be contain a bash script which prints a valid SSH public key (e.g. fetched from AWS Secrets Manager or so)."
exit 1
fi

authorized_keys=~user/.ssh/authorized_keys
authorized_keys_file=~user/.ssh/authorized_keys
public_key=$(eval "$CI_STORAGE_HOST_PUBLIC_KEY_EVAL")
if [[ "$public_key" == "" ]]; then
echo "CI_STORAGE_HOST_PUBLIC_KEY_EVAL evaluated to an empty string."
exit 1
fi

if [[ ! -f $authorized_keys ]] || ! grep -qF "$CI_STORAGE_HOST_PUBLIC_KEY" $authorized_keys; then
echo "$CI_STORAGE_HOST_PUBLIC_KEY" >> $authorized_keys
chown user:user $authorized_keys
if [[ ! -f $authorized_keys_file ]] || ! grep -qF "$public_key" $authorized_keys_file; then
echo "$public_key" >> $authorized_keys_file
chown user:user $authorized_keys_file
fi

mkdir -p /var/run/sshd
Expand Down
2 changes: 1 addition & 1 deletion docker/self-hosted-runner/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ENV GH_REPOSITORY=""
ENV GH_LABELS=""
ENV GH_TOKEN=""
ENV CI_STORAGE_HOST=""
ENV CI_STORAGE_HOST_PRIVATE_KEY=""
ENV CI_STORAGE_HOST_PRIVATE_KEY_EVAL=""

ENV DEBIAN_FRONTEND=noninteractive
RUN true \
Expand Down
4 changes: 2 additions & 2 deletions docker/self-hosted-runner/root/entrypoint.00-validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if [[ "${CI_STORAGE_HOST:=}" != "" && ! "$CI_STORAGE_HOST" =~ ^([-.[:alnum:]]+@)
exit 1;
fi

if [[ "${CI_STORAGE_HOST_PRIVATE_KEY:=}" != "" && "$CI_STORAGE_HOST_PRIVATE_KEY" != *OPENSSH\ PRIVATE\ KEY* ]]; then
echo "If CI_STORAGE_HOST_PRIVATE_KEY is passed, it must be an SSH private key.";
if [[ "${CI_STORAGE_HOST_PRIVATE_KEY_EVAL:=}" != "" && "$CI_STORAGE_HOST_PRIVATE_KEY_EVAL" != *\ * ]]; then
echo "If CI_STORAGE_HOST_PRIVATE_KEY_EVAL is passed, it must contain a shell command which prints an SSH private key (e.g. fetched from AWS Secrets Manager or so).";
exit 1;
fi
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#!/bin/bash
set -u -e

if [[ "$CI_STORAGE_HOST_PRIVATE_KEY" != "" ]]; then
echo "$CI_STORAGE_HOST_PRIVATE_KEY" > ~/.ssh/id_ed25519
if [[ "$CI_STORAGE_HOST_PRIVATE_KEY_EVAL" != "" ]]; then
eval "$CI_STORAGE_HOST_PRIVATE_KEY_EVAL" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
fi

echo "$CI_STORAGE_HOST" > ci-storage-host

if [[ "$CI_STORAGE_HOST" != "" && "$CI_STORAGE_HOST_PRIVATE_KEY" != "" ]]; then
if [[ "$CI_STORAGE_HOST" != "" && "$CI_STORAGE_HOST_PRIVATE_KEY_EVAL" != "" ]]; then
local_dir=~/actions-runner/_work/${GH_REPOSITORY##*/}/${GH_REPOSITORY##*/}
mkdir -p "$local_dir"
ci-storage load \
Expand Down

0 comments on commit 76c7b0c

Please sign in to comment.