#!/bin/bash # ============================================================================== # 02-install-fips.sh # # Run inside sys-fips to install FIPS binaries, dependencies, config, and service. # # Usage: # sudo bash 02-install-fips.sh # ============================================================================== set -euo pipefail echo "=== sys-fips Installation ===" echo "" if [ "$(id -u)" -ne 0 ]; then echo "✗ This script must be run as root (sudo)" exit 1 fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" # ── Install dependencies ──────────────────────────────────────────────────────── echo "Installing system dependencies..." apt-get update -qq apt-get install -y --no-install-recommends \ iproute2 iputils-ping dnsutils \ dnsmasq iptables nftables \ curl python3 jq \ openssh-server openssh-client \ iperf3 2>/dev/null || { echo "⚠ Some packages may not be available — continuing" } echo "✓ Dependencies installed" # ── Ensure control-socket access group exists ────────────────────────────────── if ! getent group fips >/dev/null 2>&1; then groupadd --system fips echo "✓ Created system group: fips" else echo "✓ Group exists: fips" fi # ── Locate binaries ───────────────────────────────────────────────────────────── echo "" echo "Looking for FIPS binaries..." FIPS_BIN="" FIPSCTL_BIN="" FIPSTOP_BIN="" LOCAL_BIN_DIR="${ROOT_DIR}/bin" LOCAL_RELEASE_DIR="${ROOT_DIR}/fips/target/release" # Preferred: binaries prebuilt in this same repo copy [ -z "$FIPS_BIN" ] && [ -f "${LOCAL_BIN_DIR}/fips" ] && FIPS_BIN="${LOCAL_BIN_DIR}/fips" [ -z "$FIPSCTL_BIN" ] && [ -f "${LOCAL_BIN_DIR}/fipsctl" ] && FIPSCTL_BIN="${LOCAL_BIN_DIR}/fipsctl" [ -z "$FIPSTOP_BIN" ] && [ -f "${LOCAL_BIN_DIR}/fipstop" ] && FIPSTOP_BIN="${LOCAL_BIN_DIR}/fipstop" # Fallback: release artifacts in bundled fips source tree [ -z "$FIPS_BIN" ] && [ -f "${LOCAL_RELEASE_DIR}/fips" ] && FIPS_BIN="${LOCAL_RELEASE_DIR}/fips" [ -z "$FIPSCTL_BIN" ] && [ -f "${LOCAL_RELEASE_DIR}/fipsctl" ] && FIPSCTL_BIN="${LOCAL_RELEASE_DIR}/fipsctl" [ -z "$FIPSTOP_BIN" ] && [ -f "${LOCAL_RELEASE_DIR}/fipstop" ] && FIPSTOP_BIN="${LOCAL_RELEASE_DIR}/fipstop" # Legacy fallback: individually copied binaries in QubesIncoming for incoming_dir in /home/user/QubesIncoming/*/; do [ -z "$FIPS_BIN" ] && [ -f "${incoming_dir}fips" ] && FIPS_BIN="${incoming_dir}fips" [ -z "$FIPSCTL_BIN" ] && [ -f "${incoming_dir}fipsctl" ] && FIPSCTL_BIN="${incoming_dir}fipsctl" [ -z "$FIPSTOP_BIN" ] && [ -f "${incoming_dir}fipstop" ] && FIPSTOP_BIN="${incoming_dir}fipstop" done if [ -z "$FIPS_BIN" ]; then echo "✗ Could not find 'fips' binary in this repo copy." echo " Expected one of:" echo " ${LOCAL_BIN_DIR}/fips" echo " ${LOCAL_RELEASE_DIR}/fips" echo "" echo " Build before copying into sys-fips:" echo " bash ./scripts/00-build-fips.sh" exit 1 fi echo " Found fips: $FIPS_BIN" [ -n "$FIPSCTL_BIN" ] && echo " Found fipsctl: $FIPSCTL_BIN" [ -n "$FIPSTOP_BIN" ] && echo " Found fipstop: $FIPSTOP_BIN" # ── Install binaries ──────────────────────────────────────────────────────────── install -m 755 "$FIPS_BIN" /usr/local/bin/fips echo "✓ Installed /usr/local/bin/fips" if [ -n "$FIPSCTL_BIN" ]; then install -m 755 "$FIPSCTL_BIN" /usr/local/bin/fipsctl echo "✓ Installed /usr/local/bin/fipsctl" fi if [ -n "$FIPSTOP_BIN" ]; then install -m 755 "$FIPSTOP_BIN" /usr/local/bin/fipstop echo "✓ Installed /usr/local/bin/fipstop" fi # ── Ensure runtime dirs and TUN ───────────────────────────────────────────────── mkdir -p /etc/fips /var/log/fips /var/run/fips if [ ! -c /dev/net/tun ]; then echo "Creating /dev/net/tun..." mkdir -p /dev/net mknod /dev/net/tun c 10 200 chmod 666 /dev/net/tun fi echo "✓ Runtime directories and TUN are ready" # ── Install config ────────────────────────────────────────────────────────────── if [ -f /etc/fips/fips.yaml ]; then echo "⚠ /etc/fips/fips.yaml already exists; preserving existing file" else if [ -f "${ROOT_DIR}/configs/fips.yaml" ]; then install -m 600 "${ROOT_DIR}/configs/fips.yaml" /etc/fips/fips.yaml echo "✓ Installed /etc/fips/fips.yaml" else cat > /etc/fips/fips.yaml << 'EOF' node: identity: persistent: true 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" mtu: 1472 peers: [] EOF chmod 600 /etc/fips/fips.yaml echo "✓ Installed default /etc/fips/fips.yaml" fi fi # ── Install systemd service (single node) ────────────────────────────────────── cat > /etc/systemd/system/fips.service << 'EOF' [Unit] Description=FIPS Mesh Network Daemon After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/usr/local/bin/fips --config /etc/fips/fips.yaml Restart=on-failure RestartSec=5 RuntimeDirectory=fips RuntimeDirectoryMode=0750 ProtectHome=yes PrivateTmp=yes ProtectKernelModules=yes ProtectKernelTunables=no [Install] WantedBy=multi-user.target EOF echo "✓ Installed /etc/systemd/system/fips.service" systemctl daemon-reload systemctl enable fips >/dev/null 2>&1 || true echo "" echo "=== Installation complete ===" echo "" if [ -n "${SUDO_USER:-}" ] && [ "${SUDO_USER}" != "root" ]; then echo "Control socket access tip:" echo " sudo usermod -aG fips ${SUDO_USER}" echo " (then log out/in, or use 'sudo fipsctl ...')" echo "" fi echo "Next steps:" echo " sudo bash 03-configure-identity.sh" echo " sudo bash 04-start-fips.sh" echo " sudo bash 06-configure-dns.sh" echo " sudo bash 07-route-appvms.sh"