SSHFS

来自 ArchWiki

SSHFS 是一个基于 FUSE 的文件系统客户端,用于通过 Secure Shell 连接挂载远程目录。

安装

安装 sshfs 软件包。

提示

用法

注意: 建议 以普通用户身份(而不是 root 用户)运行 SSHFS。为了实现这一点,挂载点必须由用户拥有。有关详细信息,请参阅 mount.fuse(8) § SECURITY

挂载

为了能够挂载目录,SSH 用户需要能够访问它。调用 sshfs 以挂载远程目录

$ sshfs [user@]host:[dir] mountpoint [options]

例如

$ sshfs myuser@mycomputer:/remote/path /local/path -C -p 9876

这里 -p 9876 指定端口号,-C 启用压缩。有关更多选项,请参阅 #选项 部分。

未指定时,远程路径默认为远程用户主目录。默认用户名和选项可以在 ~/.ssh/config 中按主机预定义,以简化 sshfs 的使用。有关更多信息,请参阅 OpenSSH#客户端用法

如果需要,SSH 将询问密码。如果您不想一天多次输入密码,请参阅 SSH 密钥

卸载

要卸载远程系统

$ fusermount3 -u mountpoint

示例

$ fusermount3 -u /local/path

选项

完整的选项列表可以在 sshfs(1)mount.fuse(8) 中找到。

用户 ID 映射

sshfs 可以自动在本地和远程用户 ID 之间转换。使用 idmap=user 选项将连接用户的 UID 转换为远程用户 myuser (GID 保持不变)

$ sshfs myuser@mycomputer:/remote/path /local/path -o idmap=user

如果您需要更多关于 UID 和 GID 转换的控制,请查看选项 idmap=fileuidfilegidfile

allow_root 或 allow_other

提示:mount.fuse(8) § SECURITY 中暗示的那样,您应该小心使用这些选项。
$ sshfs myuser@mycomputer:/remote/path /local/path -o allow_other,default_permissions,uid=1002,gid=1002
  • allow_other - 允许挂载者(即 root 用户)以外的其他用户访问共享。
  • allow_root - 类似于 allow_other,但文件访问仅限于挂载文件系统的用户和 root 用户。

allow_root 和 allow_other 是互斥的。此外,您需要编辑 /etc/fuse.conf 并取消注释字符串 user_allow_other 以允许所有用户使用这些选项。

  • default_permissions - 也可能被使用,因为 fuse 默认情况下不检查文件访问权限。即,使用远程文件系统上的实际权限。这允许禁止访问否则由 allow_other 授予的每个人。

更改挂载点所有权

  • uid, gid - 将报告的文件所有权设置为给定值;uid 是您的用户的数字用户 ID,gid 是您的用户的数字组 ID。

技巧与窍门

Chroot

您可能希望将特定用户限制为远程系统上的特定目录。这可以通过编辑 /etc/ssh/sshd_config 来完成

/etc/ssh/sshd_config
.....
Match User someuser
       ChrootDirectory /chroot/%u
       ForceCommand internal-sftp
       AllowTcpForwarding no
       X11Forwarding no
.....
注意: chroot 目录必须由 root 用户拥有,否则您将无法连接。

另请参阅 SFTP chroot。有关更多信息,请查看 sshd_config(5) 手册页中的 MatchChrootDirectoryForceCommand

systemd

与其他文件系统挂载类似,请参阅 systemd.mount(5) 以及可能的 systemd.automount(5)。由于 FUSE 系统及其机制,您应该使用 用户单元。使用公钥身份验证设置 SSH。

作为用户单元

本文或章节需要语言、wiki 语法或风格方面的改进。请参阅 Help:Style 以供参考。

原因: 添加一个可工作的用户 .mount 单元的示例。(在 Talk:SSHFS 中讨论)

foo.mount 放在 ${XDG_CONFIG_HOME}/systemd/user/ 中。

启动 该单元,像往常一样使用 --user 选项。

注意: systemd.automount(5) § DESCRIPTION 说:"请注意,Linux 上的自动挂载支持是特权的,因此自动挂载单元仅在系统服务管理器(和 root 用户的用户服务管理器)中可用,而不在非特权用户的服务管理器中可用。"
使用带密码的 ssh 密钥
注意: 用户必须手动输入 ssh 密钥的密码,这并非旨在在没有任何用户交互的情况下工作。

请参阅 SSH 密钥#使用 systemd 用户启动 ssh-agent

生成 .mount 和 .automount 文件

本文或章节正在考虑移除。

原因:#systemd root 和多用户 中解释了在 fstab 中使用 sshfs,并附带了很大的警告。(在 Talk:SSHFS 中讨论)

在 /etc/fstab 中创建一个条目 至少带有 _netdevx-systemd.automount 仅在您需要自动挂载功能时才必要。

