Skip to content

A PHP CLI tool for automated, encrypted HestiaCP user backups to S3 or FTP. Supports compression, retention, notifications, and resource checks. Fast, secure, and easy to configure for production servers.

License

Notifications You must be signed in to change notification settings

xnetvn-com/php-backup-remote

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

HestiaCP Remote Backup Tool

Build Status Coverage Status License: Apache-2.0

A robust PHP command-line utility to automate the backup of Hestia Control Panel user data to various remote storage providers. It supports encryption, compression, retention policies, and multi-channel notifications, optimized for servers with limited resources.

Project Structure

├── app/                # Application source code (Backup, Notification, Storage, System, Utils)
├── config/             # Configuration files (app.php, constant.php)
├── libs/               # Composer dependencies and autoload
├── storage/            # Logs and runtime data
├── tests/              # PHPUnit test cases (unit, integration, E2E, hardening)
├── tmp/                # Temporary working directory for backup operations
├── .github/            # GitHub Actions, issue templates, CODEOWNERS, PR template
├── .env.example        # Example environment configuration
├── run.php             # Main entry point for backup
├── download.php        # Restore utility
├── upload.php          # (Optional) Upload utility
├── README.md           # Project documentation
├── LICENSE             # Apache License 2.0
├── NOTICE              # Attribution notice
└── CONTRIBUTING.md     # Contribution guidelines

Features

  • Multiple Storage Backends: Upload encrypted backups to AWS S3, Backblaze B2, DigitalOcean Spaces, traditional FTP/FTPS servers, or local filesystem via Flysystem.
  • Strong Encryption: AES-256-CBC encryption (via OpenSSL) or GPG encryption with optional key management.
  • Flexible Compression: Support for gzip, zstd, bzip2, xz, zip, 7z formats with configurable compression levels.
  • Smart Rotation: Advanced retention policies supporting daily, weekly, monthly, and yearly backup retention with intelligent file grouping.
  • XBK File Format: Custom .xbk archive format supporting layered compression and encryption with filename metadata.
  • Dry-Run Mode: Safe simulation without creating, uploading, or deleting files for testing configurations.
  • Structured Logging: Comprehensive logging with Monolog supporting multiple channels and log levels.
  • Pre-flight Checks: CPU load, disk space, time window validation, and dependency verification.
  • Multi-Channel Notifications: Email (SMTP), Telegram, Discord, Slack, Microsoft Teams, Google Chat notifications.
  • Performance Optimized: Streaming operations for large files, memory-efficient processing, concurrent uploads.
  • Security Hardened: Read-only source protection, path traversal prevention, secure credential management.
  • CLI Tools Integration: Native support for 7z, zip, gzip, zstd, bzip2, xz CLI tools for optimal performance.
  • PSR Compliant: Modern PHP 8.2+ codebase following PSR-4, PSR-12, PSR-3 standards with full type declarations.

Requirements

  • PHP 8.2 or higher
  • Composer
  • PHP Extensions: ctype, mbstring, openssl, ftp (for FTP driver)
  • CLI Tools for compression/encryption:
    • gzip (install: sudo apt install gzip)
    • zstd (install: sudo apt install zstd)
    • bzip2 (install: sudo apt install bzip2)
    • xz-utils (install: sudo apt install xz-utils)
    • zip & unzip (install: sudo apt install zip unzip)
    • p7zip-full (install: sudo apt install p7zip-full)
    • gnupg (install: sudo apt install gnupg)

Supported Platforms

This tool has been tested on the following operating systems:

  • Debian/Ubuntu

    sudo apt update && sudo apt install -y php-cli php-mbstring php-common \
      unzip zip gzip zstd bzip2 xz-utils p7zip-full gnupg composer
  • CentOS/RHEL

    sudo yum install -y epel-release && sudo yum install -y php-cli php-mbstring php-common \
      unzip zip gzip zstd bzip2 xz p7zip p7zip-plugins gnupg composer
  • macOS

    brew update && brew install php composer zstd xz p7zip gnupg

Installation

git clone https://github.com/xnetvn-com/php-backup-remote.git
cd php-backup-remote
cd libs
composer install --no-dev --optimize-autoloader
cd ..

Auto-Update (Recommended)

For safe and convenient updates to the latest version:

./auto_update.sh

Note:

  • The script will automatically detect the default branch (main or master) from the remote repository.

  • If the current directory is a Git repository, it will fetch and hard reset to match the remote branch (all local changes will be overwritten).

  • If the current directory is not a Git repository, it will clone the correct branch and copy files into the current directory.

  • Your configuration files and logs will be preserved.

  • Requires git to be installed.

⚠️ Warning: This script will overwrite any local changes in the repository directory. Make sure to back up your work if needed.

