大家可能知道并用过在linux上通过smb,nfs来进行远程文件系统的共享,可是大家是否知道我们现在还可以通过ssh来进行远程文件系统的共享。你可能会说这有什么希奇的,不就是ssh远程登录嘛,再不就是sftp或者scp之类的方式,总之,这些东西熟的不能再熟了。可是我在这里要说的可不是这些东西,我要说的是通过sshfs来将远程主机的文件系统挂载到本地,之后就可以像使用本地文件系统一样使用远程文件系统了。看到这里,大家是否觉得有兴趣了呢?接下来让我们看看到底怎么来作到这点。
实际上,使用sshfs挂载远程主机的方法还不只一种,目前我知道的方法有三种,第一种是通过基于lufs的sshfs子系统来完成,第二种是通过基于fuse的sshfs程序来完成,而第三种直接通过内核支持的shfs模块就可以了。经测试,通过第二种方法来挂载的远程主机文件系统比第一种方法要稳定的多,而第三种方法是最简单也是跟系统接合最好的。第一种方法如果跟autofs来配合,可以更方便的挂载远程文件系统,不过在这样挂载的文件系统上直接打开歌曲或者电影之类的文件可能有些问题,我在以这种方式挂载的系统上听歌时,如果再对这个文件系统上的其他文件进行操作,歌曲就会停止播放。而通过后两种方法挂载的系统就没有这个问题。所以我们这里只说明后两种方法。第一种方法大家如果有兴趣可以自己研究。
这里以debian系统来作说明是因为我使用的系统是debian,我没有在其他linux系统上做过实验,但其他linux系统应该也是可以的。
一、通过sshfs挂载远程主机文件系统
首先,需要下载sshfs,这一步很简单:
# apt-get install sshfs |
另外它是基于fuse模块的,所以必须要保证你的内核模块里已经有了这个模块,debian系统的内核默认是没有编译这个模块的,不过安装这个模块在debian下很简单,首先下载fuse的源码包和工具包以及编译需要用到的程序。
# apt-get install fuse-source fuse-utils debconf-utils debhelper dpatch gettext html2text intltool-debian po-debconf devscripts kernel-package dpkg-dev module-assistant |
设置环境变量:
# export KVERS=$(uname -r) # export KSRC=/usr/src/kernel-headers-$KVERS |
下载内核头文件:
# apt-get install kernel-headers-$KVERS |
现在进入/usr/src内可以找到头文件和fuse模块的源码包,然后我们解压编译。
# cd /usr/src # tar jxvf fuse.tar.jz |
编译fuse模块:
# cd /usr/src/modules/fuse # debian/rules binary_modules |
好,完成编译,编译完的debian包可以在/usr/src/modules/(或者/usr/src/)中找到。
安装刚刚编译的fuse模块。
# dpkg -i /usr/src/modules/fuse*.deb |
好了现在第一步完成了。下面可以测试一下是否可以使用sshfs了。
首先创建一个挂载点(这里我以remotehost这个名字为例,你可以使用任何你喜欢的名字):
# mkdir /mnt/remotehost |
然后可以试试是否可以挂载远程主机文件系统了。首先我们要有一台可以通过ssh远程登录的机器,假设这台机器是192.168.1.1吧,它不需要作什么设置,只要保证它ssh服务是打开的,我们就可以挂载它的文件系统了。
# sshfs root@192.168.1.1:/ /mnt/remotehost -o sshfs_sync -o default_permissions,allow_other, allow_root,kernel_cache,hard_remove |
现在它可能会提示输入密码,输入ssh登录时需要的远程主机的root帐号密码就可以了。现在看一下是否挂载好了。
# cd /mnt/remotehost # ls |
如果挂载成功,现在应该可以看到远程机器的文件了。而且你如果使用X Window,你还可以通过文件管理器来浏览查看文件,就象使用本地硬盘一样方便了。
卸载文件系统也很简单,只需要输入:
# umount /mnt/remotehost |
就可以了。怎么样,不错吧?
怎么,你还觉得麻烦?是啊,现在每次都要通过命令行才能挂载,卸载,而且每次还都要输入密码,我也觉得好麻烦啊。如果能在开机时自动挂载,关机重启时自动卸载就方便了。别着急,下面我来介绍一种方法来实现这个愿望。此法乃原创,不足之处希望大家批评指正。
首先要解决的是怎样免去输入密码这一步,这个简单,在debian参考手册的9.5.3节──用更少的密码建立连接中可以查到。这里就不转载了。这里只就这个例子来说明一下。
首先要保证192.168.1.1上的/etc/ssh/sshd_config中设置了”PubkeyAuthentication yes”然后在本地以root帐号执行以下操作,之所以使用root帐号是因为挂载文件系统时需要用root帐号。
# ssh-keygen -t rsa # cat ~/.ssh/id_rsa.pub | ssh root@192.168.1.1 "cat - >>.ssh/authorized_keys" |
这里第一条命令执行时,可能让你输入passphrase,保留为空直接回车就可以了。而执行第二条命令时,需要输入远程系统root帐号的密码,这时必须输入正确的密码才能成功。
现在可以试试我们上面的操作是否起作用了。
# ssh root@192.168.1.1 |
如果不需要密码就已经登录了远程系统的话,那么恭喜你,成功了!现在退回到你自己的系统来继续完成下面最重要的工作吧,创建自动启动脚本。
进入/etc/init.d目录,创建下面两个文件。
第一个文件是mountsshfs,下面是文件内容。
#!/bin/sh # # mountsshfs Mount SSH filesystems. # # Version: @(#)mountsshfs 1.00-1 15-Apr-2005 andot@ujn.edu.cn # PATH=/sbin:/usr/sbin:/bin:/usr/bin export PATH # # Mount SSH file systems in /etc/sshfstab. # echo -n "Mounting SSH filesystems..." if [ -f /etc/sshfstab ] ; then ( cat /etc/sshfstab ; echo ) | sed -e '/^#/d' -e '/^$/d' | ( while read host mount_point sshfs_options fuse_options do sshfs $host $mount_point -o $sshfs_options -o $fuse_options done ) fi echo "done" : exit 0 |
第二个文件是umountsshfs,下面是文件内容。
#!/bin/sh # # umountsshfs Unmount SSH filesystems. # # Version: @(#)umountsshfs 1.00-1 15-Apr-2005 andot@ujn.edu.cn # PATH=/sbin:/usr/sbin:/bin:/usr/bin export PATH # # Unmount SSH file systems in /etc/mtab. # echo -n "Unmounting SSH filesystems..." if [ -f /etc/mtab ] ; then ( cat /etc/mtab ; echo ) | sed -e '/^#/d' -e '/^$/d' | ( while read host mount_point options do if echo $host | awk '{ if ( substr($0, 1, 6) == "sshfs#" ) exit 0; else exit 1 }' ; then umount $mount_point fi done ) fi echo "done" : exit 0 |
好了,接下来到/etc目录下来创建一个sshfstab,这个文件功能跟fstab类似,不过这里面只包含需要开机是挂载的sshfs文件系统,而不包括其他文件系统的信息。我们还是以上面的例子来创建这个文件:
# /etc/sshfstab: SSH file system information. # # <[user@]host:[dir]> root@192.168.1.1:/ /mnt/remotehost sshfs_sync default_permissions,allow_other,allow_root, kernel_cache,hard_remove |
这个文件中要挂载的系统可以包含多行,其中挂载点必须保证已经创建,上面的启动脚本中不包含创建挂载点这步。
好了现在可以用:
# /etc/init.d/mountsshfs |
来挂载所有的sshfs远程文件系统了。然后用:
# /etc/init.d/umountsshfs |
可以卸载所有已挂载的sshfs远程文件系统。现在我们要把它添加到启动里面去。在/etc/rc0.d,/etc/rc6.d中分别创建一个指向/etc/init.d/umountsshfs的软连接,注意软连接的名字关系到执行顺序。
# cd /etc/rc0.d # ln -s ../init.d/umountsshfs S15umountsshfs # cd /etc/rc6.d # ln -s ../init.d/umountsshfs S15umountsshfs |
在/etc/rc2.d,/etc/rc3.d,/etc/rc4.d,/etc/rc5.d中分别创建一个指向/etc/init.d/mountsshfs的软连接,注意软连接的名字关系到执行顺序。
# cd /etc/rc2.d # ln -s ../init.d/mountsshfs S85mountsshfs # cd /etc/rc3.d # ln -s ../init.d/mountsshfs S85mountsshfs # cd /etc/rc4.d # ln -s ../init.d/mountsshfs S85mountsshfs # cd /etc/rc5.d # ln -s ../init.d/mountsshfs S85mountsshfs |
好了。现在重新启动机器就可以了发现远程文件系统现在已经成了你的“本地”文件系统了!
二、通过shfs挂载远程主机文件系统
前面介绍的那种方法虽然可以在开机自动挂载,关机和重启可以自动卸载sshfs文件系统了,但是它不能用mount来直接指定-t参数来挂载,因此也不能直接加到/etc/fstab种,而且用df也不能列出那样的分区,所以你可能希望如果能像挂载普通分区那样挂载sshfs文件系统就好了。这也不是不可能的,下面介绍的这种方法就可以满足我们这个愿望,它是通过内核的shfs模块来实现的,它支持2.4.10以上和2.6的内核。这种方式我认为是最方便的。下面我们就看看怎么来使用它。
首先你要保证你的系统已经安装了shfs模块,如果你是默认的debian内核,它是没有这个模块的,但是不用着急,我们可以跟上面编译fuse模块那样去编译这个shfs模块,方法类似。因此下面只列出命令,不再详细解释了。
# apt-get install shfs-source shfs-utils debconf-utils debhelper dpatch gettext html2text intltool-debian po-debconf kernel-package module-assistant # export KVERS=$(uname -r) # export KSRC=/usr/src/kernel-headers-$KVERS # apt-get install kernel-headers-$KVERS # cd /usr/src # tar jxvf shfs.tar.jz # cd /usr/src/modules/shfs # debian/rules binary_modules # dpkg -i /usr/src/modules/shfs*.deb |
好了,现在shfs模块已经编译安装好了,现在可以直接用mount命令来挂载分区了。
# mount -t shfs root@192.168.1.1:/ /mnt/remotehost -o rmode=755,preserve |
这里假设/mnt/remotehost目录已经按照前面那种方法建好了。现在可以跟上面一样使用/mnt/remotehost来存取远程主机的文件系统了,是不是很方便啊?
好了,如果想要开机挂载,关机重启卸载就更方便了。首先还是要做免去ssh登录密码输入这步,这同上面那种方法中介绍的一样,这里就不在重复了。下面假设这步工作已经完成了,然后只需要修改一下/etc/fstab就可以了。而不再需要自己去编写什么mountsshfs,umountsshfs脚本,也不在需要建立/etc/sshfstab这个文件了。
root@192.168.1.1:/ /mnt/remotehost shfs rmode=755,preserve 0 0 |
添加上面这行到/etc/fstab中,就可以直接开机挂载了,关机和重启卸载了,非常简单。