Skip to content

QDRIVEdotDev/QDRIVE

Repository files navigation

   ·······························································
   :    __  __             ____    ____  ____  _____    ________ :
   :   / /_/ /_  ___      / __ \  / __ \/ __ \/  _/ |  / / ____/ :
   :  / __/ __ \/ _ \    / / / / / / / / /_/ // / | | / / __/    :
   : / /_/ / / /  __/   / /_/ / / /_/ / _, _// /  | |/ / /___    :
   : \__/_/ /_/\___/    \___\_\/_____/_/ |_/___/  |___/_____/    :
   :                                                             :
   ·······························································

QDRIVE Linux: Self-Healing Secure SFTP Infrastructure

Own your cloud. Own your files. Run it unattended.

A config-driven, self-healing SFTP server that runs behind a VPN with dynamic port forwarding. It automatically tracks port changes, updates the firewall and SSH config, and provides remote administration through Discord. No web UI, no local console needed.

One config file. One install command. Runs indefinitely without human intervention.

  ┌─────────────┐        ┌──────────────┐        ┌──────────┐
  │  VPN Client │──────▶│   Watchdog    │──────▶│   SSHD   │
  │ (port logs) │        │  (port sync) │        │  (SFTP)  │
  └─────────────┘        └──────┬───────┘        └──────────┘
                                │ health check
                         ┌──────▼───────┐
                         │   Discord    │
                         │    Bot       │
                         │  (ChatOps)   │
                         └──────────────┘

Why QDRIVE Exists

If you run an SFTP server behind a VPN with port forwarding, your forwarded port changes unpredictably. Every time it changes, you'd normally need to manually update your SSH config, firewall rules, and tell your users the new connection details.

QDRIVE automates all of that. The watchdog monitors VPN logs, detects port changes within 60 seconds, updates everything automatically, and allows users to query the new connection info from the Discord bot. Meanwhile, the bot and watchdog monitor each other's health — if either one crashes, the other brings it back.

The result is an SFTP server you deploy once and never touch again.


Origin Story

QDRIVE started as a Windows project: a PowerShell watchdog, a Python Discord bot, and a Task Scheduler held together by health files and scheduled tasks. It ran on a Beelink Mini PC from November 2025 onward with zero manual interventions.

This Linux version is a ground-up redesign. Not a port, a deliberate re-architecture that replaces every Windows-specific component with Linux-native equivalents and adds security features, automated testing, and one-command deployment that the original never had.

Windows v1.0 Linux v2.0
Process management Task Scheduler systemd services with sandboxing
Watchdog PowerShell while($true) loop Python service with signal handling
Firewall Windows Firewall rules ufw with scoped sudo
Permissions icacls POSIX ACLs (setfacl)
Config config.json with hardcoded paths Validated config.yaml, zero hardcoded paths
Installation Manual, ~45 minutes, error-prone sudo ./install.sh, ~5 minutes
Testing None 306 automated tests
Security audit None Scoped sudoers, systemd sandboxing, fail2ban
Uninstall Manual cleanup sudo ./uninstall.sh

The Windows implementation remains maintained at QDRIVE v1.0 as the Windows-native reference.


Features

Self-Healing Infrastructure

  • Mutual watchdog handshake — bot and watchdog monitor each other
  • Automatic VPN port synchronization (sshd_config + firewall + SSHD restart)
  • Fail-safe offline mode when VPN port is unavailable
  • systemd restart policies as the final safety net

Discord ChatOps

  • 8 slash commands for full remote administration
  • SSH key injection with cryptographic validation
  • Folder access control (deny/allow per user)
  • Emergency lockout and manual maintenance triggers
  • Passive event notifications to a log channel

Security by Default

  • Key-only SSH authentication (passwords disabled, enforced by installer)
  • ChrootDirectory isolation (SFTP users cannot escape the data root)
  • systemd sandboxing (ProtectSystem, ProtectHome, NoNewPrivileges)
  • Scoped sudo with per-command restrictions (no blanket command grants)
  • fail2ban integration for brute force protection
  • Admin enforcement on every privileged Discord command
  • Rate limiting (3 commands per 60 seconds per user)
  • Full audit trail of every security-relevant operation

Config-Driven Design

  • Single config.yaml controls the entire system
  • Validated at startup — malformed config prevents boot, not runtime failure
  • Provider-agnostic VPN layer (Proton VPN, Mullvad, WireGuard, custom)
  • Configurable SFTP root, folder structure, maintenance schedule, and security thresholds

Quick Start

Prerequisites

  • Any Debian-based Linux system (Raspberry Pi OS Lite, Ubuntu 22.04+)
  • Python 3.10 or newer
  • A Discord bot token (Developer Portal)
  • A VPN with port forwarding enabled (Proton VPN recommended)