/etc/fstab
remoteuser@remotehost:/remote/folder /home/foo/local_folder fuse.sshfs _netdev,x-systemd.automount,x-systemd.idle-timeout=5min,rw   0   0
提示: 如果您可以使用 sshfs 命令手动挂载远程文件系统,那么您可能可以从 /proc/mounts 复制最后一行并插入突出显示的部分。
# systemctl daemon-reload

所有生成的文件都在 /run/systemd/generator/ 中 daemon-reload 命令之后。对于用户单元,您可以复制您需要的文件并删除 fstab 行并重新加载 systemd

编写 .mount 和 .automount 文件

本文或章节需要语言、wiki 语法或风格方面的改进。请参阅 Help:Style 以供参考。

原因: 这似乎不合适,systemd root 部分从下面开始。(在 Talk:SSHFS 中讨论)

您将需要 编写两个 systemd 单元:一个挂载单元和一个可选的自动挂载单元。启用 自动挂载单元并保持挂载单元本身禁用将不会阻止启动,并且仅在尝试访问文件系统时挂载一次。这些文件需要与挂载点完全同名,并使用 "-" 符号分隔路径中的文件夹。

挂载单元,需要与挂载点完全同名(此处,/mnt/data 变为 mnt-data

systemd-escape -p --suffix=mount "/mnt/data/"
mnt-data.mount
/etc/systemd/system/mnt-data.mount
[Unit]
Description=SSHFS (remote.local)
Before=remote-fs.target

[Mount]
What=user@remote.local:/mnt/data
Where=/mnt/data
Type=fuse.sshfs
Options=_netdev,rw,nosuid,allow_other,uid=1000,gid=1000,default_permissions,follow_symlinks,idmap=user,identityfile=/home/user/.ssh/id_ed25519

[Install]
WantedBy=remote-fs.target
WantedBy=multi-user.target

自动挂载单元文件也需要与挂载点完全同名

/etc/systemd/system/mnt-data.automount
[Unit]
Description=Automount /mnt/data

[Automount]
Where=/mnt/data
TimeoutIdleSec=0

[Install]
WantedBy=multi-user.target

systemd root 和多用户

本文或章节的事实准确性存在争议。

原因: 在家庭环境中,您想要使用这些技巧的用例很少,但是您总是必须弯曲一些东西(例如 allow_other,ssh-keys ...)。使用 fstab 在启动时挂载它而无需密码可能不是真的必要。考虑为所有需要它的用户使用 systemd 用户单元。(在 Talk:SSHFS 中讨论)

自动挂载可以在启动时或按需(访问目录时)发生。对于两者,设置都在 fstab 中进行。

警告: 私有 SSH 密钥不能受密码保护才能使自动挂载工作(当触发挂载时,没有界面提示用户输入密码)。将私钥未加密地保存在磁盘上具有安全隐患。
注意: 请记住,自动挂载是通过 root 用户完成的,因此您不能使用在普通用户的 .ssh/config 中配置的主机。

要让 root 用户使用普通用户的 SSH 密钥,请在 IdentityFile 选项中指定其完整路径。

最重要的是,在客户端机器上以 root 用户身份手动使用每个 sshfs 挂载至少一次,以便将主机的签名添加到客户端的 /root/.ssh/known_hosts 文件中。这也可以通过手动将一个或多个 SSH 服务器的公钥(/etc/ssh/ssh_host_*key.pub 文件)附加到 /root/.ssh/known_hosts 来完成。

按需

使用 systemd,可以使用 /etc/fstab 条目实现按需挂载。

示例

user@host:/remote/path /local/path  fuse.sshfs x-systemd.automount,_netdev,users,idmap=user,IdentityFile=/home/user/.ssh/id_rsa,allow_other,reconnect 0 0

这里重要的挂载选项是 x-systemd.automount,_netdev

  • x-systemd.automount 完成按需魔法
  • _netdev 告诉它这是一个网络设备,而不是块设备(没有它,可能会发生“No such device”错误)

另请参阅 fstab#使用 systemd 自动挂载

注意: 编辑 /etc/fstab 后,重新加载 systemd 配置和所需的服务,可以通过运行 systemctl list-unit-files --type automount 找到这些服务。

启动时

一个关于如何使用 sshfs 通过 /etc/fstab 挂载远程文件系统的示例

user@host:/remote/path  /local/path  fuse.sshfs  _netdev  0  0

fstab 行为例

llib@192.168.1.200:/home/llib/FAH  /media/FAH2  fuse.sshfs  _netdev  0  0

如果您使用未受密码保护的用户的 SSH 密钥,则上述操作将自动工作。请参阅 使用 SSH 密钥

如果您想与多个用户一起使用 sshfs,请添加以下选项

user@domain.org:/home/user  /media/user   fuse.sshfs    allow_other,_netdev    0  0

为了确保在尝试挂载之前网络可用,不仅要设置 _netdev 挂载选项很重要,还要将 --any 或特定的 --interface 添加到您的网络管理器的相应 wait-online 服务

安全用户访问

本文或章节的事实准确性存在争议。

原因: 安全用户访问 具有误导性,allow_other 选项移除了一些“安全”方面 (mount.fuse(8) § SECURITY)。(在 Talk:SSHFS 中讨论)

当通过 fstab 自动挂载时,文件系统通常将由 root 用户挂载。默认情况下,如果您希望以普通用户身份访问并限制其他用户的访问,这将产生不希望的结果。

一个示例挂载点配置

user@host:/remote/path /local/path  fuse.sshfs noauto,x-systemd.automount,_netdev,user,idmap=user,follow_symlinks,identityfile=/home/user/.ssh/id_rsa,allow_other,default_permissions,uid=USER_ID_N,gid=USER_GID_N 0 0

请参阅 #allow_root 或 allow_other 以了解所用选项的解释。

故障排除

检查清单

首先阅读 OpenSSH#检查清单。进一步需要检查的问题是

  1. 您的 SSH 登录是否从服务器的 /etc/issue 文件发送了额外的信息?这可能会使 SSHFS 感到困惑。您应该临时禁用服务器的 /etc/issue 文件
    $ mv /etc/issue /etc/issue.orig
  2. 请记住,您在网上找到的大多数与 SSH 相关的故障排除文章都与 systemd 无关。通常 /etc/fstab 定义错误地以以下内容开头
    sshfs#user@host:/mnt/server/directory ... fuse ...
    而不是使用以下语法
    user@host:/mnt/server/directory ... fuse.sshfs ... x-systemd, ...
  3. 检查服务器源目录及其内容的所有者是否为服务器用户。
    $ chown -R user_s: /mnt/servers/directory
  4. 服务器的用户 ID 可能与客户端的不同。显然,用户名必须相同。您只需要关心客户端的用户 ID。SSHFS 将使用以下挂载选项为您转换 UID
    uid=USER_C_ID,gid=GROUP_C_ID
  5. 检查客户端的目标挂载点(目录)是否归客户端用户所有。此目录应具有与 SSHFS 挂载选项中定义的用户 ID 相同的用户 ID。
    $ chown -R user_c: /mnt/client/directory
  6. 检查客户端的挂载点(目录)是否为空。默认情况下,您不能将 SSHFS 目录挂载到非空目录。

连接被对端重置

  • 如果您尝试使用主机名访问远程系统,请尝试使用其 IP 地址,因为这可能是域名解析问题。请确保使用服务器详细信息编辑 /etc/hosts
  • 确保您的用户可以登录到服务器(尤其是在使用 AllowUsers 时)。
  • 确保在远程系统上的 /etc/ssh/sshd_config 中启用了 Subsystem sftp /usr/lib/ssh/sftp-server
  • 如果您使用非默认密钥名称并将其作为 -i .ssh/my_key 传递,这将不起作用。您必须使用 -o IdentityFile=/home/user/.ssh/my_key,并使用密钥的完整路径。
  • 如果您的 /root/.ssh/config/ 是一个符号链接,您也会收到此错误。请参阅 这个 Serverfault 主题
  • 添加选项 sshfs_debug(如 sshfs -o sshfs_debug user@server ... 中所示)可以帮助解决问题。
  • 如果这没有显示任何有用的信息,您也可以尝试添加选项 debug
  • 如果您尝试 sshfs 进入运行 DD-WRT 或类似系统的路由器,这里有一个 解决方案。(请注意,可以使用 -osftp_server=/opt/libexec/sftp-server 选项来代替修补 dropbear,用于 sshfs 命令)。
  • 如果您仅在启动时看到此情况,则可能是 systemd 尝试在网络连接可用之前进行挂载。为您的网络管理器启用适当的 wait-online 服务 可以解决此问题。
  • 旧论坛帖子:sshfs: Connection reset by peer
注意: 当为 sshfs 提供多个选项时,它们必须以逗号分隔。例如:sshfs -o sshfs_debug,IdentityFile=/path/to/key user@server ...)。

远程主机已断开连接

如果您在尝试使用 sshfs 后直接收到此消息

  • 首先确保远程机器已安装 sftp!如果没有,则无法工作。
  • 然后,检查远程机器上 /etc/ssh/sshd_configSubsystem sftp 的路径是否有效。

fstab 挂载问题

要获得详细的调试输出,请将以下内容添加到挂载选项中

ssh_command=ssh\040-vv,sshfs_debug,debug
注意: 在这里,\040 表示空格,fstab 使用空格来分隔字段。

为了能够运行 mount -av 并查看调试输出,请删除以下内容

 noauto,x-systemd.automount

某些目录为空

默认情况下,sshfs 不支持符号链接。如果这些目录恰好是符号链接,请使用

$ sshfs user@host:/remote/path /local/path -o follow_symlinks

文件未刷新

如果您在远程看到旧内容,请考虑使用选项 dir_cache=no

$ sshfs user@host:/remote/path /local/path -o dir_cache=no

快速网络上的传输速度受限

如果您观察到传输速度低于您的网络性能,并且文件复制源一方的 CPU 使用率很高,请禁用压缩(删除 -C 选项或设置 -o compression=no)。

另请参阅