diff --git a/CHANGELOG.md b/CHANGELOG.md index a038073..fe541b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +#### Packaging and Deployment + +- Arch Linux AUR packaging for `fips` (release) and `fips-git` + (development) packages with sysusers.d/tmpfiles.d integration + ([#21](https://github.com/jmcorgan/fips/pull/21), + [@dskvr](https://github.com/dskvr)) + ### Fixed - Control socket path detection in fipsctl and fipstop now checks for diff --git a/packaging/Makefile b/packaging/Makefile index a9b7cd4..d5b27d8 100644 --- a/packaging/Makefile +++ b/packaging/Makefile @@ -7,6 +7,7 @@ # make deb Build a Debian/Ubuntu .deb package # make tarball Build a systemd install tarball # make ipk Build an OpenWrt .ipk package +# make aur Build fips-git AUR package and validate with namcap # make all Build deb and tarball (default) # make clean Remove deploy/ directory @@ -14,7 +15,7 @@ SHELL := /bin/bash PACKAGING_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) PROJECT_ROOT := $(abspath $(PACKAGING_DIR)/..) -.PHONY: all deb tarball ipk clean +.PHONY: all deb tarball ipk aur clean all: deb tarball @@ -27,5 +28,8 @@ tarball: ipk: @bash $(PACKAGING_DIR)/openwrt/build-ipk.sh +aur: + @bash $(PACKAGING_DIR)/aur/build-aur.sh + clean: rm -rf $(PROJECT_ROOT)/deploy diff --git a/packaging/README.md b/packaging/README.md index aef9864..3658adc 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -9,6 +9,7 @@ All build outputs go to `deploy/` at the project root. make deb # Debian/Ubuntu .deb make tarball # systemd install tarball make ipk # OpenWrt .ipk +make aur # Arch Linux AUR package (fips-git, local build + namcap) make all # deb + tarball (default) ``` @@ -16,6 +17,7 @@ make all # deb + tarball (default) ```text packaging/ + aur/ Arch Linux AUR packaging (PKGBUILD, supporting files) common/ Shared assets (default config, hosts file) debian/ Debian/Ubuntu .deb packaging via cargo-deb systemd/ Generic Linux systemd tarball packaging @@ -78,6 +80,23 @@ bash packaging/openwrt/build-ipk.sh --arch mipsel See [openwrt/README.md](openwrt/README.md) for router-specific installation instructions. +### Arch Linux (AUR) + +Two AUR packages are maintained: `fips` (release, builds from tagged +tarball) and `fips-git` (development, builds from latest git master). + +```sh +# Build and validate locally (git variant) +make aur + +# Install from AUR +yay -S fips-git # development build from master +yay -S fips # release build from latest tag +``` + +See [aur/README.md](aur/README.md) for AUR publication instructions +and maintainer guide. + ## Shared Assets `common/` contains assets used across packaging formats: diff --git a/packaging/aur/.gitignore b/packaging/aur/.gitignore new file mode 100644 index 0000000..efbe4fd --- /dev/null +++ b/packaging/aur/.gitignore @@ -0,0 +1,5 @@ +src/ +pkg/ +fips/ +*.pkg.tar.zst +*.log diff --git a/packaging/aur/PKGBUILD b/packaging/aur/PKGBUILD new file mode 100644 index 0000000..ceefd93 --- /dev/null +++ b/packaging/aur/PKGBUILD @@ -0,0 +1,63 @@ +# Maintainer: Johnathan Corgan +pkgname=fips +pkgver=0.1.0 +pkgrel=1 +pkgdesc="Distributed, decentralized network routing protocol for mesh nodes" +url="https://github.com/jmcorgan/fips" +license=('MIT') +arch=('x86_64') +depends=('gcc-libs' 'glibc') +makedepends=('cargo') +optdepends=('systemd-resolved: .fips DNS resolution') +conflicts=('fips-git') +backup=('etc/fips/fips.yaml' 'etc/fips/hosts') +install=fips.install +source=("$pkgname-$pkgver.tar.gz::https://github.com/jmcorgan/fips/archive/v$pkgver.tar.gz" + "fips.sysusers" + "fips.tmpfiles") +b2sums=('SKIP' # tarball hash computed by CI via updpkgsums on release + '25a0552f3d67d12f48dfd40fe4776ad7c46afeeab76bd2674b48e234db3c145810a24569a8c1a7f4c186eb546f0fae2ebe1550080c0e91d8eb72ba9934c752a6' + '844257cb8e09cd935d0d6345922d0f3ec777411daca20e24175b346a7b3cb95ebce12631a9466c4d94f1588ed8d62d92514ff24025ccfd0efb358e542b454b00') +options=('!lto') + +prepare() { + cd "$pkgname-$pkgver" + cargo fetch --locked --target "$(rustc -vV | sed -n 's/host: //p')" +} + +build() { + cd "$pkgname-$pkgver" + export CARGO_TARGET_DIR=target + export SOURCE_DATE_EPOCH=$(stat -c %Y Cargo.toml) + cargo build --frozen --release +} + +check() { + cd "$pkgname-$pkgver" + export CARGO_TARGET_DIR=target + cargo test --frozen --lib +} + +package() { + cd "$pkgname-$pkgver" + + # Binaries + install -Dm0755 target/release/fips "$pkgdir/usr/bin/fips" + install -Dm0755 target/release/fipsctl "$pkgdir/usr/bin/fipsctl" + install -Dm0755 target/release/fipstop "$pkgdir/usr/bin/fipstop" + + # Systemd service files (from packaging/debian/ -- correct /usr/bin/ paths) + install -Dm0644 packaging/debian/fips.service "$pkgdir/usr/lib/systemd/system/fips.service" + install -Dm0644 packaging/debian/fips-dns.service "$pkgdir/usr/lib/systemd/system/fips-dns.service" + + # Config files (from packaging/common/) + install -Dm0600 packaging/common/fips.yaml "$pkgdir/etc/fips/fips.yaml" + install -Dm0644 packaging/common/hosts "$pkgdir/etc/fips/hosts" + + # System integration (from local source files in $srcdir) + install -Dm0644 "$srcdir/fips.sysusers" "$pkgdir/usr/lib/sysusers.d/fips.conf" + install -Dm0644 "$srcdir/fips.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/fips.conf" + + # License + install -Dm0644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE" +} diff --git a/packaging/aur/PKGBUILD-git b/packaging/aur/PKGBUILD-git new file mode 100644 index 0000000..9620372 --- /dev/null +++ b/packaging/aur/PKGBUILD-git @@ -0,0 +1,70 @@ +# Maintainer: Johnathan Corgan +pkgname=fips-git +pkgver=0.1.0.r19.g8c349f5 +pkgrel=1 +pkgdesc="Distributed, decentralized network routing protocol for mesh nodes" +url="https://github.com/jmcorgan/fips" +license=('MIT') +arch=('x86_64') +depends=('gcc-libs' 'glibc') +makedepends=('cargo' 'git') +optdepends=('systemd-resolved: .fips DNS resolution') +provides=('fips') +conflicts=('fips') +backup=('etc/fips/fips.yaml' 'etc/fips/hosts') +install=fips.install +source=("fips::git+https://github.com/jmcorgan/fips.git" + "fips.sysusers" + "fips.tmpfiles") +b2sums=('SKIP' + '25a0552f3d67d12f48dfd40fe4776ad7c46afeeab76bd2674b48e234db3c145810a24569a8c1a7f4c186eb546f0fae2ebe1550080c0e91d8eb72ba9934c752a6' + '844257cb8e09cd935d0d6345922d0f3ec777411daca20e24175b346a7b3cb95ebce12631a9466c4d94f1588ed8d62d92514ff24025ccfd0efb358e542b454b00') +options=('!lto') + +pkgver() { + cd fips + git describe --long --abbrev=7 2>/dev/null | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g' \ + || printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short=7 HEAD)" +} + +prepare() { + cd fips + cargo fetch --locked --target "$(rustc -vV | sed -n 's/host: //p')" +} + +build() { + cd fips + export CARGO_TARGET_DIR=target + export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct) + cargo build --frozen --release +} + +check() { + cd fips + export CARGO_TARGET_DIR=target + cargo test --frozen --lib +} + +package() { + cd fips + + # Binaries + install -Dm0755 target/release/fips "$pkgdir/usr/bin/fips" + install -Dm0755 target/release/fipsctl "$pkgdir/usr/bin/fipsctl" + install -Dm0755 target/release/fipstop "$pkgdir/usr/bin/fipstop" + + # Systemd service files (from packaging/debian/ -- correct /usr/bin/ paths) + install -Dm0644 packaging/debian/fips.service "$pkgdir/usr/lib/systemd/system/fips.service" + install -Dm0644 packaging/debian/fips-dns.service "$pkgdir/usr/lib/systemd/system/fips-dns.service" + + # Config files (from packaging/common/) + install -Dm0600 packaging/common/fips.yaml "$pkgdir/etc/fips/fips.yaml" + install -Dm0644 packaging/common/hosts "$pkgdir/etc/fips/hosts" + + # System integration (from local source files in $srcdir) + install -Dm0644 "$srcdir/fips.sysusers" "$pkgdir/usr/lib/sysusers.d/fips.conf" + install -Dm0644 "$srcdir/fips.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/fips.conf" + + # License + install -Dm0644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE" +} diff --git a/packaging/aur/README.md b/packaging/aur/README.md new file mode 100644 index 0000000..8da8bd4 --- /dev/null +++ b/packaging/aur/README.md @@ -0,0 +1,307 @@ +# AUR Publication Guide for FIPS + +This directory contains Arch Linux packaging files for two AUR packages: + +- **`fips`** -- release package, builds from a tagged GitHub tarball +- **`fips-git`** -- development package, builds from latest git master + +## Overview + +### Files in This Directory + +| File | Purpose | +|------|---------| +| `PKGBUILD` | Release package build script (builds from tagged tarball) | +| `PKGBUILD-git` | Git development package build script (builds from latest master) | +| `fips.install` | Pacman post-install/post-upgrade messaging | +| `fips.sysusers` | sysusers.d fragment (creates `fips` system group) | +| `fips.tmpfiles` | tmpfiles.d fragment (creates `/run/fips/`) | +| `fips.service` | Symlink to `../debian/fips.service` | +| `fips-dns.service` | Symlink to `../debian/fips-dns.service` | + +Both PKGBUILDs reference files from `packaging/debian/` (service files) and +`packaging/common/` (config files) at build time. These are pulled from the +source tree during `package()`, not from this directory. + +## Local Build and Validation + +Build and validate the `-git` package locally using the Makefile target: + +```sh +make -C packaging aur +``` + +This runs `makepkg -sf` followed by `namcap` on the resulting package. + +For manual testing of individual steps: + +```sh +# Build the -git package (uses local git clone, no network download needed) +cd packaging/aur +makepkg -sf -p PKGBUILD-git + +# Lint the built package +namcap fips-git-*.pkg.tar.zst + +# Lint the PKGBUILD itself +namcap PKGBUILD-git +``` + +The `-git` variant builds from the local git clone, so no network download is +needed for the source. The release PKGBUILD requires a tagged release tarball +on GitHub to build and cannot be tested without one. + +## Prerequisites for AUR Publication + +### 1. AUR Account + +Register at using the maintainer email +(`jcorgan@corganlabs.com`). + +### 2. SSH Key + +Generate a dedicated ed25519 key for AUR access: + +```sh +ssh-keygen -t ed25519 -f ~/.ssh/aur -C "jcorgan@corganlabs.com" -N "" +``` + +### 3. SSH Config + +Add the following to `~/.ssh/config`: + +```text +Host aur.archlinux.org + IdentityFile ~/.ssh/aur + User aur +``` + +### 4. Register the Key with AUR + +1. Copy the public key contents: + ```sh + cat ~/.ssh/aur.pub + ``` +2. Go to -> My Account -> SSH Public Key +3. Paste the public key and save + +### 5. Test the Connection + +```sh +ssh -T aur@aur.archlinux.org +``` + +This should print a welcome message or your username. If it hangs or +returns "Permission denied", verify that the key was added correctly. + +## Initial Push -- fips-git Package + +Follow these steps exactly. Each command is concrete and copy-pasteable. + +### Step 1: Clone the AUR Repo + +Cloning an AUR repo that does not yet exist creates the package entry: + +```sh +git clone ssh://aur@aur.archlinux.org/fips-git.git /tmp/aur-fips-git +``` + +If the package does not exist yet, this creates an empty repository. + +### Step 2: Copy Required Files + +From the root of the fips source repository: + +```sh +cp packaging/aur/PKGBUILD-git /tmp/aur-fips-git/PKGBUILD +cp packaging/aur/fips.install /tmp/aur-fips-git/ +cp packaging/aur/fips.sysusers /tmp/aur-fips-git/ +cp packaging/aur/fips.tmpfiles /tmp/aur-fips-git/ +``` + +Only `PKGBUILD`, `.SRCINFO`, and files referenced in `source=()` or `install=` +go into the AUR repo. Service files and config files are NOT copied -- they +come from the source tree at build time via the `source=()` git clone. + +### Step 3: Generate .SRCINFO + +This step is **critical** -- AUR requires `.SRCINFO` alongside every PKGBUILD: + +```sh +cd /tmp/aur-fips-git +makepkg --printsrcinfo > .SRCINFO +``` + +### Step 4: Commit and Push + +```sh +cd /tmp/aur-fips-git +git add PKGBUILD .SRCINFO fips.install fips.sysusers fips.tmpfiles +git commit -m "Initial import of fips-git" +git push +``` + +### Step 5: Verify + +Visit -- the package should +appear within a few seconds of the push. + +## Initial Push -- fips Release Package + +Same pattern as the `-git` package, but using the release PKGBUILD. + +### Step 1: Clone the AUR Repo + +```sh +git clone ssh://aur@aur.archlinux.org/fips.git /tmp/aur-fips +``` + +### Step 2: Copy Files + +From the root of the fips source repository: + +```sh +cp packaging/aur/PKGBUILD /tmp/aur-fips/PKGBUILD +cp packaging/aur/fips.install /tmp/aur-fips/ +cp packaging/aur/fips.sysusers /tmp/aur-fips/ +cp packaging/aur/fips.tmpfiles /tmp/aur-fips/ +``` + +### Step 3: Verify the Release PKGBUILD + +Before pushing, ensure the PKGBUILD is correct for the current release: + +1. Verify `pkgver` matches the latest tagged release (currently `0.1.0`) +2. If the tarball b2sum is a placeholder, download the tarball and compute: + ```sh + curl -sL https://github.com/jmcorgan/fips/archive/v0.1.0.tar.gz | b2sum | cut -d' ' -f1 + ``` +3. Update the first entry in `b2sums=()` in the PKGBUILD with the real hash + +### Step 4: Generate .SRCINFO + +```sh +cd /tmp/aur-fips +makepkg --printsrcinfo > .SRCINFO +``` + +### Step 5: Commit and Push + +```sh +cd /tmp/aur-fips +git add PKGBUILD .SRCINFO fips.install fips.sysusers fips.tmpfiles +git commit -m "Initial import of fips 0.1.0" +git push +``` + +### Step 6: Verify + +Visit -- the package should appear. + +## Verification + +After both packages are pushed, verify everything works end-to-end. + +### Search AUR + +```sh +yay -Ss fips +``` + +Or visit in a browser. + +### Install the Git Variant + +```sh +yay -S fips-git +``` + +### Verify the Installation + +```sh +fips --version +fipsctl --version +fipstop --version +systemctl cat fips.service +cat /usr/lib/sysusers.d/fips.conf +cat /usr/lib/tmpfiles.d/fips.conf +``` + +### Test the Release Variant + +On a separate machine or after removing `fips-git`: + +```sh +yay -R fips-git +yay -S fips +``` + +Then run the same verification commands above. + +## GitHub Secrets for CI (Phase 4 Preparation) + +For automated AUR updates via GitHub Actions, a separate SSH key is needed. + +### Step 1: Generate a CI-Specific Key + +Generate a **separate** passphrase-less ed25519 key for CI. Do NOT reuse the +personal key from the prerequisites section: + +```sh +ssh-keygen -t ed25519 -f /tmp/github-aur -C "github-actions-aur" -N "" +``` + +### Step 2: Add the Public Key to AUR + +AUR supports multiple SSH keys per account. Add the contents of +`/tmp/github-aur.pub` to the AUR account alongside the personal key: + +1. Go to -> My Account -> SSH Public Key +2. Paste the new public key (you can have multiple keys, one per line) + +### Step 3: Add the Private Key to GitHub + +1. Go to +2. Create a new repository secret named `AUR_SSH_PRIVATE_KEY` +3. Paste the contents of `/tmp/github-aur` (the private key file) + +### Step 4: Clean Up Local Key Files + +```sh +rm /tmp/github-aur /tmp/github-aur.pub +``` + +## Updating Packages + +### fips-git (Development) + +AUR convention is to only push when the PKGBUILD itself changes (new +dependencies, build flags, source URL changes, etc.). Users get new builds +automatically via: + +```sh +yay -Syu --devel +``` + +Do **NOT** push pkgver-only bumps to the AUR -- the `pkgver()` function +handles versioning at build time. + +### fips (Release) + +Push an update when a new version is tagged. The steps are: + +1. Update `pkgver` in the PKGBUILD to the new version +2. Reset `pkgrel` to `1` +3. Recompute the tarball b2sum: + ```sh + curl -sL https://github.com/jmcorgan/fips/archive/v.tar.gz | b2sum | cut -d' ' -f1 + ``` +4. Update `b2sums=()` with the new hash +5. Regenerate `.SRCINFO`: + ```sh + makepkg --printsrcinfo > .SRCINFO + ``` +6. Commit and push both `PKGBUILD` and `.SRCINFO` + +Phase 4 CI automation will handle this workflow automatically on new GitHub +releases. diff --git a/packaging/aur/build-aur.sh b/packaging/aur/build-aur.sh new file mode 100755 index 0000000..5a25418 --- /dev/null +++ b/packaging/aur/build-aur.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Build the fips-git AUR package and validate with namcap. +# +# Usage: ./build-aur.sh +# +# Prerequisites: makepkg, namcap (pacman -S namcap) +# Output: fips-git-*.pkg.tar.zst in packaging/aur/ + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +# Ensure we're on Arch Linux with makepkg available +if ! command -v makepkg &>/dev/null; then + echo "makepkg not found. This script requires Arch Linux." >&2 + exit 1 +fi + +if ! command -v namcap &>/dev/null; then + echo "namcap not found. Install with: pacman -S namcap" >&2 + exit 1 +fi + +cd "${SCRIPT_DIR}" + +echo "Building fips-git AUR package..." +makepkg -sf -p PKGBUILD-git + +echo "Running namcap validation..." +namcap PKGBUILD-git +namcap fips-git-*.pkg.tar.zst + +echo "Done." diff --git a/packaging/aur/fips-dns.service b/packaging/aur/fips-dns.service new file mode 120000 index 0000000..262b472 --- /dev/null +++ b/packaging/aur/fips-dns.service @@ -0,0 +1 @@ +../debian/fips-dns.service \ No newline at end of file diff --git a/packaging/aur/fips.install b/packaging/aur/fips.install new file mode 100644 index 0000000..616b36c --- /dev/null +++ b/packaging/aur/fips.install @@ -0,0 +1,17 @@ +post_install() { + echo ":: Enable the FIPS daemon:" + echo " systemctl enable --now fips.service" + echo "" + echo ":: Optional: enable .fips DNS routing (requires systemd-resolved):" + echo " systemctl enable --now fips-dns.service" + echo "" + echo ":: Allow non-root access to fipsctl/fipstop:" + echo " usermod -aG fips \$USER" + echo "" + echo ":: Edit /etc/fips/fips.yaml before starting." +} + +post_upgrade() { + echo ":: Restart the daemon if running:" + echo " systemctl restart fips.service" +} diff --git a/packaging/aur/fips.service b/packaging/aur/fips.service new file mode 120000 index 0000000..875e594 --- /dev/null +++ b/packaging/aur/fips.service @@ -0,0 +1 @@ +../debian/fips.service \ No newline at end of file diff --git a/packaging/aur/fips.sysusers b/packaging/aur/fips.sysusers new file mode 100644 index 0000000..dd119fc --- /dev/null +++ b/packaging/aur/fips.sysusers @@ -0,0 +1 @@ +g fips - - diff --git a/packaging/aur/fips.tmpfiles b/packaging/aur/fips.tmpfiles new file mode 100644 index 0000000..3cb9cdf --- /dev/null +++ b/packaging/aur/fips.tmpfiles @@ -0,0 +1 @@ +d /run/fips 0750 root fips -