利用SSH Filesystem实现远程文件系统

     远程文件系统的访问有很多种不同的实现方式,一些常见的连接方式比其它特定情况下的更有用。最著名的一个例子就是微软的通用互联网文件系统(CIFS),它可以容许微软Windows“映射网络驱动器”并利用资源管理器对网络进行“浏览”。另一个是最早由太阳计算机系统开发的网络文件系统(NFS),作为美国电话电报公司开发的UNIX系统配置已经有15年的历史了。尽管还存在几十种其他的选择,但这两种系统占据了网络文件系统的主流。NFS 默认要在拥有 root 权限下才能挂载 (mount) 进来,另外则是使用 NFS 使用 RPC ( portmap 或 rpcbind ) 服务来做端口映射 (Port Mapping),也代表防火墙也要多一层设置,为了安全总有那么一点不方便。对于安装了Openssh的系统来说,实际上这包含了几乎所有的开源类Unix操作系统,SSH Filesystem—作为可验证的方便安全的网络文件系统,是用来访问远程计算机上存储数据的完美选择,甚至于连在 Windows 下都可以自由挂载远程 Linux 账号下的任意一个文件夹,真的非常方便。

     SSH Filesystem是基于ssh的,所以需要在客户端计算机上安装和使用sshFS的话,就需要安装Openssh。几乎所有的Linux主要发行版本和BSD Unix操作系统,在默认配置下都已经安装了Openssh的,所以你不会需要单独安装它。此外,服务器端—你希望能够从本地客户端系统访问的计算机中的文件系统—需要运行Openssh服务器进程。

SSH Filesystem也是基于FUSE,也就是所谓的“用户空间文件系统”。FUSE在类Unix系统中提供了一个API,可以用于建立高级别的文件系统,并且可以实现不需要root权限连接的安全管理。幸运的是,主要的开放源代码类Unix操作系统的软件管理系统都应该为你提供了自动处理功能。

如何在 Linux 下通过 sshfs 挂载远程目录

1. 安装 sshfs

CentOS 6.3 ( 在CentOS 下,使用者必须加入 fuse组才能使用 FUSE 功能 )

yum install fuse-sshfs

usermod -a -G fuse username

2. 建立挂载点 (也就是要从远程对应到本机哪个文件夹)

请注意: 如果用一般使用者身分执行时,该挂载点目录的拥有者必须为使用者自己!

sshfs username@hostname:/path/to/folder /path/to/local/folder

3. 卸载 sshfs 挂载

fusermount -u /path/to/local/folder

下面演示Azure上2台CentOS主机上加载sshfs文件

[azureuser@mono ~]$ sudo yum install fuse-sshfs

[sudo] password for azureuser:

Not using downloaded repomd.xml because it is older than what we have:

Current : Fri Apr 26 20:58:04 2013

Downloaded: Fri Apr 26 20:48:40 2013

Setting up Install Process

Resolving Dependencies

--> Running transaction check

---> Package fuse-sshfs.x86_64 0:2.4-1.el6 will be installed

--> Processing Dependency: fuse >= 2.2 for package: fuse-sshfs-2.4-1.el6.x86_64

--> Processing Dependency: libfuse.so.2(FUSE_2.7)(64bit) for package: fuse-sshfs-2.4-1.el6.x86_64

--> Processing Dependency: libfuse.so.2(FUSE_2.6)(64bit) for package: fuse-sshfs-2.4-1.el6.x86_64

--> Processing Dependency: libfuse.so.2(FUSE_2.5)(64bit) for package: fuse-sshfs-2.4-1.el6.x86_64

--> Processing Dependency: libfuse.so.2(FUSE_2.4)(64bit) for package: fuse-sshfs-2.4-1.el6.x86_64

--> Processing Dependency: libfuse.so.2(FUSE_2.2)(64bit) for package: fuse-sshfs-2.4-1.el6.x86_64