See UPDATE_GUIDE.md for detailed instructions.

Quick Start

  1. Clone the repository and enter directory:

    git clone https://github.com/xnetvn-com/php-backup-remote.git
    cd php-backup-remote
  2. Install PHP dependencies (production):

    cd libs
    composer install --no-dev --optimize-autoloader
    cd ..

    For development (with dev dependencies):

    cd libs
    composer install
    cd ..
  3. Copy and customize environment settings:

    cp .env.example .env
    # Edit .env to configure backup paths, encryption, compression, and storage drivers
  4. Run a dry-run to verify settings:

    php run.php --dry-run
  5. Execute a real backup:

    php run.php

Example .env Configuration

# Core backup settings
BACKUP_PASSWORD=your-super-secret-encryption-password
BACKUP_DIRS=/backup,/home,/var/www
BACKUP_COMPRESSION=gzip   # Options: none, gzip, zstd, bzip2, xz, zip, 7z
BACKUP_COMPRESSION_LEVEL=6
BACKUP_ENCRYPTION=aes     # Options: none, aes, gpg, zip, 7z
BACKUP_ENCRYPTION_KEY_PATH=/path/to/public.key # For GPG (optional)
TMP_DIR=/tmp/php-backup-remote

# Advanced compression and encryption combinations:
# - BACKUP_COMPRESSION=7z + BACKUP_ENCRYPTION=7z: Uses 7z CLI for both compression and encryption in one step
# - BACKUP_COMPRESSION=zip + BACKUP_ENCRYPTION=zip: Uses zip CLI with AES-256 encryption in one step
# - BACKUP_COMPRESSION=7z + BACKUP_ENCRYPTION=none: Uses 7z CLI for compression only
# - BACKUP_COMPRESSION=zip + BACKUP_ENCRYPTION=none: Uses zip CLI for compression only
# - Separate steps: BACKUP_COMPRESSION=gzip + BACKUP_ENCRYPTION=aes (compress first, then encrypt)

# Rotation & retention
ROTATION_ENABLED=true
ROTATION_KEEP_LATEST=7
ROTATION_KEEP_DAILY=7
ROTATION_KEEP_WEEKLY=4
ROTATION_KEEP_MONTHLY=12
ROTATION_KEEP_YEARLY=3
ROTATION_PATTERN=*.xbk.*

# Remote storage (S3, B2, FTP, Local)
REMOTE_DRIVER=s3          # Options: s3, b2, ftp, local

# S3 settings
S3_KEY=your-s3-access-key
S3_SECRET=your-s3-secret-key
S3_REGION=ap-southeast-1
S3_BUCKET=your-s3-bucket-name
S3_ENDPOINT=https://s3.example.com
S3_USE_PATH_STYLE=true

# Backblaze B2 settings
B2_KEY=your-b2-application-key-id
B2_SECRET=your-b2-application-key
B2_BUCKET=your-b2-bucket-name
B2_REGION=us-west-002

# FTP settings
FTP_HOST=your-ftp-host
FTP_USER=your-ftp-username
FTP_PASS=your-ftp-password
FTP_ROOT=/backups
FTP_SSL=true
FTP_PASSIVE=true

# Local storage
LOCAL_PATH=/mnt/backup-disk

# Performance & resource limits
ALLOWED_START_TIME=01:00
ALLOWED_END_TIME=05:00
MAX_CPU_LOAD=2.5
MIN_DISK_FREE_PERCENT=15
MEMORY_LIMIT=256M
TIME_LIMIT=3600

# Notification settings
EMAIL_SMTP_HOST=smtp.example.com
EMAIL_SMTP_PORT=587
EMAIL_SMTP_USER=your-email@example.com
EMAIL_SMTP_PASS=your-smtp-password
EMAIL_SMTP_ENCRYPTION=tls
ADMIN_EMAIL=admin@example.com

TELEGRAM_BOT_TOKEN=your-telegram-bot-token
TELEGRAM_CHAT_ID=your-telegram-chat-id

DISCORD_WEBHOOK=your-discord-webhook-url
SLACK_WEBHOOK=your-slack-webhook-url
TEAMS_WEBHOOK=your-teams-webhook-url
GOOGLE_CHAT_WEBHOOK=your-google-chat-webhook-url
NOTIFY_INTERVAL_MINUTES=180

# Advanced options
DRY_RUN=false
LOG_CHANNEL=app
LOG_PATH=storage/logs/app.log
LOG_LEVEL=info
LOCK_FILE=storage/.backup.lock

# Security
ENFORCE_READONLY=true
SAFE_MODE=true

# Developer/debug
DEBUG=false
VERBOSE=false

# Custom user hooks (optional)
PRE_BACKUP_HOOK=/path/to/pre-backup.sh
POST_BACKUP_HOOK=/path/to/post-backup.sh

