通过 WireGuard 访问 NFS 共享文件

有时 VPS 的硬盘会不够用,如果只是用来存储数据,比起直接扩容/升级,趁着各种活动的时候另购一台大硬盘 VPS 往往更加划算。
跨地区挂载我一般使用 WebDAV(HTTPS) + Rclone,而同地区挂载为了速度和性能,NFS(Network File System,网络文件系统)是更好的选择。不过 NFS 自身不提供加密功能,在公网或能内网互通的机房上需通过 TLS 或 Kerberos 加密,也可以使用本文介绍的方法,利用 WireGuard 协议进行加密传输。
* 需要注意 WireGuard 协议通过 UDP 传输流量,部分服务商会对 UDP 进行 QoS,导致体验不佳。选择该方案前建议先使用 iperf3 测试 UDP 速度,确保服务商未作限制。
这里假设 VPS A 作为服务端存储数据,VPS B 作为客户端运行服务,通过 WireGuard 建立加密隧道,使 VPS B 能够安全地访问 VPS A 上的数据文件。以下操作演示环境为 Debian 12,默认以 root 用户进行。
配置 WireGuard
1. 安装 WireGuard
在两台 VPS 上都安装 WireGuard:
apt install wireguard
2. 生成密钥对
在两台 VPS 上分别生成 WireGuard 密钥对 private.key
和 public.key
:
umask 077
wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
umask
3. 配置 WireGuard
我这里内网 IP 选择使用 10.0.1.0/24,VPS A(服务端)的 IP 设置为 10.0.1.1,VPS B(客户端)的 IP 设置为 10.0.1.2。你可以替换为其他网段或自己喜欢的保留地址。
a. 修改 VPS A(服务端)的配置文件 /etc/wireguard/wg0.conf
:
[Interface]
Address = 10.0.1.1/24
ListenPort = 51820
PrivateKey = <VPS A 服务端私钥>
[Peer]
PublicKey = <VPS B 客户端公钥>
AllowedIPs = 10.0.1.2/32
# [Peer]
# PublicKey = <VPS C 客户端公钥>
# AllowedIPs = 10.0.1.3/32
b. 修改 VPS B(客户端)的配置文件 /etc/wireguard/wg0.conf
:
[Interface]
Address = 10.0.1.2/24
PrivateKey = <VPS B 客户端私钥>
[Peer]
PublicKey = <VPS A 服务端公钥>
Endpoint = <VPS A 服务端公网 IP>:51820
AllowedIPs = 10.0.1.1/32
# PersistentKeepalive = 25
c. 在两台 VPS 上分别启动 WireGuard:
systemctl enable wg-quick@wg0.service
systemctl start wg-quick@wg0.service
systemctl status wg-quick@wg0.service
d. 检查是否连接成功:
wg show
运行上面命令后如果有流量数据或者能 ping 通对方说明可以正常通信,之后建议删除两台 VPS 上的密钥文件 /etc/wireguard/private.key
。
* 如果 VPS A(服务端)上开启了防火墙,记得放行 WireGuard 端口给 VPS B(客户端),比如 ufw 防火墙:
ufw allow from <VPS B 公网 IP> to any port 51820
配置 NFS
1. NFS 服务端(VPS A)
a. 安装 NFS 服务端:
apt install nfs-kernel-server
b. 添加共享目录。编辑 /etc/exports
文件,假如这里要共享 /mnt/data/share
目录,文件最后添加:
/mnt/data/share 10.0.1.2(rw,sync,no_subtree_check,no_root_squash)
这表示将 /mnt/data/share
目录共享给 IP 地址为 10.0.1.2
的客户端。
其中:
rw
: 文件权限。客户端拥有读写权限。sync
: 同步写入。写操作会立即写入磁盘,比 async 更安全,但稍慢。no_subtree_check
: 禁用子目录检查。禁用可以提高性能并避免某些权限错误。no_root_squash
: 不压缩 root 权限。客户端的 root 用户拥有服务端的 root 权限(安全性较低,一般用于信任的环境),默认是将客户端的 root 映射为匿名用户。
如果选择 root_squash
记得修改目录权限,保证客户端用户能正常读写。
应用配置更改:
exportfs -ra
c. 可选安全配置。确保 NFS 服务仅监听 WireGuard 接口,并且关闭 NFSv2 和 NFSv3,只使用 NFSv4。编辑 /etc/default/nfs-kernel-server
,添加设置:
# 注释前面的 RPCMOUNTDOPTS 变量行,添加下面内容
RPCMOUNTDOPTS="--manage-gids -N 2 -N 3 -H 10.0.1.1"
RPCNFSDOPTS="-N 2 -N 3"
修改 /etc/nfs.conf
:
[nfsd]
host=10.0.1.1
重启 NFS 服务:
systemctl restart nfs-kernel-server
* NFSv4 不需要 rpcbind 服务,可以禁用以避免不必要的启动和资源消耗:
systemctl mask rpcbind.service
systemctl mask rpcbind.socket
* 如果 VPS A(服务端)上开启了防火墙,记得放行 NFS 内网端口给 VPS B(客户端),比如 ufw 防火墙:
ufw allow from 10.0.1.2 to any port 2049
ufw allow from 10.0.1.2 to any port 111
2. NFS 客户端(VPS B)
a. 安装 NFS 客户端:
apt install nfs-common
b. 创建挂载点并挂载共享目录。假如这里要挂载到 /mnt/vps-a
目录:
mkdir -p /mnt/vps-a
mount -t nfs -o vers=4.2 10.0.1.1:/mnt/data/share /mnt/vps-a
现在,你可以尝试 ls /mnt/vps-a -l
查看 VPS A 上的共享文件了。
3. 开机自动挂载
编辑 /etc/fstab
文件,添加以下行:
10.0.1.1:/mnt/data/share /mnt/vps-a nfs vers=4.2,x-systemd.requires=wg-quick@wg0.service 0 0
其中 x-systemd.requires=wg-quick@wg0.service
表示在尝试挂载这个文件系统之前,必须先成功启动 wg-quick@wg0.service
服务;0 0
这两个数字分别代表 dump
命令的备份频率和 fsck
命令的文件系统检查顺序。对于网络文件系统,通常设置为 0 0
,表示不进行备份和检查。
至此,成功实现了在 VPS B 系统启动时自动挂载 NFS 文件系统,通过 WireGuard 加密隧道访问另一台 VPS A 服务器上的共享文件。
EOF
如果你觉得这篇文章还不错,可以考虑支持作者。