通過配置 Ubuntu 的 SFTP 服務並使用 bind mount 共享指定目錄,可在 Windows 上藉助 FreeFileSync 實現安全、高效的鏡像同步。

1. 需求

先説一下筆者的需求:實現 Ubuntu 系統機器與其他機器的數據共享,尤其是讓 Ubuntu 系統下的某個目錄鏡像到 Windows 本地環境中。

2. 協議

除了安裝現成的軟件,一種比較好的方案是基於 Ubuntu 系統本身來搭建 SFTP 服務。SFTP(SSH File Transfer Protocol)是一種通過 SSH 加密通道安全傳輸文件的網絡協議,是運維人員的首選文件傳輸方式。SFTP 是 SSH 協議的一個子系統,必須先建立 SSH 連接才能使用 SFTP。

SSH(Secure Shell)提供安全的遠程登錄和命令執行,可作為其他協議的安全隧道。

3. 操作

筆者的目的是將 /home/ubuntu/data 這個目錄共享出去。

3.1 配置

安裝並運行 SSH :

sudo apt update
sudo apt install openssh-server -y
sudo systemctl enable --now ssh

創建專用 SFTP 用户,使用禁止用户通過 SSH 登錄到交互式終端的 shell:

# 創建用户,禁止 shell 登錄,主目錄設為 /home/ubuntu/data
sudo useradd -d /home/ubuntu/data -s /usr/sbin/nologin sftpuser

# 設置密碼(客户端連接時用)
sudo passwd sftpuser

設置目錄權限,SFTP 的 chroot 要求 chroot 目錄必須由 root 擁有且不可寫,但子目錄可以給用户寫:

# 創建父目錄作為 chroot 根(必須 root 所有)
sudo mkdir -p /sftp/sftpuser

# chroot 根目錄必須是 root:root 且 755
sudo chown root:root /sftp/sftpuser
sudo chmod 755 /sftp/sftpuser

假設我們想要共享的目錄就是 /home/ubuntu/data :

# 軟鏈接
sudo ln -s /home/ubuntu/data /sftp/sftpuser/upload

# 子目錄(upload)歸 sftpuser 所有,可讀寫
sudo chown sftpuser:sftpuser /sftp/sftpuser/upload
sudo chmod 755 /sftp/sftpuser/upload

配置 SSH 支持 SFTP chroot,在 /etc/ssh/sshd_config 文件末尾添加以下內容:

Match User sftpuser
    ChrootDirectory /sftp/sftpuser
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
    PermitTunnel no

表示當用户是 sftpuser 時,將其限制在 /sftp/sftpuser 目錄中,且只能使用 SFTP。

最後重啓 SSH 服務:

sudo systemctl restart ssh

3.2 測試

如果在 Windows 下測試是否能訪問遠端 Ubuntu 的 SFTP 服務,可以直接使用 PowerShell ,因為現在主流的 Windows 10/11 已經內置可 OpenSSH 客户端:

sftp sftpuser@Ubuntu-IP

輸入密碼後就可以進入 sftp> 提示符。不過筆者在進入 upload 目錄的時候失敗了:

sftp> dir
upload
sftp> cd upload
realpath /upload: No such file

這是因為筆者前面設置的路徑 /sftp/sftpuser/upload 是一個軟鏈接,而 OpenSSH 的 internal-sftp 在 chroot 環境中默認不解析軟鏈接。為了保證通用性,這裏還是換成 bind mount 的方式。

刪除原來的軟鏈接:

sudo rm -f /sftp/sftpuser/upload

創建一個普通目錄作為掛載點:

sudo mkdir /sftp/sftpuser/upload

使用 bind mount 將真實 data 目錄掛載進去:

sudo mount --bind /home/ubuntu/data /sftp/sftpuser/upload

設置權限,確保 sftpuser 可讀寫:

sudo chown sftpuser:sftpuser /sftp/sftpuser/upload
# 注意:bind mount 後權限繼承原目錄,所以也要檢查源目錄
sudo chown sftpuser:sftpuser /home/ubuntu/data

如果需要設置開機自動掛載,可以在 /etc/fstab 中添加一行:

/home/ubuntu/data /sftp/sftpuser/upload none bind 0 0

重啓 SSH :

sudo systemctl restart ssh

再次進行測試:

sftp sftpuser@Ubuntu-IP

3.3 鏡像

Windows下有非常多的客户端可以連接 SFTP 服務並且實現文件操作,比如 WinSCP、FileZilla 等等。不過筆者的目的是將 /home/ubuntu/data 這個文件的數據鏡像下來,並且定期同步。因此筆者使用的是 FreeFileSync 這款開源軟件。FreeFileSync 是專門用來文件夾比較和同步的,也可以支持 SFTP 服務。

設置 SFTP 服務參數:

進行文件比較和鏡像同步:

另外 FreeFileSync 還提供了一個 RealTimeSync 工具,進行設置後可以實時同步文件夾。其實這個功能差不多就是一些網盤提供的文件同步功能了,非常實用。