484 lines
12 KiB
Markdown
484 lines
12 KiB
Markdown
# TISBackup
|
|
|
|
A comprehensive server-side backup orchestration system for managing automated backups of databases, files, and virtual machines across remote Linux and Windows systems.
|
|
|
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
[](https://www.python.org/downloads/)
|
|
|
|
## Overview
|
|
|
|
TISBackup is a Python-based backup solution that provides:
|
|
|
|
- **Pluggable backup drivers** for different data sources (databases, files, VMs)
|
|
- **Web-based management interface** for monitoring and controlling backups
|
|
- **CLI tool** for automation and scripting
|
|
- **Automated scheduling** via cron
|
|
- **Backup retention management** with configurable policies
|
|
- **Status monitoring** with Nagios integration
|
|
- **Docker deployment** for easy setup and isolation
|
|
|
|
### Supported Backup Types
|
|
|
|
| Type | Description | Driver |
|
|
|------|-------------|--------|
|
|
| **Files & Directories** | rsync-based file backups | `rsync+ssh` |
|
|
| **Btrfs Snapshots** | Snapshot-based incremental backups | `rsync+btrfs+ssh` |
|
|
| **MySQL** | Database dumps via SSH | `mysql+ssh` |
|
|
| **PostgreSQL** | Database dumps via SSH | `pgsql+ssh` |
|
|
| **SQL Server** | SQL Server backups | `sqlserver+ssh` |
|
|
| **Oracle** | Oracle database backups | `oracle+ssh` |
|
|
| **Samba4 AD** | Active Directory backups | `samba4` |
|
|
| **XenServer VMs** | XVA exports and metadata | `xen-xva`, `xcp-dump-metadata` |
|
|
| **VMware** | VMDK backups | `vmdk` |
|
|
| **Network Devices** | Switch configuration backups | `switch` |
|
|
|
|
## Quick Start
|
|
|
|
### Prerequisites
|
|
|
|
- Docker and Docker Compose
|
|
- SSH access to remote servers
|
|
- Ed25519, ECDSA, or RSA SSH keys (DSA not supported)
|
|
|
|
### Installation
|
|
|
|
1. **Clone the repository:**
|
|
```bash
|
|
git clone https://github.com/tranquilit/TISbackup.git
|
|
cd TISbackup
|
|
```
|
|
|
|
2. **Build the Docker image:**
|
|
```bash
|
|
docker build . -t tisbackup:latest
|
|
```
|
|
|
|
3. **Create directory structure:**
|
|
```bash
|
|
mkdir -p /var/tisbackup/{backup/log,config,ssh}
|
|
```
|
|
|
|
Expected structure:
|
|
```
|
|
/var/tisbackup/
|
|
├── backup/ # Backup storage location
|
|
│ └── log/ # SQLite database and logs
|
|
├── config/ # Configuration files
|
|
│ ├── tisbackup-config.ini
|
|
│ └── tisbackup_gui.ini
|
|
├── ssh/ # SSH keys
|
|
│ ├── id_ed25519 # Private key (Ed25519 recommended)
|
|
│ └── id_ed25519.pub # Public key
|
|
└── compose.yaml # Docker Compose configuration
|
|
```
|
|
|
|
4. **Generate SSH keys:**
|
|
```bash
|
|
# Ed25519 (recommended - most secure and modern)
|
|
ssh-keygen -t ed25519 -f /var/tisbackup/ssh/id_ed25519 -C "tisbackup@yourserver"
|
|
|
|
# Or ECDSA (also secure)
|
|
ssh-keygen -t ecdsa -b 521 -f /var/tisbackup/ssh/id_ecdsa -C "tisbackup@yourserver"
|
|
|
|
# Or RSA (legacy support, minimum 4096 bits)
|
|
ssh-keygen -t rsa -b 4096 -f /var/tisbackup/ssh/id_rsa -C "tisbackup@yourserver"
|
|
```
|
|
|
|
⚠️ **Note:** DSA keys are no longer supported due to security vulnerabilities.
|
|
|
|
5. **Deploy public key to remote servers:**
|
|
```bash
|
|
ssh-copy-id -i /var/tisbackup/ssh/id_ed25519.pub root@remote-server
|
|
```
|
|
|
|
6. **Generate Flask secret key:**
|
|
```bash
|
|
python3 -c "import secrets; print(secrets.token_hex(32))"
|
|
```
|
|
Save this key for the next step.
|
|
|
|
7. **Create Docker Compose configuration:**
|
|
```yaml
|
|
# /var/tisbackup/compose.yaml
|
|
services:
|
|
tisbackup_gui:
|
|
container_name: tisbackup_gui
|
|
image: "tisbackup:latest"
|
|
volumes:
|
|
- ./config/:/etc/tis/
|
|
- ./backup/:/backup/
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
environment:
|
|
# SECURITY: Use the secret key you generated above
|
|
- TISBACKUP_SECRET_KEY=your-secret-key-here
|
|
restart: unless-stopped
|
|
ports:
|
|
- 9980:8080
|
|
|
|
tisbackup_cron:
|
|
container_name: tisbackup_cron
|
|
image: "tisbackup:latest"
|
|
volumes:
|
|
- ./config/:/etc/tis/
|
|
- ./ssh/:/config_ssh/
|
|
- ./backup/:/backup/
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
restart: always
|
|
command: "/bin/bash /opt/tisbackup/cron.sh"
|
|
```
|
|
|
|
8. **Configure backups:**
|
|
|
|
Create `/var/tisbackup/config/tisbackup-config.ini`:
|
|
```ini
|
|
[global]
|
|
backup_base_dir = /backup/
|
|
# Backup retention in days
|
|
backup_retention_time = 90
|
|
# Maximum backup age for Nagios checks (hours)
|
|
maximum_backup_age = 30
|
|
|
|
# Example: File backup via rsync
|
|
[webserver-files]
|
|
type = rsync+ssh
|
|
server_name = webserver.example.com
|
|
remote_dir = /var/www/
|
|
compression = True
|
|
exclude_list = "/var/www/cache/**","/var/www/temp/**"
|
|
private_key = /config_ssh/id_ed25519
|
|
ssh_port = 22
|
|
|
|
# Example: MySQL database backup
|
|
[database-mysql]
|
|
type = mysql+ssh
|
|
server_name = db.example.com
|
|
db_name = production_db
|
|
db_user = backup_user
|
|
db_passwd = backup_password
|
|
private_key = /config_ssh/id_ed25519
|
|
ssh_port = 22
|
|
```
|
|
|
|
Create `/var/tisbackup/config/tisbackup_gui.ini`:
|
|
```ini
|
|
[general]
|
|
config_tisbackup = /etc/tis/tisbackup-config.ini
|
|
sections =
|
|
ADMIN_EMAIL = admin@example.com
|
|
base_config_dir = /etc/tis/
|
|
backup_base_dir = /backup/
|
|
```
|
|
|
|
9. **Start services:**
|
|
```bash
|
|
cd /var/tisbackup
|
|
docker compose up -d
|
|
```
|
|
|
|
10. **Access web interface:**
|
|
```
|
|
http://localhost:9980
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Backup Types Configuration
|
|
|
|
#### File Backups (rsync+ssh)
|
|
```ini
|
|
[backup-name]
|
|
type = rsync+ssh
|
|
server_name = hostname.example.com
|
|
remote_dir = /path/to/backup/
|
|
compression = True
|
|
exclude_list = "/path/exclude1/**","/path/exclude2/**"
|
|
private_key = /config_ssh/id_ed25519
|
|
ssh_port = 22
|
|
```
|
|
|
|
#### Btrfs Snapshots (rsync+btrfs+ssh)
|
|
```ini
|
|
[backup-name]
|
|
type = rsync+btrfs+ssh
|
|
server_name = hostname.example.com
|
|
remote_dir = /mnt/btrfs/data/
|
|
compression = True
|
|
private_key = /config_ssh/id_ed25519
|
|
ssh_port = 22
|
|
```
|
|
|
|
#### MySQL Database (mysql+ssh)
|
|
```ini
|
|
[backup-name]
|
|
type = mysql+ssh
|
|
server_name = hostname.example.com
|
|
db_name = database_name
|
|
db_user = backup_user
|
|
db_passwd = backup_password
|
|
private_key = /config_ssh/id_ed25519
|
|
ssh_port = 22
|
|
```
|
|
|
|
#### PostgreSQL Database (pgsql+ssh)
|
|
```ini
|
|
[backup-name]
|
|
type = pgsql+ssh
|
|
server_name = hostname.example.com
|
|
db_name = database_name
|
|
private_key = /config_ssh/id_ed25519
|
|
ssh_port = 22
|
|
```
|
|
|
|
#### XenServer VM (xen-xva)
|
|
```ini
|
|
[backup-name]
|
|
type = xen-xva
|
|
server_name = vm-name
|
|
xcphost = xenserver.example.com
|
|
password_file = /etc/tis/xen-password
|
|
private_key = /config_ssh/id_ed25519
|
|
```
|
|
|
|
### Pre/Post Execution Hooks
|
|
|
|
You can execute commands before and after backups:
|
|
|
|
```ini
|
|
[backup-name]
|
|
type = rsync+ssh
|
|
server_name = hostname.example.com
|
|
remote_dir = /data/
|
|
private_key = /config_ssh/id_ed25519
|
|
preexec = systemctl stop application
|
|
postexec = systemctl start application
|
|
remote_user = root
|
|
ssh_port = 22
|
|
```
|
|
|
|
## CLI Usage
|
|
|
|
### Running Backups
|
|
|
|
```bash
|
|
# Run all backups
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py backup
|
|
|
|
# Run specific backup
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py -s backup-name backup
|
|
|
|
# Dry run
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py -d backup
|
|
```
|
|
|
|
### Cleanup Old Backups
|
|
|
|
```bash
|
|
# Remove backups older than retention period
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py cleanup
|
|
```
|
|
|
|
### Nagios Monitoring
|
|
|
|
```bash
|
|
# Check backup status
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py checknagios
|
|
|
|
# Check specific backup
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py -s backup-name checknagios
|
|
```
|
|
|
|
### List Available Drivers
|
|
|
|
```bash
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py listdrivers
|
|
```
|
|
|
|
### Backup Statistics
|
|
|
|
```bash
|
|
# Dump statistics for last 20 backups
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py dumpstat
|
|
|
|
# Specify number of backups
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py -n 50 dumpstat
|
|
```
|
|
|
|
## Development
|
|
|
|
### Prerequisites
|
|
|
|
- Python 3.14+
|
|
- uv (Python package manager)
|
|
|
|
### Setup Development Environment
|
|
|
|
```bash
|
|
# Install dependencies
|
|
uv sync --locked
|
|
|
|
# Run linter
|
|
uv run ruff check .
|
|
|
|
# Auto-fix linting issues
|
|
uv run ruff check --fix .
|
|
```
|
|
|
|
### Running Locally
|
|
|
|
```bash
|
|
# Run web GUI (requires config at /etc/tis/tisbackup_gui.ini)
|
|
python3 tisbackup_gui.py
|
|
|
|
# Run CLI
|
|
python3 tisbackup.py -c /etc/tis/tisbackup-config.ini backup
|
|
```
|
|
|
|
## Security
|
|
|
|
TISBackup implements several security best practices:
|
|
|
|
### SSH Key Security
|
|
|
|
- **Ed25519 keys are recommended** (most secure, modern algorithm)
|
|
- ECDSA and RSA keys are supported
|
|
- **DSA keys are explicitly not supported** (deprecated, insecure)
|
|
- Key algorithm priority: Ed25519 → ECDSA → RSA
|
|
|
|
### Flask Session Security
|
|
|
|
- Secret key loaded from `TISBACKUP_SECRET_KEY` environment variable
|
|
- Falls back to cryptographically secure random key if not set
|
|
- No hardcoded secrets in source code
|
|
|
|
### Command Execution Safety
|
|
|
|
- All system commands use `subprocess.run()` with list arguments
|
|
- Input validation for device paths and partition names
|
|
- Timeout protection on all subprocess calls
|
|
- No use of `shell=True` in new code
|
|
|
|
### Best Practices
|
|
|
|
1. **Use Ed25519 keys** for all SSH connections
|
|
2. **Set unique Flask secret key** via environment variable
|
|
3. **Use reverse proxy** (nginx) with TLS for web interface
|
|
4. **Restrict network access** to backup server
|
|
5. **Regular security updates** of base Docker image
|
|
6. **Monitor backup logs** for suspicious activity
|
|
|
|
## Reverse Proxy Setup
|
|
|
|
Example nginx configuration for HTTPS access:
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name tisbackup.example.com;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/tisbackup.example.com/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/tisbackup.example.com/privkey.pem;
|
|
|
|
# Security headers
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
|
|
location / {
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header Host $host;
|
|
proxy_pass http://localhost:9980/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
}
|
|
}
|
|
```
|
|
|
|
## Architecture
|
|
|
|
TISBackup uses a modular driver-based architecture:
|
|
|
|
- **Core CLI** ([tisbackup.py](tisbackup.py)): Backup orchestration and scheduling
|
|
- **Web GUI** ([tisbackup_gui.py](tisbackup_gui.py)): Flask-based management interface
|
|
- **Backup Drivers** ([libtisbackup/](libtisbackup/)): Pluggable modules for different backup types
|
|
- **Task Queue** ([tasks.py](tasks.py), [config.py](config.py)): Async job processing with Huey
|
|
- **State Database**: SQLite for tracking backup history and statistics
|
|
|
|
Each backup type is implemented as a driver class inheriting from `backup_generic`, allowing easy extension for new backup sources.
|
|
|
|
## Troubleshooting
|
|
|
|
### Backups Not Running
|
|
|
|
1. Check cron logs:
|
|
```bash
|
|
docker logs tisbackup_cron
|
|
```
|
|
|
|
2. Verify SSH connectivity:
|
|
```bash
|
|
docker exec tisbackup_cron ssh -i /config_ssh/id_ed25519 root@remote-server
|
|
```
|
|
|
|
3. Check backup configuration:
|
|
```bash
|
|
docker exec tisbackup_cron python3 /opt/tisbackup/tisbackup.py -c /etc/tis/tisbackup-config.ini -d backup
|
|
```
|
|
|
|
### Web Interface Not Accessible
|
|
|
|
1. Check GUI container logs:
|
|
```bash
|
|
docker logs tisbackup_gui
|
|
```
|
|
|
|
2. Verify port mapping:
|
|
```bash
|
|
docker ps | grep tisbackup_gui
|
|
```
|
|
|
|
3. Check configuration:
|
|
```bash
|
|
docker exec tisbackup_gui cat /etc/tis/tisbackup_gui.ini
|
|
```
|
|
|
|
### Permission Errors
|
|
|
|
Ensure proper file permissions:
|
|
```bash
|
|
chmod 600 /var/tisbackup/ssh/id_ed25519
|
|
chmod 644 /var/tisbackup/ssh/id_ed25519.pub
|
|
chown -R root:root /var/tisbackup/
|
|
```
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome! Please:
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch
|
|
3. Follow the existing code style (use `ruff` for linting)
|
|
4. Add tests if applicable
|
|
5. Submit a pull request
|
|
|
|
## License
|
|
|
|
TISBackup is licensed under the GNU General Public License v3.0 (GPLv3).
|
|
|
|
See [LICENSE](LICENSE) for the full license text.
|
|
|
|
## Support & Documentation
|
|
|
|
- **Documentation**: [https://tisbackup.readthedocs.io](https://tisbackup.readthedocs.io/en/latest/index.html)
|
|
- **Issues**: [GitHub Issues](https://github.com/tranquilit/TISbackup/issues)
|
|
- **Original Author**: [Tranquil IT](https://www.tranquil.it)
|
|
|
|
## Credits
|
|
|
|
Developed by Tranquil IT for system administrators managing backup infrastructure.
|
|
|
|
Security improvements and modernization contributed by the community.
|