Install Dependencies

sudo apt update
sudo apt install -y openssh-server python3 python3-venv ufw acl lsof psmisc fail2ban

Deploy

git clone https://github.com/QDRIVEdotDev/QDRIVE.git
cd QDRIVE

# Create your config
cp config.example.yaml config.yaml
nano config.yaml    # Set your Discord token and admin ID

# Validate without making changes
sudo ./install.sh --dry-run

# Deploy
sudo ./install.sh

The installer shows you exactly what it will do and asks for confirmation before making any changes. See What the Installer Does for full details.

Verify

From Discord:

  • /qdrive — see your server's IP, port, and status
  • /qstatus — see disk usage, watchdog state, and SSHD status

From the command line:

sudo systemctl status qdrive-watchdog qdrive-bot sshd

Discord Commands

Command Access Purpose
/qdrive Public Reports current IP, port, and SSHD status
/qstatus Admin System health: disk usage, service states, last maintenance
/qstart Admin Start the watchdog service
/qlock Admin ⚠️ Emergency lockout — stops watchdog, terminates all connections
/qrestart Admin ⚠️ Trigger weekly maintenance (QLOCK + log rotation + reboot)
/qaddkey Admin ⚠️ Inject an SSH public key into a user vault
/qdeny Admin Deny standard user access to a folder
/qallow Admin Restore standard user access to a folder

⚠️ = requires button confirmation before executing.

Admin commands are enforced by Discord user ID. Only the user ID specified in config.yaml can execute them. All unauthorized attempts are logged.


Architecture

QDRIVE/
├── config.yaml                    # Your configuration (only file you edit)
├── config.example.yaml            # Annotated template
├── install.sh                     # One-command deployment
├── uninstall.sh                   # Clean removal
├── requirements.txt               # Python dependencies
├── src/
│   ├── core/
│   │   ├── config.py              # Typed config loader with validation
│   │   ├── audit.py               # Structured security event logging
│   │   └── vpn_providers.py       # VPN provider registry
│   ├── bot/
│   │   └── qbot.py                # Discord bot (8 slash commands)
│   ├── watchdog/
│   │   └── watchdog.py            # Port sync + bot health monitor
│   └── maintenance/
│       ├── maintenance.py         # Weekly routine (QLOCK → rotate → reboot)
│       └── qlock.py               # Surgical file handle termination
├── systemd/                       # Service units (deployed by installer)
├── templates/                     # sshd_config, sudoers, fail2ban templates
├── tests/                         # 306 automated tests
└── docs/
    ├── QDRIVE_DEPLOYMENT_GUIDE.md
    ├── QDRIVE_OPERATIONS_MANUAL.md
    └── QDRIVE_SECURITY_OVERVIEW.md

How the Pieces Interact

The Watchdog (qdrive-watchdog.service) runs a 60-second loop:

  1. Checks if SSHD is running — starts it if not
  2. Reads VPN logs for the current forwarded port
  3. If the port changed: backs up sshd_config, updates it, updates ufw, restarts SSHD
  4. If the VPN port is unavailable: marks config # Port OFFLINE (fail-safe)
  5. Checks the bot's health file — restarts the bot service if stale or missing

The Bot (qdrive-bot.service) connects to Discord and handles slash commands:

  1. Writes a heartbeat timestamp every 60 seconds (the watchdog reads this)
  2. Responds to commands, enforces admin checks, logs security events
  3. Pushes notifications to the log channel when significant events occur

Maintenance (qdrive-maintenance.service) runs weekly via a systemd timer:

  1. Executes the QLOCK protocol (stop SSHD, clear file handles, verify clean)
  2. Rotates old audit log backups
  3. Writes a SUCCESS handshake file
  4. Reboots the system

Each component is isolated — the bot cannot modify sshd_config, the watchdog cannot write to Discord, and QLOCK cannot restart SSHD. These boundaries are enforced by systemd sandboxing and verified by contract tests.


What the Installer Does

Transparency matters. Here is everything install.sh does to your system, in order. The --dry-run flag runs the validation phases without making any changes.

Phase Action Reversible?
1 Validates config.yaml and checks prerequisites are installed Read-only
2 Creates system users: qdrive-system, plus the standard/admin users named in your config (qdrive and qdriveadmin by default), with nologin shell userdel to remove
3 Creates SFTP directory structure with POSIX ACLs, plus runtime state and log directories rm -rf to remove
4 Adds fstab entry and mounts external drive if configured (nofail) Remove the fstab line
5 Copies application to /opt/qdrive, creates Python venv, installs dependencies rm -rf /opt/qdrive
6 Backs up existing sshd_config, deploys hardened template, validates with sshd -t Restore from backup
7 Deploys /etc/sudoers.d/qdrive (scoped permissions), validates with visudo -cf rm /etc/sudoers.d/qdrive
8 Deploys systemd unit files and configures sshd.service for cross-distro compatibility rm unit files; full cleanup via uninstall.sh
9 Configures fail2ban SSH jail if enabled Remove jail file
10 Enables and starts services, enables ufw, restarts SSHD sudo ./uninstall.sh
11 Runs final health check Read-only

