Skip to content

Commit

Permalink
Merge pull request #34 from SgtCoDFish/slc-updates
Browse files Browse the repository at this point in the history
Updates from KubeCon in SLC
  • Loading branch information
cert-manager-prow[bot] authored Nov 29, 2024
2 parents 4fd0a30 + 921a468 commit c642e70
Show file tree
Hide file tree
Showing 16 changed files with 397 additions and 112 deletions.
7 changes: 4 additions & 3 deletions Dockerfile.controller
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
FROM alpine:edge
FROM alpine:3.20

ARG $TARGETARCH

WORKDIR /root

RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories \
&& apk add --update --no-cache python3 py3-pillow py3-future py3-jinja2 py3-bottle py3-pip py3-usb imagemagick ttf-opensans libqrencode-tools step-cli openssl bash curl libusb fontconfig ttf-dejavu jq kubectl@testing timg@testing \
RUN apk add --update --no-cache python3 py3-pillow py3-future py3-jinja2 py3-bottle py3-pip py3-usb imagemagick ttf-opensans libqrencode-tools step-cli openssl bash curl libusb fontconfig ttf-dejavu jq kubectl timg \
&& python3 -m venv /venv && . /venv/bin/activate \
&& pip3 install --no-cache-dir --upgrade brother_ql \
&& curl -sSL https://github.com/pklaus/brother_ql_web/archive/refs/heads/master.tar.gz | tar xz -C /root \
Expand Down
86 changes: 42 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ work forever, the other URLs and IPs presented in this README are temporary.
- [Local development](#local-development)
- [Local development on the UI](#local-development-on-the-ui)
- [Local development on the controller (that creates PNGs and prints them)](#local-development-on-the-controller-that-creates-pngs-and-prints-them)
- [`pem-to-png`](#pem-to-png)
- [`cert-card`](#cert-card)
- [Testing the printer](#testing-the-printer)
- [Testing pem-to-png](#testing-pem-to-png)
- [Testing cert-card](#testing-cert-card)
- [Troubleshooting](#troubleshooting)
- [From the CLI: `usb.core.USBError: [Errno 13] Access denied (insufficient permissions)`](#from-the-cli-usbcoreusberror-errno-13-access-denied-insufficient-permissions)
- [From the CLI: `usb.core.USBError: [Errno 16] Resource busy`](#from-the-cli-usbcoreusberror-errno-16-resource-busy)
Expand Down Expand Up @@ -227,8 +227,7 @@ https://print-your-cert.cert-manager.io
## Staff: test things

For anyone who is in the cert-manager org and wants to test or debug
things:
For anyone who is authorized and wants to test or debug things:

- [Install tailscale](https://tailscale.com/download/).
- Run `tailscale up`, it should open something in your browser → "Sign in
Expand All @@ -243,9 +242,6 @@ things:
ssh [email protected]
```

> The public keys of each cert-manager org member have been added to the
> `authorized_keys` of the Pi.
## Running everything on the Raspberry Pi (on the booth)

Once on the booth, you will need to perform these ten tasks:
Expand Down Expand Up @@ -273,29 +269,16 @@ upgrade` on the first day of KubeCon in Amsterdam and ended up spending half
First, unplug the micro SD card from the Raspberry Pi and plug it into your
laptop using a micro-SD-to-SD card adaptor.

Then, install Raspberry OS (Debian Bookworm) on the Pi using the Imager program.
In the Imager program settings, I changed the username to `pi` and the password
to something secret (usually the default password is `raspberry`, I changed it;
see the label on the side of the Raspberry Pi).

Then, you will need to mount the micro SD card to your laptop using a
SD-to-micro-SD adaptor. Once the SD card is mounted, set the following variable
to where the SD card is mounted:
Then, install Raspberry OS on the microSD card using the Imager program.
In the Imager program settings, change the username to `certmanager` and the password
to something secret.

```sh
# On macOS:
PI=/Volumes/bootfs
```
Be sure also to enable SSH with password authentication.

Then, enable SSH on the Pi:

```bash
touch $PI/ssh
```
You can also use the imager to setup a WiFi connection, which might be helpful
with initial setup at home.

There used to be a way to configure the Wifi password without a screen and
keyboard, but that's not possible anymore with Bookworm
([source](https://www.raspberrypi.com/documentation/computers/configuration.html#connect-to-a-wireless-network)).
At the conference, you should be able to use the GUI to set up a WiFi connection.

> If the Wifi doesn't work, somehow SSH into the Pi and run `wpa_cli`:
>
Expand All @@ -322,7 +305,7 @@ keyboard, but that's not possible anymore with Bookworm
> sudo ifconfig wlan0 up
> ```
Then, unmount the micro SD card from your laptop and plug it into the Raspberry.
Then, unmount the micro SD card from your laptop and plug it into the Raspberry Pi.
### Booth: Set Up Tailscale on the Raspberry Pi
Expand Down Expand Up @@ -352,8 +335,13 @@ machine with your Tailnet in <https://login.tailscale.com/admin/machines>. That
way, you can stay logged to your tailnet but still be able to access the
Raspberry Pi.

Then, go back to your laptop and run the following command to make sure everyone
in the cert-manager org can SSH into the Pi:
#### Allowing SSH Access to cert-manager org members

If desired, the script below will allow SSH access to cert-manager org members.

This might be overkill; you can also just download any GitHub user's SSH keys
using `curl -LO https://github.com/<user>.keys` and then append the contents of
that file to `.ssh/authorized_keys`.

```bash
curl -sH "Authorization: token $(lpass show github.com -p)" https://api.github.com/orgs/cert-manager/members \
Expand Down Expand Up @@ -482,8 +470,7 @@ To create the VM `print-your-cert`, you can use the following command:
> [!NOTE]
>
> Use the GCP zone closest to the KubeCon venue. The examples below use
> `europe-west1-c` (Belgium) since the venue was in Paris (I didn't pick Paris
> as it doesn't have f1-micro VMs).
> `europe-west1-c` (Belgium). Try to pick a zone with low CO2 emissions.
> [!NOTE]
>
Expand Down Expand Up @@ -581,6 +568,17 @@ sudo systemctl restart caddy.service
EOF
```

Finally, you'll need to ensure that the tailscale ACLs allow traffic to the pi.

Visit [the Tailscale admin panel](https://login.tailscale.com/admin/acls/file) and set the "hosts" key
to include the Pi, and ensure that there's an ACL allowing traffic:

```text
"acls": [
{"action": "accept", "users": ["*"], "ports": ["raspberrypi:*"]},
]
```

### Prerequisite: install k3s on the Raspberry Pi

This prerequisite is useful both for local development and for running the
Expand Down Expand Up @@ -677,7 +675,7 @@ Now, ssh into the Raspberry Pi and launch the UI:
# From your laptop.
ssh pi docker rm -f print-your-cert-ui
ssh pi docker run -d --restart=always --name print-your-cert-ui --net=host \
-v '/home/pi/.kube/config:/home/nonroot/.kube/config' \
-v '/home/certmanager/.kube/config:/home/nonroot/.kube/config' \
ghcr.io/cert-manager/print-your-cert-ui:latest \
--issuer print-your-cert-ca \
--issuer-kind ClusterIssuer \
Expand Down Expand Up @@ -761,7 +759,7 @@ Now, SSH into the Raspberry Pi and launch the controller:
```sh
ssh pi sudo chmod a+r ~/.kube/config
ssh pi docker rm -f print-your-cert-controller
ssh pi docker run -d --restart=always --name print-your-cert-controller --privileged -v /dev/bus/usb:/dev/bus/usb -v /home/pi/.kube/config:/root/.kube/config --net=host ghcr.io/cert-manager/print-your-cert-controller:latest
ssh pi docker run -d --restart=always --name print-your-cert-controller --privileged -v /dev/bus/usb:/dev/bus/usb -v /home/certmanager/.kube/config:/root/.kube/config --net=host ghcr.io/cert-manager/print-your-cert-controller:latest
```

You can also run the "debug" printer UI (brother_ql_web) if you want to make
Expand Down Expand Up @@ -933,24 +931,24 @@ To use the guestbook, make sure the UI is running locally too (see above).
### Local development on the controller (that creates PNGs and prints them)
The controller is made in two pieces: `pem-to-png` that turns one PEM into two
PNGs, and `print-your-cert-controller` that runs `pem-to-png` every time a
The controller is made in two pieces: `cert-card` which produces a PNG with the label(s),
and `print-your-cert-controller` that runs `cert-card` every time a
certificate object in Kubernetes becomes ready.
#### `pem-to-png`
#### `cert-card`
pem-to-png is what turns a PEM file into two PNGs: `front.png` and `back.png`.
`cert-card` which produces a PNG with the label(s)
```sh
brew install imagemagick qrencode step svn
brew install imagemagick qrencode step
brew install homebrew/cask-fonts/font-open-sans
brew install homebrew/cask-fonts/font-dejavu
```
To run it, for example:
```sh
./pem-to-png <<EOF
./cert-card <<EOF
-----BEGIN CERTIFICATE-----
MIICXDCCAgOgAwIBAgIQdPaTuGSUDeosii4dbdLBgTAKBggqhkjOPQQDAjAnMSUw
IwYDVQQDExxUaGUgY2VydC1tYW5hZ2VyIG1haW50YWluZXJzMB4XDTIyMDUxNjEz
Expand Down Expand Up @@ -978,16 +976,16 @@ convert -size 230x30 -background white -font /usr/share/fonts/TTF/OpenSans-Regul
brother_ql --model QL-820NWB --printer usb://0x04f9:0x209d print --label 62 example.png
```

#### Testing pem-to-png
#### Testing cert-card

```shell=sh
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -utf8 -subj "/CN=Maël Valais <[email protected]>/O=Jetstack" -reqexts v3_req -extensions v3_ca -out ca.crt
step certificate create "CN=Foo Bar <[email protected]>" foo.crt foo.key --ca ca.crt --ca-key ca.key --password-file /dev/null
pem-to-png <foo.crt
timg pem-to-png.png
cert-card <foo.crt
timg cert-card.png
read
brother_ql --model QL-820NWB --printer usb://0x04f9:0x209d print --label 62 pem-to-png.png
brother_ql --model QL-820NWB --printer usb://0x04f9:0x209d print --label 62 cert-card.png
```

## Troubleshooting
Expand Down
45 changes: 29 additions & 16 deletions cert-card
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ set -euo pipefail
certname=${1:-}
fetchkey=${2:-}

cardcolor=${3:-"w"}

if [[ -z $certname || -z $fetchkey ]]; then
echo "usage: $0 <certname> <fetchkey>"
fi
Expand Down Expand Up @@ -67,32 +69,43 @@ cat >/tmp/crt-$certname

line1=$(
cat <<EOF
Thank you for visiting the cert-manager
booth! We hope you are enjoying
your time in Paris.
Thank you for visiting the cert-manager booth
at KubeCon NA 2024!
We hope you\'re enjoying Salt Lake City!
EOF
)

line2=$(
cat <<EOF
This card is proof that you
were there! On the back of
the card, the QR code
links to your certificate.
The QR code will allow you to download your
certificate and sign the guestbook!
$(step certificate inspect --short /tmp/crt-$certname | sed -e 's/\[\(.*\)\]/\n\1/' -e 's/Certificate (\(.*\))/Certificate\nAlgorithm: \1/' | sed 's/^ //')
EOF
)

# \( -gravity NorthEast logo.png -resize 160 -background white -alpha remove -alpha off -monochrome \) -geometry +40+20 -composite \
# \( -gravity East kubecon-eu-2022-logo.png -resize 280 -background white -alpha remove -alpha off -monochrome \) -geometry +80+10 \
convert -size 696x492 canvas:white \
\( -gravity NorthWest -font Open-Sans-Regular -pointsize 22 -fill black -annotate +0-0 "$line1" \) -geometry +0+0 \
\( -gravity NorthWest -font Open-Sans-Regular -pointsize 22 -fill black -annotate +0+115 "$line2" \) -geometry +0+0 \
\( -gravity SouthWest -font DejaVu-Sans-Mono -pointsize 22 -fill black -annotate +0+0 "$(step certificate inspect --short /tmp/crt-$certname | sed -e 's/\[\(.*\)\]/\n\1/' -e 's/Certificate (\(.*\))/Certificate\nAlgorithm: \1/' | sed 's/^ //')" \) -geometry +0+0 \
-background None -layers Flatten front-$certname.png

#convert -size 696x1109 canvas:white \
# \( -gravity NorthWest -font Open-Sans-Regular -pointsize 22 -fill black -annotate +0-0 "$line1" \) -geometry +0+0 \
# \( -gravity NorthWest -font Open-Sans-Regular -pointsize 22 -fill black -annotate +0+115 "$line2" \) -geometry +0+0 \
# \( -gravity NorthEast -font Open-Sans-Regular -pointsize 44 -fill black -annotate +0-0 "$cardcolor" \) -geometry +0+0 \
# \( -gravity SouthWest -font DejaVu-Sans-Mono -pointsize 22 -fill black -annotate +0+0 "$(step certificate inspect --short /tmp/crt-$certname | sed -e 's/\[\(.*\)\]/\n\1/' -e 's/Certificate (\(.*\))/Certificate\nAlgorithm: \1/' | sed 's/^ //')" \) -geometry +0+0 \
# -background None -layers Flatten front-$certname.png
#
# TODO: update this URL
url="http://print-your-cert.cert-manager.io/certificate?certName=$certname&fetchKey=$fetchkey"
# url="http://192.168.1.171:8080/certificate?certName=$certname&fetchKey=$fetchkey"
echo "$url" >&2
echo "$url" | qrencode --type PNG --margin 4 -o - | convert -size 696x492 canvas:white \
\( -gravity Center -monochrome -filter point -interpolate nearest - -resize 492 \) -composite back-$certname.png

echo "$url" | qrencode --type PNG --margin 4 -o - | convert -size 696x1109 canvas:white \
\( -gravity SouthWest -font Open-Sans-Regular -pointsize 22 -fill black -annotate +0-0 "$line1" \) -geometry +0+0 \
\( -gravity SouthWest -font Open-Sans-Regular -pointsize 22 -fill black -annotate +0+115 "$line2" \) -geometry +0+0 \
\( -gravity SouthEast -font Open-Sans-Regular -pointsize 44 -fill black -annotate +0-0 "$cardcolor" \) -geometry +0+0 \
\( -gravity SouthEast -annotate +415+415 -monochrome -filter point -interpolate nearest - -resize 492 \) -geometry +0+0 \
-background None -layers Flatten front-$certname.png

#echo "$url" >&2
#echo "$url" | qrencode --type PNG --margin 4 -o - | convert -size 696x1109 canvas:white \
# \( -gravity Center -monochrome -filter point -interpolate nearest - -resize 492 \) -composite back-$certname.png
4 changes: 3 additions & 1 deletion cluster_issuer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ spec:
organizationalUnits:
- cert-manager
countries: # Change for the country you're issuing in!
- FR
- US
localities: # Change for the city you're issuing in!
- Salt Lake City
duration: 438000h # 50 years.
issuerRef:
name: root-print-your-cert-ca-issuer
Expand Down
49 changes: 43 additions & 6 deletions guestbook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,28 @@

## Setup

1. Manually copied a locally built guestbook binary, litestream.yml, the systemd service, the cert, key and CA files to the remote VM.
2. Installed litestream manually, then moved litestream.yml to /etc/litestream.yml
3. Moved the systemd unit to /usr/lib/systemd/system
4. Created /var/guestbook
5. Ran the guestbook with init-db to create the db, moved it to /var/guestbook
6. Enabled litestream and the systemd unit
1. Create a VM for running the guestbook in the cert-manager-general GCP project.
- Example CLI command is below
- Be sure to use a debian-based Linux distro
2. On a running k8s cluster with cert-manager (not on the guestbook VM):
- Set up a [Google Cloud DNS secret](https://cert-manager.io/docs/configuration/acme/dns01/google/)
- Be sure to use the cert-manager-general project!
- Apply `letsencrypt-cert.yaml`
- Export the resulting cert and key
3. Manually copy the following files to the remote guestbook VM:
- Locally built guestbook binary
- litestream.yml
- guestbook.service
- The cert chain and key from Let's Encrypt
- The root CA from the Pi (used for mTLS)
4. Install litestream [manually](https://litestream.io/install/debian/) with `dpkg`
5. Move `litestream.yml` to `/etc/litestream.yml`
- Check that the bucket configuration is correct and that the VM's SA has access to the bucket
- Litestream will back the database up to GCS when a write occurs
6. Move `guestbook.service` to `/usr/lib/systemd/system`
7. Create `/var/guestbook`
8. Run `sudo guestbook -init-db -db-path /var/guestbook/guestbook.sqlite`
9. `sudo systemctl enable --now guestbook.service litestream.service`

## Root CA

Expand Down Expand Up @@ -66,3 +82,24 @@ Certificate:
40:02:20:66:ad:b0:9f:97:d9:56:ec:7c:65:71:7b:07:1d:b6:
64:4a:6c:b7:6d:c6:58:0c:1f:6a:64:d4:98:12:e5:80:50
```

## gcloud CLI for VM

```bash
gcloud compute instances create print-your-cert-guestbook-20241127-090928 \
--project=cert-manager-general \
--zone=us-central1-f \
--machine-type=e2-medium \
--network-interface=network-tier=PREMIUM,stack-type=IPV4_ONLY,subnet=default \
--maintenance-policy=MIGRATE \
--provisioning-model=STANDARD \
--service-account=guestbook-sa@cert-manager-general.iam.gserviceaccount.com \
--scopes=https://www.googleapis.com/auth/devstorage.read_write,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/trace.append \
--tags=https-server \
--create-disk=auto-delete=yes,boot=yes,device-name=print-your-cert-guestbook,image=projects/debian-cloud/global/images/debian-12-bookworm-v20241009,mode=rw,size=10,type=pd-balanced \
--no-shielded-secure-boot \
--shielded-vtpm \
--shielded-integrity-monitoring \
--labels=goog-ec-src=vm_add-gcloud \
--reservation-affinity=any
```
2 changes: 1 addition & 1 deletion guestbook/guestbook.service
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ After=network.target
# TODO: Add custom user
# User=guestbook
# Group=guestbook
ExecStart=/usr/bin/guestbook -ca-cert /var/guestbook/ca.crt -tls-chain /etc/ssl/tls.chain -tls-key /etc/ssl/tls.key -db-path /var/guestbook/guestbook.sqlite
ExecStart=/usr/bin/guestbook -ca-cert /var/guestbook/ca.crt -tls-chain /etc/ssl/tls.chain -tls-key /etc/ssl/tls.key -db-path /var/guestbook/guestbook.sqlite -listen 0.0.0.0:443
StandardOutput=journal
StandardError=journal
Type=simple
Expand Down
Loading

0 comments on commit c642e70

Please sign in to comment.