SSHFS:通过 SSH 超级轻松的文件访问

作者:Matthew E. Hoskins

像 scp、sftp 和 rsync 这样的工具允许我们在这些帐户之间轻松安全地复制文件。但是,如果我们不想在使用文件之前将文件复制到本地系统,该怎么办?通常,这将是传统网络文件系统(如 NFS、OpenAFS 或 Samba)的用武之地。不幸的是,设置这些网络文件系统需要在两个系统上都具有管理员权限。

进入 SSHFS 和 FUSE

幸运的是,只要您具有 SSH 访问权限,就可以使用 SSHFS 挂载和使用远程目录树,就像它们是本地目录一样。SSHFS 在远程端不需要任何特殊软件,只需要一个支持 SFTP 扩展的现代 SSH 服务器。所有现代 Linux 发行版都支持此扩展,该扩展已添加到 2000 年 11 月发布的 OpenSSH 2.3.0 版本中。

SSHFS 构建于 FUSE 用户空间文件系统框架项目之上。FUSE 允许用户空间软件(在本例中为 SSH)向用户呈现虚拟文件系统接口。这类似于 /proc 和 /sys 文件系统如何以目录树中文件的形式呈现内核内部信息。SSHFS 连接到远程系统,并执行所有必要的操作,以提供远程文件的常规文件系统接口的外观和感觉。

安装 SSHFS 和 FUSE

我在将要挂载远程目录的工作站上使用 Fedora Core 4。远程系统也是 Fedora Core 4,但是任何运行带有 SFTP 扩展的现代 SSH 服务器的 *NIX 系统都可以工作。您的 Linux 内核还必须启用用户空间文件系统功能,无论是内置的还是作为模块。

SSHFS 所需的所有软件都可以作为可使用 yum 为 Fedora Core 4 安装的软件包获得。只需运行

$ yum install fuse-sshfs

这将自动安装 SSHFS、FUSE 和 fuse-lib 依赖项。您也可以从源代码构建 SSHFS,但稍后会详细介绍。

在您可以以非 root 用户身份使用 SSHFS 或任何其他基于 FUSE 的文件系统之前,您必须首先将这些用户添加到 fuse 组。在我的例子中,我的用户名是 matt。这可以从命令行以 root 身份使用以下命令完成

$ usermod  -a -G fuse matt

fuse 组允许您限制哪些用户可以使用基于 FUSE 的文件系统。这很重要,因为 FUSE 安装了 setuid 程序,这始终带有安全隐患。在高度安全的系统上,应该评估和控制对此类程序的访问。

安装和配置软件后,我们就可以试用了。为了演示基本功能,我将连接到名为 my.randombox.com 的远程系统。SSHFS 的默认操作是挂载远程用户的 home 目录;这是 SSHFS 最常见的用途。就像挂载任何其他文件系统一样,您需要一个名为挂载点的空目录,远程文件系统将挂载在该目录下。我创建了一个名为 randombox_home 的挂载点,然后调用 sshfs 命令来挂载远程文件系统。以下是操作方法

$ cd $HOME
$ mkdir randombox_home
$ sshfs  matt@my.randombox.com:  randombox_home
matt@my.randombox.com's password: ************
$ ls -l randombox_home/
-rw-r-----  1 matt users     7286 Feb 11 08:59 sshfs.article.main.txt
drwx------  1 matt users     2048 Mar 21  2001 projects
drwx------  1 matt users     2048 Dec  1  2000 Mail
drwxr-xr-x  1 matt users     4096 Jun  8  2002 public_html
$ cp ~/my_web_site/index.html randombox_home/public_html/

就这样。我在 my.randombox.com 上的 home 目录现在已挂载到本地工作站上的 randombox_home 目录下。在后台,FUSE、SSHFS 和远程 SSH 服务器正在完成所有繁重的工作,以使我的远程 home 目录看起来像任何其他本地文件系统一样。如果您想挂载 home 目录以外的目录,只需将其放在 sshfs 命令行上的冒号之后。您甚至可以指定 / 来挂载整个远程系统。当然,您只能访问远程用户帐户具有权限的文件和目录。其他所有内容都将收到“权限被拒绝”消息。下面显示了一个示例

