Security Guide

Best practices for securing your Borg Web UI installation.


Quick Security Checklist

  • Change default admin password immediately
  • Use HTTPS with reverse proxy (production)
  • Restrict volume mounts to necessary directories only
  • Set appropriate PUID/PGID for file permissions
  • Use SSH keys (not passwords) for remote repositories
  • Enable firewall rules to limit access
  • Regularly update to latest version
  • Backup the /data volume (contains database and keys)
  • Review and rotate SSH keys periodically
  • Monitor application logs for suspicious activity

Authentication Security

Change Default Password

On first login, you’ll be prompted to change the default password (admin123).

To change later:

  1. Go to Settings > Profile
  2. Enter current password
  3. Enter new password (minimum 8 characters)
  4. Confirm new password

Strong Password Requirements

Use passwords with:

  • Minimum 12 characters
  • Mix of uppercase and lowercase
  • Numbers and special characters
  • Unique to this application (no reuse)

Example strong password: B0rg!Backup#2025$Secure

User Management

For multi-user setups:

  1. Create individual accounts for each user
  2. Assign appropriate permissions (admin vs. regular user)
  3. Disable or delete inactive accounts
  4. Review user access regularly

Network Security

Use HTTPS in Production

Never expose Borg Web UI directly to the internet without HTTPS.

Option 1: Nginx Reverse Proxy