# Example for multiple backup sources
# BACKUP_DIRS=/backup,/home/user1,/home/user2,/var/www/html

Configuration

Copy the example environment file and edit your settings:

cp .env.example .env

Open .env and configure:

Variable Description Default
BACKUP_PASSWORD Password for AES or GPG encryption (choose a strong secret) REQUIRED
BACKUP_DIRS Comma-separated absolute paths to backup user directories /backup
BACKUP_COMPRESSION Compression method (none, gzip, zstd, bzip2, xz, zip, 7z) none
BACKUP_COMPRESSION_LEVEL Compression level (1-9, default 6) 6
BACKUP_ENCRYPTION Encryption method (none, aes, gpg, zip, 7z) aes
BACKUP_ENCRYPTION_KEY_PATH Path to public key for GPG encryption (optional) Not set
REMOTE_DRIVER Override to use a single storage driver: s3, b2, ftp or local Not set
TMP_DIR Temporary directory for backup operations /tmp/php-backup-remote

Compression & Encryption CLI Usage

Configuration CLI Tools Used Description
BACKUP_COMPRESSION=7z + BACKUP_ENCRYPTION=7z 7z a (single step) 7z CLI compresses and encrypts in one command
BACKUP_COMPRESSION=zip + BACKUP_ENCRYPTION=zip zip -e (single step) zip CLI compresses with traditional encryption
BACKUP_COMPRESSION=7z + BACKUP_ENCRYPTION=none 7z a (compression only) 7z CLI for compression only
BACKUP_COMPRESSION=zip + BACKUP_ENCRYPTION=none zip (compression only) zip CLI for compression only
BACKUP_COMPRESSION=gzip + BACKUP_ENCRYPTION=aes gzip + openssl Separate compression and encryption steps
BACKUP_COMPRESSION=zstd + BACKUP_ENCRYPTION=gpg zstd + gpg Separate compression and encryption steps

Note: The zip CLI uses traditional password-based encryption (not AES-256). For stronger encryption, use 7z or separate AES encryption.

S3 Driver Settings

Variable Description
S3_KEY S3 access key
S3_SECRET S3 secret key
S3_REGION S3 region
S3_BUCKET S3 bucket name
S3_ENDPOINT Custom endpoint (for non-AWS providers)
S3_USE_PATH_STYLE true if using path-style URLs (e.g., DigitalOcean Spaces)

Backblaze B2 Settings

Variable Description
B2_KEY Backblaze B2 application key ID
B2_SECRET Backblaze B2 application key
B2_BUCKET Backblaze B2 bucket name
B2_REGION Backblaze B2 region (optional)

FTP Driver Settings

Variable Description
FTP_HOST FTP server hostname
FTP_USER FTP username
FTP_PASS FTP password
FTP_ROOT Base directory on FTP server (optional)
FTP_SSL true or false for FTPS (optional)
FTP_PASSIVE true (passive) or false (active) (recommended: true)

Local Storage Settings

Variable Description
LOCAL_PATH Local file system path for backups

Rotation Settings

Variable Description Default
ROTATION_ENABLED Enable automatic rotation true
ROTATION_KEEP_LATEST Number of recent backups to keep 7
ROTATION_KEEP_DAILY Number of daily backups to keep 7
ROTATION_KEEP_WEEKLY Number of weekly backups to keep 4
ROTATION_KEEP_MONTHLY Number of monthly backups to keep 12
ROTATION_KEEP_YEARLY Number of yearly backups to keep 3
ROTATION_PATTERN Pattern to match backup files for rotation *.xbk.*

Performance Limits

Variable Description Default
ALLOWED_START_TIME Earliest allowed backup time (HH:MM), empty to disable 01:00
ALLOWED_END_TIME Latest allowed backup time (HH:MM), empty to disable 05:00
MAX_CPU_LOAD Max 1-min CPU load average, 0 to disable 2.5
MIN_DISK_FREE_PERCENT Minimum free disk % in temp dir 15
MEMORY_LIMIT PHP memory limit (e.g., 256M) 256M
TIME_LIMIT Max script time in seconds, 0 for unlimited 3600

Notification Settings

Variable Description Default
EMAIL_SMTP_HOST SMTP server host -
EMAIL_SMTP_PORT SMTP server port 587
EMAIL_SMTP_USER SMTP username -
EMAIL_SMTP_PASS SMTP password -
EMAIL_SMTP_ENCRYPTION SMTP encryption method (tls, ssl, or empty for none) tls
ADMIN_EMAIL Email address to receive notifications -
TELEGRAM_BOT_TOKEN Telegram bot token -
TELEGRAM_CHAT_ID Telegram chat ID -
DISCORD_WEBHOOK Discord webhook URL -
SLACK_WEBHOOK Slack webhook URL -
TEAMS_WEBHOOK Microsoft Teams webhook URL -
GOOGLE_CHAT_WEBHOOK Google Chat webhook URL -
NOTIFY_INTERVAL_MINUTES Cool-down period between notifications (minutes) 180