--> Processing Dependency: libfuse.so.2()(64bit) for package: fuse-sshfs-2.4-1.el6.x86_64

--> Running transaction check

---> Package fuse.x86_64 0:2.8.3-4.el6 will be installed

---> Package fuse-libs.x86_64 0:2.8.3-4.el6 will be installed

--> Finished Dependency Resolution

Dependencies Resolved

================================================================================

Package Arch Version Repository Size

================================================================================

Installing:

fuse-sshfs x86_64 2.4-1.el6 epel 52 k

Installing for dependencies:

fuse x86_64 2.8.3-4.el6 base 71 k

fuse-libs x86_64 2.8.3-4.el6 base 74 k

Transaction Summary

================================================================================

Install 3 Package(s)

Total download size: 198 k

Installed size: 553 k

Is this ok [y/N]: y

Downloading Packages:

(1/3): fuse-2.8.3-4.el6.x86_64.rpm | 71 kB 00:00

(2/3): fuse-libs-2.8.3-4.el6.x86_64.rpm | 74 kB 00:00

(3/3): fuse-sshfs-2.4-1.el6.x86_64.rpm | 52 kB 00:00

--------------------------------------------------------------------------------

Total 236 kB/s | 198 kB 00:00

warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY

Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

Importing GPG key 0x0608B895:

Userid : EPEL (6) <epel@fedoraproject.org>

Package: epel-release-6-8.noarch (installed)

From : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

Is this ok [y/N]: y

Running rpm_check_debug

Running Transaction Test

Transaction Test Succeeded

Running Transaction

Installing : fuse-2.8.3-4.el6.x86_64 1/3

Installing : fuse-libs-2.8.3-4.el6.x86_64 2/3

Installing : fuse-sshfs-2.4-1.el6.x86_64 3/3

Verifying : fuse-sshfs-2.4-1.el6.x86_64 1/3

Verifying : fuse-libs-2.8.3-4.el6.x86_64 2/3

Verifying : fuse-2.8.3-4.el6.x86_64 3/3

Installed:

fuse-sshfs.x86_64 0:2.4-1.el6

Dependency Installed:

fuse.x86_64 0:2.8.3-4.el6 fuse-libs.x86_64 0:2.8.3-4.el6

Complete!

[azureuser@mono ~]$ sudo usermod -a -G fuse azureuser

[azureuser@mono ~]$ sudo mkdir /usr/local/youhaoda

[azureuser@mono ~]$ sudo sshfs azureuser@youhaoda.cloudapp.net:/usr/local/src /usr/local/youhaoda

The authenticity of host 'youhaoda.cloudapp.net (168.63.212.151)' can't be established.

RSA key fingerprint is c7:fb:53:84:ac:13:74:0b:08:55:b4:06:34:57:22:7c.

Are you sure you want to continue connecting (yes/no)? y

Please type 'yes' or 'no': yes

azureuser@youhaoda.cloudapp.net's password:

[azureuser@mono ~]$ ls /usr/local/youhaoda -l

ls: ÎÞ·¨·ÃÎÊ/usr/local/youhaoda: ȨÏÞ²»¹»

[azureuser@mono ~]$ sudo ls /usr/local/youhaoda -l

×ÜÓÃÁ¿ 82004

drwxr-xr-x. 1 root root 4096 8ÔÂ 2 17:21 jexus-5.4.3

-rw-r--r--. 1 root root 179047 8ÔÂ 6 07:44 jexus-5.4.3.tar.gz

drwxrwxrwx. 1 1000 users 4096 9ÔÂ 21 03:21 libgdiplus-2.10

-rw-r--r--. 1 root root 1962898 2ÔÂ 14 2011 libgdiplus-2.10.tar.bz2

drwxr-xr-x. 1 1000 users 4096 9ÔÂ 21 03:27 mono-3.2.3

-rw-r--r--. 1 root root 81810387 9ÔÂ 17 23:08 mono-3.2.3.tar.bz2

如何在 Windows 下通过 sshfs 加载远程目录

