Posted in

備份Synology NAS上的檔案到Oracle Cloud VPS作為備援server

目前我的Synology NAS上有跑docker,並且我想要將跑在docker上的Vaultwarden(自架密碼管理器)進行備份,不然哪天資料消失密碼也隨之消失,正好前陣子有註冊Oracle Cloud (Free Tier),免費的總容量(400GB)也夠我備份密碼庫這種小檔案,所以我就想說能不能讓Oracle當我的備援server,同時也備份部份資料,這樣也算是異地備份,所以就開始著手研究(問ChatGPT),其實簡單來說就是從Linux備份到另一台Linux,以下是操作過程:

前置作業

  • 本地主機(我這邊是Synology NAS DSM 7.2.2,Linux)
  • 遠端主機,Oracle VPS(Ubuntu Linux),或是你自己的server
  • 遠端主機公網 IP
  • 欲備份檔案
  • 遠端主機私鑰

我這邊要備份的檔案路徑是:

/volume1/docker/vaultwarden

開始設定

到Synology NAS控制台 >> 任務排程表 >>新增

排程任務 >> 使用者定義指令碼

一般

  • 任務名稱: 我這邊是vaultwarden backup
  • 使用者帳號: 因為我這邊資料夾只有開權限給管理員群組,所以我這邊用NAS管理員帳號

排程

  • 依照想要備份的頻率或特定哪一天做設定,我這邊是設定每天

任務設定

  • 執行指令:
#!/bin/bash
DATE=$(date +%F) #取得當前日期作為檔名
TMP="/volume1/docker/vaultwarden_backup_${DATE}.tar.gz" #暫存的位置及檔名
REMOTE_USER="ubuntu" #遠端主機的使用者名稱
REMOTE_HOST="xxx.xxx.xxx.xxx" #更換成遠端主機的IP位置
REMOTE_PATH="/home/ubuntu/nas_backups/" #欲備份在遠端主機某個目錄下
SSH_KEY="/volume1/docker/ssh_key/id_rsa.key" #VPS的存取私鑰位置(建立VPS時下載的,先放到NAS上讓NAS可以讀取)

# 如果暫存位置在欲壓縮的檔案下要排除備份檔自己(目前不需要)
#tar czf "$TMP" -C "/volume1/docker" --exclude="vaultwarden_backup_*.tar.gz" vaultwarden

# 上傳備份檔(指定完整檔名)
scp -o StrictHostKeyChecking=no -i "$SSH_KEY" "$TMP" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}vaultwarden_backup_${DATE}.tar.gz"

# 刪除本地備份檔
rm "$TMP"

***建立排程任務後先不要執行***

要更改私鑰的權限

似乎在DSM介面即使設置私鑰擁有者和權限為管理員,進行ssh連線時仍會跳錯誤說權限太open,所以只好在NAS的系統後台執行(透過指令),有兩種方式可以解決:

  1. 透過ssh進入NAS操作(不熟Linux的人不太建議)
  2. 透過任務排程表建立一次性任務來執行

指令:

chmod 600 /volume1/docker/ssh_key/id_rsa.key

建立好後先執行任務

建議可以開日誌紀錄來查看指令是否執行正常:

到日誌儲存位置查看output log有沒有error

要先建立指紋

由於任務排程器沒有互動功能,而且第一次與遠端主機建立連線時會先確認指紋是否存在(確認此遠端主機是否可信任),所以我們必須先建立指紋,才不會出錯,同樣是要ssh進入NAS或透過任務排程表

總而言之第一次建立連現時會出現以下:

ssh -i /volume1/docker/ssh_key/id_rsa.key ubuntu@xxx.xxx.xxx.xxx
The authenticity of host 'xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

這邊要輸入yes才能繼續連線

yes

如過透過ssh進入NAS就是以上的操作
如果要建立任務,指令如下:

ssh -i /volume1/docker/ssh_key/id_rsa.key ubuntu@xxx.xxx.xxx.xxx
yes

一樣執行後查看log有無出錯

手動試試執行一開始的備份任務

如果log沒輸出錯誤的話,那這時檔案應該已經正確傳送到遠端主機,我們來確認一下

果然有看到檔案

在遠端主機上啟動docker服務當作備援server

docker安裝的部分就跳過,網路上應該有很多教學,接下來要建立腳本來執行:

  1. 找到最新備份檔
  2. 刪除目前docker運行資料
  3. 解壓縮至目標目錄
  4. 重啟docker服務以套用新的備份資料

接下來我先在使用者根目錄建立sh資料夾,存放腳本,接著新增腳本

mkdir ~/sh
vi vaultwarden.sh
#!/bin/bash

BACKUP_DIR="/home/ubuntu/nas_backups" #剛才在NAS任務排程表打上的目標目錄
DATA_DIR="/home/ubuntu/docker" #存放docker的資料目錄

# 找最新備份檔
LATEST_BACKUP=$(ls -1t "$BACKUP_DIR"/*.tar.gz | head -n1)

if [ -z "$LATEST_BACKUP" ]; then
  echo "找不到備份檔"
  exit 1
fi

# 停止容器
docker stop vaultwarden

# 清空舊資料
rm -rf $DATA_DIR/*

echo "解壓備份檔:$LATEST_BACKUP"
tar -xzf "$LATEST_BACKUP" -C "$DATA_DIR"

# 啟動容器
docker start vaultwarden

把腳本檔設置成可執行

chmod +x~/sh/vaultwarden.sh

接著手動執行腳本試試

sh/vaultwarden.sh

沒有出錯的話應該就正常跑起來了,到這裡備份算是很成功,但是還需要在這裡進行定期執行腳本,我是設定每天從NAS備份,所以我的腳本就設定一天執行一次,設定crontab

crontab -e

選擇偏好的文本編輯器,然後在裡面加上

30 0 * * * /home/ubuntu/sh/vaultwarden.sh >> /home/ubuntu/sh/sh_log/vaultwarden.log 2>&1
欄位意義
0分鐘
2小時(凌晨2點)
*每天
*每月
*每週的任何一天
/home/ubuntu/sh/vaultwarden.sh指定要執行的腳本
>> ...將輸出記錄到 log 檔案中
2>&1把錯誤輸出(stderr)也重導向到標準輸出(stdout)
標準輸出(1)標準錯誤(2) 都寫入 log

然後別忘記建立log的資料夾sh_log

mkdir ~/sh/sh_log

簡單的備援伺服器就設定完成

不過如果要讓vaultwarden正常運作還必須要用ssl加密連線(https),之後會詳細說明如何設定(透過反向代理)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *