Add comprehensive documentation for v0.2.0
- README.md: full project overview with features, install extras, CLI reference, web UI routes, config table, architecture diagrams, security model, /health API, and development setup - CLAUDE.md: updated for monorepo — reflects inlined subpackages, new import patterns, pip extras, and added modules - docs/deployment.md: practical RPi deployment guide covering hardware, OS setup, security hardening (swap/coredumps/firewall), installation, systemd service, config reference, fieldkit setup, key management, operational security limitations, troubleshooting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
638
docs/deployment.md
Normal file
638
docs/deployment.md
Normal file
@@ -0,0 +1,638 @@
|
||||
# SooSeF Deployment Guide
|
||||
|
||||
Deploying SooSeF on a Raspberry Pi for airgapped LAN use.
|
||||
|
||||
This guide is for field deployers: IT staff at NGOs, technically competent journalists,
|
||||
and anyone setting up a shared SooSeF instance on a local network with no internet access.
|
||||
|
||||
---
|
||||
|
||||
## 1. Hardware Requirements
|
||||
|
||||
**Minimum:**
|
||||
|
||||
- Raspberry Pi 4 Model B, 2 GB RAM (4 GB recommended)
|
||||
- 32 GB microSD card (Class 10 / A2 recommended)
|
||||
- USB-C power supply (5V 3A, official RPi PSU recommended)
|
||||
- Ethernet cable or pre-configured Wi-Fi for LAN
|
||||
|
||||
**Optional:**
|
||||
|
||||
- USB GPS module (e.g., VK-162) for geofencing
|
||||
- Momentary push button + 10k pull-down resistor on GPIO pin 17 for hardware killswitch
|
||||
- USB drive for airgap package transfer and key backups
|
||||
- Case with passive cooling (no fan noise in sensitive environments)
|
||||
|
||||
If you plan to use the hardware killswitch button, wire it between GPIO 17 and 3.3V with
|
||||
a 10k pull-down to GND. The default requires a 5-second hold to trigger (configurable via
|
||||
`gpio_killswitch_hold_seconds` in config).
|
||||
|
||||
---
|
||||
|
||||
## 2. OS Setup
|
||||
|
||||
Install **Raspberry Pi OS Lite (64-bit, Bookworm or later)**. The desktop environment is
|
||||
unnecessary and wastes resources.
|
||||
|
||||
After first boot:
|
||||
|
||||
```bash
|
||||
# Set hostname
|
||||
sudo hostnamectl set-hostname soosef-node
|
||||
|
||||
# Create a dedicated service user
|
||||
sudo useradd -m -s /bin/bash soosef
|
||||
sudo passwd soosef
|
||||
|
||||
# Enable SSH (if not already)
|
||||
sudo systemctl enable --now ssh
|
||||
|
||||
# Update system packages (do this before going airgapped)
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
```
|
||||
|
||||
Set a strong password. If possible, use SSH key authentication and disable password login
|
||||
in `/etc/ssh/sshd_config` (`PasswordAuthentication no`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Security Hardening
|
||||
|
||||
### 3.1 Disable or encrypt swap
|
||||
|
||||
Python does not zero memory when objects are garbage-collected. Cryptographic keys,
|
||||
passwords, and plaintext can persist in swap long after the process exits. On an SD card,
|
||||
this data may survive even after the swap file is deleted (wear leveling).
|
||||
|
||||
**Option A: Disable swap entirely (recommended if you have 4 GB+ RAM)**
|
||||
|
||||
```bash
|
||||
sudo dphys-swapfile swapoff
|
||||
sudo systemctl disable dphys-swapfile
|
||||
sudo rm /var/swap
|
||||
```
|
||||
|
||||
**Option B: Encrypted swap (if you need swap on 2 GB models)**
|
||||
|
||||
```bash
|
||||
sudo dphys-swapfile swapoff
|
||||
sudo systemctl disable dphys-swapfile
|
||||
|
||||
# Use dm-crypt with a random key (regenerated each boot)
|
||||
echo "swap /dev/mmcblk0p3 /dev/urandom swap,cipher=aes-xts-plain64,size=256" | sudo tee -a /etc/crypttab
|
||||
echo "/dev/mapper/swap none swap sw 0 0" | sudo tee -a /etc/fstab
|
||||
```
|
||||
|
||||
Adjust the device path to match your partition layout.
|
||||
|
||||
### 3.2 Disable core dumps
|
||||
|
||||
A core dump from the SooSeF process would contain key material in plaintext.
|
||||
|
||||
```bash
|
||||
echo "* hard core 0" | sudo tee -a /etc/security/limits.conf
|
||||
echo "kernel.core_pattern=/dev/null" | sudo tee -a /etc/sysctl.d/99-soosef.conf
|
||||
sudo sysctl -p /etc/sysctl.d/99-soosef.conf
|
||||
```
|
||||
|
||||
### 3.3 Firewall
|
||||
|
||||
```bash
|
||||
sudo apt install -y ufw
|
||||
sudo ufw default deny incoming
|
||||
sudo ufw default allow outgoing
|
||||
sudo ufw allow ssh
|
||||
sudo ufw allow 5000/tcp # SooSeF web UI
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
If running fully airgapped, also deny outgoing:
|
||||
|
||||
```bash
|
||||
sudo ufw default deny outgoing
|
||||
```
|
||||
|
||||
### 3.4 Disable unnecessary services
|
||||
|
||||
```bash
|
||||
sudo systemctl disable bluetooth
|
||||
sudo systemctl disable avahi-daemon
|
||||
sudo systemctl disable triggerhappy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Installation
|
||||
|
||||
### 4.1 System dependencies
|
||||
|
||||
```bash
|
||||
sudo apt install -y \
|
||||
python3 python3-pip python3-venv python3-dev \
|
||||
libjpeg-dev libjpeg62-turbo-dev zlib1g-dev \
|
||||
libffi-dev libssl-dev \
|
||||
shred coreutils
|
||||
```
|
||||
|
||||
`libjpeg-dev` is required for Pillow and jpeglib (DCT steganography). `libffi-dev` is
|
||||
required for argon2-cffi.
|
||||
|
||||
### 4.2 Create virtual environment
|
||||
|
||||
```bash
|
||||
sudo -u soosef -i # Switch to the soosef user
|
||||
|
||||
python3 -m venv ~/soosef-env
|
||||
source ~/soosef-env/bin/activate
|
||||
pip install --upgrade pip wheel
|
||||
```
|
||||
|
||||
### 4.3 Install SooSeF
|
||||
|
||||
**If the Pi has internet access (pre-deployment):**
|
||||
|
||||
```bash
|
||||
pip install "soosef[web,cli,fieldkit]"
|
||||
```
|
||||
|
||||
For hardware killswitch support via GPIO:
|
||||
|
||||
```bash
|
||||
pip install "soosef[rpi]"
|
||||
```
|
||||
|
||||
The `rpi` extra includes `web`, `cli`, `fieldkit`, and `gpiozero`.
|
||||
|
||||
**For airgapped install (no internet on the Pi):**
|
||||
|
||||
On an internet-connected machine with the same architecture (aarch64 for RPi 4):
|
||||
|
||||
```bash
|
||||
mkdir soosef-wheels
|
||||
pip download "soosef[rpi]" -d soosef-wheels/
|
||||
```
|
||||
|
||||
Copy the `soosef-wheels/` directory to a USB drive, then on the Pi:
|
||||
|
||||
```bash
|
||||
pip install --no-index --find-links /media/usb/soosef-wheels/ "soosef[rpi]"
|
||||
```
|
||||
|
||||
### 4.4 Verify installation
|
||||
|
||||
```bash
|
||||
soosef --version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Initial Setup
|
||||
|
||||
### 5.1 Initialize SooSeF
|
||||
|
||||
```bash
|
||||
soosef init
|
||||
```
|
||||
|
||||
This creates the `~/.soosef/` directory structure:
|
||||
|
||||
```
|
||||
~/.soosef/
|
||||
config.json Unified configuration
|
||||
identity/ Ed25519 signing keypair (verisoo)
|
||||
private.pem
|
||||
public.pem
|
||||
identity.meta.json
|
||||
stegasoo/ Stegasoo state
|
||||
channel.key AES-256-GCM channel key
|
||||
attestations/ Verisoo attestation log and index
|
||||
chain/ Hash chain data
|
||||
auth/ Web UI user database (SQLite)
|
||||
certs/ Self-signed TLS certificates
|
||||
fieldkit/ Killswitch, deadman, tamper, USB, geofence state
|
||||
temp/ Ephemeral upload/processing files
|
||||
instance/ Flask session data
|
||||
audit.jsonl Append-only audit trail
|
||||
```
|
||||
|
||||
The `identity/` and `auth/` directories are created with mode 0700.
|
||||
|
||||
`soosef init` generates:
|
||||
|
||||
- An Ed25519 identity keypair (for signing attestations)
|
||||
- A channel key (for steganographic encoding)
|
||||
- A default `config.json`
|
||||
|
||||
### 5.2 First user setup
|
||||
|
||||
Start the server and create the first admin user through the web UI:
|
||||
|
||||
```bash
|
||||
soosef serve --host 0.0.0.0 --no-https
|
||||
```
|
||||
|
||||
Navigate to `http://<pi-ip>:5000` from a device on the same LAN. The web UI will prompt
|
||||
you to create the first user account.
|
||||
|
||||
After creating the admin account, stop the server (Ctrl+C) and restart with HTTPS
|
||||
(see Section 6).
|
||||
|
||||
---
|
||||
|
||||
## 6. Running
|
||||
|
||||
### 6.1 Basic usage
|
||||
|
||||
```bash
|
||||
# LAN-only, no HTTPS (acceptable if the network is physically isolated)
|
||||
soosef serve --host 0.0.0.0 --no-https
|
||||
|
||||
# With self-signed HTTPS (recommended)
|
||||
soosef serve --host 0.0.0.0
|
||||
|
||||
# Custom port
|
||||
soosef serve --host 0.0.0.0 --port 8443
|
||||
```
|
||||
|
||||
On first HTTPS start, SooSeF auto-generates a self-signed certificate at
|
||||
`~/.soosef/certs/cert.pem`. Browsers will show a certificate warning -- this is expected
|
||||
for self-signed certs. Instruct users to accept the warning or distribute the cert file
|
||||
to client devices.
|
||||
|
||||
SooSeF uses Waitress (pure Python, no C dependencies) as its production server with 4
|
||||
worker threads by default. Adjust with `--workers`.
|
||||
|
||||
### 6.2 systemd service
|
||||
|
||||
Create `/etc/systemd/system/soosef.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=SooSeF Security Fieldkit
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=soosef
|
||||
Group=soosef
|
||||
WorkingDirectory=/home/soosef
|
||||
Environment="PATH=/home/soosef/soosef-env/bin:/usr/bin"
|
||||
ExecStart=/home/soosef/soosef-env/bin/soosef serve --host 0.0.0.0 --workers 4
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
# Hardening
|
||||
NoNewPrivileges=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=read-only
|
||||
ReadWritePaths=/home/soosef/.soosef
|
||||
PrivateTmp=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Enable and start:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now soosef
|
||||
sudo journalctl -u soosef -f # Watch logs
|
||||
```
|
||||
|
||||
Add `--no-https` to `ExecStart` if running on a physically isolated LAN where TLS is
|
||||
unnecessary.
|
||||
|
||||
---
|
||||
|
||||
## 7. Configuration
|
||||
|
||||
Configuration lives at `~/.soosef/config.json`. Edit it directly or use the web admin
|
||||
panel. All fields have sensible defaults -- you only need to set what you want to change.
|
||||
|
||||
| Field | Default | Description |
|
||||
|---|---|---|
|
||||
| `host` | `127.0.0.1` | Bind address. Set to `0.0.0.0` for LAN access. |
|
||||
| `port` | `5000` | TCP port for the web UI. |
|
||||
| `https_enabled` | `true` | Enable self-signed HTTPS. |
|
||||
| `auth_enabled` | `true` | Require login. Do not disable this. |
|
||||
| `max_upload_mb` | `50` | Maximum file upload size in MB. |
|
||||
| `session_timeout_minutes` | `15` | Idle session expiry. Lower is safer. |
|
||||
| `login_lockout_attempts` | `5` | Failed logins before lockout. |
|
||||
| `login_lockout_minutes` | `15` | Lockout duration. |
|
||||
| `killswitch_enabled` | `false` | Enable software killswitch. |
|
||||
| `deadman_enabled` | `false` | Enable dead man's switch. |
|
||||
| `deadman_interval_hours` | `24` | Hours between required check-ins. |
|
||||
| `deadman_grace_hours` | `2` | Grace period after missed check-in before purge. |
|
||||
| `deadman_warning_webhook` | `""` | URL to POST a JSON warning when check-in is overdue. Must be a public URL (SSRF protection blocks private IPs). |
|
||||
| `usb_monitoring_enabled` | `false` | Monitor for unauthorized USB devices. |
|
||||
| `tamper_monitoring_enabled` | `false` | File integrity monitoring. |
|
||||
| `chain_enabled` | `true` | Wrap attestations in a hash chain. |
|
||||
| `chain_auto_wrap` | `true` | Automatically chain verisoo attestations. |
|
||||
| `backup_reminder_days` | `7` | Warn if no backup in this many days. |
|
||||
| `gpio_killswitch_pin` | `17` | GPIO pin for hardware killswitch button. |
|
||||
| `gpio_killswitch_hold_seconds` | `5.0` | Required hold time to trigger hardware killswitch. |
|
||||
|
||||
Example minimal config for a field deployment:
|
||||
|
||||
```json
|
||||
{
|
||||
"host": "0.0.0.0",
|
||||
"port": 5000,
|
||||
"https_enabled": true,
|
||||
"session_timeout_minutes": 10,
|
||||
"deadman_enabled": true,
|
||||
"deadman_interval_hours": 12,
|
||||
"deadman_grace_hours": 1,
|
||||
"killswitch_enabled": true,
|
||||
"backup_reminder_days": 3
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Fieldkit Setup
|
||||
|
||||
### 8.1 Dead man's switch
|
||||
|
||||
The dead man's switch requires periodic check-ins. If you miss a check-in, SooSeF sends
|
||||
a warning during the grace period. If the grace period expires without a check-in, the
|
||||
killswitch fires automatically and destroys all key material and data.
|
||||
|
||||
Arm it:
|
||||
|
||||
```bash
|
||||
soosef fieldkit deadman arm --interval 12 --grace 1
|
||||
```
|
||||
|
||||
This requires a check-in every 12 hours, with a 1-hour grace period.
|
||||
|
||||
Check in:
|
||||
|
||||
```bash
|
||||
soosef fieldkit checkin
|
||||
```
|
||||
|
||||
You can also check in through the web UI at `/fieldkit`.
|
||||
|
||||
Check status:
|
||||
|
||||
```bash
|
||||
soosef status
|
||||
```
|
||||
|
||||
The dead man's switch enforcement loop runs as a background thread inside `soosef serve`,
|
||||
checking every 60 seconds. It will send a webhook warning (if configured) during the grace
|
||||
period, then execute a full purge if the grace period expires.
|
||||
|
||||
Disarm:
|
||||
|
||||
```bash
|
||||
soosef fieldkit deadman disarm
|
||||
```
|
||||
|
||||
### 8.2 Geofence
|
||||
|
||||
If you have a USB GPS module, you can set a geographic boundary. SooSeF will trigger the
|
||||
killswitch if the device moves outside the fence.
|
||||
|
||||
```bash
|
||||
soosef fieldkit geofence set --lat 50.4501 --lon 30.5234 --radius 5000
|
||||
```
|
||||
|
||||
Coordinates are in decimal degrees, radius in meters.
|
||||
|
||||
### 8.3 USB whitelist
|
||||
|
||||
Record currently connected USB devices as the trusted baseline:
|
||||
|
||||
```bash
|
||||
soosef fieldkit usb learn
|
||||
```
|
||||
|
||||
When monitoring is enabled, SooSeF will alert (or trigger killswitch, depending on config)
|
||||
if an unknown USB device is connected.
|
||||
|
||||
### 8.4 Tamper baseline
|
||||
|
||||
Record file integrity baselines for critical files:
|
||||
|
||||
```bash
|
||||
soosef fieldkit tamper baseline
|
||||
```
|
||||
|
||||
SooSeF monitors for unexpected changes to tracked files when tamper monitoring is enabled.
|
||||
|
||||
---
|
||||
|
||||
## 9. Key Management
|
||||
|
||||
SooSeF manages two separate key domains:
|
||||
|
||||
- **Ed25519 identity key** (`~/.soosef/identity/`) -- used for signing attestations.
|
||||
This is your provenance identity.
|
||||
- **AES-256-GCM channel key** (`~/.soosef/stegasoo/channel.key`) -- used for
|
||||
steganographic encoding/decoding. Shared with anyone who needs to read your
|
||||
stego messages.
|
||||
|
||||
These are separate security concerns and are never merged.
|
||||
|
||||
### 9.1 Backup
|
||||
|
||||
Back up keys regularly. SooSeF warns if no backup has been taken within the
|
||||
`backup_reminder_days` window (default: 7 days).
|
||||
|
||||
```bash
|
||||
soosef keys backup --output /media/usb/soosef-backup.enc
|
||||
```
|
||||
|
||||
This creates an encrypted bundle. You will be prompted for a passphrase. Store the USB
|
||||
drive physically separate from the Pi.
|
||||
|
||||
### 9.2 Restore
|
||||
|
||||
```bash
|
||||
soosef keys restore --input /media/usb/soosef-backup.enc
|
||||
```
|
||||
|
||||
### 9.3 Key rotation
|
||||
|
||||
Generate a new channel key (the old one is overwritten):
|
||||
|
||||
```bash
|
||||
soosef init --no-identity
|
||||
```
|
||||
|
||||
Generate a new identity (the old one is overwritten -- all previous attestations will
|
||||
reference the old fingerprint):
|
||||
|
||||
```bash
|
||||
soosef init --no-channel
|
||||
```
|
||||
|
||||
After rotating keys, take a fresh backup immediately.
|
||||
|
||||
### 9.4 Trusting collaborator keys
|
||||
|
||||
Import a collaborator's public key so you can verify their attestations:
|
||||
|
||||
```bash
|
||||
soosef keys trust --import /media/usb/collaborator-pubkey.pem
|
||||
```
|
||||
|
||||
Verify the fingerprint out-of-band (in person, over a secure channel) before trusting.
|
||||
|
||||
---
|
||||
|
||||
## 10. Operational Security Notes
|
||||
|
||||
SooSeF is a tool, not a shield. Understand what it cannot do.
|
||||
|
||||
### What SooSeF does not protect against
|
||||
|
||||
- **Physical coercion.** If someone forces you to unlock the device or reveal passwords,
|
||||
no software can help. The killswitch is for situations where you can act before
|
||||
interception, not during.
|
||||
- **Social engineering.** SooSeF cannot prevent users from being tricked into revealing
|
||||
credentials or disabling security features.
|
||||
- **Leaving the browser open.** The session timeout helps, but if someone walks up to an
|
||||
unlocked browser session, they have access. Train users to close the browser or lock the
|
||||
screen.
|
||||
- **Compromised client devices.** SooSeF secures the server. If a user's laptop has
|
||||
malware, their browser session is compromised regardless of what the server does.
|
||||
|
||||
### Shred limitations on flash storage
|
||||
|
||||
The killswitch uses `shred` on Linux (3-pass overwrite + zero). On spinning disks, this
|
||||
is effective. On SD cards and SSDs, **it is not reliable** because:
|
||||
|
||||
- Flash translation layers remap physical blocks. Overwritten data may persist on
|
||||
remapped blocks.
|
||||
- Wear leveling distributes writes across the flash, meaning the original block may be
|
||||
preserved.
|
||||
|
||||
SooSeF's defense against this is **cryptographic erasure**: destroy the keys first, then
|
||||
the data. Even if fragments of encrypted data survive on flash, they are useless without
|
||||
the keys. The killswitch destroys keys before anything else, and keys are small enough to
|
||||
fit in a single flash block.
|
||||
|
||||
This is why full-disk encryption matters -- see below.
|
||||
|
||||
### Full-disk encryption (LUKS)
|
||||
|
||||
For serious deployments, encrypt the entire SD card (or at least the data partition) with
|
||||
LUKS. This way, even if the SD card is physically seized:
|
||||
|
||||
- All data at rest is encrypted
|
||||
- Shred limitations are irrelevant because the underlying storage is encrypted
|
||||
- Power-off = data inaccessible (assuming the LUKS passphrase is strong)
|
||||
|
||||
Setting up LUKS on Raspberry Pi OS is beyond the scope of this guide, but the short
|
||||
version is: create an encrypted partition, mount it at `/home/soosef/.soosef`, and
|
||||
configure auto-unlock via a keyfile on a separate USB (remove the USB after boot in
|
||||
hostile environments).
|
||||
|
||||
### Memory considerations
|
||||
|
||||
Python does not securely zero memory. Key material, passwords, and plaintext may persist
|
||||
in process memory and swap. The mitigations in Section 3 (disable swap, disable core
|
||||
dumps) reduce the window, but a memory dump of the running process would expose secrets.
|
||||
This is a fundamental limitation of Python-based security tools.
|
||||
|
||||
---
|
||||
|
||||
## 11. Troubleshooting
|
||||
|
||||
### Health check
|
||||
|
||||
SooSeF exposes a `/health` endpoint on the web UI. Hit it from the LAN to verify the
|
||||
server is running:
|
||||
|
||||
```bash
|
||||
curl -k https://<pi-ip>:5000/health
|
||||
```
|
||||
|
||||
The `-k` flag skips certificate verification for self-signed certs.
|
||||
|
||||
### System status
|
||||
|
||||
```bash
|
||||
soosef status
|
||||
```
|
||||
|
||||
This checks identity key, channel key, trusted keys, dead man's switch state, geofence,
|
||||
chain status, and backup status.
|
||||
|
||||
### Common issues
|
||||
|
||||
**scipy fails to build on Raspberry Pi**
|
||||
|
||||
scipy requires Fortran and BLAS libraries. On Raspberry Pi OS:
|
||||
|
||||
```bash
|
||||
sudo apt install -y gfortran libopenblas-dev
|
||||
```
|
||||
|
||||
If the build still fails (common on low-memory Pis), increase swap temporarily during
|
||||
install, then disable it again:
|
||||
|
||||
```bash
|
||||
sudo dphys-swapfile swapon
|
||||
pip install scipy
|
||||
sudo dphys-swapfile swapoff
|
||||
```
|
||||
|
||||
Or use pre-built wheels:
|
||||
|
||||
```bash
|
||||
pip install --prefer-binary scipy
|
||||
```
|
||||
|
||||
**Argon2 OOM on low-memory Pi (2 GB)**
|
||||
|
||||
Argon2 password hashing is memory-intensive by design. If the server crashes during login
|
||||
on a 2 GB Pi with other services running, either:
|
||||
|
||||
- Free memory by disabling unnecessary services
|
||||
- Reduce Argon2 memory cost (not recommended -- weakens password hashing)
|
||||
|
||||
The default Argon2 parameters use ~64 MB per hash operation. With 2 GB total RAM and a
|
||||
running server, this is tight but workable if nothing else is competing for memory.
|
||||
|
||||
**Web UI unreachable from LAN**
|
||||
|
||||
1. Check that `host` is set to `0.0.0.0` in config, not `127.0.0.1`
|
||||
2. Check firewall: `sudo ufw status` -- port 5000 must be allowed
|
||||
3. Check the service is running: `sudo systemctl status soosef`
|
||||
4. Check the Pi's IP: `ip addr show`
|
||||
|
||||
**Certificate warnings in browser**
|
||||
|
||||
Expected with self-signed certificates. Users must click through the warning. To avoid
|
||||
this, distribute `~/.soosef/certs/cert.pem` to client devices and install it as a
|
||||
trusted certificate.
|
||||
|
||||
**Dead man's switch fires unexpectedly**
|
||||
|
||||
The switch checks every 60 seconds. If the Pi loses power or the service crashes and
|
||||
does not restart within `interval_hours + grace_hours`, the switch will fire on the next
|
||||
start. Make sure the systemd service is set to `Restart=on-failure` and the Pi has
|
||||
reliable power.
|
||||
|
||||
If you need to perform maintenance, disarm the switch first:
|
||||
|
||||
```bash
|
||||
soosef fieldkit deadman disarm
|
||||
```
|
||||
|
||||
Re-arm when maintenance is complete.
|
||||
|
||||
**Permission errors on ~/.soosef/**
|
||||
|
||||
The `identity/`, `auth/`, and `certs/` directories are mode 0700. If running under a
|
||||
different user than the one who ran `soosef init`, you will get permission denied errors.
|
||||
Always run SooSeF as the same user.
|
||||
|
||||
```bash
|
||||
ls -la ~/.soosef/
|
||||
```
|
||||
Reference in New Issue
Block a user