$ cd $HOME
$ mkdir randombox_slash
$ sshfs  matt@my.randombox.com:/  randombox_slash
matt@my.randombox.com's password:
$ ls -l randombox_slash/
total 0
drwxr-xr-x  1 root root   4096 Nov 15 10:51 bin
drwxr-xr-x  1 root root   1024 Nov 16 07:11 boot
drwxr-xr-x  1 root root 118784 Jan 26 08:35 dev
drwxr-xr-x  1 root root   4096 Feb 17 10:37 etc
drwxr-xr-x  1 root root   4096 Nov 29 09:30 home
drwxr-xr-x  1 root root   4096 Jan 24  2003 initrd
drwxr-xr-x  1 root root   4096 Nov 15 10:53 lib
drwx------  1 root root  16384 Nov 11 10:21 lost+found
drwxr-xr-x  1 root root   4096 Nov 11 10:38 mnt
drwxr-xr-x  1 root root   4096 Jan 24  2003 opt
dr-xr-xr-x  1 root root      0 Jan 26 08:11 proc
drwx------  1 root root   4096 Mar  3 09:34 root
drwxr-xr-x  1 root root   8192 Nov 15 13:50 sbin
drwxrwxrwt  1 root root   4096 Mar  5 18:41 tmp
drwxr-xr-x  1 root root   4096 Nov 11 10:55 usr
drwxr-xr-x  1 root root   4096 Jan 20 08:16 var
$ cat randombox_slash/etc/shadow
cat: randombox_slash/etc/shadow: Permission denied
$ ls -l randombox_slash/root/
ls: reading directory randombox_slash/root/: Permission denied
total 0
$ ls -l randombox_slash/home/matt/
-rw-r-----  1 matt users     7286 Feb 11 08:59 sshfs.article.main.txt
drwx------  1 matt users     2048 Mar 21  2001 projects
drwx------  1 matt users     2048 Dec  1  2000 Mail
drwxr-xr-x  1 matt users     4096 Jun  8  2002 public_html
$
自动化连接

从上面的示例中可以看出,我需要输入密码才能完成与远程系统的 SSH 连接。这可以通过在本地和远程用户帐户之间创建信任关系来消除。这并非在所有情况下都适用,因为它本质上使帐户从安全角度来看是等效的。一个帐户上的任何恶意活动都可能通过信任传播到其他系统,因此请谨慎并充分了解设置信任关系的含义。要开始设置此功能,您需要创建一个 SSH 密钥对,其中包括分别名为 id_rsa 和 id_rsa.pub 的公钥和私钥文件。

公钥被复制到远程系统并放置在 $HOME/.ssh/authorized_keys 文件中。某些系统可能除了 authorized_keys 之外或代替 authorized_keys 使用文件名 authorized_keys2。

这允许任何拥有私钥的用户在没有密码的情况下进行身份验证。我们使用以下命令创建密钥对ssh-keygen。文件会自动放置在本地系统上的 $HOME/.ssh 目录中的正确位置。由于我们已经挂载了我的远程 home 目录,因此将公钥附加到 authorized_keys 文件非常容易。以下是所需的所有步骤(假设您创建了等效于 randombox_home 目录并将其挂载)

$ cd $HOME
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/matt/.ssh/id_rsa): <ENTER>
Enter passphrase (empty for no passphrase):  <ENTER>
Enter same passphrase again:  <ENTER>
Your identification has been saved in /home/matt/.ssh/id_rsa.
Your public key has been saved in /home/matt/.ssh/id_rsa.pub.
The key fingerprint is:
fa:e7:7c:e1:cb:7b:66:8b:67:07:05:99:7f:05:b9:4a matt@myworkstation
$ mkdir randombox_home/.ssh
$ chmod 700 randombox_home/.ssh
$ cat .ssh/id_rsa.pub >> randombox_home/.ssh/authorized_keys
$ chmod 600 randombox_home/.ssh/authorized_keys

在上面的示例中,我们使用空密码短语创建密钥对,然后将公钥附加到远程 home 目录中的 authorized_keys 文件,并设置权限。完成此操作后,我不再需要在连接到远程帐户时键入密码。为了测试这一点,我们首先使用以下命令卸载远程 home 目录

$ fusermount -u randombox_home

为了测试信任关系,我们可以尝试在远程系统上运行 uptime 命令

$ ssh matt@my.randombox.com uptime
12:20:40  up 38 days,  4:12,  0 users,  load average: 0.11, 0.04, 0.01

很好,不需要密码。信任关系工作正常。如果您在使此信任关系工作方面遇到问题,请检查两个系统上 .ssh 中文件的权限。很多时候,宽松的权限会阻止 SSH 使用密钥文件。此外,请查看 syslog 日志文件。OpenSSH 的 sshd 服务器将消息记录到 syslog 中,这通常有助于诊断密钥文件问题。您可能需要在 sshd_config 文件(通常位于 /etc/ssh/ 中)中提高日志记录详细程度。

您还可以通过在上面的示例中运行带有 -vvv 选项的 ssh 来调试连接以提高详细程度。现在,让我们再次挂载远程目录。这次它不会提示我输入密码

