{"id":1733,"date":"2018-05-30T09:57:03","date_gmt":"2018-05-30T09:57:03","guid":{"rendered":"https:\/\/blog.datentraeger.li\/?p=1733"},"modified":"2018-06-10T14:04:27","modified_gmt":"2018-06-10T14:04:27","slug":"backup-mit-restic","status":"publish","type":"post","link":"https:\/\/blog.datentraeger.li\/?p=1733","title":{"rendered":"restic"},"content":{"rendered":"<p>Bin grad wieder mal dabei, mein Home &#8220;ein bisschen&#8221; zu sichern. Bisher hab ich meist <a href=\"https:\/\/github.com\/bit-team\/backintime\" target=\"blank_\">BackInTime<\/a> verwendet. Das funktionierte auch immer tadellos. Irgendwann hab ich mir aber mal Restic gebookmarkt, weil ich es noch interessant gefunden hab. Also sichere ich ab jetzt mein Home mit <a href=\"https:\/\/restic.net\/\" target=\"blank_\">Restic<\/a>, um das ganze ein bisschen genauer kennenzulernen&#8230;<\/p>\n<p>Restic unterst\u00fczt derzeit einige Cloud-Storages, lokale Verzeichnisse und SFTP als <a href=\"https:\/\/github.com\/restic\/restic#backends\" target=\"blank_\">Backends<\/a>. Ich habe nur mit lokalen Directories rumgespielt.<\/p>\n<p>Restic ist in Go geschrieben und unterst\u00fctzt die <a href=\"https:\/\/restic.readthedocs.io\/en\/stable\/020_installation.html\" target=\"blank_\">g\u00e4ngigsten Systeme<\/a>, bei Debian ist es auch in den <a href=\"https:\/\/packages.debian.org\/search?keywords=restic&amp;searchon=names&amp;suite=all&amp;section=all\" target=\"blank_\">Repositories<\/a>, wobei Stable eine sehr alte Version beinhaltet.<\/p>\n<h2>Features<\/h2>\n<p>Einige Features von restic sind:<\/p>\n<ul>\n<li>Deduplikation<\/li>\n<li><a href=\"https:\/\/restic.readthedocs.io\/en\/stable\/070_encryption.html\" target=\"blank_\">Verschl\u00fcsslung<\/a><\/li>\n<li><a href=\"https:\/\/restic.readthedocs.io\/en\/stable\/index.html\" target=\"blank_\">gute Dokumentation<\/a><\/li>\n<li>freie Software (<a href=\"https:\/\/github.com\/restic\/restic\/blob\/master\/LICENSE\" target=\"blank_\">BSD 2-Clause<\/a>)<\/li>\n<\/ul>\n<h2>Backup-Repository initialisieren<\/h2>\n<p>Einen Backup-Storage muss man erst mal initialisieren, um darin Snapshots abzulegen. Die Syntax ist ziemlich git-like:<\/p>\n<pre>restic -r \/mnt\/storage init\r\ncreated restic repository 5a7a387b38 at \/mnt\/storage\/\r\n\r\nPlease note that knowledge of your password is required to access\r\nthe repository. Losing your password means that your data is\r\nirrecoverably lost.\r\n<\/pre>\n<h3>Keys managen<\/h3>\n<p>Passw\u00f6rter von Repositories k\u00f6nnen nat\u00fcrlich auch <a href=\"https:\/\/restic.readthedocs.io\/en\/latest\/070_encryption.html?highlight=passwd%20change\" target=\"blank_\">ge\u00e4ndert werden<\/a>. Das Command &#8216;key&#8217; halt subcommands f\u00fcr list\/add\/passwd\/remove. &#8216;passwd&#8217; wird zum \u00e4ndern eines Passwortes verwendet.<\/p>\n<pre class=\"\">restic -r \/mnt\/storage key list\r\nenter password for repository: \r\npassword is correct\r\n ID          User        Host        Created\r\n----------------------------------------------------------------------\r\n*fcd3db62    peter       peanut      2018-06-01 12:48:04\r\n----------------------------------------------------------------------\r\n<\/pre>\n<p>Das Passwort eines Repositories kann man also etwa so \u00e4ndern:<\/p>\n<pre class=\"lang:default decode:true \">restic -r \/mnt\/storage key passwd\r\nenter password for repository: \r\npassword is correct\r\nenter password for new key: \r\nenter password again: \r\nsaved new key as &lt;Key of peter@host, created on 2018-06-06 17:02:50.78646922 +0200 CEST m=+11.944291578&gt;<\/pre>\n<h2>Backup erstellen<\/h2>\n<p>Nachdem der Backup-Storage initialisiert wurde, kann man eigentlich auch schon mit Backups loslegen. Damit Restic weiss, wo sich der Storage befindet, gibt man ihn mit -r an.<\/p>\n<pre>restic -r \/mnt\/storage backup \/home\r\nenter password for repository:\r\npassword is correct\r\nscan [\/home\/]\r\n[0:02] 1829 directories, 51117 files, 4.070 GiB\r\n...\r\n<\/pre>\n<h3>Exports<\/h3>\n<p>Wenn man nicht st\u00e4ndig den Backup-Pfad, das Passwort, etc mitgeben m\u00f6chte, kann man diese Werte einfach exportieren. Das macht das ganze auch recht gut scriptbar<\/p>\n<pre>export RESTIC_REPOSITORY=\/mnt\/storage\r\nexport RESTIC_PASSWORD=\"I9n7G7G0ZpDWA3GOcJbIuwQCGvGUBkU5\"\r\n...\r\n<\/pre>\n<p>oder direkt<\/p>\n<pre>RESTIC_PASSWORD=foobar restic -r \/mnt\/storage\/ snapshots\r\npassword is correct\r\nID        Date                 Host        Tags        Directory\r\n----------------------------------------------------------------------\r\n1978082b  2018-05-30 16:45:41  peanut                  \/home\/peter\/work\r\n984f8b7a  2018-05-30 16:53:55  peanut                  \/home\/peter\/work\r\n----------------------------------------------------------------------\r\n2 snapshots\r\n<\/pre>\n<p>eine weitere Variante das Passwort mitzugeben ist der <a href=\"https:\/\/restic.readthedocs.io\/en\/stable\/faq.html?highlight=export#how-can-i-specify-encryption-passwords-automatically\" target=\"blank_\">&#8211;password-file Parameter<\/a>.<\/p>\n<h3>Excludes<\/h3>\n<p><a href=\"https:\/\/restic.readthedocs.io\/en\/stable\/040_backup.html#including-and-excluding-files\" target=\"blank_\">Excludes<\/a> k\u00f6nnen via Paramter (&#8211;exclude=, beliebig oft anwendbar) oder mit einem File (&#8211;exclude-file=) mitgegeben werden<\/p>\n<pre>restic -r \/mnt\/storage backup ~\/work --exclude=\"*.c\" --exclude-file=excludes.txt<\/pre>\n<p>Beim exclude-file ist zu beachten, dass die Pfade relativ angegeben werden, wenn ich vom Home aus bspw. einen Snapshot ohne den ~\/Downloads-Folder erstellen m\u00f6chte, sollte der Pfad lediglich mit Downloads definiert werden.<\/p>\n<h3>Tags<\/h3>\n<p>Snapshots k\u00f6nnen auch getaggt werden, was sicherlich oft hilfreich sein kann.<\/p>\n<p>Mit &#8216;add&#8217; k\u00f6nnen Tags hinterlegt werden (was sich beliebig oft auch wiederholen l\u00e4sst)<\/p>\n<pre>RESTIC_PASSWORD=foobar restic -r \/mnt\/storage tag --add TEST e9b91671\r\n<\/pre>\n<p>verwendet man &#8216;set&#8217;, werden bestehende Tags \u00fcberschrieben<\/p>\n<pre>RESTIC_PASSWORD=foobar restic -r \/mnt\/storage tag --set BARFUSS 80aeff8\r\n<\/pre>\n<p>Dann gibt es halt nat\u00fcrlich noch remove etc, aber das findet man alles in der <a href=\"html?highlight=tag#manage-tags\" target=\"blank_\">Dokumentation<\/a> oder der Manpage von restic-tag.<\/p>\n<h3>Backups l\u00f6schen<\/h3>\n<p>Snapshots k\u00f6nnen nat\u00fcrlich auch wieder <a href=\"https:\/\/restic.readthedocs.io\/en\/stable\/060_forget.html\" target=\"blank_\">entfernt<\/a> werden.<\/p>\n<pre>RESTIC_PASSWORD=foobar restic -r \/mnt\/storage\/ snapshots \r\npassword is correct\r\nID        Date                 Host        Tags         Directory\r\n----------------------------------------------------------------------\r\n1978082b  2018-05-30 16:45:41  peanut                   \/home\/peter\/work\r\n984f8b7a  2018-05-30 16:53:55  peanut                   \/home\/peter\/work\r\n28d32dc0  2018-05-30 17:15:43  peanut      BARFUSS      \/home\/peter\/.vim\r\n-------------\r\n<\/pre>\n<p>Mittels forget und der Snapshot-ID kann nun ein Snapshot entfernt werden<\/p>\n<pre>RESTIC_PASSWORD=foobar restic -r \/mnt\/storage\/ forget 28d32dc0\r\npassword is correct\r\nremoved snapshot 28d32dc0\r\n<\/pre>\n<p>Die referenzierten Files sind jedoch immer noch im Repository hinterlegt. Um komplett aufzur\u00e4umen verwendet man prune<\/p>\n<pre>RESTIC_PASSWORD=foobar restic -r \/mnt\/storage\/ prune \r\npassword is correct\r\ncounting files in repo\r\nbuilding new index for repo\r\n[0:04] 100.00%  623 \/ 623 packs\r\nrepository contains 623 packs (82727 blobs) with 2.813 GiB\r\nprocessed 82727 blobs: 0 duplicate blobs, 0B duplicate\r\nload all snapshots\r\nfind data that is still in use for 2 snapshots\r\n[0:06] 100.00%  2 \/ 2 snapshots\r\nfound 78083 of 82727 data blobs still in use, removing 4644 blobs\r\nwill remove 0 invalid files\r\nwill delete 13 packs and rewrite 0 packs, this frees 34.548 MiB\r\ncounting files in repo\r\n[0:00] 100.00%  610 \/ 610 packs\r\nfinding old index files\r\nsaved new indexes as [0eb873bc]\r\nremove 5 old index files\r\n[0:00] 100.00%  13 \/ 13 packs deleted\r\ndone\r\n<\/pre>\n<p>Anstatt jedoch st\u00e4ndig zwei Commands auszuf\u00fchren, kann man auch den Parameter &#8216;&#8211;prune&#8217; beim forget mitgeben.<\/p>\n<pre>RESTIC_PASSWORD=foobar restic -r \/mnt\/storage\/ forget 28d32dc0 --prune\r\n<\/pre>\n<h4>Policies<\/h4>\n<p>Mit <a href=\"https:\/\/restic.readthedocs.io\/en\/stable\/060_forget.html#removing-snapshots-according-to-a-policy\" target=\"blank_\">Policies<\/a> kann man festlegen, welche Snapshots behalten werden sollen. Man kann st\u00fcndliche, t\u00e4gliche, j\u00e4hrliche oder monatliche Snapshots definieren und\/oder auch tags definieren, die behalten werden sollen.<\/p>\n<pre>restic forget --tag foo --keep-last 1<\/pre>\n<p>Es lassen sich auch gleich mehrere Tags definieren<\/p>\n<pre>restic forget --tag foo --tag bar --keep-last 1<\/pre>\n<p>Ein anderes Beispiel aus der Dokumentation: Die aktuellsten 7 t\u00e4glichen Snapshots, dann 4 w\u00f6chentliche (da die letzten 7 bereits eine Woche sind), die 11-12 Snapshots am letzten Tag des Monats und zus\u00e4tzlich 75 der letzten-Tag-des-Jahres Snapshots behalten:<\/p>\n<pre>forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75<\/pre>\n<h4>abgebrochene Backups<\/h4>\n<p>Wird ein laufendes Backup abgebrochen (z.B. mit C-c), sieht man zwar keine Snapshots, jedoch wurden bereits Daten geschrieben, also Speicherplatz verwendet. Generell sollte nach einiger Zeit auch ein resume m\u00f6glich sein (siehe <a href=\"https:\/\/github.com\/restic\/restic\/issues\/1211\" target=\"_blank\" rel=\"noopener\">Github issue<\/a>), d.h., dass wenn ein erneutes Backup erstellt wird, erkennt restic, dass die bereits gesicherten Daten vorhanden sind und von wird dort weiter machen anstatt komplett von vorne zu beginnen. Mittels <a href=\"https:\/\/restic.readthedocs.io\/en\/stable\/060_forget.html?highlight=prune\" target=\"_blank\" rel=\"noopener\">prune<\/a> k\u00f6nnen &#8220;verwaiste&#8221; Daten aber jederzeit entfernt werden.<\/p>\n<pre class=\"lang:default decode:true \">restic prune<\/pre>\n<h2>Restore<\/h2>\n<p>Mit snapshots lassen sich alle Backups eines Repositories anzeigen<\/p>\n<pre>restic -r \/mnt\/storage snapshots<\/pre>\n<p>Um einen Snapshot aufzulisten, verwendet man ls<\/p>\n<pre>restic -r \/mnt\/storage ls<\/pre>\n<p>Nun kann man bspw. nur ein File restoren<\/p>\n<pre>restic restore -t \/tmp\/restore -i \"*.odt\"<\/pre>\n<p>oder das komplette Backup<\/p>\n<pre>restic restore -t \/tmp\/restore\/<\/pre>\n<h3>FUSE-Mount<\/h3>\n<p>Das Backup l\u00e4sst sich aber auch einfach mounten und man kann damit &#8220;ganz normal&#8221; arbeiten<\/p>\n<pre>RESTIC_PASSWORD=foobar restic -r \/media\/peter\/hitachi1tb\/backup\/ mount ~\/mnt\r\npassword is correct\r\nMountpoint \/home\/peter\/mnt doesn't exist, creating it\r\nNow serving the repository at \/home\/peter\/mnt\r\nDon't forget to umount after quitting!\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"Bin grad wieder mal dabei, mein Home &#8220;ein bisschen&#8221; zu sichern. Bisher hab ich meist BackInTime verwendet. Das funktionierte auch immer tadellos. Irgendwann hab ich mir aber mal Restic gebookmarkt, weil ich es noch interessant gefunden hab. Also sichere ich ab jetzt mein Home mit Restic, um das ganze ein&hellip;\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48,36],"tags":[],"class_list":["post-1733","post","type-post","status-publish","format-standard","hentry","category-backup","category-cli"],"_links":{"self":[{"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=\/wp\/v2\/posts\/1733","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1733"}],"version-history":[{"count":56,"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=\/wp\/v2\/posts\/1733\/revisions"}],"predecessor-version":[{"id":1875,"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=\/wp\/v2\/posts\/1733\/revisions\/1875"}],"wp:attachment":[{"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1733"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1733"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.datentraeger.li\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1733"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}