如何使用 SSHFS 通过 SSH 挂载远程文件系统
作者 Paul White, Alex Garnett
导言
通过 SSH 连接使用 SFTP 或 SCP 来传输文件,是一种很受欢迎的在服务器之间移动少量数据的方法。然而有些时候,人们可能需要在两个远程环境之间共享整个目录或整个文件系统。虽然这可以通过配置 SMB 或 NFS 挂载来实现,但这两种方法都需要额外的依赖,并可能引入安全问题或导致额外开销。 作为一种替代选择,你可以安装 SSHFS,通过单独使用 SSH 来挂载一个远程目录。这有一个显著的优势,就是不需要额外的配置,而且可以从远程系统的 SSH 用户那里继承权限。当你需要以交互方式单独读取大量文件时, SSHFS 尤为有用。
前期准备
- 两个 Linux 被配置为允许 SSH 访问的服务器。其中一个可以是本地机器而不是云服务器。你可以按照我们的《初始服务器设置指南》,通过直接从一台机器连接到另一台机器来实现这一点。
第1步 - 安装 SSHFS
SSHFS 适用于大多数 Linux 发行版。在 Ubuntu 上,你可以使用 apt
来安装它。
首先,使用 apt update
来刷新你的软件包来源:
$ sudo apt update
然后,使用 apt install
来安装 sshfs
软件包。
$ sudo apt install sshfs
注意:SSHFS 可以通过使用名为 FUSE 的文件系统库安装在 Mac 或 Windows 上,提供了与 Linux 环境的互操作性。Mac 或 Windows 上的 SSHFS 将使用与本教程相同的概念和连接细节,但可能需要你使用不同的配置界面或安装第三方库。本教程将只涉及 Linux 上的 SSHFS,但这些步骤应该也适用于 Mac 或 Windows 的FUSE实现。 你可以从项目的 GitHub 仓库安装 Windows 版的 SSHFS。 可以从 macFUSE 项目安装 Mac 版的 SSHFS。
第2步 - 挂载远程文件系统
当你在 Linux 环境下挂载一个远程文件系统时,你首先需要一个空目录来挂载它。大多数 Linux 环境包括一个叫做 /mnt
的目录,如果你需要需要一个空目录,可以在其中创建子目录。
注意:在 Windows 上,远程文件系统有时会用自己的盘符(如 G:
)来挂载,而在Mac上,它们通常被挂载在 /Volumes
目录下。
使用 mkdir
命令在 /mnt
中创建一个名为 droplet
的子目录:
$ sudo mkdir /mnt/droplet
现在你可以使用 sshfs
挂载一个远程目录了。
$ sudo sshfs -o allow_other,default_permissions sammy@your_other_server:~/ /mnt/droplet
这个命令的各个选项表现如下:
-o
出现在各种挂载选项之前(这一点与通常用于非 SSH 的磁盘挂载的mount
命令相同)。在这个例子中,你使用allow_other
来允许其他用户访问这个挂载(这样它就像一个正常的磁盘挂载,因为sshfs
默认是不允许这样做的),还有default_permissions
(这样它就使用普通的文件系统权限)。sammy@your_other_server:~/
提供到远程目录的完整路径,包括远程用户名sammy
、远程服务器your_other_server
和路径,在这里~/
为远程用户的主目录。这与 SSH 或 SCP 使用的语法相同。/mnt/droplet
是被用作装载点的本地目录的路径。 如果你收到这样一条信息:Connection reset by peer
,请确保你已经把你的 SSH 密钥复制到了远程系统。sshfs
在后台使用一个普通的 SSH 连接,如果这是你第一次通过 SSH 连接到远程系统,你可能被提示接受远程主机的密钥指纹。
Output
The authenticity of host '164.90.133.64 (164.90.133.64)' can't be established.
ED25519 key fingerprint is SHA256:05SYulMxeTDWFZtf3/ruDDm/3mmHkiTfAr+67FBC0+Q.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? Yes
注意:如果你在不使用 sudo
权限的前提下用 SSHFS 挂载一个远程目录,你可以使用 sudo groupadd fuse
在你的本地机器上创建一个名为 fuse
的用户组,然后使用 sudo usermod -a -G fuse sammy
将你的本地用户加入该组。
你可以使用 ls
来列出挂载目录中的文件,看它们是否与远程目录的内容相匹配。
$ ls /mnt/droplet
Output
remote_file1 remote_file2
现在你就可以处理远程服务器上的文件了,就像把远程服务器当做一个连接到本地机器的物理设备一样。例如,如果你在 /mnt/droplet
目录下创建一个文件,该文件将出现在你的虚拟服务器上。同样,你可以把文件复制到 /mnt/droplet
文件夹中或从该文件夹中复制出来,它们将在后台上传到你的远程服务器或从你的远程服务器上传。
值得注意的是,mount
命令只是为你当前的会话挂载远程磁盘。如果虚拟服务器或本地机器关机或重启,你将需要使用相同的过程来再次挂载它。
如果你不再需要这个挂载,你可以用 umount
命令卸载它:
$ sudo umount /mnt/droplet
在最后一步,你将学习如何配置永久挂载。
第3步 - 永久挂载远程文件系统
与其他类型的磁盘和网络挂载一样,你可以使用 SSHFS 配置一个永久挂载。要做到这一点,你需要在一个名为 /etc/fstab
的文件中添加一个配置项,该文件会在启动时处理 Linux 文件系统挂载。
使用 nano
或你喜欢的文本编辑器打开 /etc/fstab
:
$ sudo nano /etc/fstab
在该文件的末尾,添加一个这样的条目: /etc/fstab
…
sammy@your_other_server:~/ /mnt/droplet fuse.sshfs noauto,x-systemd.automount,_netdev,reconnect,identityfile=/home/sammy/.ssh/id_rsa,allow_other,default_permissions 0 0
永久挂载通常需要一些不同的选项来确保它们的行为符合预期。选项表现如下:
sammy@your_other_server:~/
还是远程路径,就像以前一样。/mnt/droplet
还是本地路径。fuse.sshfs
指定了用于挂载这个远程目录的驱动。noauto,x-systemd.automount,_netdev,reconnect
是一组选项,它们共同作用于网络驱动器的永久挂载,以确保在本地机器或远程机器的网络连接断开的情况下表现得“优雅(即让用户无感知)”。identityfile=/home/sammy/.ssh/id_rsa
指定一个本地 SSH 密钥的路径,这样远程目录就可以自动挂载。注意,这个例子假设你的本地和远程用户名都是sammy
——这里指的是本地路径。指定本地 SSH 密钥路径是必要的,因为/etc/fstab
实际上是以 root 身份运行的,而且这样才能知道哪个用户名的 SSH 配置要检查远程服务器所信任的密钥。allow_other,default_permissions
使用与上面mount
命令相同的权限。0 0
标志着远程文件系统在出现错误时不应被本地机器转储或验证。在挂载本地磁盘时,这些选项可能有所不同。 保存并关闭该文件。如果你使用的是nano
,按Ctrl+X
,然后在提示时按Y
,再按ENTER
。然后你可以通过重启你的本地机器来测试/etc/fstab
的配置,例如使用sudo reboot now
,并验证挂载是否被自动重新创建。 应该注意的是,永久的 SSHFS 挂载不一定总是受欢迎的选择。SSH 连接和 SSHFS 的性质意味着它通常更适合于临时的、一次性的解决方案,而 SMB 或 NFS 挂载的配置可能会有更多冗余和其他选项。也就是说,SSHFS 非常灵活,更重要的是,它作为一个成熟的文件系统驱动,允许你在/etc/fstab
中像配置其他磁盘挂载一样配置它,并根据需要使用它。不过要小心,不要意外通过 SSH 暴露出你不想暴露的那些远程文件系统。
结语
在本教程中,你配置了从一个 Linux 环境到另一个环境的 SSHFS 挂载。尽管它不是生产部署中最具扩展性或性能最佳的解决方案,但 SSHFS 只需经过最少的配置就能变得非常有用。