$ cd $HOME
$ mkdir randombox_home
$ sshfs  matt@my.randombox.com:  randombox_home
$ ls -l randombox_home/
-rw-r-----  1 matt users     7286 Feb 11 10:33 sshfs.article.main.txt
drwx------  1 matt users     2048 Mar 21  2001 projects
drwx------  1 matt users     2048 Dec  1  2000 Mail
drwxr-xr-x  1 matt users     4096 Jun  8  2002 public_html
与 GNOME 桌面集成

在最后一个示例中,我们配置并自动化了远程目录的非交互式挂载。由于我们不再被提示输入密码,我们可以将 SSHFS 挂载集成到脚本中,或者更好的是集成到 GNOME 桌面中。要配置 GNOME 自动挂载我们的远程 home 目录,我们将 SSHFS 挂载命令配置为会话启动程序。这是在“会话首选项”对话框中完成的。导航到“桌面”→“首选项”→“更多首选项”→“会话”->“添加”,然后如图 1 所示填写对话框。

SSHFS: Super Easy File Access over SSH

图 1. 设置 GNOME 启动命令以挂载 SSHFS 共享。

下次登录时,GNOME 会自动为我挂载远程目录,如图 2 所示。

SSHFS: Super Easy File Access over SSH

图 2. GNOME 自动挂载远程目录。

请注意,GNOME 在退出会话时并不可靠地终止此命令。您可以使用fusermount -u randombox_home命令手动卸载远程目录。另一种选择是通过修改 $HOME/.Xclients-default 文件来自动化卸载,以按如下方式运行 fusermount 命令

#!/bin/bash
# (c) 2001 Red Hat, Inc.

WM="gnome-session"
WMPATH="/usr/bin /usr/X11R6/bin /usr/local/bin"

# Kludged to run fusermount upon gnome logout.  20060301-MEH
for p in $WMPATH ; do
     [ -x $p/$WM ] && $p/$WM; fusermount  -u randombox_home; exit 0
done

exit 1

请注意,每次运行 switchdesk 实用程序时,.Xclients-default 文件都会被重写。每次使用 switchdesk 实用程序更改默认桌面窗口管理器时,都必须修改此文件。

最后,您可以将适当的 sshfs 命令添加到适合您的发行版的启动文件中。这样,您的系统将在每次启动桌面时自动挂载所有 SSHFS 目录。

从源代码构建 SSHFS

如果您的特定 Linux 发行版未预先打包 SSHFS,或者您只是想从源代码构建它,这也非常容易。首先,确认您已安装内核模块开发所需的任何文件或软件包。您需要这些来构建 FUSE 内核模块。然后,从 SourceForge 下载 FUSE 和 SSHFS 的最新源代码 tarball(请参阅在线资源)。将下载的 tarball 文件放在临时目录中,然后在该目录中使用以下命令构建和安装

$ tar -xzf fuse-2.5.2.tar.gz
$ cd fuse-2.5.2
$ ./configure --prefix=/usr
$ make
$ su  -c "make install"
$ cd ..
$ tar -xzf sshfs-fuse-1.5.tar.gz
$ cd sshfs-fuse-1.5
$ ./configure --prefix=/usr
$ make
$ su  -c "make install"

安装完所有内容后,您就可以执行之前介绍的任何示例了。安装后,sshfs 和 fusermount 命令将安装在 /usr/bin 中。

结论

SSHFS 和 FUSE 允许挂载和使用任何远程存储,就像任何其他文件系统一样。如果您可以使用 SSH 登录,您就拥有所需的所有访问权限。

正如我之前所说,FUSE 是一个用于创建用户空间文件系统的框架。SSHFS 只是冰山一角。还有基于 FUSE 的文件系统可以透明地加密您的文件 (EncFS)、浏览蓝牙设备 (BTFS) 或将 CVS 存储库挂载为文件系统 (CvsFS)。也许您想知道如何处理 Gmail 帐户中的所有可用空间?好吧,GmailFS 允许您挂载您的 Gmail 帐户并像本地文件系统一样使用它。请参阅 FUSE 网站以获取这些和更多精彩项目,或者您可能想编写自己的项目。FUSE 具有 Perl、Python、TCL、C、C#、Ruby 和其他语言的语言绑定。

本文的资源: /article/8943

Matthew E. Hoskins 是新泽西理工学院的高级 UNIX 系统管理员,他在那里维护许多公司管理系统。他喜欢尝试使各种不同的系统和软件协同工作,通常使用薄薄的一层 Perl(在本地称为“MattGlue”)。不编写系统时,他经常可以在厨房里找到黑客技术。Matt 是专业记者协会的成员。他渴望听到您的反馈,可以通过 matt@njit.edu 与他联系。

加载 Disqus 评论