史上最強跨平台、多端加密同步神器,你有用過嗎?

  • 2019 年 10 月 31 日
  • 筆記

什麼是 Restic

Restic 是一款 GO 語言開發的開源免費且快速、高效和安全的跨平台備份工具。Restic 使用加密技術來保證你的數據安全性和完整性,可以將本地數據加密後傳輸到指定的存儲。

Restic 同樣支援增量備份,可隨時備份和恢復備份。Restic 支援大多數主流作業系統,比如:LinuxmacOSWindows 以及一些較小眾的作業系統 FreeBSDOpenBSD 等。

項目地址:https://github.com/restic/restic

Restic 支援的存儲類型

Restic 支援的存儲種類比較多,大致有如下這些類型:

  • 本地存儲
  • SFTP
  • REST Server
  • Amazon S3
  • Minio Server
  • OpenStack Swift
  • Backblaze B2
  • Microsoft Azure Blob Storage
  • Google Cloud Storage
  • 通過 Rclone 掛載的存儲 (比如:Google Drive、OneDrive 等)

Restic 與 Rclone 的區別

ResticRclone 都是開源的命令行文件備份(同步)工具,但卻有著很本質的區別。

  1. 兩者的相同點
  • 兩者都是基於命令行的開源文件同步和備份工具。
  • 兩者都支援將文件備份到本地、遠程伺服器或對象存儲。
  1. 兩者不同點
  • Rclone 面向的是文件同步,即保證兩端文件的一致,也可以增量備份。
  • Restic 面向的是文件備份和加密,文件先加密再傳輸備份,而且是增量備份,即每次只備份變化的部分。
  • Rclone 倉庫配置保存在本地,備份的文件會保持原樣的同步於存儲倉庫中。
  • Restic 配置資訊直接寫在倉庫,只要有倉庫密碼,在任何安裝了 Restic 的電腦上都可以操作倉庫。
  • Rclone 不記錄文件版本,無法根據某一次備份找回特定時間點上的文件。
  • Restic 每次備份都會生成一個快照,記錄當前時間點的文件結構,可以找回特定時間點的文件。
  • Rclone 可以在配置的多個存儲端之間傳輸文件。

總的來說,RcloneRestic 各有所長,要根據不同的業務需求選擇使用。比如:網站數據的增量備份,用 Resitc 就比較合適。而常規文件的遠程備份歸檔,用 Rclone 就很合適。

安裝 Restic

Restic 可以通過系統軟體包安裝,也可以直接下載最新的二進位包方式進行安裝。

  1. 通過軟體包安裝
  • Debian & Ubuntu
$ apt-get install restic
  • RHEL & CentOS
$ yum install yum-plugin-copr$ yum copr enable copart/restic$ yum install restic
  • Fedora
$ dnf install restic
  • Arch Linux
$ pacman -S restic
  • macOS
$ brew install restic

更多平台的軟體包安裝方法可參見官方文檔:https://restic.readthedocs.io/en/stable/020_installation.html

  1. 通過二進位版本安裝

通過預編譯好的二進位版本進行安裝,非常的簡單。只要根據自己所需的平台選擇對應的版本下載即可,這裡以 Linux 系統為例:

# 下載指定版本的安裝包$ wget https://github.com/restic/restic/releases/download/v0.9.5/restic_0.9.5_linux_amd64.bz2  # 解壓並刪除壓縮包$ bzip2 -d restic*.bz2 && rm -rf restic*.bz2  # 增加執行許可權$ chmod +x restic*  # 移動二進位文件到指定目錄$ mv restic* /usr/local/bin/restic  # 驗證所安裝的版本$ restic version

如果以後需要更新到最新版本,只需運行以下命令就可完成。

# 直接升級二進位文件到最新版本$ restic self-update
  1. Restic 常用語法命令

Restic 支援的命令和參數比較多,你可以使用 --help 參數來查看它們的基本用法。

