Skip to content

标题: Unix系列(14)--将S端目录mount到C端文件系统中

创建: 2024-03-07 09:45 修改: 2024-03-13 20:49 链接: https://scz.617.cn/unix/202403070945.txt


目录:

☆ 原始需求
☆ sshfs
    1) 使用示例
    2) idmap
☆ gvfs
    1) gio+sftp
☆ rclone
    1) webdav
        1.1) For Linux
        1.2) For Windows
    2) sftp
☆ dufs
☆ 其它(未测试)

☆ 原始需求

S、C两台Linux。想在S端执行一个静态ELF,并在C端执行与之配合的程序,将S端指 定目录mount到C端文件系统中,使得C端可以只读方式访问mount点。有点类似NFS的 需求,但S端比较特殊,不考虑NFS Server在S端布署成功的可能。希望是一批静态 ELF在S端执行,对权限控制、写操作无要求。

网上求助后,若干网友提及几种备选方案,包括但不限于sshfs、rclone、dufs。其 中sshfs依赖S端sftp服务可用,目标环境S端不满足此要求,但本文记录了sshfs的常 规用法。作为WebDAV服务端,dufs比rclone小巧许多,只有3.6MB。作为客户端, rclone支持多种协议,不确认dufs能否用作客户端,本文WebDAV客户端统一用rclone 或Windows。本文简单演示了对权限控制、写操作的支持。

☆ sshfs

From UID(7575775504)

参看


https://help.ubuntu.com/community/SSHFS

how to map users and group with sshfs - [2013-07-04] https://unix.stackexchange.com/questions/81707/how-to-map-users-and-group-with-sshfs


1) 使用示例

假设S端有SSH服务且从C端可用sftp访问S端:

sftp -4C -P @ sftp -4C -P 22 [email protected]

若sftp不可达,sshfs不可用

在C端安装sshfs:

apt install sshfs

假设需将S端/home/scz/src/目录挂到C端~/src/mnt/点

在C端创建mount点:

mkdir ~/src/mnt

在C端挂接mount点:

sshfs -C -o port=,idmap=user,dir_cache=yes,reconnect,ServerAliveInterval=5 @: sshfs -C -o port=22,idmap=user,dir_cache=yes,reconnect,ServerAliveInterval=5 [email protected]:/home/scz/src ~/src/mnt

ls -l ~/src/mnt ls -ld ~/src/mnt

在C端卸载mount点:

fusermount -u ~/src/mnt fusermount3 -u ~/src/mnt

"ServerAliveInterval=5"用于保活,另一种指定方式如下:


Your ssh session will automatically log out if it is idle. To keep the connection active (alive) add this to ~/.ssh/config or to /etc/ssh/ssh_config on the client.

ServerAliveInterval 5

This will send a "keep alive" signal to the server every 5 seconds. You can usually increase this interval, and I use 120.


sshfs还有一些可能用得上的参数,比如:

password_stdin allow_other disable_hardlink transform_symlinks follow_symlinks max_conns=N

查看man手册了解之。

sshfs的passive模式到底怎么用的,man手册里的例子硬是没看懂。

2) idmap


-o idmap=TYPE

How to map remote UID/GIDs to local values. Possible values are:

none no translation of the ID space (default).

user map the UID/GID of the remote user to UID/GID of the mounting user.

idmap有3种值,只讨论none与user。idmap只影响stat()或ls的显示效果,不带来任 何实际权限相关的问题,S端权限控制与正常SSH登录无异。

a) 假设C端scz,S端root,指定"idmap=none"

sshfs -C -o port=22,idmap=none,dir_cache=yes,reconnect,ServerAliveInterval=5 [email protected]:/root/src ~/src/mnt

在C端

$ ls -ldn ~/src/mnt drwxr-xr-x 1 0 0 4096 Mar 7 10:24 /home/scz/src/mnt/

b) 假设C端scz,S端root,指定"idmap=user"

sshfs -C -o port=22,idmap=user,dir_cache=yes,reconnect,ServerAliveInterval=5 [email protected]:/root/src ~/src/mnt

在C端

