Backup con Btrfs con Send/Receive via SSH: Guida Completa snapper btrbk

Backup con Btrfs con Send/Receive via SSH: Guida Completa snapper btrbk

btrbk Remote Backup Configuration Guide

Overview

This guide explains how to configure btrbk for remote backup operations, including integration with existing snapper snapshots and privilege separation via SSH.

Prerequisites

Source System (where snapshots are created)

  • btrfs-progs >= v4.12
  • Perl interpreter
  • btrbk package
  • OpenSSH

Target System (backup server)

  • btrfs-progs (for receive operations)
  • OpenSSH
  • btrbk user account

Installation

Source System

# Debian/Ubuntu
apt install btrbk

# Fedora/RHEL
dnf install btrbk

# Arch Linux
pacman -S btrbk

Target System

# Only needs btrfs-progs
apt install btrfs-progs

SSH Configuration

Generate SSH Key on Source System

# Create dedicated SSH key for btrbk
ssh-keygen -t rsa -b 4096 -f /etc/btrbk/ssh/id_rsa -C "btrbk@source-hostname" -N ""

# Set correct permissions
chmod 600 /etc/btrbk/ssh/id_rsa
chmod 644 /etc/btrbk/ssh/id_rsa.pub

Configure Target System

Create btrbk user and setup:

# Create btrbk user
useradd -r -s /bin/false btrbk

# Create backup directory structure
mkdir -p /mnt/backup/{hostname}
chown -R btrbk:btrbk /mnt/backup

# Create SSH directory
mkdir -p /var/lib/btrbk/.ssh
chown -R btrbk:btrbk /var/lib/btrbk

Configure sudo for privilege separation (optional but recommended):

visudo
# Add the following lines:
btrbk ALL=(root) NOPASSWD: /sbin/btrfs, /usr/sbin/btrbk, /bin/readlink

Add source SSH key to authorized_keys with restrictions:

# Create authorized_keys with command restriction
echo 'from="192.168.1.100",command="/usr/share/btrbk/scripts/ssh_filter_btrbk.sh -l --target --delete" '$(cat /etc/btrbk/ssh/id_rsa.pub) >> /var/lib/btrbk/.ssh/authorized_keys

# Set proper permissions
chmod 600 /var/lib/btrbk/.ssh/authorized_keys
chmod 700 /var/lib/btrbk/.ssh

btrbk Configuration Examples

Basic Remote Backup Configuration

File: /etc/btrbk/btrbk.conf

timestamp_format        long

# Global retention policy
snapshot_preserve_min   2d
snapshot_preserve       14d

target_preserve_min     no
target_preserve         20d 10w *m

# SSH settings
ssh_identity            /etc/btrbk/ssh/id_rsa
ssh_user                btrbk
ssh_compression         yes

# Snapshot directory (relative to volume)
snapshot_dir            btrbk_snapshots

# Volume configuration with remote target
volume /
  subvolume @
    target send-receive    ssh://backup-server.example.com/mnt/backup/hostname/root
    snapshot_name          root
    
  subvolume @home
    target send-receive    ssh://backup-server.example.com/mnt/backup/hostname/home
    snapshot_name          home

Snapper Integration Configuration

If you already use snapper and want to backup its snapshots:

timestamp_format        long

# Global settings
snapshot_preserve_min   2d
snapshot_preserve       14d

target_preserve_min     no
target_preserve         20d 10w *m

# SSH settings
ssh_identity            /etc/btrbk/ssh/id_rsa
ssh_user                btrbk

# Use snapper's snapshot directory
snapshot_dir            .snapshots

volume /
  subvolume @
    snapshot_name          root
    snapshot_create        no     # Don't create new snapshots
    target                 ssh://backup-server/mnt/backup/hostname/root
    incremental            yes
    
  subvolume @home
    snapshot_name          home
    snapshot_create        no
    target                 ssh://backup-server/mnt/backup/hostname/home
    incremental            yes

Multiple Targets Configuration

timestamp_format        long

# Global settings
snapshot_preserve_min   2d
snapshot_preserve       14d

target_preserve_min     no
target_preserve         20d 10w *m

# SSH settings
ssh_identity            /etc/btrbk/ssh/id_rsa

volume /
  snapshot_dir          btrbk_snapshots
  
  subvolume @
    # Local backup target
    target              /mnt/local-backup/hostname/root
    # Remote backup target
    target              ssh://backup-server-1.example.com/mnt/backup/hostname/root
    # Secondary remote target
    target              ssh://backup-server-2.example.com/backup/hostname/root

Compressed Transfer Configuration

For slow or metered connections:

# Add to global section
stream_compress         zstd
stream_compress_level   3
stream_compress_threads 4

# Optional: rate limiting
rate_limit              50m
rate_limit_remote       yes

Complex Retention Policy

