mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
Add packaging subsystem with systemd tarball installer
Packaging directory structure: - packaging/common/ — shared config (fips.yaml) used by all formats - packaging/systemd/ — systemd-specific installer and service units Systemd packaging includes: - build-tarball.sh: builds release binaries and creates a self-contained install tarball with stripped binaries - fips.service: systemd unit running the daemon with security hardening - fips-dns.service: oneshot unit configuring resolvectl to route .fips domain queries to the FIPS DNS shim on 127.0.0.1:5354 - install.sh: deploys binaries to /usr/local/bin, installs systemd units, creates fips group for non-root control socket access - uninstall.sh: removes service and binaries, optional --purge for config and identity key files - README.install.md: installation and configuration guide Default config enables UDP (2121), TCP inbound (8443), TUN, and DNS resolver. Identity is ephemeral by default for privacy; operators can uncomment persistent: true to maintain a stable npub for static peer publishing. Ethernet transport is commented out for per-node setup.
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
# FIPS Installation Guide
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
tar xzf fips-*-linux-*.tar.gz
|
||||
cd fips-*-linux-*/
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
## What Gets Installed
|
||||
|
||||
| File | Location |
|
||||
|------|----------|
|
||||
| fips (daemon) | /usr/local/bin/fips |
|
||||
| fipsctl (CLI) | /usr/local/bin/fipsctl |
|
||||
| fipstop (TUI) | /usr/local/bin/fipstop |
|
||||
| Configuration | /etc/fips/fips.yaml |
|
||||
| Identity key | /etc/fips/fips.key (auto-generated) |
|
||||
| Public key | /etc/fips/fips.pub (auto-generated) |
|
||||
| systemd unit | /etc/systemd/system/fips.service |
|
||||
|
||||
A system group `fips` is created for control socket access.
|
||||
|
||||
## Post-Install Configuration
|
||||
|
||||
Edit `/etc/fips/fips.yaml` before starting the service.
|
||||
|
||||
### 1. Identity
|
||||
|
||||
By default, the node generates a new ephemeral identity on each start
|
||||
for privacy. If the node's npub will be published for others to use as a
|
||||
static peer, enable a stable identity by uncommenting `persistent: true`
|
||||
in the identity section:
|
||||
|
||||
```yaml
|
||||
node:
|
||||
identity:
|
||||
persistent: true
|
||||
```
|
||||
|
||||
On first start with persistence enabled, a keypair is auto-generated and saved:
|
||||
|
||||
- `/etc/fips/fips.key` (mode 0600) — secret key
|
||||
- `/etc/fips/fips.pub` (mode 0644) — public key (npub)
|
||||
|
||||
The same identity is reused on subsequent starts. Alternatively, set
|
||||
`node.identity.nsec` to use a specific key.
|
||||
|
||||
### 2. Ethernet Transport
|
||||
|
||||
If using Ethernet for local mesh discovery, uncomment the ethernet section
|
||||
and set the interface name:
|
||||
|
||||
```yaml
|
||||
transports:
|
||||
ethernet:
|
||||
interface: "eth0"
|
||||
discovery: true
|
||||
announce: true
|
||||
auto_connect: true
|
||||
accept_connections: true
|
||||
```
|
||||
|
||||
### 3. Static Peers
|
||||
|
||||
For bootstrapping over UDP or TCP, add known peers:
|
||||
|
||||
```yaml
|
||||
peers:
|
||||
- npub: "npub1..."
|
||||
alias: "gateway"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "217.77.8.91:2121" # public FIPS testing node
|
||||
connect_policy: auto_connect
|
||||
```
|
||||
|
||||
### 4. DNS Resolver
|
||||
|
||||
FIPS includes a DNS responder for `.fips` domain names (port 5354).
|
||||
To integrate with systemd-resolved:
|
||||
|
||||
```bash
|
||||
sudo resolvectl dns fips0 127.0.0.1:5354
|
||||
sudo resolvectl domain fips0 ~fips
|
||||
```
|
||||
|
||||
To make this persistent, create a systemd-networkd override or add a
|
||||
drop-in for the fips0 interface.
|
||||
|
||||
## Firewall Ports
|
||||
|
||||
| Port | Protocol | Purpose |
|
||||
|------|----------|---------|
|
||||
| 2121 | UDP | Peer-to-peer mesh traffic |
|
||||
| 8443 | TCP | Inbound peer connections |
|
||||
|
||||
## Service Management
|
||||
|
||||
```bash
|
||||
# Start / stop / restart
|
||||
sudo systemctl start fips
|
||||
sudo systemctl stop fips
|
||||
sudo systemctl restart fips
|
||||
|
||||
# View logs
|
||||
sudo journalctl -u fips -f
|
||||
|
||||
# Switch to debug logging
|
||||
sudo systemctl set-environment RUST_LOG=debug
|
||||
sudo systemctl restart fips
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
```bash
|
||||
# Quick status
|
||||
fipsctl show status
|
||||
|
||||
# Interactive dashboard
|
||||
fipstop
|
||||
|
||||
# Other queries
|
||||
fipsctl show peers
|
||||
fipsctl show links
|
||||
fipsctl show sessions
|
||||
fipsctl show routing
|
||||
fipsctl show transports
|
||||
```
|
||||
|
||||
## Non-Root Access to fipsctl/fipstop
|
||||
|
||||
Add your user to the `fips` group:
|
||||
|
||||
```bash
|
||||
sudo usermod -aG fips $USER
|
||||
```
|
||||
|
||||
Log out and back in for the group change to take effect.
|
||||
|
||||
## Uninstall
|
||||
|
||||
```bash
|
||||
# Remove binaries and service, keep configuration
|
||||
sudo ./uninstall.sh
|
||||
|
||||
# Remove everything including /etc/fips/ and the fips group
|
||||
sudo ./uninstall.sh --purge
|
||||
```
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build FIPS release binaries and create an install tarball.
|
||||
#
|
||||
# Usage: ./packaging/build-tarball.sh
|
||||
# Output: deploy/fips-<version>-linux-<arch>.tar.gz
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PACKAGING_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
PROJECT_ROOT="$(cd "${PACKAGING_DIR}/.." && pwd)"
|
||||
|
||||
# Extract version from Cargo.toml
|
||||
VERSION=$(grep '^version' "${PROJECT_ROOT}/Cargo.toml" | head -1 | sed 's/.*"\(.*\)"/\1/')
|
||||
ARCH=$(uname -m)
|
||||
TARBALL_NAME="fips-${VERSION}-linux-${ARCH}"
|
||||
DEPLOY_DIR="${PROJECT_ROOT}/deploy"
|
||||
STAGING_DIR="${DEPLOY_DIR}/${TARBALL_NAME}"
|
||||
|
||||
echo "Building FIPS v${VERSION} for ${ARCH}..."
|
||||
|
||||
# Build release binaries (tui is a default feature, includes fipstop)
|
||||
cargo build --release --manifest-path="${PROJECT_ROOT}/Cargo.toml"
|
||||
|
||||
# Create staging directory
|
||||
rm -rf "${STAGING_DIR}"
|
||||
mkdir -p "${STAGING_DIR}"
|
||||
|
||||
# Copy binaries
|
||||
cp "${PROJECT_ROOT}/target/release/fips" "${STAGING_DIR}/"
|
||||
cp "${PROJECT_ROOT}/target/release/fipsctl" "${STAGING_DIR}/"
|
||||
cp "${PROJECT_ROOT}/target/release/fipstop" "${STAGING_DIR}/"
|
||||
|
||||
# Strip binaries to reduce size
|
||||
strip "${STAGING_DIR}/fips" "${STAGING_DIR}/fipsctl" "${STAGING_DIR}/fipstop"
|
||||
|
||||
# Copy packaging files
|
||||
cp "${SCRIPT_DIR}/install.sh" "${STAGING_DIR}/"
|
||||
cp "${SCRIPT_DIR}/uninstall.sh" "${STAGING_DIR}/"
|
||||
cp "${SCRIPT_DIR}/fips.service" "${STAGING_DIR}/"
|
||||
cp "${SCRIPT_DIR}/fips-dns.service" "${STAGING_DIR}/"
|
||||
cp "${PACKAGING_DIR}/common/fips.yaml" "${STAGING_DIR}/"
|
||||
cp "${SCRIPT_DIR}/README.install.md" "${STAGING_DIR}/"
|
||||
|
||||
chmod +x "${STAGING_DIR}/install.sh" "${STAGING_DIR}/uninstall.sh"
|
||||
|
||||
# Create tarball
|
||||
cd "${DEPLOY_DIR}"
|
||||
tar czf "${TARBALL_NAME}.tar.gz" "${TARBALL_NAME}/"
|
||||
rm -rf "${STAGING_DIR}"
|
||||
|
||||
echo ""
|
||||
echo "Tarball created: deploy/${TARBALL_NAME}.tar.gz"
|
||||
ls -lh "${TARBALL_NAME}.tar.gz"
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Configure DNS routing for .fips domain
|
||||
After=systemd-resolved.service
|
||||
Wants=systemd-resolved.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/bash -c 'while ! ip link show fips0 >/dev/null 2>&1; do sleep 1; done; /usr/bin/resolvectl dns fips0 127.0.0.1:5354; /usr/bin/resolvectl domain fips0 ~fips'
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,28 @@
|
||||
[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
|
||||
|
||||
# Logging: RUST_LOG controls verbosity.
|
||||
# Use "info" for production, "debug" for troubleshooting.
|
||||
Environment=RUST_LOG=info
|
||||
|
||||
# Control socket directory (/run/fips/).
|
||||
# Group-readable so 'fips' group members can use fipsctl/fipstop.
|
||||
RuntimeDirectory=fips
|
||||
RuntimeDirectoryMode=0750
|
||||
|
||||
# Security hardening (daemon runs as root for TUN and raw sockets)
|
||||
ProtectHome=yes
|
||||
PrivateTmp=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelTunables=no
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Executable
+147
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env bash
|
||||
# FIPS Install Script
|
||||
#
|
||||
# Installs the FIPS mesh network daemon as a systemd service.
|
||||
#
|
||||
# Usage: sudo ./install.sh
|
||||
#
|
||||
# Files installed:
|
||||
# /usr/local/bin/fips Daemon binary
|
||||
# /usr/local/bin/fipsctl CLI query tool
|
||||
# /usr/local/bin/fipstop TUI monitor
|
||||
# /etc/fips/fips.yaml Configuration (preserved if exists)
|
||||
# /etc/systemd/system/fips.service systemd unit
|
||||
# /etc/systemd/system/fips-dns.service DNS routing for .fips domain
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
INSTALL_PREFIX="/usr/local"
|
||||
CONFIG_DIR="/etc/fips"
|
||||
CONFIG_FILE="${CONFIG_DIR}/fips.yaml"
|
||||
SYSTEMD_DIR="/etc/systemd/system"
|
||||
FIPS_GROUP="fips"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# --- Preflight checks ---
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Error: This script must be run as root (use sudo)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "${SCRIPT_DIR}/fips" ]; then
|
||||
echo "Error: fips binary not found in ${SCRIPT_DIR}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v systemctl &>/dev/null; then
|
||||
echo "Error: systemctl not found. This script requires systemd." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e /dev/net/tun ]; then
|
||||
echo "Warning: /dev/net/tun not found. TUN support may not work." >&2
|
||||
echo " Load the module with: modprobe tun" >&2
|
||||
fi
|
||||
|
||||
# --- Create fips group for control socket access ---
|
||||
|
||||
if ! getent group "${FIPS_GROUP}" &>/dev/null; then
|
||||
groupadd --system "${FIPS_GROUP}"
|
||||
echo "Created system group '${FIPS_GROUP}'."
|
||||
fi
|
||||
|
||||
# --- Install binaries ---
|
||||
|
||||
echo "Installing binaries to ${INSTALL_PREFIX}/bin/"
|
||||
install -m 0755 "${SCRIPT_DIR}/fips" "${INSTALL_PREFIX}/bin/fips"
|
||||
install -m 0755 "${SCRIPT_DIR}/fipsctl" "${INSTALL_PREFIX}/bin/fipsctl"
|
||||
if [ -f "${SCRIPT_DIR}/fipstop" ]; then
|
||||
install -m 0755 "${SCRIPT_DIR}/fipstop" "${INSTALL_PREFIX}/bin/fipstop"
|
||||
fi
|
||||
|
||||
# --- Install configuration ---
|
||||
|
||||
mkdir -p "${CONFIG_DIR}"
|
||||
|
||||
if [ -f "${CONFIG_FILE}" ]; then
|
||||
echo "Configuration exists at ${CONFIG_FILE}, not overwriting."
|
||||
install -m 0644 "${SCRIPT_DIR}/fips.yaml" "${CONFIG_DIR}/fips.yaml.template"
|
||||
echo " New template installed as ${CONFIG_DIR}/fips.yaml.template"
|
||||
else
|
||||
install -m 0600 "${SCRIPT_DIR}/fips.yaml" "${CONFIG_FILE}"
|
||||
echo "Configuration installed to ${CONFIG_FILE}"
|
||||
fi
|
||||
|
||||
# --- Install systemd unit ---
|
||||
|
||||
was_active=false
|
||||
if systemctl is-active --quiet fips.service 2>/dev/null; then
|
||||
was_active=true
|
||||
echo "Stopping running fips service..."
|
||||
systemctl stop fips.service
|
||||
fi
|
||||
|
||||
dns_was_active=false
|
||||
if systemctl is-active --quiet fips-dns.service 2>/dev/null; then
|
||||
dns_was_active=true
|
||||
echo "Stopping running fips-dns service..."
|
||||
systemctl stop fips-dns.service
|
||||
fi
|
||||
|
||||
install -m 0644 "${SCRIPT_DIR}/fips.service" "${SYSTEMD_DIR}/fips.service"
|
||||
install -m 0644 "${SCRIPT_DIR}/fips-dns.service" "${SYSTEMD_DIR}/fips-dns.service"
|
||||
systemctl daemon-reload
|
||||
echo "systemd units installed."
|
||||
|
||||
# --- Configure runtime directory group ownership ---
|
||||
# systemd creates /run/fips/ with RuntimeDirectory, but we need the
|
||||
# group set to 'fips' so group members can access the control socket.
|
||||
# Create a tmpfiles.d entry for this.
|
||||
|
||||
cat > /etc/tmpfiles.d/fips.conf <<'TMPFILES'
|
||||
d /run/fips 0750 root fips -
|
||||
TMPFILES
|
||||
echo "tmpfiles.d entry created for /run/fips/ ownership."
|
||||
|
||||
# --- Enable service ---
|
||||
|
||||
systemctl enable fips.service
|
||||
systemctl enable fips-dns.service
|
||||
echo "Services enabled (will start on boot)."
|
||||
|
||||
# Restart if they were running before
|
||||
if $was_active; then
|
||||
echo "Restarting fips service..."
|
||||
systemctl start fips.service
|
||||
fi
|
||||
if $dns_was_active; then
|
||||
echo "Restarting fips-dns service..."
|
||||
systemctl start fips-dns.service
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Installation complete ==="
|
||||
echo ""
|
||||
echo "Before starting the service, edit ${CONFIG_FILE}:"
|
||||
echo ""
|
||||
echo " 1. Set a persistent identity (if publishing npub for static peers)"
|
||||
echo " Uncomment 'persistent: true' in the identity section."
|
||||
echo " A keypair will be generated and saved on first start."
|
||||
echo ""
|
||||
echo " 2. Configure Ethernet transport interface (if using)"
|
||||
echo " Uncomment the ethernet section and set the interface name."
|
||||
echo ""
|
||||
echo " 3. Add static peers (if bootstrapping over UDP/TCP)"
|
||||
echo ""
|
||||
echo "Start the service:"
|
||||
echo " sudo systemctl start fips"
|
||||
echo ""
|
||||
echo "Monitor:"
|
||||
echo " sudo journalctl -u fips -f"
|
||||
echo " fipsctl show status"
|
||||
echo " fipstop"
|
||||
echo ""
|
||||
echo "To use fipsctl/fipstop without sudo, add your user to the fips group:"
|
||||
echo " sudo usermod -aG fips \$USER"
|
||||
echo " (log out and back in for group membership to take effect)"
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
# FIPS Uninstall Script
|
||||
#
|
||||
# Removes the FIPS daemon, service, and optionally configuration.
|
||||
#
|
||||
# Usage: sudo ./uninstall.sh [--purge]
|
||||
# --purge Also remove /etc/fips/ and the fips system group
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PURGE=false
|
||||
if [ "${1:-}" = "--purge" ]; then
|
||||
PURGE=true
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Error: This script must be run as root (use sudo)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Stop and disable service ---
|
||||
|
||||
if systemctl is-active --quiet fips-dns.service 2>/dev/null; then
|
||||
echo "Stopping fips-dns service..."
|
||||
systemctl stop fips-dns.service
|
||||
fi
|
||||
|
||||
if systemctl is-enabled --quiet fips-dns.service 2>/dev/null; then
|
||||
systemctl disable fips-dns.service
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet fips.service 2>/dev/null; then
|
||||
echo "Stopping fips service..."
|
||||
systemctl stop fips.service
|
||||
fi
|
||||
|
||||
if systemctl is-enabled --quiet fips.service 2>/dev/null; then
|
||||
systemctl disable fips.service
|
||||
fi
|
||||
|
||||
# --- Remove systemd units ---
|
||||
|
||||
rm -f /etc/systemd/system/fips.service
|
||||
rm -f /etc/systemd/system/fips-dns.service
|
||||
systemctl daemon-reload
|
||||
echo "systemd units removed."
|
||||
|
||||
# --- Remove tmpfiles.d entry ---
|
||||
|
||||
rm -f /etc/tmpfiles.d/fips.conf
|
||||
|
||||
# --- Remove binaries ---
|
||||
|
||||
rm -f /usr/local/bin/fips /usr/local/bin/fipsctl /usr/local/bin/fipstop
|
||||
echo "Binaries removed."
|
||||
|
||||
# --- Optionally remove configuration and group ---
|
||||
|
||||
if $PURGE; then
|
||||
echo "Purging /etc/fips/ (including identity key files)..."
|
||||
rm -rf /etc/fips/
|
||||
|
||||
if getent group fips &>/dev/null; then
|
||||
groupdel fips
|
||||
echo "System group 'fips' removed."
|
||||
fi
|
||||
|
||||
echo "Configuration and group removed."
|
||||
else
|
||||
echo "Configuration and identity preserved at /etc/fips/"
|
||||
echo " Use --purge to remove everything (including key files and group)."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Uninstall complete."
|
||||
Reference in New Issue
Block a user