Skip to content

Commit

Permalink
Add secret management for root passwords (#131)
Browse files Browse the repository at this point in the history
* initial config (w/o gitignore)

* Update .gitignore

* update to example env

* add more gitignore safeguards

* Update README.md

* add iroh

* add source back to setup script

* push workflow

* fix path

* make it rerun

* try secrets

* fix dir

* env fixup

* headless gpg

* add client side decryption

* try sourcing via shortcut

* docs, cache ig?

* build?

* fix dumb dumb

* fix nero
  • Loading branch information
jr1221 authored Mar 18, 2024
1 parent 16ec8b0 commit 0de0400
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 5 deletions.
60 changes: 60 additions & 0 deletions .github/workflows/build_image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#
name: Create and publish a Docker image

# Configures this workflow to run every time a docker artificat is edited
on:
push:
paths:
- 'odysseus/Dockerfile'
- 'odysseus/docker_scripts/**'

# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
#
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Encrypt and inject passwords
shell: bash
working-directory: ./odysseus
env:
ODY_AP_ROOT_PASSWORD: ${{ secrets.ODY_AP_ROOT_PASSWORD }}
ODY_TPU_ROOT_PASSWORD: ${{ secrets.ODY_TPU_ROOT_PASSWORD }}
ODY_IROH_ROOT_PASSWORD: ${{ secrets.ODY_IROH_ROOT_PASSWORD }}
MASTER_PASSWORD: ${{ secrets.ODY_MASTER_PASSWORD }}
run: for i in ODY_AP_ROOT_PASSWORD ODY_TPU_ROOT_PASSWORD ODY_IROH_ROOT_PASSWORD; do echo "$i=${!i}" >> SECRETS.env; done && gpg --batch --symmetric --passphrase "$MASTER_PASSWORD" --no-symkey-cache --cipher-algo AES256 SECRETS.env
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: ./odysseus
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@

.DS_Store
odysseus/outputs/**

# for passwords
odysseus/SECRETS.env
odysseus/SECRETS.env-example
# redundant safeguard for all env files named SECRETS.env in case it is renamed wrong
**/*SECRETS.env*
4 changes: 4 additions & 0 deletions odysseus/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ WORKDIR /home/odysseus/build

RUN git clone https://gitlab.com/buildroot.org/buildroot.git && cd ./buildroot && git checkout 2024.02


WORKDIR /home/odysseus/outputs/
COPY ./docker_scripts /home/odysseus/scripts
RUN echo "source /home/odysseus/scripts/setup_env.sh" >> ~/.bashrc

# install password using wildcard so failures arent deadly
COPY ./SECRETS.env.* /home/odysseus/

ENTRYPOINT "/bin/bash"
14 changes: 14 additions & 0 deletions odysseus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ Download and install to PATH git and docker.
git clone https://github.com/Northeastern-Electric-Racing/Siren.git
git submodule update --init --recursive
cd ./odysseus
```
At this point, copy the file `SECRETS.env-example` to `SECRETS.env`, if you want to use non-default passwords edit this file.

Once that is done, run:
```
docker compose run --rm --build odysseus # Future launches can omit `--build` for time savings and space savings, but it should be used if the Dockerfile or docker_out_of_tree.sh files change.
```
Now you are in the docker container. To build cd into the defconfig directory (either ap, or tpu), then run the make command alias:
Expand Down Expand Up @@ -84,6 +89,15 @@ Notes about docker:
- Launch time is longer
- Space is used up by rebuilds, prune often or omit `--build`

### Passwords
Root passwords are stored via Github secrets and an encrypted file within a ghcr docker image. Below are the steps to load and decrypt such passwords for use by buildroot. Requirements are you know the team's master password and are running x86_64.

1. Authenticate with ghcr. First make a [classic PAT](https://github.com/settings/tokens/new) with the permission `read:packages`. Make sure to copy the token, then run `sudo docker login ghcr.io -u <GITHUB_USERNAME> -p <PAT>`
2. cd into odysseus folder and `docker compose pull`
3. Run `docker compose run odysseus` to enter the docker image. At this point the image should be identical to a locally built one, but it is less preferable for development purposes.
4. Run `load-secrets` and enter the master password. Consult Odysseus lead if you need this info. Now your passwords are loaded (can be viewed with `env | grep ODY`), and will be set when you make the sdcard.img. Note this step must be repeated on each `docker compose run odysseus`, and if the passwords change on Github steps 2 and 3 must be rerun as well.



See below to learn more about developing, and check confluence for most info. Once in the docker image, all the normal make commands (in an out-of-tree context only) apply.

Expand Down
9 changes: 9 additions & 0 deletions odysseus/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ version: "3.8"
services:
odysseus:
build: .
image: ghcr.io/northeastern-electric-racing/odysseus:52-root-secrets
command: /bin/bash
privileged: true
tty: true
stdin_open: true
# for fakeroot failure
ulimits:
nofile:
Expand All @@ -17,7 +19,14 @@ services:
environment:
- BR2_DL_DIR=/home/odysseus/shared_data/dl
- BR2_CCACHE_DIR=/home/odysseus/shared_data/ccache
- ODY_TPU_ROOT_PASSWORD=password
- ODY_IROH_ROOT_PASSWORD=password
- ODY_AP_ROOT_PASSWORD=password

volumes:
shared_data:
labels:
com.northeastern_electric_racing.description: "Shared output between buildroot runs"



4 changes: 4 additions & 0 deletions odysseus/docker_scripts/load-secrets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

# must be sourced for this to work
eval "$(gpg -d --no-symkey-cache --cipher-algo AES256 /home/odysseus/SECRETS.env.gpg)"
3 changes: 2 additions & 1 deletion odysseus/docker_scripts/setup_env.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/bin/bash

alias make-current="/home/odysseus/scripts/make-current.sh"
alias load-secrets="source /home/odysseus/scripts/load-secrets.sh"

# for each defconfig make output subdirectory
# for each defconfig make output subdirectory
make -C /home/odysseus/build/buildroot O=/home/odysseus/outputs/tpu BR2_EXTERNAL=/home/odysseus/build/odysseus_tree raspberrypi4_64_tpu_defconfig
make -C /home/odysseus/build/buildroot O=/home/odysseus/outputs/ap BR2_EXTERNAL=/home/odysseus/build/odysseus_tree raspberrypi3_64_ap_defconfig
make -C /home/odysseus/build/buildroot O=/home/odysseus/outputs/iroh BR2_EXTERNAL=/home/odysseus/build/odysseus_tree raspberrypi3_64_iroh_defconfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_ODY_TREE_PATH)/patches"
BR2_PER_PACKAGE_DIRECTORIES=y
BR2_TARGET_GENERIC_HOSTNAME="raspberrypi-ap"
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
BR2_TARGET_GENERIC_ROOT_PASSWD="password"
BR2_TARGET_GENERIC_ROOT_PASSWD="$(ODY_AP_ROOT_PASSWORD)"
BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_ODY_TREE_PATH)/overlays/rootfs_overlay_common $(BR2_EXTERNAL_ODY_TREE_PATH)/overlays/rootfs_overlay_nrc_common $(BR2_EXTERNAL_ODY_TREE_PATH)/overlays/rootfs_overlay_ap"
BR2_ROOTFS_PRE_BUILD_SCRIPT="$(BR2_EXTERNAL_ODY_TREE_PATH)/pre-make-ap.sh"
BR2_ROOTFS_POST_BUILD_SCRIPT="board/raspberrypi3-64/post-build.sh"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_ODY_TREE_PATH)/patches"
BR2_PER_PACKAGE_DIRECTORIES=y
BR2_TARGET_GENERIC_HOSTNAME="raspberrypi-iroh"
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
BR2_TARGET_GENERIC_ROOT_PASSWD="password"
BR2_TARGET_GENERIC_ROOT_PASSWD="$(ODY_IROH_ROOT_PASSWORD)"
BR2_TARGET_TZ_INFO=y
BR2_TARGET_LOCALTIME="America/New_York"
BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_ODY_TREE_PATH)/overlays/rootfs_overlay_iroh"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_ODY_TREE_PATH)/patches"
BR2_PER_PACKAGE_DIRECTORIES=y
BR2_TARGET_GENERIC_HOSTNAME="raspberrypi-sta"
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
BR2_TARGET_GENERIC_ROOT_PASSWD="password"
BR2_TARGET_GENERIC_ROOT_PASSWD="$(ODY_TPU_ROOT_PASSWORD)"
BR2_TARGET_TZ_INFO=y
BR2_TARGET_LOCALTIME="America/New_York"
BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_ODY_TREE_PATH)/overlays/rootfs_overlay_common $(BR2_EXTERNAL_ODY_TREE_PATH)/overlays/rootfs_overlay_nrc_common $(BR2_EXTERNAL_ODY_TREE_PATH)/overlays/rootfs_overlay_tpu"
Expand Down

0 comments on commit 0de0400

Please sign in to comment.