Configuration Backup with Git
Configuration Backup with Git
Section titled “Configuration Backup with Git”Every VyOS commit can trigger a script. This guide sets up a post-commit hook that exports your config, commits it to a local Git repo, and pushes to a remote — giving you full version history of every router change.
Based on brav0charlie’s workflow (original blog offline, preserved via Wayback Machine). Adapted for VyOS 1.4+.
Architecture
Section titled “Architecture”VyOS Router Git Server (Gitea/GitHub/GitLab)┌──────────────────────────┐ ┌─────────────────────┐│ commit │ │ ││ ↓ │ │ config-router01/ ││ post-hook script: │ push │ ├── router01 ││ 1. export config │────────▶│ │ .commands.conf ││ 2. git add -A │ │ │ .config.boot ││ 3. git commit │ │ └── ... ││ 4. git push │ │ │└──────────────────────────┘ └─────────────────────┘Prerequisites
Section titled “Prerequisites”Git on VyOS
Section titled “Git on VyOS”The default VyOS ISO does not include Git. You have two options:
- Build a custom image with Git included (see Image Automation)
- Install Git on a running system (won’t survive upgrades):
# Temporary — lost on reboot/upgradesudo apt update && sudo apt install -y gitPreferred: build a custom image. One-time effort, permanent result.
SSH Agent Forwarding
Section titled “SSH Agent Forwarding”So your router can push to the remote without storing keys on it:
# ~/.ssh/config on your LOCAL machineHost vyos-router HostName 192.168.1.1 User admin ForwardAgent yesGit Repository
Section titled “Git Repository”Create a private repository. Never make router configs public — they contain secrets, keys, and network topology.
Recommended: self-hosted Gitea in Docker, or private GitHub/GitLab repo.
1. Clone Repo on VyOS
Section titled “1. Clone Repo on VyOS”# Log into VyOS, set Git identitygit config --global user.name "VyOS Router"
# Clone into persistent storagecd /config/user-data/config/user-data persists across reboots and upgrades. Everything else in / is ephemeral.
2. Create the Post-Commit Hook
Section titled “2. Create the Post-Commit Hook”sudo mkdir -p /config/scripts/commit/post-hooks.dsudo nano /config/scripts/commit/post-hooks.d/99-git-commitPaste the script:
#!/bin/vbash
# Post-commit hook: export config, commit to git, pushREPO_PATH=/config/user-dataCONFIG_REPO=config-router01 # <-- change thisTIMESTAMP="$(date '+%Y-%m-%dT%H:%M:%S %Z')"
# Commit message — set env var $M for custom message# Usage: M="added VLAN 20" commit;saveif [ -z "$M" ]; then MSG="Auto-commit by $USER@$HOSTNAME: $TIMESTAMP"else MSG="$M"fi
# Source VyOS script functionssource /opt/vyatta/etc/functions/script-template
USERPATH=$PWDcd $REPO_PATH/$CONFIG_REPOecho "> [$TIMESTAMP] Beginning git commit & push..."
# Pull latest/usr/bin/git pull
# Export config in two formatsrun show configuration commands > $REPO_PATH/$CONFIG_REPO/$HOSTNAME.commands.confrun show configuration commands json > $REPO_PATH/$CONFIG_REPO/$HOSTNAME.config.json
# Git workflow/usr/bin/git add -A/usr/bin/git commit -m "$MSG"/usr/bin/git push
echo "> [$TIMESTAMP] Git commit & push completed."cd $USERPATH
# Clean upCONFIG_REPO=""REPO_PATH=""TIMESTAMP=""USERPATH=""MSG=""M=""3. Make Executable
Section titled “3. Make Executable”sudo chmod +x /config/scripts/commit/post-hooks.d/99-git-commitEvery commit now triggers the backup:
configureset system host-name vyos-gw-newcommitsave# → Script runs, pushes config to GitCustom commit message:
# Set $M before commitM="Changed WAN DNS to Cloudflare" commit;saveWhat You Get
Section titled “What You Get”Two files per commit in your repo:
| File | Content |
|---|---|
hostname.commands.conf | Full config as set commands — human-readable, diffable |
hostname.config.json | Full config as JSON — machine-parseable |
# View historygit log --oneline
# See what changedgit diff HEAD~1 hostname.commands.conf
# Restore a previous configgit show abc1234:hostname.commands.confRestoring from Backup
Section titled “Restoring from Backup”If your router dies, restore the config to a fresh VyOS install:
# On new VyOScd /config/user-datacd config-router01
# Load saved configconfigureload hostname.commands.confcommitsaveAlternative: Manual Script (No Hook)
Section titled “Alternative: Manual Script (No Hook)”If you prefer manual control, skip the hook and run on-demand:
cd /config/user-data/config-router01run show configuration commands > $(hostname).commands.confrun show configuration commands json > $(hostname).config.jsongit add -Agit commit -m "Manual backup $(date -Iseconds)"git pushRun it: source /config/scripts/backup-config.sh
Sanitizing Secrets (Optional)
Section titled “Sanitizing Secrets (Optional)”If you must use a less-private repo, filter secrets before commit:
# Add before git add in post-hooksed -i '/plaintext-password/d' $HOSTNAME.commands.confsed -i '/pre-shared-secret/d' $HOSTNAME.commands.confsed -i '/private-key/d' $HOSTNAME.commands.confBetter: use a private self-hosted repo and don’t sanitize — you want the full config for disaster recovery.
Verification
Section titled “Verification”# Check hook is in placels -la /config/scripts/commit/post-hooks.d/
# Test manuallysudo /config/scripts/commit/post-hooks.d/99-git-commit
# Check Git statuscd /config/user-data/config-router01git log --oneline -5Summary
Section titled “Summary”| Step | Command |
|---|---|
| Build image with Git | --custom-package git (see image automation guide) |
| Clone repo | cd /config/user-data && git clone <url> |
| Create hook | /config/scripts/commit/post-hooks.d/99-git-commit |
| Use | commit;save — backed up automatically |
| Custom message | M="description" commit;save |