Resilient infrastructure for small Linux servers and homelabs.
MiniOps is a security-conscious Bash toolkit for turning a small Linux server, mini PC, reused computer, or homelab node into maintainable infrastructure. It combines conservative host hardening, encrypted Restic backups, systemd timers, restore testing, operational checks, and plain-language runbooks.
Warning
MiniOps is experimental. Test every change in a disposable or non-production environment first, keep an independent recovery path, and review generated configuration before applying it.
Small servers often start with a few manual commands and become critical without acquiring repeatable operations. MiniOps provides auditable building blocks while keeping secrets outside version control and requiring explicit confirmation for sensitive changes.
- Preflight checks for supported Linux and systemd environments
- SSH key-only hardening with lockout protection and rollback
- Optional UFW, Fail2ban, auditd, AppArmor, and Tailscale integration
- Encrypted Restic backups to local or SFTP repositories
- Locking, freshness checks, retention, and integrity verification
- Isolated automated restore tests that never overwrite source data
- Hardened systemd services and persistent timers
- A safe, partially degradable terminal dashboard
- Reboot and power-recovery validation procedures
- Incident-oriented operational runbooks
- Tests, ShellCheck, Markdownlint, and secret scanning in CI
┌──────────────────────┐
│ Protected Linux host │
│ files + databases │
└──────────┬───────────┘
│ systemd timer
▼
┌──────────────────────┐
│ MiniOps backup │
│ lock + Restic │
└──────────┬───────────┘
│ private network or Tailscale
▼
┌──────────────────────┐
│ SFTP backup node │
│ encrypted repository │
└──────────┬───────────┘
│
├── integrity checks
├── retention
└── isolated restore tests
git clone https://github.com/YOUR_ACCOUNT/MiniOps.git
cd MiniOps
make test
sudo ./scripts/install.sh --dry-runReview the example configuration:
cp config/miniops.env.example /tmp/miniops.env
cp config/backup.env.example /tmp/backup.envRun preflight checks:
./scripts/preflight-check.shPreview the core, backup, and status modules:
sudo ./scripts/install.sh \
--modules core,backup,status \
--dry-runSee Quick start before applying any change.
The installer places configuration under /etc/miniops, executable tools
under /usr/local/sbin, state under /var/lib/miniops, and systemd units
under /etc/systemd/system.
sudo ./scripts/install.sh --help
sudo ./scripts/install.sh --modules core,backup,statusSensitive modules such as SSH and UFW require explicit selection and confirmation. The installer will not harden SSH unless it verifies at least one public key for the configured administrative account.
Detailed instructions are in Installation.
MINIOPS_ADMIN_USER=adminuser
MINIOPS_TIMEZONE=Etc/UTC
MINIOPS_STATE_DIR=/var/lib/miniops
MINIOPS_LOG_DIR=/var/log/miniops
RESTIC_REPOSITORY=sftp:backupuser@100.x.x.x:/path/to/repository
RESTIC_PASSWORD_FILE=/etc/miniops/secrets/restic-password
MINIOPS_BACKUP_SOURCES_FILE=/etc/miniops/backup-sources
MINIOPS_BACKUP_EXCLUDES_FILE=/etc/miniops/backup-excludesNever commit the real files. See Configuration and Security model.
After installation:
miniops-statusExample with fictitious data:
MiniOps status — miniops-node
Time: 2030-01-15 09:30:00 UTC
Uptime: 12 days, 4 hours
Load / CPU: 0.18 0.11 0.08 / 7%
Memory: 1.2 GiB / 8.0 GiB
Disk /: 18 GiB / 120 GiB (15%)
Tailscale: Running (100.x.x.x)
SSH / UFW: active / active
Fail2ban: active
Backup timer: active; next 2030-01-16 02:00 UTC
Last backup: 2030-01-15 02:04 UTC
Snapshots: 14
Repository size: 8.4 GiB
Last check: 2030-01-12 04:09 UTC
Last restore test: 2030-01-01 06:34 UTC
SMART: PASSED
Warnings: none
The dashboard does not print secret values, password-file paths, SSH
credentials, or repository credentials. Components that are unavailable are
reported as not installed, permission required, or unknown.
MiniOps follows these defaults:
- secrets are stored outside the repository with mode
0600; - SSH hardening uses a drop-in, preserves the old configuration, and validates
with
sshd -tbefore reload; - network changes are opt-in and dry-run capable;
- backup processes use locks and avoid secrets in arguments and logs;
- restore tests use temporary directories and clean them on exit;
- systemd units use least privilege and filesystem protections where practical;
- examples are intentionally fictitious.
Read Security model and Threat model before deployment.
Initial targets:
- Ubuntu LTS releases using systemd
- Current stable Debian releases using systemd
CI exercises generic Bash behavior on Ubuntu. Hardware-specific power recovery, AppArmor policy compatibility, storage behavior, and complete distribution integration require validation on the target host. Other Linux distributions are currently untested.
Requirements:
- Bash 4.4 or newer
- systemd
- OpenSSH
- coreutils, util-linux, and curl
- Restic for backups
- optional: Tailscale, UFW, Fail2ban, auditd, AppArmor, smartmontools
- MiniOps does not configure firmware or power-recovery registers.
- UFW and SSH mistakes can cause remote lockout; retain console access.
- A successful backup is not proof of recoverability; keep restore tests.
- Restic repository passwords must be backed up separately.
- SFTP server hardening varies by distribution and must be reviewed.
- The project does not replace monitoring, UPS hardware, or off-site strategy.
See Limitations.
Version 0.1.0 focuses on conservative Bash automation, encrypted backups,
terminal status, documentation, and CI safety checks. See Roadmap
for planned improvements.
Bug reports, documentation improvements, tests, and narrowly scoped features are welcome. Read Contributing, Code of Conduct, and Support.
Security issues must follow Security policy.
MiniOps is available under the MIT License.