# Hourly backups: keep last 24 hours
# Daily backups: keep last 7 days
# Weekly backups: keep last 10 weeks  
# Monthly backups: keep all
# Yearly backups: keep all

target_preserve         24h 7d 10w *m *y
target_preserve_min     no

# For snapshots
snapshot_preserve       48h 14d 4w
snapshot_preserve_min   2d

ssh_filter_btrbk.sh Usage

The ssh_filter_btrbk.sh script restricts SSH access to safe btrfs operations.

Installation on Target System

# Copy the filter script
cp /usr/share/btrbk/scripts/ssh_filter_btrbk.sh /usr/local/bin/
chmod +x /usr/local/bin/ssh_filter_btrbk.sh

authorized_keys Examples

# Source with deletion rights (push backup)
command="/usr/local/bin/ssh_filter_btrbk.sh -l --source --delete",restrict ssh-rsa AAAAB3...

# Target with deletion rights (receive backup)
command="/usr/local/bin/ssh_filter_btrbk.sh -l --target --delete",restrict ssh-rsa AAAAB3...

# Read-only source (pull backup)
command="/usr/local/bin/ssh_filter_btrbk.sh -l --send -p /home -p /data",restrict ssh-rsa AAAAB3...

Systemd Timer Setup

Service File: /etc/systemd/system/btrbk.service

[Unit]
Description=Create btrfs snapshots and backup to remote server
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/btrbk -c /etc/btrbk/btrbk.conf run --progress
User=root
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Timer File: /etc/systemd/system/btrbk.timer

[Unit]
Description=Create btrfs snapshots and backup to remote server

[Timer]
OnCalendar=*:0/5      # Every 5 minutes
Persistent=true
RandomizedDelaySec=60

[Install]
WantedBy=timers.target

Enable and Start

systemctl daemon-reload
systemctl enable btrbk.timer
systemctl start btrbk.timer
systemctl enable btrbk.service

Testing and Validation

Dry Run (Test Configuration)

btrbk -c /etc/btrbk/btrbk.conf -n run

Test SSH Connectivity

ssh -i /etc/btrbk/ssh/id_rsa btrbk@backup-server.example.com "btrfs --version"

Run First Backup Manually

btrbk -c /etc/btrbk/btrbk.conf run --progress

List Snapshots and Backups

btrbk -c /etc/btrbk/btrbk.conf list
btrbk -c /etc/btrbk/btrbk.conf list snapshots
btrbk -c /etc/btrbk/btrbk.conf list targets

Check Configuration

btrbk -c /etc/btrbk/btrbk.conf config print

Monitoring and Logging

Enable Transaction Log

transaction_log        /var/log/btrbk.log
transaction_syslog     local0

Check Logs

# View transaction log
tail -f /var/log/btrbk.log

# View via journald
journalctl -u btrbk.service -f

Common Issues and Solutions

Issue: Permission Denied

# Verify SSH key permissions
chmod 600 /etc/btrbk/ssh/id_rsa
chmod 644 /etc/btrbk/ssh/id_rsa.pub

# Check sudoers configuration
visudo -c

Issue: Connection Timeout

# Test SSH connection
ssh -v -i /etc/btrbk/ssh/id_rsa btrbk@backup-server

# Check firewall rules
iptables -L -n | grep 22

Issue: Incremental Backup Fails

# Check for broken parent chain
btrbk -c /etc/btrbk/btrbk.conf list

# Force non-incremental backup
btrbk -c /etc/btrbk/btrbk.conf run --force

Arch Linux Pacman Integration

File: /etc/pacman.d/hooks/90-btrbk-snapshot.hook

[Trigger]
Operation = Upgrade
Operation = Install
Operation = Remove
Type = Package
Target = *

[Action]
Description = Creating btrbk snapshot before pacman transaction
When = PreTransaction
Exec = /usr/bin/btrbk -c /etc/btrbk/btrbk.conf snapshot

Restore Procedures

List Available Backups

btrbk -c /etc/btrbk/btrbk.conf list targets

Restore from Backup

# On the target system
btrfs receive /mnt/backup/target < /path/to/snapshot.backup

# Or directly from source
ssh root@source "btrfs send /path/to/snapshot" | btrfs receive /mnt/backup/target

Create Read-Write Subvolume from Snapshot

btrfs subvolume snapshot /mnt/backup/target/snapshot.20240101 /mnt/backup/target/restored

Best Practices

  1. Use privilege separation: Don't allow root SSH login directly
  2. Test configuration: Always run dry-run before first actual backup
  3. Monitor retention: Check disk usage regularly
  4. Test restores: Periodically verify backup integrity
  5. Use compression: For slow network connections
  6. Schedule appropriately: Consider network usage patterns
  7. Document configuration: Keep configuration files well-commented

Additional Resources