The installer backs up your existing sshd_config before replacing it. Your backup is at /etc/ssh/sshd_config.bak.TIMESTAMP.

The installer validates the new sshd_config with sshd -t before applying it. If validation fails, it restores the backup automatically.

The installer verifies password authentication is disabled in the final config. If it isn't, the installer aborts.

To completely undo everything: sudo ./uninstall.sh


Configuration

Copy config.example.yaml to config.yaml and edit it. Every field is commented. The essential fields:

discord:
  token: "your-bot-token"              # From Discord Developer Portal
  admin_id: "your-discord-user-id"     # Right-click → Copy User ID
  log_channel_id: ""                   # Optional: channel for event notifications

server:
  sftp_root: /srv/qdrive               # Where SFTP data lives (configurable)

vpn:
  provider: protonvpn                  # protonvpn | mullvad | wireguard | custom

Full configuration reference is in config.example.yaml.


Security Model

QDRIVE's security posture is documented in detail in docs/QDRIVE_SECURITY_OVERVIEW.md. The highlights:

  • No passwords, ever. SSH key authentication only. The installer enforces this.
  • Chroot jail. SFTP users cannot escape the data directory or run commands.
  • Sandboxed services. systemd prevents each service from accessing files it doesn't need.
  • Scoped sudo. Every sudo entry restricts qdrive-system to specific binaries. Most commands have exact-argument restrictions: pkill is locked to pkill -9 sshd, ufw to allow/delete allow with /tcp, systemctl to specific service+action pairs. A small number of commands — setfacl, fuser, and lsof — currently use bounded wildcards while application-layer validation handles path scoping. Tightening these to argument-level restrictions is tracked as a future enhancement.
  • Audit trail. Every port change, key injection, lockout, and unauthorized access attempt is logged with timestamp, actor, and detail.
  • No telemetry. QDRIVE makes no network calls except the Discord gateway and one IP lookup (api.ipify.org when /qdrive is invoked). No analytics, no phone-home, no data collection.

Testing

pip install -r requirements.txt pytest --break-system-packages
python3 -m pytest tests/ -v

306 tests covering config validation, audit logging, rate limiting, SSH key validation, path sanitization, sshd_config manipulation, firewall management, bot health monitoring, QLOCK sequencing, maintenance routines, systemd unit structure, template rendering, sudoers scoping, and architectural contract enforcement.

All tests run in memory with mocked subprocess calls. No network connections, no system changes, no root required.


Documentation

Document Purpose
docs/QDRIVE_DEPLOYMENT_GUIDE.md Step-by-step installation walkthrough
docs/QDRIVE_OPERATIONS_MANUAL.md How everything works, command reference, troubleshooting
docs/QDRIVE_SECURITY_OVERVIEW.md Attack surface analysis, breach simulations, trust boundaries

Requirements

  • OS: Debian-based Linux (Raspberry Pi OS Lite 64-bit, Ubuntu 22.04+)
  • Python: 3.10 or newer
  • Packages: openssh-server python3 python3-venv ufw acl lsof psmisc fail2ban
  • Python deps: discord.py==2.7.1, PyYAML==6.0.3 (pinned, installed automatically by install.sh)
  • Hardware: Runs on anything — Raspberry Pi 5, any x86 machine, cloud VPS
  • VPN: Any provider with port forwarding (Proton VPN fully supported, others in progress)

Uninstall

sudo ./uninstall.sh

Removes all services, application files, runtime state, logs, sudoers config, and fail2ban jail. Does not remove your SFTP data, system users, or sshd_config changes (restore from backup manually if desired).


License

GNU Affero General Public License v3.0 — see LICENSE for the full text.

QDRIVE is licensed under AGPL v3 to keep it aligned with its purpose: a tool for self-hosters running their own infrastructure. The AGPL ensures that modified versions offered as a network service remain open-source, so the project stays in the hands of the homelab community rather than being wrapped into closed-source SaaS products.


QDRIVE is an independent open-source project. It is not affiliated with Proton VPN, Mullvad, Discord, or any other third-party service.

About

Self-healing SFTP infrastructure with ChatOps management, VPN port synchronization, and systemd sandboxing. Linux-native rebuild of QDRIVE v1.0.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors