chore: doc tweaks

This commit is contained in:
Julian Sommer
2026-04-17 15:27:14 +10:00
parent 4f991095ee
commit c469eecfa1
14 changed files with 143 additions and 127 deletions
+1 -1
View File
@@ -1154,7 +1154,7 @@ func runAdminInitMultiNode(cmd *cobra.Command, accessKey, secretKey, accountID,
fmt.Printf(" Waiting for %d more node(s) to join...\n", expectedNodes-1)
fmt.Printf(" Token expires in %s\n\n", tokenTTL)
fmt.Printf(" Other nodes should run:\n")
fmt.Printf(" spx admin join --host %s --token %s --node <name> --bind <ip>\n\n", formationAddr, joinToken)
fmt.Printf(" sudo spx admin join --host %s --token %s --node <name> --bind <ip>\n\n", formationAddr, joinToken)
// Wait for all nodes to register
if err := fs.WaitForCompletion(formationTimeout); err != nil {
+118 -63
View File
@@ -1,6 +1,6 @@
---
title: "Air-Gapped Install"
description: "Deploy Spinifex in environments without internet connectivity. Covers offline package caching, USB deployment, and package verification."
description: "Deploy Spinifex in environments without internet connectivity. Covers using a pre-built release tarball, mirrored APT packages, and locally-staged cloud images."
category: "Getting Started"
tags:
- install
@@ -9,8 +9,8 @@ tags:
resources:
- title: "Spinifex Repository"
url: "https://github.com/mulgadc/spinifex"
- title: "apt-cacher-ng"
url: "https://wiki.debian.org/AptCacherNg"
- title: "External Connection Inventory"
url: "/docs/security/network-connections"
---
# Air-Gapped Installation
@@ -29,103 +29,158 @@ resources:
In air-gapped or disconnected environments, Spinifex can be deployed without internet access. This guide covers preparing offline packages on a connected machine, creating USB deployment media, and installing on the target server with package verification.
**Deployment methods:**
- **apt-cacher-ng** — Local APT cache for Debian/Ubuntu packages
- **Go module cache** — Pre-downloaded Go dependencies
- **USB deployment** — Portable installation media with all dependencies
- **GPG verification** — Cryptographic package integrity checks
## Instructions
## Step 1. Prepare Packages (on a connected machine)
## Step 1. Download the Release (on a connected machine)
Set up a local APT cache to collect all required packages:
Each Spinifex release publishes a self-contained tarball, the matching `setup.sh`, and a SHA-256 checksum to GitHub Releases. Resolve the latest tag and download the assets for your architecture:
```bash
sudo apt install apt-cacher-ng
sudo systemctl enable --now apt-cacher-ng
ARCH=amd64 # or arm64
TAG=$(curl -fsSL https://api.github.com/repos/mulgadc/spinifex/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4)
BASE="https://github.com/mulgadc/spinifex/releases/download/${TAG}"
curl -fsSLO "${BASE}/spinifex-${TAG}-linux-${ARCH}.tar.gz"
curl -fsSLO "${BASE}/spinifex-${TAG}-linux-${ARCH}.tar.gz.sha256"
curl -fsSLO "${BASE}/setup.sh"
sha256sum -c "spinifex-${TAG}-linux-${ARCH}.tar.gz.sha256"
```
Pre-download all Spinifex dependencies:
## Step 2. Stage Dependencies (on the connected machine)
Pre-download the APT packages installed by the production setup. `apt install --download-only` writes `.deb` files to `/var/cache/apt/archives/` without installing them, so the connected machine isn't modified:
```bash
sudo apt install --download-only nbdkit nbdkit-plugin-dev pkg-config \
qemu-system qemu-utils qemu-kvm libvirt-daemon-system \
libvirt-clients libvirt-dev make gcc unzip xz-utils file \
ovn-central ovn-host openvswitch-switch
sudo apt update
sudo apt install --download-only -y \
nbdkit nbdkit-plugin-dev pkg-config \
qemu-system-x86 qemu-utils qemu-kvm \
libvirt-daemon-system libvirt-clients libvirt-dev \
ovn-central ovn-host openvswitch-switch \
dhcpcd-base make gcc jq curl iproute2 netcat-openbsd \
wget unzip xz-utils file
```
## Step 2. Create USB Deployment Media
Download AWS CLI v2:
```bash
mkdir -p /media/spinifex-deploy/{apt-packages,go-cache,spinifex-source}
curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" \
-o awscliv2.zip
```
Mirror the cloud image you intend to run as guest VMs:
```bash
mkdir -p images
curl -fsSL "https://cdimage.debian.org/cdimage/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2" \
-o images/debian-12-amd64.qcow2
```
## Step 3. Assemble Transfer Media
```bash
mkdir -p /media/spinifex-deploy/{tarball,apt-packages,aws,images}
cp spinifex-${TAG}-linux-${ARCH}.tar.gz /media/spinifex-deploy/tarball/
cp setup.sh /media/spinifex-deploy/
cp /var/cache/apt/archives/*.deb /media/spinifex-deploy/apt-packages/
cp -r ~/go/pkg/mod/cache/ /media/spinifex-deploy/go-cache/
cp -r ~/Development/mulga/spinifex /media/spinifex-deploy/spinifex-source/
cp awscliv2.zip /media/spinifex-deploy/aws/
cp images/*.qcow2 /media/spinifex-deploy/images/
```
## Step 3. Verify Package Integrity
## Step 4. Install on the Air-Gapped Target
Sign and verify packages before transferring to the target:
```bash
gpg --import /media/spinifex-deploy/mulga-signing-key.asc
gpg --verify spinifex-v1.0.tar.gz.sig spinifex-v1.0.tar.gz
sha256sum -c /media/spinifex-deploy/checksums.sha256
```
## Step 4. Install on the Target Server
Mount the USB and install:
Mount the media, install APT dependencies, install AWS CLI, then run `setup.sh` with the local tarball:
```bash
sudo mount /dev/sdb1 /mnt/usb
sudo dpkg -i /mnt/usb/apt-packages/*.deb
cp -r /mnt/usb/spinifex-source ~/Development/mulga/spinifex
cd ~/Development/mulga/spinifex && make build
sudo apt-get install -f --no-download # resolve any leftover deps from local cache
cd /tmp && unzip /mnt/usb/aws/awscliv2.zip && sudo ./aws/install
INSTALL_SPINIFEX_TARBALL=/mnt/usb/tarball/spinifex-*-linux-*.tar.gz \
INSTALL_SPINIFEX_SKIP_APT=1 \
INSTALL_SPINIFEX_SKIP_AWS=1 \
bash /mnt/usb/setup.sh
```
Then follow the [Source Install](/docs/install-source) guide from Step 3 (Setup OVN) onwards.
Run `setup.sh` without `sudo` — the script handles privilege escalation internally and ends by `exec`-ing into a `newgrp spinifex` subshell so your current shell picks up `spinifex` group membership. Without that membership, AWS CLI cannot traverse `/etc/spinifex/` (mode `0750`) to read `ca.pem` and Step 9 will fail with a TLS error. Type `exit` to leave the subshell when finished.
## Step 5. Setup OVN Networking
`spx admin init` requires OVN/OVS to be configured before the daemon can manage tenant networks. `setup-ovn.sh` ships in the tarball and runs purely against local commands (no network access required):
```bash
sudo /usr/local/share/spinifex/setup-ovn.sh --management
```
If your WAN interface is a physical NIC rather than a bridge, pass `--wan-bridge=br-wan --wan-iface=<nic>`.
## Step 6. Initialize Without Telemetry
```bash
sudo spx admin init --node node1 --nodes 1 --no-telemetry
```
This generates the cluster configuration, TLS certificates, installs the CA into the system trust store, and writes AWS CLI credentials. See [Single-Node Install](/docs/install) for what `spx admin init` does.
## Step 7. Start Services
`setup.sh` enables `spinifex.target` but does not start it on a fresh install. Start it now so predastore is online before you import images:
```bash
sudo systemctl start spinifex.target
```
## Step 8. Import Cloud Images
Register the pre-staged image with Spinifex:
```bash
sudo spx admin images import --file /mnt/usb/images/debian-12-amd64.qcow2 \
--distro debian --version 12 --arch x86_64
```
## Step 9. Verify
```bash
export AWS_PROFILE=spinifex
aws ec2 describe-instance-types
aws ec2 describe-images
```
If both calls return data, your air-gapped install is working. Continue to [Setting Up Your Cluster](/docs/setting-up-your-cluster) to launch your first instance.
## Troubleshooting
### Missing Dependencies After dpkg Install
### Missing APT Dependencies
Some packages may have unresolved dependencies. Fix with:
`dpkg -i` does not resolve transitive dependencies. After installing, run:
```bash
sudo dpkg -i /mnt/usb/apt-packages/*.deb
sudo apt-get install -f
sudo apt-get install -f --no-download
```
The `-f` flag tells apt to fix broken dependencies using what's available locally.
The `--no-download` flag forces apt to use only what's in the local cache. If a dependency is genuinely missing, add it to the `apt --download-only` step on the connected machine and re-stage.
### GPG Verification Fails
### Setup.sh Tries to Download Anyway
The signing key may not match or the download was corrupted. Re-import the key and verify:
Confirm both skip flags are exported and that `INSTALL_SPINIFEX_TARBALL` points at a readable file:
```bash
gpg --import /media/spinifex-deploy/mulga-signing-key.asc
gpg --verify spinifex-v1.0.tar.gz.sig spinifex-v1.0.tar.gz
sudo INSTALL_SPINIFEX_TARBALL=/mnt/usb/tarball/spinifex-...tar.gz \
INSTALL_SPINIFEX_SKIP_APT=1 \
INSTALL_SPINIFEX_SKIP_AWS=1 \
bash -x /mnt/usb/setup.sh
```
If verification still fails, re-download the package on the connected machine and compare checksums:
### Init Telemetry Attempted
```bash
sha256sum spinifex-v1.0.tar.gz
```
`spx admin init` posts a one-shot record to `https://install.mulgadc.com/install`. Pass `--no-telemetry` on every `init` and `join` invocation, or export `SPX_NO_TELEMETRY=1` in the operator's shell profile.
### Go Module Cache Errors
### Image Import Fails
The Go module cache may have been incompletely copied. On the connected machine, re-export the full cache:
```bash
cp -r ~/go/pkg/mod/cache/ /media/spinifex-deploy/go-cache/
```
On the target, restore it:
```bash
mkdir -p ~/go/pkg/mod/
cp -r /mnt/usb/go-cache ~/go/pkg/mod/cache
```
`spx admin images import --file` requires the distro/version/arch flags so the image registers in the catalogue. If the import succeeds but `aws ec2 describe-images` returns empty, check `journalctl -u spinifex-daemon -f` for predastore upload errors.
@@ -31,7 +31,7 @@ resources:
A Spinifex cluster distributes services across multiple servers for high availability, data durability, and fault tolerance. Cluster formation is automatic — the init node waits for peers to join, then distributes credentials, CA certificates, and configuration.
**Network requirements:**
**Network Requirements:**
- Minimum 1 NIC per server (2 recommended for production)
- UDP port 6081 open between hosts (Geneve tunnels)
@@ -59,7 +59,7 @@ export AWS_AZ=us-east-1a
## Step 3. Setup OVN Networking
Server 1 runs OVN central and must be set up first. If your WAN interface is already a bridge (e.g. `br-wan`), setup-ovn.sh auto-detects it. Otherwise use `--wan-bridge=br-wan --wan-iface=eth1` (dedicated WAN NIC).
Server 1 runs OVN central and must be set up first. If your WAN interface is already a bridge, setup-ovn.sh auto-detects it. Otherwise use `--wan-bridge=br-wan --wan-iface=eth1` (dedicated WAN NIC).
**Server 1:**
@@ -104,8 +104,6 @@ sudo spx admin init \
--port 4432 --region $AWS_REGION --az $AWS_AZ
```
Save the admin credentials — they will not be shown again.
The init output displays the join command including the token:
```
@@ -114,7 +112,7 @@ The init output displays the join command including the token:
Token expires in 30m0s
Other nodes should run:
spx admin join --host 10.0.0.1:4432 --token spx_join_a8Bf3x9Kz2mN --node <name> --bind <ip>
sudo spx admin join --host 10.0.0.1:4432 --token spx_join_a8Bf3x9Kz2mN --node <name> --bind <ip>
```
**Server 2 — Join** (while init is running):
@@ -135,8 +133,7 @@ sudo spx admin join \
--region $AWS_REGION --az $AWS_AZ
```
> **Note:** The join token expires 30 minutes after init by default. For larger deployments
> with slower provisioning, use `--token-ttl 2h` on the init command.
**Note:** The join token expires 30 minutes after init by default. For larger deployments with slower provisioning, use `--token-ttl 2h`
## Step 5. Start Services
@@ -181,7 +178,7 @@ sudo ss -tlnp | grep 6642
### CA Certificate Not Trusted
```bash
sudo cp ~/spinifex/config/ca.pem /usr/local/share/ca-certificates/spinifex-ca.crt
sudo cp /etc/spinifex/ca.pem /usr/local/share/ca-certificates/spinifex-ca.crt
sudo update-ca-certificates
```
+4 -36
View File
@@ -52,43 +52,17 @@ export PATH=$PATH:/usr/local/go/bin
```bash
cd spinifex
./scripts/clone-deps.sh
./scripts/dev-setup.sh
```
Confirm `./bin/spx` exists.
## Step 3. Setup OVN
If your WAN interface is already a bridge (e.g. `br-wan`), setup-ovn.sh auto-detects it:
```bash
./scripts/setup-ovn.sh --management
```
If your WAN is a physical NIC:
```bash
# Dedicated WAN NIC (not your SSH connection):
./scripts/setup-ovn.sh --management --wan-bridge=br-wan --wan-iface=eth1
```
## Step 4. Development initialisation
## Step 3. Development Initialisation
```bash
./scripts/dev-install.sh
```
Note, this will bootstrap a single node development environment
This bootstraps a single-node development environment: builds binaries, configures OVN, initialises the cluster, installs the CA certificate, and starts all services.
## Step 5. Start services
```bash
sudo systemctl status spinifex.target
```
Start all services
## Step 6. Verify Installation
## Step 4. Verify Installation
```bash
export AWS_PROFILE=spinifex
@@ -109,15 +83,9 @@ Continue to [Setting Up Your Cluster](/docs/setting-up-your-cluster) to import a
export PATH=$PATH:/usr/local/go/bin
```
### ./bin/spx Missing After Build
```bash
./scripts/dev-setup.sh
```
### CA Certificate Not Trusted
```bash
sudo cp ~/spinifex/config/ca.pem /usr/local/share/ca-certificates/spinifex-ca.crt
sudo cp /etc/spinifex/ca.pem /usr/local/share/ca-certificates/spinifex-ca.crt
sudo update-ca-certificates
```
+3 -4
View File
@@ -29,7 +29,7 @@ resources:
## Overview
Spinifex is an open-source infrastructure platform that brings core AWS services — EC2, VPC, EBS, and S3 — to bare-metal, edge, and on-prem environments.
Spinifex is an open-source infrastructure platform that brings core AWS services to bare-metal, edge, and on-prem environments.
This guide installs Spinifex on a single server using the binary installer. For multi-server clusters, see [Multi-Node Install](/docs/install-multi-node). To build from source, see [Source Install](/docs/install-source).
@@ -65,10 +65,9 @@ If your WAN interface is already a bridge (e.g. `br-wan`), setup-ovn.sh auto-det
sudo /usr/local/share/spinifex/setup-ovn.sh --management
```
If your WAN is a physical NIC, choose one:
If your WAN is a physical NIC:
```bash
# Dedicated WAN NIC (not your SSH connection):
sudo /usr/local/share/spinifex/setup-ovn.sh --management --wan-bridge=br-wan --wan-iface=eth1
```
@@ -86,7 +85,7 @@ This is recommended for production and required in multi-node deployments. See [
sudo spx admin init --node node1 --nodes 1
```
This auto-detects your network topology, generates configuration and TLS certificates, installs the CA into the system trust store, and configures AWS CLI credentials. Save the admin credentials printed during init — they will not be shown again.
This auto-detects your network topology, generates configuration and TLS certificates, installs the CA into the system trust store, and configures AWS CLI credentials (saved in `~/.aws/credentials`)
## Step 4. Start Services
@@ -34,7 +34,7 @@ resources:
## Overview
This guide assumes Spinifex is already installed and running. If not, follow one of the installation guides first:
- [Binary Install (Single Node)](/docs/install)
- [Single-Node Install)](/docs/install)
- [Multi-Node Install](/docs/install-multi-node)
- [Source Install](/docs/install-source)
@@ -57,11 +57,12 @@ spx admin images list
```
```
NAME | DISTRO | VERSION | ARCH | BOOT
debian-12-arm64 | debian | 12 | arm64 | bios
debian-12-x86_64 | debian | 12 | x86_64 | bios
ubuntu-24.04-arm64 | ubuntu | 24.04 | arm64 | bios
ubuntu-24.04-x86_64 | ubuntu | 24.04 | x86_64 | bios
NAME | DISTRO | VERSION | ARCH | BOOT
debian-12-arm64 | debian | 12 | arm64 | bios
debian-12-x86_64 | debian | 12 | x86_64 | bios
lb-alpine-3.21.6-x86_64 | alpine | 3.21.6 | x86_64 | bios
ubuntu-24.04-arm64 | ubuntu | 24.04 | arm64 | bios
ubuntu-24.04-x86_64 | ubuntu | 24.04 | x86_64 | bios
```
Import an image:
+1 -1
View File
@@ -10,7 +10,7 @@ resources:
- title: "Spinifex Repository"
url: "https://github.com/mulgadc/spinifex"
- title: "Single-Node Install"
url: "https://docs.mulgadc.com/docs/install"
url: "/docs/install"
---
# Updating Spinifex
@@ -129,7 +129,7 @@ Operators own remediation for layers Spinifex does not ship:
| Host OS + kernel | Track distribution advisories (Debian DSA, Ubuntu USN) at matching cadence. |
| OVN / OVS | Patched via the operator's package channel alongside the OS. |
| QEMU / KVM / libvirt | As above — hypervisor CVEs affect tenant isolation. |
| Host AV / EDR agent | See https://docs.mulgadc.com/docs/security/malware-protection §2. |
| Host AV / EDR agent | See [Malware Protection §2](/docs/security/malware-protection). |
Operators should subscribe to the `mulgadc/spinifex` release feed (Watch → Custom → Releases + Security Advisories) so Critical/High advisories arrive via GitHub's notification channel rather than polling.
+1 -1
View File
@@ -114,7 +114,7 @@ Spinifex nodes initiate a small, fixed set of outbound connections.
**Update checks and metadata.** Spinifex does not check for updates and does not consume a cloud metadata service (`169.254.169.254` is served *by* the cluster to guest VMs). Node software updates come from the operator's OS package channel. The install-telemetry endpoint above is the only vendor-operated destination contacted by a node; closed-egress deployments should disable it and record the opt-out in the security plan.
**Air-gapped deployments.** The three image URLs are the only destinations needed for the standard image catalogue. Mirror them locally and use `spx admin images import --file` with pre-staged files. Telemetry must also be disabled. See [Air-gapped install](https://docs.mulgadc.com/docs/install-airgapped).
**Air-gapped deployments.** The three image URLs are the only destinations needed for the standard image catalogue. Mirror them locally and use `spx admin images import --file` with pre-staged files. Telemetry must also be disabled. See [Air-Gapped Install](/docs/install-airgapped).
## 3. Cross-Node (Internal) Connections
@@ -144,7 +144,7 @@ Every entry into a protected space must produce a log entry capturing:
### 4.3 Integration with Spinifex Logs
Forward physical-access events to the same SIEM or log collector used for Spinifex service logs (see [Malware Protection §3](https://docs.mulgadc.com/docs/security/malware-protection#3-scan-schedule-sil1-3145)) so a `master.key` access attempt can be correlated with a physical entry into the rack.
Forward physical-access events to the same SIEM or log collector used for Spinifex service logs (see [Malware Protection §3](/docs/security/malware-protection#3-scan-schedule-sil1-3145)) so a `master.key` access attempt can be correlated with a physical entry into the rack.
## 5. Manage Physical Access Devices (PE.L1-3.10.5)
@@ -199,7 +199,7 @@ Use this list to confirm a site meets the four CMMC practices before admitting S
- CCTV or equivalent monitoring covers the rack fronts, rears, and console positions, with 30-day minimum retention.
- Physical access logs are produced for every entry, retained 12 months, and reviewed on the cadence in [§4.2](#42-retention-and-review).
- Door-forced, door-held, and out-of-hours events alert the on-call operator.
- Physical access events forwarded to the SIEM used for Spinifex service logs (see [Malware Protection §3](https://docs.mulgadc.com/docs/security/malware-protection#3-scan-schedule-sil1-3145)).
- Physical access events forwarded to the SIEM used for Spinifex service logs (see [Malware Protection §3](/docs/security/malware-protection#3-scan-schedule-sil1-3145)).
- Device register reconciles quarterly against the access-control system and physical key count; discrepancies are closed before sign-off.
- Lost-device and termination procedures trigger immediate revocation per [§5.2](#52-control-b).
- System security plan references this guide and records the facility, access-control product, CCTV retention, and log-forwarding destination.
@@ -58,7 +58,6 @@ Deploy a VPC with public and private subnets where the private subnet has no int
- Spinifex installed and running (see [Installing Spinifex](/docs/install))
- A Debian 12 AMI imported (see [Setting Up Your Cluster](/docs/setting-up-your-cluster))
- OpenTofu or Terraform installed
- `AWS_PROFILE=spinifex` configured
## Instructions
@@ -68,7 +68,6 @@ Deploy two Nginx web servers behind an internet-facing Application Load Balancer
- Spinifex installed and running (see [Installing Spinifex](/docs/install))
- A Debian 12 AMI imported (see [Setting Up Your Cluster](/docs/setting-up-your-cluster))
- OpenTofu or Terraform installed
- `AWS_PROFILE=spinifex` configured
## Instructions
@@ -45,7 +45,6 @@ Deploy a complete Nginx web server on Spinifex using Terraform/OpenTofu. This wo
- Spinifex installed and running (see [Installing Spinifex](/docs/install))
- A Debian 12 AMI imported (see [Setting Up Your Cluster](/docs/setting-up-your-cluster))
- OpenTofu or Terraform installed
- `AWS_PROFILE=spinifex` configured
## Instructions
@@ -55,7 +55,6 @@ Deploy an EC2 instance running a Flask file-sharing web application backed by S3
- Predastore running (S3 API on port 8443)
- A Debian 12 AMI imported (see [Setting Up Your Cluster](/docs/setting-up-your-cluster))
- OpenTofu or Terraform installed
- `AWS_PROFILE=spinifex` configured
- The EC2 instance must be able to reach Predastore — use the host's br-wan IP, not localhost
## Instructions