$ ls -ldn ~/src/mnt drwxr-xr-x 1 1000 1000 4096 Mar 7 10:24 /home/scz/src/mnt/

对比a、b两组实验,"idmap=none"未做任何映射,S端uid(0)/gid(0)直接用于C端ls 显示;"idmap=user"做了映射,将S端uid(0)/gid(0)映射成C端uid(1000)/gid(1000), 让C端看上去在操作C端用户scz所拥有的文件、目录。

演示中用了"ls -n",避免歧义;若不指定-n,这些uid/gid会根据C端/etc/passwd、 /etc/group显示成名字,若用"idmap=none",极易带来视觉上的困扰,但不构成任何 安全问题。

☆ gvfs

From bluerust

参看gio(1)、gvfs(7)

1) gio+sftp

在C端挂接mount点:

gio help mount

gio mount sftp://@:/ gio mount sftp://[email protected]:22/

gio mount sftp://@:// gio mount sftp://[email protected]:22/home/scz/src/

在C端卸载mount点:

gio mount -u sftp://[email protected]:22/home/scz/src/ gio mount -u sftp://[email protected]:22/ gio mount -u sftp://[email protected]/

在C端查看mount点:

gio help info gio info sftp://[email protected]:22/home/scz/src/ gio info sftp://[email protected]:22/ gio info sftp://[email protected]/

$ gio info sftp://[email protected]:22/home/scz/src/ | grep "local path" local path: /run/user/1000/gvfs/sftp:host=192.168.65.21,user=scz/home/scz/src

$ cd /run/user/1000/gvfs/sftp:host=192.168.65.21,user=scz/home/scz/src $ ls -l (显示S端/home/scz/src/目录)

如下命令可知mount点何在:

$ mount | grep gvfsd-fuse | grep $(id -u) gvfsd-fuse on /run/user/1000/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)

$ echo $XDG_RUNTIME_DIR/gvfs /run/user/1000/gvfs

$ ls -l $XDG_RUNTIME_DIR/gvfs drwxr-xr-x 1 scz scz 4096 Sep 19 2022 'sftp:host=192.168.65.21,user=scz'/

$ cd $XDG_RUNTIME_DIR/gvfs/sftp:host=192.168.65.21,user=scz $ ls -l (显示S端根目录)

本例mount点是"$XDG_RUNTIME_DIR/gvfs/sftp:host=192.168.65.21,user=scz",而 非"$XDG_RUNTIME_DIR/gvfs/sftp:host=192.168.65.21,user=scz/home/scz/src"。 无论"gio mount"是否携带,都将"remote root directory"挂上 来,相比之下,sshfs可挂载具体的

好像"gio mount"无法手工指定,或可"ln -s"建个符号链接出 来。

ln -s $XDG_RUNTIME_DIR/gvfs/sftp:host=192.168.65.21,user=scz ~/src/mnt ls -l ~/src/mnt/home/scz/src

只用sftp协议,gio没啥优势啊。不过gio支持其他协议,比如smb、http、ftp、nfs、 dav等等,参看gvfs(7)。

☆ rclone

From UID(2031821051)

参看


https://rclone.org/ https://rclone.org/install/ https://rclone.org/downloads/ https://downloads.rclone.org/rclone-current-linux-amd64.zip https://downloads.rclone.org/v1.65.2/rclone-v1.65.2-linux-amd64.zip

Frequently Asked Questions https://rclone.org/faq/

Syntax for config-less operation - [2019-09-25] https://forum.rclone.org/t/syntax-for-config-less-operation/12011 https://rclone.org/docs (:backend:path/to/dir)

Global Flags https://rclone.org/flags/

Rclone Commands https://rclone.org/commands/ https://rclone.org/commands/rclone_serve/ https://rclone.org/commands/rclone_mount/ https://rclone.org/commands/rclone_config/

https://github.com/rclone/rclone https://github.com/rclone/rclone/releases https://github.com/rclone/rclone/releases/download/v1.65.2/rclone-v1.65.2-linux-amd64.zip


1) webdav

参看


https://rclone.org/commands/rclone_serve_webdav/