$ restic --helprestic is a backup program which allows saving multiple revisions of files anddirectories in an encrypted repository stored on different backends.  Usage:  restic [command]  Available Commands:  backup        Create a new backup of files and/or directories  cache         Operate on local cache directories  cat           Print internal objects to stdout  check         Check the repository for errors  diff          Show differences between two snapshots  dump          Print a backed-up file to stdout  find          Find a file or directory  forget        Remove snapshots from the repository  generate      Generate manual pages and auto-completion files (bash, zsh)  help          Help about any command  init          Initialize a new repository  key           Manage keys (passwords)  list          List objects in the repository  ls            List files in a snapshot  migrate       Apply migrations  mount         Mount the repository  prune         Remove unneeded data from the repository  rebuild-index Build a new index file  restore       Extract the data from a snapshot  snapshots     List all snapshots  stats         Count up sizes and show information about repository data  tag           Modify tags on snapshots  unlock        Remove locks other processes created  version       Print version information  Flags:      --cacert file              file to load root certificates from (default: use system certificates)      --cache-dir string         set the cache directory. (default: use system default cache directory)      --cleanup-cache            auto remove old cache directories  -h, --help                     help for restic      --json                     set output mode to JSON for commands that support it      --key-hint string          key ID of key to try decrypting first (default: $RESTIC_KEY_HINT)      --limit-download int       limits downloads to a maximum rate in KiB/s. (default: unlimited)      --limit-upload int         limits uploads to a maximum rate in KiB/s. (default: unlimited)      --no-cache                 do not use a local cache      --no-lock                  do not lock the repo, this allows some operations on read-only repos  -o, --option key=value         set extended option (key=value, can be specified multiple times)  -p, --password-file string     read the repository password from a file (default: $RESTIC_PASSWORD_FILE)  -q, --quiet                    do not output comprehensive progress report  -r, --repo string              repository to backup to or restore from (default: $RESTIC_REPOSITORY)      --tls-client-cert string   path to a file containing PEM encoded TLS client certificate and private key  -v, --verbose n[=-1]           be verbose (specify --verbose multiple times or level n)  Use "restic [command] --help" for more information about a command.

Git 等程式類似 Restic 有許多子命令,每個子命令都有自己的命令行選項。如果你要列出每個子命令的幫助選項,可以使用類似下面的命令語法。

# 以備份子命令為例$ restic backup --helpThe "backup" command creates a new snapshot and saves the files and directoriesgiven as the arguments.  Usage:  restic backup [flags] FILE/DIR [FILE/DIR] ...  Flags:  -e, --exclude pattern                  exclude a pattern (can be specified multiple times)      --exclude-caches                   excludes cache directories that are marked with a CACHEDIR.TAG file. See http://bford.info/cachedir/spec.html for the Cache Directory Tagging Standard      --exclude-file file                read exclude patterns from a file (can be specified multiple times)      --exclude-if-present stringArray   takes filename[:header], exclude contents of directories containing filename (except filename itself) if header of that file is as provided (can be specified multiple times)      --files-from string                read the files to backup from file (can be combined with file args/can be specified multiple times)  -f, --force                            force re-reading the target files/directories (overrides the "parent" flag)  -h, --help                             help for backup      --hostname hostname                set the hostname for the snapshot manually. To prevent an expensive rescan use the "parent" flag  -x, --one-file-system                  exclude other file systems      --parent string                    use this parent snapshot (default: last snapshot in the repo that has the same target files/directories)      --stdin                            read backup from stdin      --stdin-filename string            file name to use when reading from stdin (default "stdin")      --tag tag                          add a tag for the new snapshot (can be specified multiple times)      --time string                      time of the backup (ex. '2012-11-01 22:08:41') (default: now)      --with-atime                       store the atime for all files and directories  Global Flags:      --cacert file              file to load root certificates from (default: use system certificates)      --cache-dir string         set the cache directory. (default: use system default cache directory)      --cleanup-cache            auto remove old cache directories      --json                     set output mode to JSON for commands that support it      --key-hint string          key ID of key to try decrypting first (default: $RESTIC_KEY_HINT)      --limit-download int       limits downloads to a maximum rate in KiB/s. (default: unlimited)      --limit-upload int         limits uploads to a maximum rate in KiB/s. (default: unlimited)      --no-cache                 do not use a local cache      --no-lock                  do not lock the repo, this allows some operations on read-only repos  -o, --option key=value         set extended option (key=value, can be specified multiple times)  -p, --password-file string     read the repository password from a file (default: $RESTIC_PASSWORD_FILE)  -q, --quiet                    do not output comprehensive progress report  -r, --repo string              repository to backup to or restore from (default: $RESTIC_REPOSITORY)      --tls-client-cert string   path to a file containing PEM encoded TLS client certificate and private key  -v, --verbose n[=-1]           be verbose (specify --verbose multiple times or level n)

