{"id":6,"date":"2015-01-12T15:07:02","date_gmt":"2015-01-12T15:07:02","guid":{"rendered":"http:\/\/www.contentecontent.com\/blog\/?p=6"},"modified":"2016-04-04T12:17:56","modified_gmt":"2016-04-04T11:17:56","slug":"automated-rsync-backups-from-a-webserver-to-qnap-nas","status":"publish","type":"post","link":"https:\/\/www.contentecontent.com\/blog\/2015\/01\/automated-rsync-backups-from-a-webserver-to-qnap-nas\/","title":{"rendered":"Automated rsync backups from a webserver to Qnap NAS"},"content":{"rendered":"<p>How to make a daily copy of backup files from a webserver on Debian to a local NAS using rsync over SSH.<\/p>\n<p><!--more--><\/p>\n<p>On my webserver I make a dump of most databases every day, using a command like this:<\/p>\n<pre><code>mysqldump dbName --opt --user=dbUsername --password=dbPassword | gzip &gt; \"\/home\/backups\/dbName\/dbName_`date +%d`.sql.gz\"\n<\/code><\/pre>\n<p>This creates nicely gzipped files, one for each day of the month. The command is in a shell script which is executed by a cron task. As an extra backup, I wanted to have a copy of these files on a different server: my Qnap NAS. The NAS runs a version of Linux, so all required tools are present: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Rsync\">rsync<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Secure_Shell\">SSH<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cron\">cron<\/a>. rsync will compare the local and remote directories and synchronize them as needed. It&#8217;s a smart tool: it only copies new or modified files, saving time and bandwidth.<\/p>\n<h2>Set up the rsync script<\/h2>\n<p>Log in to the NAS as the admin user, preferably over SSH with a tool like <a href=\"http:\/\/www.putty.org\/\">Putty<\/a>.<\/p>\n<p>On the NAS, I created a shell script <code>backup.sh<\/code> containing these lines:<\/p>\n<pre><code>#!\/bin\/sh\nrsync -ae ssh tom@www.example.com:\/home\/backups\/ \/share\/toms\/serverbackups\/\n<\/code><\/pre>\n<p><code>-a<\/code> puts rsync into archive mode, which makes the operation recursive and keeps timestamps, amongst others.<\/p>\n<p><code>-e ssh<\/code> makes rsync run through an SSH tunnel, making the operation pretty secure.<\/p>\n<p>The command will sync <code>\/home\/backups\/<\/code> on <code>www.example.com<\/code> with <code>\/share\/toms\/serverbackups<\/code> on the NAS. <code>toms<\/code> is a shared folder on the NAS; <code>serverbackups<\/code> is where I want to store the backups. <code>tom<\/code> is the user on the webserver who created and owns the database backups.<\/p>\n<p>You&#8217;ll need to write the script using the lovely <code>vi<\/code>, which is the only text editor available on Qnap NAS. Or just create the script on your PC and copy it to the NAS. (<strong>Update 4-4-2016:<\/strong> don&#8217;t do that. It may append unwanted characters to the command, such as <code>\\#015<\/code>. Use vi on the NAS.)<\/p>\n<p>Store backup.sh somewhere in a shared folder but definitely not in the root folder, as that one is recreated at every server reboot. I stored it in <code>\/share\/toms\/scripts\/<\/code> and made it executable to admin only with<\/p>\n<pre><code>chmod u+x \/share\/toms\/scripts\/backup.sh\n<\/code><\/pre>\n<p>Check that the rsync command works by running it from the NAS command line. It should prompt for <code>tom<\/code>&#8216;s server password, and then start copying files.<\/p>\n<p>If that works, the next step is to enable login without you entering the password all the time: authorize with keys.<\/p>\n<h2>SSH keys<\/h2>\n<p>On the NAS, run the <code>ssh-keygen<\/code> command to generate a set of keys. It will prompt for a passphrase: don&#8217;t enter anything, just hit enter.<\/p>\n<p>Copy the contents of <code>~\/.ssh\/id_rsa.pub<\/code> (the public key) on the NAS to <code>\/home\/tom\/.ssh\/authorized_keys<\/code> on the webserver. Create the directory and file if they don&#8217;t yet exist and set tom as the owner. <code>chmod<\/code> the directory to <code>0700<\/code> and the file to <code>0600<\/code>, so only the user tom can read them.<\/p>\n<p>Next, test the password-free login:<\/p>\n<pre><code>ssh -l tom www.example.com\n<\/code><\/pre>\n<p>If that works, the next step is to automate the task.<\/p>\n<h2>Setting up the cron task on the Qnap NAS<\/h2>\n<p>Run this to add a command to the crontab&#8217;s config file:<\/p>\n<pre><code>echo \"45 15 * * * \/share\/toms\/scripts\/backup.sh\" &gt;&gt; \/etc\/config\/crontab\n<\/code><\/pre>\n<p>The command will run the script every day at 15:45.<\/p>\n<p>Finally, reload the running cron daemon with the altered config file:<\/p>\n<pre><code>crontab \/etc\/config\/crontab\n<\/code><\/pre>\n<p>This way our added command will persist over NAS reboots, contrary to using <code>crontab -e<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to make a daily copy of backup files from a webserver on Debian to a local NAS using rsync over SSH.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[2,3,5,4],"class_list":["post-6","post","type-post","status-publish","format-standard","hentry","category-server-admin","tag-debian","tag-nas","tag-rsync","tag-ssh"],"_links":{"self":[{"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/posts\/6","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/comments?post=6"}],"version-history":[{"count":14,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/posts\/6\/revisions"}],"predecessor-version":[{"id":13,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/posts\/6\/revisions\/13"}],"wp:attachment":[{"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/media?parent=6"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/categories?post=6"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/tags?post=6"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}