272 lines
6.9 KiB
Bash
Executable File
272 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# User-only installer for Qubes AppVM persistence model.
|
|
# Nothing is written to /usr, /etc, or other root-owned paths.
|
|
#
|
|
# Installs into $HOME:
|
|
# - nsigner -> ~/.local/bin/nsigner
|
|
# - fips/fipsctl/fipstop -> ~/.local/bin/
|
|
# - fips config -> ~/.config/fips/fips.yaml
|
|
# - user service -> ~/.config/systemd/user/fips.service
|
|
#
|
|
# Usage:
|
|
# bash install_qube_fips_nsigner.sh
|
|
# bash install_qube_fips_nsigner.sh --help
|
|
#
|
|
# Optional env vars:
|
|
# NSIGNER_VERSION=v0.0.6
|
|
# FIPS_VERSION=v0.2.0-rel
|
|
# NSIGNER_GITEA_TOKEN=<token> # if n_signer release assets are private
|
|
# NSIGNER_BINARY_URL=<direct url to nsigner_static_x86_64>
|
|
|
|
NSIGNER_VERSION="${NSIGNER_VERSION:-v0.0.6}"
|
|
FIPS_VERSION="${FIPS_VERSION:-v0.2.0-rel}"
|
|
|
|
NSIGNER_RELEASE_PAGE="https://git.laantungir.net/laantungir/n_signer/releases/tag/${NSIGNER_VERSION}"
|
|
NSIGNER_API_TAG_URL="https://git.laantungir.net/api/v1/repos/laantungir/n_signer/releases/tags/${NSIGNER_VERSION}"
|
|
NSIGNER_GIT_URL="https://git.laantungir.net/laantungir/n_signer.git"
|
|
|
|
FIPS_RELEASE_PAGE="https://github.com/jmcorgan/fips/releases/tag/${FIPS_VERSION}"
|
|
FIPS_ARCHIVE_URL="https://github.com/jmcorgan/fips/archive/refs/tags/${FIPS_VERSION}.tar.gz"
|
|
|
|
PREFIX_BIN="${HOME}/.local/bin"
|
|
PREFIX_CFG="${HOME}/.config"
|
|
PREFIX_DATA="${HOME}/.local/share/nsigner-fips-install"
|
|
SYSTEMD_USER_DIR="${HOME}/.config/systemd/user"
|
|
|
|
log() { printf "\033[1;34m[INFO]\033[0m %s\n" "$*"; }
|
|
warn() { printf "\033[1;33m[WARN]\033[0m %s\n" "$*"; }
|
|
err() { printf "\033[1;31m[ERR ]\033[0m %s\n" "$*"; }
|
|
|
|
show_help() {
|
|
cat <<EOF
|
|
Usage: bash install_qube_fips_nsigner.sh [options]
|
|
|
|
User-only install (Qubes AppVM friendly):
|
|
- n_signer ${NSIGNER_VERSION}
|
|
- FIPS ${FIPS_VERSION}
|
|
- user-level systemd service for FIPS
|
|
|
|
Options:
|
|
-h, --help Show this help and exit
|
|
|
|
Optional env vars:
|
|
NSIGNER_VERSION=v0.0.6
|
|
FIPS_VERSION=v0.2.0-rel
|
|
NSIGNER_GITEA_TOKEN=<token> # required if n_signer release assets are private
|
|
NSIGNER_BINARY_URL=<direct url to nsigner_static_x86_64>
|
|
|
|
Install paths:
|
|
~/.local/bin/nsigner
|
|
~/.local/bin/fips
|
|
~/.local/bin/fipsctl
|
|
~/.local/bin/fipstop
|
|
~/.config/fips/fips.yaml
|
|
~/.config/systemd/user/fips.service
|
|
EOF
|
|
}
|
|
|
|
require_cmd() {
|
|
command -v "$1" >/dev/null 2>&1 || {
|
|
err "Missing command: $1"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
install_build_deps() {
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
log "Installing build/runtime dependencies via apt"
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
ca-certificates curl jq tar gzip git python3 \
|
|
build-essential pkg-config libssl-dev zlib1g-dev \
|
|
rustc cargo
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
log "Installing build/runtime dependencies via dnf"
|
|
sudo dnf install -y \
|
|
ca-certificates curl jq tar gzip git python3 \
|
|
gcc make pkgconf-pkg-config openssl-devel zlib-devel \
|
|
rust cargo
|
|
else
|
|
err "Unsupported distro: need apt-get or dnf to install build dependencies"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
prepare_dirs() {
|
|
mkdir -p "${PREFIX_BIN}" "${PREFIX_CFG}/fips" "${PREFIX_DATA}" "${SYSTEMD_USER_DIR}"
|
|
}
|
|
|
|
download_nsigner_asset_url() {
|
|
local headers=()
|
|
if [[ -n "${NSIGNER_GITEA_TOKEN:-}" ]]; then
|
|
headers=(-H "Authorization: token ${NSIGNER_GITEA_TOKEN}")
|
|
fi
|
|
|
|
curl -fsSL "${headers[@]}" "${NSIGNER_API_TAG_URL}" \
|
|
| jq -r '.assets[]?.browser_download_url // empty' \
|
|
| grep -E 'nsigner_static_x86_64$' \
|
|
| head -n1 || true
|
|
}
|
|
|
|
install_nsigner() {
|
|
log "Installing n_signer ${NSIGNER_VERSION}"
|
|
log "Release page: ${NSIGNER_RELEASE_PAGE}"
|
|
|
|
local asset_url="${NSIGNER_BINARY_URL:-}"
|
|
if [[ -z "${asset_url}" ]]; then
|
|
asset_url="$(download_nsigner_asset_url)"
|
|
fi
|
|
|
|
if [[ -z "${asset_url}" ]]; then
|
|
err "Could not find downloadable n_signer x86_64 release binary for ${NSIGNER_VERSION}."
|
|
err "Provide NSIGNER_BINARY_URL or NSIGNER_GITEA_TOKEN so the release asset can be resolved."
|
|
exit 1
|
|
fi
|
|
|
|
log "Using n_signer binary URL: ${asset_url}"
|
|
if [[ -n "${NSIGNER_GITEA_TOKEN:-}" ]]; then
|
|
curl -fL -H "Authorization: token ${NSIGNER_GITEA_TOKEN}" -o "${PREFIX_BIN}/nsigner" "${asset_url}"
|
|
else
|
|
curl -fL -o "${PREFIX_BIN}/nsigner" "${asset_url}"
|
|
fi
|
|
chmod 0755 "${PREFIX_BIN}/nsigner"
|
|
log "Installed ${PREFIX_BIN}/nsigner from release binary"
|
|
}
|
|
|
|
install_fips() {
|
|
log "Installing FIPS ${FIPS_VERSION}"
|
|
log "Release page: ${FIPS_RELEASE_PAGE}"
|
|
|
|
rm -rf "${PREFIX_DATA}/fips-src"
|
|
mkdir -p "${PREFIX_DATA}/fips-src"
|
|
|
|
curl -fL -o "${PREFIX_DATA}/fips.tar.gz" "${FIPS_ARCHIVE_URL}"
|
|
tar -xzf "${PREFIX_DATA}/fips.tar.gz" -C "${PREFIX_DATA}/fips-src" --strip-components=1
|
|
|
|
(
|
|
cd "${PREFIX_DATA}/fips-src"
|
|
cargo build --release
|
|
|
|
install -m 0755 ./target/release/fips "${PREFIX_BIN}/fips"
|
|
install -m 0755 ./target/release/fipsctl "${PREFIX_BIN}/fipsctl"
|
|
|
|
if [[ -x ./target/release/fipstop ]]; then
|
|
install -m 0755 ./target/release/fipstop "${PREFIX_BIN}/fipstop"
|
|
fi
|
|
)
|
|
|
|
log "Installed FIPS binaries into ${PREFIX_BIN}"
|
|
}
|
|
|
|
write_fips_user_config() {
|
|
local cfg="${PREFIX_CFG}/fips/fips.yaml"
|
|
if [[ -f "${cfg}" ]]; then
|
|
warn "Keeping existing ${cfg}"
|
|
return
|
|
fi
|
|
|
|
cat >"${cfg}" <<'EOF'
|
|
# User-local FIPS config for AppVM persistence
|
|
# Edit peers to join your mesh.
|
|
|
|
node:
|
|
identity:
|
|
persistent: true
|
|
|
|
# Try userspace tun name; adjust if your environment requires a different setting.
|
|
tun:
|
|
enabled: true
|
|
name: fips0
|
|
mtu: 1280
|
|
|
|
dns:
|
|
enabled: true
|
|
bind_addr: "127.0.0.1"
|
|
port: 5354
|
|
|
|
transports:
|
|
udp:
|
|
bind_addr: "0.0.0.0:2121"
|
|
tcp:
|
|
bind_addr: "0.0.0.0:8443"
|
|
|
|
peers: []
|
|
EOF
|
|
|
|
log "Wrote ${cfg}"
|
|
}
|
|
|
|
write_fips_user_service() {
|
|
local svc="${SYSTEMD_USER_DIR}/fips.service"
|
|
cat >"${svc}" <<EOF
|
|
[Unit]
|
|
Description=FIPS mesh daemon (user)
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=${PREFIX_BIN}/fips --config ${PREFIX_CFG}/fips/fips.yaml
|
|
Restart=on-failure
|
|
RestartSec=2
|
|
Environment=RUST_LOG=info
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
EOF
|
|
|
|
log "Wrote ${svc}"
|
|
}
|
|
|
|
start_fips_user_service() {
|
|
require_cmd systemctl
|
|
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable --now fips
|
|
|
|
if systemctl --user is-active --quiet fips; then
|
|
log "fips user service: active"
|
|
else
|
|
warn "fips user service is not active"
|
|
warn "Check logs with: journalctl --user -u fips -n 200 --no-pager"
|
|
fi
|
|
}
|
|
|
|
post_checks() {
|
|
export PATH="${PREFIX_BIN}:${PATH}"
|
|
|
|
log "Running post-install checks"
|
|
require_cmd nsigner
|
|
require_cmd fips
|
|
require_cmd fipsctl
|
|
|
|
nsigner --version || true
|
|
fips --version || true
|
|
|
|
log "User binaries installed in: ${PREFIX_BIN}"
|
|
log "If needed, add to shell PATH: export PATH=\"${PREFIX_BIN}:\$PATH\""
|
|
log "Edit peers in: ${PREFIX_CFG}/fips/fips.yaml"
|
|
}
|
|
|
|
main() {
|
|
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
show_help
|
|
exit 0
|
|
fi
|
|
|
|
install_build_deps
|
|
prepare_dirs
|
|
install_nsigner
|
|
install_fips
|
|
write_fips_user_config
|
|
write_fips_user_service
|
|
start_fips_user_service
|
|
post_checks
|
|
|
|
log "Completed user-only install of n_signer + FIPS"
|
|
}
|
|
|
|
main "$@"
|