Advanced Options

Variable Description Default
DRY_RUN Simulate backup without writing/uploading files false
LOG_CHANNEL Log channel name (for Monolog) app
LOG_PATH Path to log file storage/logs/app.log
LOG_LEVEL Log level (info, debug, error, etc.) info
LOCK_FILE Path to lock file to prevent concurrent runs storage/.backup.lock

Security Options

Variable Description Default
ENFORCE_READONLY Enforce read-only mode for BACKUP_DIRS true
SAFE_MODE Enable extra safety checks (recommended) true

Developer/Debug Options

Variable Description Default
DEBUG Enable debug mode false
VERBOSE Enable verbose output false

Custom User Hooks

Variable Description Default
PRE_BACKUP_HOOK Path to script to run before backup Not set
POST_BACKUP_HOOK Path to script to run after backup Not set

Security & Data Integrity

  • Read-Only Guarantee for BACKUP_DIRS: All files and directories specified in BACKUP_DIRS are treated as strictly read-only. The backup system will never modify, delete, move, or overwrite any original file in these directories. All backup, compression, and encryption operations are performed on temporary copies in a dedicated temp directory (TMP_DIR). This ensures absolute safety and integrity of your source data.

  • AES-256-CBC Encryption: Industry-standard encryption with OpenSSL implementation providing strong data protection at rest and in transit.

  • GPG Encryption Support: Alternative encryption using GnuPG with public key cryptography for enhanced security scenarios.

  • Path Traversal Protection: Comprehensive validation to prevent directory traversal attacks and unauthorized file access.

  • Secure Credential Management: Environment-based credential storage with optional encryption for sensitive configuration values.

  • Automated Security Tests: The project includes automated tests to verify that no write, delete, or move operations are ever performed directly in BACKUP_DIRS.

  • CLI Tool Security: Secure invocation of external compression and encryption tools with proper argument sanitization.

  • File Permissions: Proper temporary directory permissions (0700) and secure file handling throughout the backup process.

  • Best Practice: Always set appropriate file system permissions to enforce read-only access for the backup process user on your backup source directories.

Usage

Run Backup

Real backup:

php run.php

Dry-run (simulate):

php run.php --dry-run

Restore Backup

php download.php --user=<username> --version=<YYYY-MM-DD_HH-MM-SS> [--remote=<driver>] [--outdir=<path>]

Automate with Cron

30 2 * * * /usr/bin/php /path/to/php-backup-remote/run.php > /dev/null 2>&1

How It Works

  1. Initialization: Load .env and bootstrap services.
  2. Locking: Prevent concurrent runs with a lock file.
  3. Pre-flight Checks: CPU, disk space, and time-window validation.
  4. Archive: Create compressed archive per user directory using TAR with configurable compression.
  5. Encrypt: Encrypt archive with AES-256-CBC or GPG using OpenSSL/CLI tools.
  6. Upload: Stream to configured remote storage backends (S3/B2/FTP/Local).
  7. Cleanup: Remove local temporary files and release lock.
  8. Rotation: List remote files and delete older backups beyond retention policy.
  9. Notification: Send success or failure alerts via multiple channels.

Testing

Run PHPUnit unit tests:

./libs/vendor/bin/phpunit --configuration=phpunit.xml

Test Coverage

The project includes comprehensive test coverage:

  • Unit Tests: Core functionality, encryption, compression, storage operations
  • Integration Tests: Component interaction, backup workflows, storage backends
  • Edge Case Tests: Large files, special characters, error conditions
  • Security Tests: Encryption strength, credential management, path validation
  • Performance Tests: Memory usage, streaming operations, concurrent access

For test coverage report generation:

# Install Xdebug (if not already installed)
sudo apt install php8.2-xdebug

# Generate coverage report
./libs/vendor/bin/phpunit --coverage-html coverage/

Contributing

We welcome contributions from the community! Please see CONTRIBUTING.md for detailed guidelines. All contributors must follow the CODEOWNERS and use the provided pull request template. Issues and feature requests should use the appropriate issue templates.

  • Security Contact: Please report security vulnerabilities via security_vulnerability.md or email license@xnetvn.net.
  • CI/CD: All code is automatically tested, linted, scanned for secrets and vulnerabilities, and must pass all checks before merging.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

About

A PHP CLI tool for automated, encrypted HestiaCP user backups to S3 or FTP. Supports compression, retention, notifications, and resource checks. Fast, secure, and easy to configure for production servers.

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published