WebDAV https://rclone.org/webdav/

How to configure a WebDAV server using rclone https://tutorials.garnerpcsquad.com/readme/how-to-configure-a-webdav-server-using-rclone


1.1) For Linux


S端

cd /home/scz/src/rclone ./rclone serve -h ./rclone serve webdav -h | less

./rclone serve webdav ~/src \ --addr 192.168.65.21:8080 \ --vfs-cache-mode writes

C端

mkdir ~/src/mnt cd /home/scz/src/rclone ./rclone mount -h | less

./rclone mount \ --webdav-url http://192.168.65.21:8080 \ --vfs-cache-mode writes \ :webdav:/ ~/src/mnt

高版本Ctrl-C打断C端rclone时自动umount,也可用如下命令umount,低版本Ctrl-C 不会自动umount。

fusermount -u ~/src/mnt

C端不需要"--webdav-vendor any"参数

S端

cd /home/scz/src/rclone ./rclone serve -h ./rclone serve webdav -h | less

./rclone serve webdav ~/src \ --addr 192.168.65.21:8080 \ --user webdavuser --pass webdavpass \ --vfs-cache-mode writes

C端

curl -s -u webdavuser:webdavpass -o some.txt http://192.168.65.21:8080/some.txt

mkdir ~/src/mnt cd /home/scz/src/rclone ./rclone mount -h | less

./rclone mount \ --webdav-url http://192.168.65.21:8080 \ --webdav-user webdavuser --webdav-pass $(./rclone obscure webdavpass) \ --vfs-cache-mode writes \ :webdav:/ ~/src/mnt

./rclone mount \ --vfs-cache-mode writes \ ":webdav,url='http://192.168.65.21:8080',user=webdavuser,pass=$(./rclone obscure webdavpass):/" ~/src/mnt

fusermount -u ~/src/mnt

C端不能直接提供明文口令"webdavpass",必须先用"rclone obscure webdavpass"获 取非明文口令,若直接提供明文口令,C端报错:

Failed to create file system for ":webdav:/": couldn't decrypt password: input too short when revealing password - is it obscured?

若口令错误,C端报错:

401 Unauthorized

只列子目录

./rclone lsd \ --webdav-user webdavuser --webdav-pass $(./rclone obscure webdavpass) \ --webdav-url http://192.168.65.21:8080 :webdav:/

遍历目录树

./rclone lsl \ --webdav-user webdavuser --webdav-pass $(./rclone obscure webdavpass) \ --webdav-url http://192.168.65.21:8080 :webdav:/ | less

./rclone lsl \ --webdav-user webdavuser --webdav-pass $(./rclone obscure webdavpass) \ --webdav-url http://192.168.65.21:8080 :webdav:/rclone

lsd、lsl没啥用,mount后想干啥不成?

1.2) For Windows

从Vista开始,Windows的WebClient服务使得资源管理器可直接访问WebDAV资源


S端

cd /home/scz/src/rclone ./rclone serve -h ./rclone serve webdav -h | less

./rclone serve webdav ~/src \ --addr 192.168.65.21:8080 \ --user webdavuser --pass webdavpass \ --vfs-cache-mode writes


假设C端是Win10,为访问S端"rclone serve webdav",需修改如下注册表项


Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters] "BasicAuthLevel"=dword:00000002


reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\WebClient\Parameters" /v "BasicAuthLevel" /t REG_DWORD /d 2 /f reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\WebClient\Parameters" /v "BasicAuthLevel"

BasicAuthLevel缺省为1,需改成2


0 Basic authentication disabled 1 Basic authentication enabled for SSL connections only 2 Basic authentication enabled for SSL connections and for non-SSL connections If required


简单点说,S端未用HTTPS,C端BasicAuthLevel为1时无法访问S端。重启WebClient服 务使BasicAuthLevel新值生效:

sc stop WebClient && sc start WebClient

设BasicAuthLevel为1,在C端资源管理器地址栏中访问

\192.168.65.21@8080\DavWWWRoot

弹错误提示框


Network Error

Windows cannot access \192.168.65.21@8080\DavWWWRoot