配置 Restic 支援的存儲方式

安裝好 Restic 後,我們需要配置下存儲方式。也就是你想備份數據到本地,還是其它遠程服務上。

本文將主要講講最常用的本地、SFTP 兩種備份方式,其它遠程庫配置方法可參考官方文檔:https://tinyurl.com/yazw4oha 。

  1. 配置本地存儲倉庫
# 備份到本地 /home/mike/backup 文件夾$ restic init --repo /home/mike/backup
  1. 配置 SFTP 方式的存儲倉庫

該方法適合將文件備份到另一台伺服器上。首先,我們需要在兩台伺服器間配置免密碼登錄。

注意:以下將需要備份的伺服器稱為 A,備份伺服器稱為 B。

2.1 配置 SSH 免密碼登錄

這部分內容比較基礎,就不在這裡展開了。如果你不會配置可以參考以下兩篇文章:

  • 「CentOS 下配置 SSH 免密碼登錄」:https://zhuanlan.zhihu.com/p/45025702
  • 「SSH 和 ssh-copy-id 以及批量多機無密碼登陸詳解」: https://www.cnblogs.com/operationhome/p/9166583.html

2.2 在伺服器 A 上進行數據備份

# root 為伺服器 B 的用戶名,192.168.1.100 為 B 伺服器 IP,埠默認為 22,/home/mike/backup 為伺服器 B 上的目錄,如果不存在則會自動創建。$ restic -r sftp:[email protected]:/home/mike/backup init

如果伺服器 B 的 SSH 默認埠不是 22,你就需要簡單調整下 A 伺服器上的 SSH 配置文件。

# 在伺服器 A 中 ~/.ssh 目錄創建一個 config 文件,並新增如下內容。# 分別是 B 伺服器的 IP、用戶名和 SSH 的埠。$ vim ~/.ssh/configHost 192.168.1.100    User root    Port 2000

由於上面配置了默認的 B 伺服器的用戶名和密碼,現在就可以直接只寫 B 伺服器的 IP 就可以了。

$ restic -r sftp:192.168.1.100:/home/mike/backup init

注意:以上配置過程中都會要求你輸入密碼,切記不要遺忘。

使用 Restic 備份數據

經過上面的步驟,我們已經完成了備份存儲的初始化。現在我就來看幾個 Restic 備份的例子。

以下我們所有演示的例子均是將 A 伺服器上 /var/www/ 目錄下的文件備份到 B 伺服器上的 /home/mike/backup 目錄下。

創建備份快照

以下命令是備份的 /var/www 整個目錄,如果只需備份目錄中單個文件,比如:/var/www/mike.zip,那備份內容就可以改成 /var/www/mike.zip

# 本地備份$ restic -r /home/mike/backup --verbose backup /var/www  # SFTP 備份$ restic -r sftp:192.168.1.100:/home/mike/backup --verbose backup /var/www

如果你不想備份目錄下全部的內容,你還可以用以下參數排除或包含指定的備份目錄或者文件。

