├── LICENSE ├── README.md └── config ├── scripts └── post-config.d │ ├── hooks.sh │ └── ssh_keys.sh └── user-data ├── backup_user_private.key ├── edgerouter-backup.conf └── hooks └── 03-edgerouter-backup.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 T Bryce Yehl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # edgerouter-backup 2 | 3 | Ubiquiti's EdgeOS provides `system config-management commit-archive location` as a way to push configuration commits to a remote location. For my use, I have two problems with it: 4 | 5 | 1. Backups are in their brace-y format instead of CLI commands. 6 | 2. They use a unique filename for each commit. 7 | 8 | I want to put my configuration files into source control, so maintaining the same filename is preferable. I also find the CLI format to be easier to read and `diff` against. 9 | 10 | This backup script hooks into the EdgeRouter `commit` process and generates configuration files in both CLI and brace-y formats, along with a full configuration backup in `.tar.gz` form that is directly restore-able via the management GUI. The files are then sent to a remote server via `scp`, and `git commit` & `git push` are run on the remote server -- avoiding having to install `git` on the EdgeRouter itself. This script can be used along side `config-management` or as a replacement. 11 | 12 | These scripts do not modify any EdgeOS-provided files. The locations of all the files will survive reboots and firmware upgrades. I've personally tested this on an ER-8 and ER-X-SFP running v1.9.1.1 firmware and verified firmware survivability by upgrading to v1.9.1.1unms. Should work on any EdgeRouter model. Might work on the USG / USG Pro but that's rather pointless -- back up your UniFi Controller. 13 | 14 | 15 | ### **IMPORTANT** 16 | 17 | These configuration dumps **ARE NOT SANITIZED**. They may contain plaintext passwords for some services. **Do not publish to a publicly accessible git repo.** 18 | 19 | --- 20 | 21 | * [Installation](#installation) 22 | * [EdgeRouter Configuration](#edgerouter-configuration) 23 | * [Remote Host Configuration](#remote-host-configuration) 24 | * [Caveats](#caveats) 25 | * [Alternatives](#alternatives) 26 | 27 | --- 28 | 29 | ### Installation 30 | 31 | Copy contents of `config` directory to `/config` on EdgeRouter. 32 | 33 | 34 | ### EdgeRouter Configuration 35 | 36 | Edit `/config/user-data/edgerouter-backup.conf` with your information: 37 | 38 | #!/bin/bash 39 | 40 | # Default commit message 41 | DEFAULT_COMMIT_MESSAGE="Auto commit by edgerouter-backup" 42 | 43 | # Path to private key for SSH / SCP 44 | SSH_KEYFILE=/config/user-data/backup_user_private.key 45 | SSH_USER=username 46 | SSH_HOST=host 47 | SSH_PORT=port 48 | 49 | # Path to git repo on SSH_HOST 50 | REPO_PATH=\~/edgerouter-backups 51 | 52 | # Names for EdgeRouter configuration backup files. If you are backing 53 | # up multiple EdgeRouters to the same place you'll want to ensure that 54 | # FNAME_BASE is unique to each EdgeRouter 55 | FNAME_BASE=$HOSTNAME 56 | 57 | FNAME_CONFIG=$FNAME_BASE.config.conf 58 | FNAME_CLI=$FNAME_BASE.commands.conf 59 | FNAME_BACKUP=$FNAME_BASE.backup.tar.gz 60 | 61 | Edit the `SSH_KEYFILE` file to have the private key for `SSH_USER` 62 | 63 | `sudo chmod +x /config/scripts/post-config.d/*.sh && sudo /config/scripts/post-config.d/hooks.sh && sudo /config/scripts/post-config.d/ssh_keys.sh` 64 | 65 | 66 | ### Remote Host Configuration 67 | 68 | * Make sure your SSH key works for `SSH_USER` (ie: place public key in `~/.ssh/authorized_users`) 69 | * Create git repo in `REPO_PATH`. 70 | * Configure git settings for repo as desired. 71 | * Verify that `git commit -m "Commit Message"` and `git push` execute without interaction. 72 | 73 | 74 | ### Caveats 75 | 76 | There's no error-handling in these scripts at all. 77 | 78 | If your `SSH_HOST` is unreachable, the config file won't get pushed and it will not try again. If you're making changes from the command line you will see the errors and can run `sudo /config/user-data/hooks/03-edgerouter-backup.sh` manually to try again. 79 | 80 | You could also set up a cron job to perform the push periodically: 81 | 82 | set system task-scheduler task commit-push executable path /config/user-data/hooks/03-edgerouter-backup.sh 83 | set system task-scheduler task commit-push interval 1h 84 | 85 | `git` is smart enough not to `commit` or `push` when no actual changes have been made, however, this script is not -- the backups will be generated and transferred every time `03-edgerouter-backup.sh` runs. 86 | 87 | 88 | ### Alternatives 89 | 90 | If you have many EdgeRouters, a proper network configuration management system such as [RANCID](http://www.shrubbery.net/rancid/) or [Oxidized](https://github.com/ytti/oxidized) may be more appropriate. 91 | -------------------------------------------------------------------------------- /config/scripts/post-config.d/hooks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source /config/user-data/edgerouter-backup.conf 3 | 4 | # Fix ownership / permissions 5 | sudo chown -R root:vyattacfg /config/user-data 6 | sudo chown -R root:vyattacfg /config/scripts 7 | sudo chmod -R ug+w /config/user-data 8 | sudo chmod -R ug+w /config/scripts 9 | sudo chmod g-w $SSH_KEYFILE 10 | 11 | # Ensure scripts are executable 12 | sudo chmod +x /config/user-data/hooks/* 13 | 14 | # Generate symlinks to hook script(s) 15 | sudo ln -fs /config/user-data/hooks/* /etc/commit/post-hooks.d/ 16 | 17 | exit 0 18 | -------------------------------------------------------------------------------- /config/scripts/post-config.d/ssh_keys.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source /config/user-data/edgerouter-backup.conf 3 | 4 | # This script runs at boot of the EdgeRouter 5 | 6 | # Set ownership and permissions for root user so that ssh/scp don't complain. 7 | sudo chown root $SSH_KEYFILE 8 | sudo chmod 600 $SSH_KEYFILE 9 | 10 | exit 0 -------------------------------------------------------------------------------- /config/user-data/backup_user_private.key: -------------------------------------------------------------------------------- 1 | # Put your private key here. -------------------------------------------------------------------------------- /config/user-data/edgerouter-backup.conf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Default commit message 4 | DEFAULT_COMMIT_MESSAGE="Auto commit by edgerouter-backup on $HOSTNAME" 5 | 6 | # SSH Information 7 | SSH_USER= 8 | SSH_HOST= 9 | SSH_PORT=22 10 | 11 | # Path to private key for SSH_USER 12 | SSH_KEYFILE=/config/user-data/${SSH_USER}_private.key 13 | 14 | # Path to git repo on SSH_HOST 15 | REPO_PATH=\~/edgerouter-backups 16 | 17 | # Names for EdgeRouter configuration backup files. If you are backing 18 | # up multiple EdgeRouters to the same place you'll want to ensure that 19 | # FNAME_BASE is unique to each EdgeRouter 20 | FNAME_BASE=$HOSTNAME 21 | 22 | FNAME_CONFIG=$FNAME_BASE.config.conf 23 | FNAME_CLI=$FNAME_BASE.commands.conf 24 | 25 | # Base filename, no .tar.gz extension! 26 | FNAME_BACKUP=$FNAME_BASE.backup 27 | -------------------------------------------------------------------------------- /config/user-data/hooks/03-edgerouter-backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source /config/user-data/edgerouter-backup.conf 3 | 4 | # This script runs during the commit 5 | 6 | # Pull commit info 7 | COMMIT_VIA=${COMMIT_VIA:-other} 8 | COMMIT_CMT=${COMMIT_COMMENT:-$DEFAULT_COMMIT_MESSAGE} 9 | 10 | # If no comment, replace with default 11 | if [ "$COMMIT_CMT" == "commit" ]; 12 | then 13 | COMMIT_CMT=$DEFAULT_COMMIT_MESSAGE 14 | fi 15 | 16 | # Check if rollback 17 | if [ $# -eq 1 ] && [ $1 = "rollback" ]; 18 | then 19 | COMMIT_VIA="rollback/reboot" 20 | fi 21 | 22 | TIME=$(date +%Y-%m-%d" "%H:%M:%S) 23 | USER=$(whoami) 24 | 25 | GIT_COMMIT_MSG="$COMMIT_CMT | by $USER | via $COMMIT_VIA | $TIME" 26 | 27 | # Remove temporary files 28 | #echo "edgerouter-backup: Removing temporary files" 29 | sudo rm /tmp/edgerouter-backup-$FNAME_CONFIG &> /dev/null 30 | sudo rm /tmp/edgerouter-backup-$FNAME_CLI &> /dev/null 31 | sudo rm /tmp/edgerouter-backup-$FNAME_BACKUP.tar &> /dev/null 32 | 33 | 34 | # Generate temporary config files 35 | sudo cli-shell-api showConfig --show-active-only --show-ignore-edit --show-show-defaults > /tmp/edgerouter-backup-$FNAME_CONFIG 36 | sudo cli-shell-api showConfig --show-commands --show-active-only --show-ignore-edit --show-show-defaults > /tmp/edgerouter-backup-$FNAME_CLI 37 | sudo find /config/* | grep -v "/config/dhcpd.leases" | xargs tar cf /tmp/edgerouter-backup-$FNAME_BACKUP.tar &> /dev/null 38 | 39 | # Push config files 40 | echo "edgerouter-backup: Copying backup files to $SSH_USER@$SSH_HOST:$REPO_PATH" 41 | sudo scp -P $SSH_PORT -q -i $SSH_KEYFILE -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /tmp/edgerouter-backup-$FNAME_CONFIG $SSH_USER@$SSH_HOST:$REPO_PATH/$FNAME_CONFIG > /dev/null 42 | sudo scp -P $SSH_PORT -q -i $SSH_KEYFILE -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /tmp/edgerouter-backup-$FNAME_CLI $SSH_USER@$SSH_HOST:$REPO_PATH/$FNAME_CLI > /dev/null 43 | sudo cat /tmp/edgerouter-backup-$FNAME_BACKUP.tar | sudo ssh -p $SSH_PORT -q -i $SSH_KEYFILE -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST "gzip -cnq9 > $REPO_PATH/$FNAME_BACKUP.tar.gz" > /dev/null 44 | 45 | # git commit and git push on remote host 46 | echo "edgerouter-backup: Triggering 'git commit'" 47 | sudo ssh -p $SSH_PORT -q -i $SSH_KEYFILE -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $SSH_USER@$SSH_HOST 'bash -s' << ENDSSH > /dev/null 48 | cd $REPO_PATH 49 | git add $REPO_PATH/$FNAME_CONFIG 50 | git add $REPO_PATH/$FNAME_CLI 51 | git add $REPO_PATH/$FNAME_BACKUP.tar.gz 52 | git commit -m "$GIT_COMMIT_MSG" 53 | git push 54 | ENDSSH 55 | 56 | echo "edgerouter-backup: Complete" 57 | --------------------------------------------------------------------------------