Check the spelling of the name. Otherwise, there might be a problem with your network, To try to identify and resolve network problems, click Diagnose.

Error code: 0x80070043

The network name cannot be found.

设BasicAuthLevel为2,在C端资源管理器地址栏中访问

\192.168.65.21@8080\DavWWWRoot

弹框提示输入user/pass,完成认证即可。重启WebClient服务,之前的认证信息失效, 需再次认证。上面是最快捷的C端用法,但有一些互相抄来抄去的文档提及其他操作 路径,本质未变。

This PC->Computer->Add a network location

一路继续,直至提示输入"Internet or network address",输入

http://192.168.65.21:8080

弹框提示输入user/pass,完成认证,提示"Type a name for this network location", 名字任意,比如"192.168.65.21"。之后"This PC"中有名为"192.168.65.21"的项目, 可点击打开,可右键删除。

可映射盘符,但非必要步骤:

This PC->Computer->Map network drive->

Drive T Folder http://192.168.65.21:8080

选中"Connect using different credentials",点击Finish,弹框提示输入user/pass, 完成认证,至此C端可用T盘访问S端。也可命令行映射盘符:

net use T: \192.168.65.21@8080\DavWWWRoot (CLI提示输入user/pass) net use T: \192.168.65.21@8080\DavWWWRoot /u:webdavuser webdavpass (直接认证) net use T: /d (删除映射)

2) sftp

参看:


https://rclone.org/commands/rclone_serve_sftp/

SFTP https://rclone.org/sftp/



S端

cd /home/scz/src/rclone ./rclone serve -h ./rclone serve sftp -h | less

./rclone serve sftp ~/src \ --addr 192.168.65.21:2022 \ --user sftpuser --pass sftppass \ --vfs-cache-mode writes

C端

mkdir ~/src/mnt cd /home/scz/src/rclone ./rclone mount -h | less

./rclone mount \ --sftp-shell-type none \ --sftp-host 192.168.65.21 --sftp-port 2022 \ --sftp-user sftpuser --sftp-pass $(./rclone obscure sftppass) \ --vfs-cache-mode writes \ :sftp:/ ~/src/mnt

./rclone mount \ --vfs-cache-mode writes \ :sftp,shell_type=none,host=192.168.65.21,port=2022,user=sftpuser,pass=$(./rclone obscure sftppass):/ ~/src/mnt

fusermount -u ~/src/mnt

☆ dufs

From UID(1832267322) & UID(2104719861)


https://github.com/sigoden/dufs https://github.com/sigoden/dufs/releases https://github.com/sigoden/dufs/releases/download/v0.40.0/dufs-v0.40.0-i686-unknown-linux-musl.tar.gz


S端

cd /home/scz/src/dufs ./dufs -h

./dufs ~/src \ -b 192.168.65.21 -p 8080 \ -a dufsuser:dufspass@/:rw \ -A \ --log-format=''

C端 (For Linux)

curl -s -u dufsuser:dufspass -o some.txt http://192.168.65.21:8080/some.txt

mkdir ~/src/mnt cd /home/scz/src/rclone ./rclone mount -h | less

./rclone mount \ --webdav-url http://192.168.65.21:8080 \ --webdav-user dufsuser --webdav-pass $(./rclone obscure dufspass) \ --vfs-cache-mode writes \ :webdav:/ ~/src/mnt

./rclone mount \ --vfs-cache-mode writes \ ":webdav,url='http://192.168.65.21:8080',user=dufsuser,pass=$(./rclone obscure dufspass):/" ~/src/mnt

fusermount -u ~/src/mnt

若从S端向C端复制文件碰上I/O错,检查C端rclone版本,可能太低了

C端 (For Windows)

net use T: \192.168.65.21@8080\DavWWWRoot /u:dufsuser dufspass net use T: /d


若只是WebDAV的mount需求,dufs相比rclone有个优势,服务端dufs 3.6MB,服务端 rclone 56MB,dufs更小巧。

☆ 其它(未测试)

From UID(1832267322)


dave - The simple WebDAV server https://github.com/micromata/dave

https://github.com/ods-im/CuteHttpFileServer