1. 安装 sshfs 相关软件

安装步骤可参考文章 SSHFS in Windows。目前 Dokan library ( v0.6.0 ) 可支持 Windows 8 操作系统,但你必须在应用程序启动时以系统管理员身分执行,才可以正常安装!

image

2. 加载SSHFS 网络驱动器

运行 Sshfs Manager 之后,会在系统里出现一个黄色图示

image

打开Sshfs Manager,点选 Add 按钮,并配置 SSH 连接信息与磁盘名称 (Drive Name) 与 驱动器号 (Drive Letter)

image

mount后的效果如下 :

image

相关链接:

远程文件系统客户端源码, 超过7000行C++源代码, 其中包含RF32c.dll动态库整个工程源码, 源代码文件清单如下: \RFClient\unit_rc\CmdQueue.cpp \RFClient\unit_rc\CmdQueue.h \RFClient\unit_rc\RCClient.h \RFClient\unit_rc\RCClientObj.cpp \RFClient\unit_rc\RCClientObj.h \RFClient\units\RFCenter.cpp \RFClient\units\RFCenter.h \RFClient\units\RFCExports.cpp \RFClient\units\RFCExports.h \RFClient\units\RFCFileObj.cpp \RFClient\units\RFCFileObj.h \RFClient\units\RFCFindObj.cpp \RFClient\units\RFCFindObj.h \RFClient\units\RFConnObj.cpp \RFClient\units\RFConnObj.h \RFClient\units\RFCUtils.cpp \RFClient\units\RFCUtils.h 接口定义如下: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* 接口相关函数 */ // 接口初始化/释放函数 void __stdcall RFCInitialize(); void __stdcall RFCUninitialize(); // 接口版本信息, 格式: "x.x.x.x (build yyyy.mm.dd)" // AVersion 返回版本号, 如: 0x0708090A 表示 7.8.9.10 char* __stdcall RFCGetVersion(long* AVersion); // 取当前操作的最后错误码(注: 用于 RFConnCreate, RFCFindFirst 和 RFCFileCreate) long __stdcall RFCGetLastError(); // 接口属性操作 long __stdcall RFCGetInt(long Attrib, long* AValue); long __stdcall RFCGetStr(long Attrib, char* AValue, long* ALen); long __stdcall RFCSetInt(long Attrib, long AValue); long __stdcall RFCSetStr(long Attrib, const char* AValue, long ALen); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* 连接的相关函数 */ // 连接创建/释放 void* __stdcall RFConnCreate(const char* AHost, long APort, const char* APassword); void __stdcall RFConnFree(void* AConnObj); // 连接打开/关闭 long __stdcall RFConnOpen(void* AConnObj); void __stdcall RFConnClose(void* AConnObj); // 连接属性操作 long __stdcall RFConnGetInt(void* AConnObj, long Attrib, long* AValue); long __stdcall RFConnGetStr(void* AConnObj, long Attrib, char* AValue, long* ALen); long __stdcall RFConnSetInt(void* AConnObj, long Attrib, long AValue); long __stdcall RFConnSetStr(void* AConnObj, long Attrib, const char* AValue, long ALen); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* 文件/目录操作的相关函数 */ // 读取/设置文件属性 long __stdcall RFCGetFileAttr(void* AConnObj, const char* AFileName, long* Attrib); long __stdcall RFCSetFileAttr(void* AConnObj, const char* AFileName, long Attrib); // 文件存在/删除/移动文件或目录 long __stdcall RFCFileExisted(void* AConnObj, const char* AFileName); long __stdcall RFCDeleteFile(void* AConnObj, const char* AFileName); long __stdcall RFCMoveFile(void* AConnObj, const char* AOldName, const char* ANewName); // 目录存在/创建/删除 long __stdcall RFCDirExisted(void* AConnObj, const char* APathName); long __stdcall RFCCreateDir(void* AConnObj, const char* APathName, bool AForced = false); long __stdcall RFCRemoveDir(void* AConnObj, const char* APathName, bool AForced = false); // 磁盘操作相关函数 long __stdcall RFCDriveType(void* AConnObj, const char* ADrive, long* AType); long __stdcall RFCDiskSpace(void* AConnObj, const char* APath, __int64* ATotalSpace, __int64* AFreeSpace); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* 文件查找的相关函数 */ void* __stdcall RFCFindFirst(void* AConnObj, const char* APath, TRFCFindItem* AItem); long __stdcall RFCFindNext(void* AFindObj, TRFCFindItem* AItem); long __stdcall RFCFindClose(void* AFindObj); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* 文件读写的相关函数 */ // 创建/释放文件对象 void* __stdcall RFCFileCreate(void* AConnObj, const char* AFileName, long AMode, bool ANeedCreate, long AFileAttr); long __stdcall RFCFileFree(void* AFile); // 读写数据 long __stdcall RFCFileRead(void* AFile, void* ABuffer, long ASize); long __stdcall RFCFileWrite(void* AFile, const void* ABuffer, long ASize); // 文件定位/清除文件缓存/设置文件末尾 long __stdcall RFCFileSeek(void* AFile, long* AOffset, long AOrigin); long __stdcall RFCFileSeek64(void* AFile, __int64* AOffset, long AOrigin); long __stdcall RFCFileFlush(void* AFile); long __stdcall RFCFileSetEOF(void* AFile); // 读取文件信息 long __stdcall RFCFileGetInfo(void* AFile, TRFCFileInfo* AInfo); long __stdcall RFCFileGetSize(void* AFile, __int64* ASize); // 读取/设置文件时间 long __stdcall RFCFileGetTime(void* AFile, double* ACreateTime, double* AModifyTime); long __stdcall RFCFileSetTime(void* AFile, const double* ACreateTime, const double* AModifyTime);
远程文件系统服务器源码, 超过9000行C++源代码, 其中包含服务程序RFSvc.exe和RF32s.dll动态库源码, 文件清单如下: \RFServer\unit_rc\RCServer.h \RFServer\unit_rc\RCServerObj.cpp \RFServer\unit_rc\RCServerObj.h \RFServer\units\RFAppObj.cpp \RFServer\units\RFAppObj.h \RFServer\units\RFCenter.cpp \RFServer\units\RFCenter.h \RFServer\units\RFConnObj.cpp \RFServer\units\RFConnObj.h \RFServer\units\RFExports.cpp \RFServer\units\RFExports.h \RFServer\units\RFFileObj.cpp \RFServer\units\RFFileObj.h \RFServer\units\RFFindObj.cpp \RFServer\units\RFFindObj.h \RFServer\units\RFUtils.cpp \RFServer\units\RFUtils.h \RFServer\units_shell\RFServer.h \RFServer\units_shell\RFSvc.cpp 接口定义如下: // 初始化/释放接口 void __stdcall RFInitialize(); void __stdcall RFUninitialize(); // 接口版本信息, 格式: "x.x.x.x (build yyyy.mm.dd)" char* __stdcall RFGetVersion(long* AVersion); // 设置(注: 若要调用则必须在 RFInitialize 之前调用) // 1. RFSetLogRoot 设置日志根路径, 默认值: CurrAppFilePath + "log_rf\\" // 2. RFSetCfgFile 设置配置文件名, 默认值: CurrAppFilePath + "RFServer.ini" void __stdcall RFSetLogRoot(const char* ALogRoot); void __stdcall RFSetCfgFile(const char* ACfgFile); // 接口属性相关函数 long __stdcall RFGetInt(long Attrib, long* AValue); long __stdcall RFGetStr(long Attrib, char* AValue, long* ASize); long __stdcall RFSetInt(long Attrib, long AValue); long __stdcall RFSetStr(long Attrib, const char* AValue, long ASize); // 启动/停止函数 long __stdcall RFStart(); void __stdcall RFStop();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值