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
/datavolume (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:
- Go to Settings > Profile
- Enter current password
- Enter new password (minimum 8 characters)
- 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:
- Create individual accounts for each user
- Assign appropriate permissions (admin vs. regular user)
- Disable or delete inactive accounts
- 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:
- Go to SSH Keys
- Click Generate SSH Key
- 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 servecommand 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
- Watch GitHub repository for security releases
- Check GitHub Security Advisories
- Review release notes for security fixes
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:
- Verify backups are accessible
- Check data integrity
- Confirm encryption keys work
- Document restore procedures
Incident Response
If Credentials Are Compromised
- Change passwords immediately
- Admin password in Borg Web UI
- Repository passphrases
- Remote server passwords
- Rotate SSH keys
- Generate new keys
- Deploy to servers
- Remove old keys
- Rotate SECRET_KEY
docker exec borg-web-ui rm /data/.secret_key docker restart borg-web-ui -
Review logs for unauthorized access
- Check backups for tampering
If Container Is Compromised
- Stop the container immediately
docker stop borg-web-ui - Preserve logs for analysis
docker logs borg-web-ui > incident-logs.txt -
Check for malware
-
Restore from known-good backup
-
Investigate root cause
- Update and strengthen security
Security Best Practices Summary
- Authentication
- Strong unique passwords
- Change default credentials
- Regular password rotation
- Network
- Always use HTTPS in production
- Restrict access by IP/VPN
- Never expose directly to internet
- File System
- Restrict volume mounts
- Use read-only for sources
- Proper PUID/PGID
- SSH
- Use keys, not passwords
- Restrict key permissions
- Non-standard ports
- Repositories
- Always use encryption
- Strong passphrases
- Backup repository keys
- Monitoring
- Enable logging
- Review logs regularly
- Set up failure alerts
- Updates
- Keep software current
- Subscribe to security announcements
- Test updates in staging first
Security Resources
Reporting Security Issues
If you discover a security vulnerability:
- Do NOT open a public issue
- Email: security contact via GitHub Security Advisories
- Include:
- Description of vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
We take security seriously and will respond promptly.