--include 指定一次或多次以包含一個或者多個目錄或文件--exclude 指定一次或多次以排除一個或多個目錄或文件--exclude-caches 指定一次以排除包含特殊文件的目錄--exclude-file 指定一次或多次以排除給定文件中列出的項目--exclude-if-present 如果目錄內容包含給定文件,則指定一次或多次排除目錄的內容

具體用法可以參考官方文檔: https://restic.readthedocs.io/en/stable/040_backup.html#including-and-excluding-files

Restic 還支援直接將命令的輸出進行重定向,比如:將備份好的資料庫文件直接通過 SFTP 方式備份到另一台伺服器。

# 將 WordPress 資料庫備份到另一台伺服器,並命名為 WordPress_Backup.sql$ mysqldump -uroot -ppasswd 000000 --databases WordPress | restic -r sftp:192.168.1.100:/home/mike/backup backup --stdin --stdin-filename WordPress_Backup.sql

列出備份快照

備份完成後,可以使用以下命令查看備份的快照資訊。您可以看到我們在第一次備份期間的快照 ID,拍攝快照的時間戳,主機名,標籤以及備份的目錄。

# 查看所有備份快照  $ restic -r sftp:192.168.1.100:/home/mike/backup snapshotsID        Time                 Host        Tags              Paths---------------------------------------------------------------------ef5ff5fe  2019-08-25 17:03:57  Mike-Dev01                          /home/mike/backup9f0bc19e  2019-08-26 17:18:57  Mike-Dev02                          /home/devops/backup---------------------------------------------------------------------  # 只查看 /home/mike/backup 目錄的備份快照$ restic -r sftp:192.168.1.100:/home/mike/backup snapshots --path="/home/mike/backup"ID        Time                 Host        Tags              Paths---------------------------------------------------------------------ef5ff5fe  2019-08-25 17:03:57  Mike-Dev01                          /home/mike/backup---------------------------------------------------------------------  # 只查看主機名為 Mike-Dev01 的備份快照$ restic -r sftp:192.168.1.100:/home/mike/backup snapshots --host Mike-Dev01ID        Time                 Host        Tags              Paths---------------------------------------------------------------------ef5ff5fe  2019-08-25 17:03:57  Mike-Dev01                          /home/mike/backup---------------------------------------------------------------------  # 列出某個快照中所包含的文件$ restic ls ef5ff5fesnapshot ef5ff5fe of [/home/mike/backup] at 2019-08-25 20:35:39.450146467 +0800 CST):/backup/backup/2019-04-19_2004334933.jpg/backup/2019-04-13_15-00-15.png/backup/2019-04-16_15-19-39.png/backup/2019-04-16_15-20-22.png/backup/2019-04-18_17-11-52.png

從上面的結果,我們可以看到 Tags 列是空的。這是因為備份時沒有使用 --tag 參數,下面我們演示下 --tag 參數的使用。

# 給備份文件指定標籤$ restic -r sftp:192.168.1.100:/home/mike/backup --verbose backup /var/www --tag site

如果你想加入更多標籤來更詳細的區分備份,那就在後面多加幾個 --tag 參數。

恢復備份快照

這裡以 SFTP 存儲倉庫為例,我們將遠程存儲目錄 /home/mike/backup 的備份文件恢復到本地 /var/wwww 文件夾。

# restore 後面指定為要恢復備份的 ID$ restic -r sftp:[email protected]:/home/mike/backup restore ef5ff5fe --target /var/wwww  # 你也可以直接使用 latest 來恢復最後一次的備份文件$ restic -r sftp:[email protected]:/home/mike/backup restore latest --target /var/wwww

刪除備份快照

如果你不在再要一些備份快照,你可以直接使用下面的命令刪除指定的備份快照。

# ef5ff5fe 為要刪除文件的 ID$ restic -r sftp:[email protected]:/home/mike/backup forget ef5ff5fe

