mirror of
https://github.com/aphrody-labs/mullvadvpn-app.git
synced 2026-10-14 06:19:11 +00:00
Merge branch 'add-container-sigstore'
This commit is contained in:
5 files changed
+188
No files matched your search
@@ -11,6 +11,10 @@ on:
|
||||
- ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
|
||||
- android/gradle/verification-metadata.xml
|
||||
- android/gradle/wrapper/gradle-wrapper.properties
|
||||
- building/build-and-publish.sh
|
||||
- building/mullvad-app-container-signing.asc
|
||||
- building/linux-container-image-tag.txt
|
||||
- building/android-container-image-tag.txt
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
verify-signatures:
|
||||
|
||||
File renamed without changes.
@@ -0,0 +1,68 @@
|
||||
# Mullvad VPN app build containers
|
||||
|
||||
Substitute `${repo}` with the actual absolute path to this repository
|
||||
|
||||
## Building and publishing a container image
|
||||
|
||||
These instructions describe how to set up the trusted machine that builds, signs and publishes
|
||||
the container images to ghcr.io.
|
||||
|
||||
If you `sudo` into a `build` account that do the builds, you need to set the permissions on the tty,
|
||||
so podman can ask for the passphrase for the gpg key:
|
||||
```
|
||||
realuser@server $ sudo chown build:build $(tty)
|
||||
realuser@server $ sudo -u build -i
|
||||
```
|
||||
|
||||
|
||||
Configure podman to store signatures when building and pushing images. `~/.config/containers/registries.d/mullvad.yaml`:
|
||||
```yml
|
||||
docker:
|
||||
ghcr.io/mullvad:
|
||||
sigstore-staging: file://${repo}/building/sigstore
|
||||
```
|
||||
|
||||
Build and publish the container image. Tag it with the github hash of the current commit
|
||||
```
|
||||
git checkout -b update-build-container
|
||||
|
||||
./build-and-publish.sh (linux|android)
|
||||
|
||||
git push # And create a PR
|
||||
```
|
||||
|
||||
|
||||
## Pulling, verifying and using build images
|
||||
|
||||
These instructions describe how anyone can pull the images and verify them with GPG before using them.
|
||||
|
||||
Copy the Mullvad app container signing GPG key to somewhere outside the repository (so a `git pull` can't overwrite it with a malicious key):
|
||||
```
|
||||
cp ${repo}/building/mullvad-app-container-signing.asc /path/to/mullvad-app-container-signing.asc
|
||||
```
|
||||
|
||||
Configure a strict policy for podman when pulling from `ghcr.io/mullvad`. `~/.config/containers/policy.json`:
|
||||
```json
|
||||
{
|
||||
"default": [{ "type": "insecureAcceptAnything" }],
|
||||
"transports": {
|
||||
"docker": {
|
||||
"ghcr.io/mullvad": [
|
||||
{
|
||||
"type": "signedBy",
|
||||
"keyType": "GPGKeys",
|
||||
"keyPath": "/path/to/mullvad-app-container-signing.asc"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Configure podman to fetch image signatures from the in-repo sigstore directory. `~/.config/containers/registries.d/mullvad.yaml`:
|
||||
```yml
|
||||
docker:
|
||||
ghcr.io/mullvad:
|
||||
sigstore: file://${repo}/building/sigstore
|
||||
```
|
||||
|
||||
Executable
+95
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script will build, sign and publish the Mullvad VPN app build image(s)
|
||||
# for either linux or android, depending on the first argument.
|
||||
# Please see `README.md` for setup instructions *before* running this script
|
||||
|
||||
set -eu
|
||||
|
||||
CONTAINER_SIGNING_KEY_FINGERPRINT=1E551687D67F5FD820BEF2C4D7C17F87A0D3D215
|
||||
REGISTRY_HOST="ghcr.io"
|
||||
REGISTRY_ORG="mullvad"
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
REPO_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
|
||||
cd "$REPO_DIR"
|
||||
|
||||
source "$REPO_DIR/scripts/utils/log"
|
||||
|
||||
tag="$(git rev-parse --short HEAD)"
|
||||
|
||||
case ${1-:""} in
|
||||
linux)
|
||||
container_name="mullvadvpn-app-build"
|
||||
containerfile_path="$SCRIPT_DIR/Dockerfile"
|
||||
container_context_dir="$REPO_DIR"
|
||||
container_image_tag_path="$SCRIPT_DIR/linux-container-image-tag.txt"
|
||||
;;
|
||||
android)
|
||||
container_name="mullvadvpn-app-build-android"
|
||||
containerfile_path="$REPO_DIR/android/docker/Dockerfile"
|
||||
container_context_dir="$REPO_DIR/android/docker/"
|
||||
container_image_tag_path="$SCRIPT_DIR/android-container-image-tag.txt"
|
||||
;;
|
||||
*)
|
||||
log_error "Invalid platform. Specify 'linux' or 'android' as first argument"
|
||||
exit 1
|
||||
esac
|
||||
full_container_name="$REGISTRY_HOST/$REGISTRY_ORG/$container_name"
|
||||
|
||||
log_header "Building $full_container_name tagged as '$tag' and 'latest'"
|
||||
podman build -f "$containerfile_path" "$container_context_dir" --no-cache \
|
||||
-t "$full_container_name:$tag" \
|
||||
-t "$full_container_name:latest"
|
||||
|
||||
# Temporary directory to store image digest and signature in.
|
||||
# This is a hack since two consecutive `podman push` seems
|
||||
# to overwrite the signatures. We want to keep the signature
|
||||
# for both the 'latest' and '$tag' tags.
|
||||
tmp_signature_dir=$(mktemp -d)
|
||||
|
||||
function delete_tmp_signature_dir {
|
||||
rm -rf "$tmp_signature_dir"
|
||||
}
|
||||
trap 'delete_tmp_signature_dir' EXIT
|
||||
|
||||
log_header "Pushing $full_container_name:latest"
|
||||
podman push "$full_container_name:latest" \
|
||||
--sign-by $CONTAINER_SIGNING_KEY_FINGERPRINT \
|
||||
--digestfile "$tmp_signature_dir/digest_latest"
|
||||
|
||||
digest=$(cat "$tmp_signature_dir/digest_latest")
|
||||
log_success "Pushed image with digest $digest"
|
||||
# Backup the signature so we can restore it after the second podman push later
|
||||
signature_dir="$SCRIPT_DIR/sigstore/$REGISTRY_ORG/$container_name@${digest/:/=}"
|
||||
if [[ -f "$signature_dir/signature-2" ]]; then
|
||||
log_error "Did not expect $signature_dir/signature-2 to exist"
|
||||
exit 1
|
||||
fi
|
||||
cp "$signature_dir/signature-1" "$tmp_signature_dir/signature-2"
|
||||
|
||||
log_header "Pushing $full_container_name:$tag"
|
||||
podman push "$full_container_name:$tag" \
|
||||
--sign-by $CONTAINER_SIGNING_KEY_FINGERPRINT \
|
||||
--digestfile "$tmp_signature_dir/digest_$tag"
|
||||
|
||||
if ! cmp -s "$tmp_signature_dir/digest_latest" "$tmp_signature_dir/digest_$tag"; then
|
||||
log_error "Digests differ between 'latest' and '$tag' pushes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp "$tmp_signature_dir/signature-2" "$signature_dir/"
|
||||
|
||||
log_info "Storing container tag to $container_image_tag_path"
|
||||
echo "$tag" > "$container_image_tag_path"
|
||||
|
||||
log_header "Commiting signatures and new tag name to git"
|
||||
git add "$container_image_tag_path" "$signature_dir"
|
||||
GPG_TTY=$(tty) git commit -S -m "Updating build container for $1 to $tag"
|
||||
|
||||
log_success "***********************"
|
||||
log_success ""
|
||||
log_success "Done building and pushing $full_container_name with tags '$tag' and 'latest'"
|
||||
log_success "Make sure to push the changes to git"
|
||||
log_success ""
|
||||
log_success "***********************"
|
||||
@@ -0,0 +1,21 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEY2pmvhYJKwYBBAHaRw8BAQdAOOJocdP7MXSesmmMuA7JXxo0ZVV7aiT1ZFxo
|
||||
oGKmAcS0NU11bGx2YWQgVlBOIGFwcCAoQ29udGFpbmVyIHNpZ25pbmcpIDxhcHBA
|
||||
bXVsbHZhZC5uZXQ+iIoEExYKADICGwMCF4AWIQQeVRaH1n9f2CC+8sTXwX+HoNPS
|
||||
FQUCY4X7/AILCQIVCgUWAgMBAAIeBQAKCRDXwX+HoNPSFRSUAPwIcRuvdzVqufOj
|
||||
UsbK+qEz9WTqR2QMSGU2LPtkFJyygAEAzhaAFgklONznxpPx0BWI7/hCkYmg2siI
|
||||
/KfdA3wkkgWJAjMEEAEIAB0WIQShGYcC/D4KCamuW3XVodTyZt6N3wUCY4X68wAK
|
||||
CRDVodTyZt6N39SuD/9JkAAT06imUiB+bKs6BbdRFPnztAxcQPJztbAmIdch2Nly
|
||||
6gQyxnrbf0voTBcFs0idRyzYcCgliq+7SqHBgOHtGnOgNH1IDNkEnU2lF4kioGnY
|
||||
w+6hETBb5KH/ywze+p1fEe8+Id9l5mfnZJwvciSpMKc3CQKMSGzPgPSdTjgN4TtF
|
||||
U6ckwd3QAVMl1lOp6enznnLdtjnWlQU/qFI97YY7r7IdkOhVeI5oENMBPJWjlEZr
|
||||
9wHBedm0ZatplW16myikJZJ/VCGU0HLRNz+Ki6FEvV4VcxLKSlCkBwdk3mjpb++r
|
||||
CKqgyEZOH47icK3blAbZvYZVHSl4P5BMW67YLUAp627PpWllyJDKt5Tt+gbGJ6Q3
|
||||
Jwaw6/eDObEVArV/bnNnk3T07IcDotlcm0HUIUJeVKLuBQOsyo6zyRW6iCzwbgHN
|
||||
Bt8N99DQE2d9nySkzGDGZOmHjRLMF/q7NPbzdI0bwoE3D8S8w1VSKVqmGbkfR8W8
|
||||
a7ZibDR3W7x6ofi9owFd9XEM/SQGDU99FxvLLHUy//2Ox/iPxdUWygzWchneDaFL
|
||||
MnGJ5GEgsfz7zdzBjXcYxU3jEdEHzlkiRcdqM8mjTM+1xmOT3ed30sf04uHHYzu6
|
||||
Gm/EaXoAwZGtr/HZ8teR6yEr+R57JrICOVOLHYbjSprJmOWBcskMefpiwK9EUA==
|
||||
=0W2k
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
Reference in new issue
Block a user