server {
    listen 443 ssl http2;
    server_name backups.example.com;

    ssl_certificate /etc/letsencrypt/live/backups.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/backups.example.com/privkey.pem;

    # Strong SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://localhost:8081;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Option 2: Traefik with Let’s Encrypt

services:
  borg-ui:
    image: ainullcode/borg-ui:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.borg-ui.rule=Host(`backups.example.com`)"
      - "traefik.http.routers.borg-ui.entrypoints=websecure"
      - "traefik.http.routers.borg-ui.tls.certresolver=letsencrypt"
      - "traefik.http.services.borg-ui.loadbalancer.server.port=8081"

Option 3: Caddy (Automatic HTTPS)

backups.example.com {
    reverse_proxy localhost:8081
}

Restrict Access by IP

Docker-level restriction:

ports:
  - "127.0.0.1:8081:8081"  # Only localhost

Firewall rules:

# Linux (ufw)
sudo ufw allow from 192.168.1.0/24 to any port 8081

# Linux (iptables)
sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 8081 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8081 -j DROP

VPN Access

For remote access, use VPN instead of exposing to internet:

  • WireGuard
  • OpenVPN
  • Tailscale
  • ZeroTier

File System Security

Restrict Volume Mounts

Default (too permissive for production):

volumes:
  - /:/local:rw  # Access to entire filesystem

Recommended (principle of least privilege):

volumes:
  # Backup sources (read-only)
  - /home/user/documents:/sources/documents:ro
  - /home/user/photos:/sources/photos:ro

  # Backup destination (read-write)
  - /mnt/backups:/backups:rw

  # Application data
  - borg_data:/data
  - borg_cache:/home/borg/.cache/borg

Set Appropriate Permissions

Match container user with host user:

environment:
  - PUID=1000  # Your user ID
  - PGID=1000  # Your group ID

This prevents:

  • Unauthorized file access
  • Permission denied errors
  • Files owned by root when created by container

Read-Only Mounts for Sources

Always mount backup sources as read-only:

volumes:
  - /important/data:/sources/data:ro  # :ro = read-only

This prevents accidental modification or deletion during backups.


SSH Security

Use SSH Keys (Not Passwords)

Always use SSH keys for remote repositories.

Generate keys through the web interface:

  1. Go to SSH Keys
  2. Click Generate SSH Key
  3. Use ED25519 (modern) or RSA 4096 (compatible)

Restrict SSH Key Access

On the remote server, restrict what the key can do:

# In ~/.ssh/authorized_keys
command="borg serve --restrict-to-path /backups/borg-repo",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3... borg-web-ui

This:

  • Limits to borg serve command only
  • Restricts access to specific path
  • Disables port forwarding
  • Disables X11 forwarding
  • Prevents interactive shell

SSH Server Hardening

On remote backup servers:

# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers backup-user
Port 2222  # Use non-standard port

Restart SSH: sudo systemctl restart sshd


Repository Security

Use Encryption

Always encrypt repositories, especially for offsite/cloud backups.

Choose encryption mode when creating repository:

  • repokey-blake2 (recommended) - Key stored in repo, fast
  • keyfile-blake2 - Key stored locally only
  • repokey - AES-256, widely compatible

Strong Passphrases

Use strong repository passphrases:

  • Minimum 20 characters
  • Mix of characters, numbers, symbols
  • Generated randomly (use password manager)
  • Unique per repository

Example: Xk9#mP2$vL8@qR5!wT3&hN7*

Store Passphrases Securely

  • Use a password manager (Bitwarden, 1Password, KeePass)
  • Never commit passphrases to git
  • Document where passphrase is stored
  • Have a recovery plan

Backup Repository Keys

For keyfile encryption mode:

# Export key
docker exec borg-web-ui borg key export /path/to/repo backup-key.txt

# Store securely (offline, encrypted USB drive, password manager)

Without the key, your backups are unrecoverable.


Application Security

SECRET_KEY Rotation

The SECRET_KEY is used for session management and JWT tokens.

To rotate:

docker exec borg-web-ui rm /data/.secret_key
docker restart borg-web-ui

Note: This logs out all users and invalidates all tokens.

Database Encryption

The SQLite database contains:

  • User credentials (hashed)
  • Repository configurations
  • Notification service URLs (may contain credentials)
  • SSH key paths

Protect /data volume:

  • Secure file permissions
  • Regular backups
  • Encrypt at rest (LUKS, dm-crypt)

Secure Notification URLs

Notification service URLs often contain credentials:

mailto://user:app_password@gmail.com?smtp=smtp.gmail.com
slack://TokenA/TokenB/TokenC/

Best practices:

  • Don’t share notification configurations
  • Rotate tokens periodically
  • Use least-privilege service accounts

Monitoring and Auditing

Enable Logging

environment:
  - LOG_LEVEL=INFO  # or DEBUG for troubleshooting

Logs are stored at /data/logs/borg-ui.log

Review Logs Regularly

# View recent logs
docker exec borg-web-ui tail -f /data/logs/borg-ui.log

# Search for failed logins
docker exec borg-web-ui grep "authentication failed" /data/logs/borg-ui.log

# Check for errors
docker exec borg-web-ui grep "ERROR" /data/logs/borg-ui.log

Monitor Failed Login Attempts

Watch for suspicious activity:

# Failed authentication attempts
docker logs borg-web-ui 2>&1 | grep "401 Unauthorized"

# Multiple failed attempts from same IP
docker logs borg-web-ui 2>&1 | grep "authentication" | sort | uniq -c

Set Up Alerts

Use notifications to get alerts for:

  • Backup failures
  • Schedule failures
  • System errors

Update Security

Keep Software Updated

# Check for updates
docker pull ainullcode/borg-ui:latest

# Update
docker compose pull
docker compose up -d

Subscribe to Security Announcements


Backup Security

Backup Strategy

3-2-1 Rule:

  • 3 copies of data
  • 2 different media types
  • 1 offsite backup

Secure Backup Locations

For offsite backups:

  • Use encrypted repositories
  • Verify physical security of remote location
  • Use VPN or SSH tunnels for transmission
  • Regular integrity checks

Test Restores

Regularly test restoring from backups:

  1. Verify backups are accessible
  2. Check data integrity
  3. Confirm encryption keys work
  4. Document restore procedures

Incident Response

If Credentials Are Compromised

  1. Change passwords immediately
    • Admin password in Borg Web UI
    • Repository passphrases
    • Remote server passwords
  2. Rotate SSH keys
    • Generate new keys
    • Deploy to servers
    • Remove old keys
  3. Rotate SECRET_KEY
    docker exec borg-web-ui rm /data/.secret_key
    docker restart borg-web-ui
    
  4. Review logs for unauthorized access

  5. Check backups for tampering

If Container Is Compromised

  1. Stop the container immediately
    docker stop borg-web-ui
    
  2. Preserve logs for analysis
    docker logs borg-web-ui > incident-logs.txt
    
  3. Check for malware

  4. Restore from known-good backup

  5. Investigate root cause

  6. Update and strengthen security

Security Best Practices Summary

  1. Authentication
    • Strong unique passwords
    • Change default credentials
    • Regular password rotation
  2. Network
    • Always use HTTPS in production
    • Restrict access by IP/VPN
    • Never expose directly to internet
  3. File System
    • Restrict volume mounts
    • Use read-only for sources
    • Proper PUID/PGID
  4. SSH
    • Use keys, not passwords
    • Restrict key permissions
    • Non-standard ports
  5. Repositories
    • Always use encryption
    • Strong passphrases
    • Backup repository keys
  6. Monitoring
    • Enable logging
    • Review logs regularly
    • Set up failure alerts
  7. Updates
    • Keep software current
    • Subscribe to security announcements
    • Test updates in staging first

Security Resources


Reporting Security Issues

If you discover a security vulnerability:

  1. Do NOT open a public issue
  2. Email: security contact via GitHub Security Advisories
  3. Include:
    • Description of vulnerability
    • Steps to reproduce
    • Potential impact
    • Suggested fix (if any)

We take security seriously and will respond promptly.


Back to top

Copyright © 2024 Karan Hudia. Distributed under the GPL-3.0 License.