不過上面的命令只是將快照記錄清除了,但快照中包含的文件數據仍存儲在存儲庫中。如果要徹底清除未引用的數據,你必須運行 prune 命令:

$ restic -r sftp:[email protected]:/home/mike/backup pruneenter password for repository:  counting files in repobuilding new index for repo[0:00] 100.00%  22 / 22 filesrepository contains 22 packs (8512 blobs) with 100.092 MiB bytesprocessed 8512 blobs: 0 duplicate blobs, 0B duplicateload all snapshotsfind data that is still in use for 1 snapshots[0:00] 100.00%  1 / 1 snapshotsfound 8433 of 8512 data blobs still in usewill rewrite 3 packscreating new index[0:00] 86.36%  19 / 22 filessaved new index as 544a5084done

清理完成後,存儲庫的空間就會釋放出來。當然你也可以直接使用 --prune 參數來將上面兩步合成為一步:

# ef5ff5fe 為要刪除文件的 ID$ restic -r sftp:[email protected]:/home/mike/backup forget ef5ff5fe --prune

使用 Restic 進行自動備份

  1. 免密碼操作存儲倉庫

上面的備份中我們都手工輸入了密碼,如果需要定期備份當然是通過一個腳本來實現是最方便,但是在使用腳本備份時如果要顯示輸入訪問存儲倉庫的密碼肯定不適用的。這裡我們就需要使用 --password-file 參數來達到自動讀取密碼的目的。

# 將密碼保存在 /home/mike/resticpasswd 文本中$ echo '000000' > /home/mike/resticpasswd  # 在備份命令中使用 --password-file 參數來讀取文本中的密碼$ restic -r sftp:[email protected]:/home/mike/backup --verbose backup /var/www --password-file /home/mike/resticpasswd

除了使用 --password-file 參數指定密碼外,你也可以使用環境變數來指定一些 Restic 所需的參數。例如,使用騰訊雲的對象存儲就可以使用下面這些環境變

export TencentCloud_ACCESS_KEY_ID="your-access-key"export TencentCloud_SECRET_ACCESS_KEY="your-secret-key"export RESTIC_REPOSITORY="s3:server-url/bucket-name"export RESTIC_PASSWORD="a-strong-password"
  1. 結合 Cron 完成自動備份

Restic 中的 forget 命令可以幫助你來維護快照的運行存檔。你可以使用 restic forget --prune 來設置每小時、每日、每周等保留的備份數量,任何不符合策略的備份都將從存儲庫中清除。

這裡我們將使用 Cron 系統服務每 30 分鐘運行一次備份任務。

$ crontab -e30 * * * * /usr/local/bin/restic -r sftp:[email protected]:/home/mike/backup backup --password-file /home/mike/resticpasswd -q /var/www; /usr/local/bin/restic forget -q --prune --keep-hourly 24 --keep-daily 7

上面的計劃任務里,其中 30 * * * * 定義了 Cron 中任務運行的時間,這裡定義為每隔 30 分鐘運行。--keep-hourly 24 --keep-daily 7 定義了根據指定的保留標誌並刪除不再需要的舊快照,在這裡我們是將 24 小時內的快照保留 7 天。

更多策略可參考官方文檔:https://restic.readthedocs.io/en/latest/060_forget.html#removing-snapshots-according-to-a-policy

參考文檔

  1. https://www.google.com
  2. https://restic.readthedocs.io/en/latest/
  3. https://www.moerats.com/archives/897/
  4. https://cloud.tencent.com/developer/article/1160729
  5. https://it.ismy.fun/2018/04/22/restic-backup-to-aliyun-oss/
  6. https://zhuanlan.zhihu.com/p/66324926
  7. https://www.elasticfeed.com/e8590b1297e81b6e7ab19c66be4f037d/
  8. https://www.vmvps.com/restic-a-new-opensource-backup-free-tool-to-backup-your-vps-files.html