月度归档:2025年10月

Debian/Ubuntu系统下,配置并使用SFTP,分用户分目录

前缀、文档修改记录

20251009 初始化编辑此文章,完稿

章节1、需求描述

Debian/Ubuntu的Linux系统内,SFTP权限分配问题,用户user1 可以访问 /data/user1 路径和 /data/share路径, 用户user2可以访问/data/user2和/data/share路径,这样,每个用户可以拥有自己独立的存储目录,也可以有共享的目录访问权限

章节2、环境描述

今日的测试环境 Debian 12的1台Linux服务器,作为文件服务器,/data目录有做完软RAID后的500GB空间,基本不怕丢失文件的哦。

典型的 SFTP 用户目录权限隔离 + 共享目录权限设计

user1 只能访问 /data/user1 和 /data/share
user2 只能访问 /data/user2 和 /data/share
两个用户互相不能访问对方的私有目录
/data/share 为公共共享目录(权限:可读写)
最安全和推荐的方法是使用 sshd_config 配置 SFTP Chroot Jail,然后利用 Bind Mount 来挂载共享目录。

用 Chroot 限制 SFTP 用户的根目录;
用组(group)控制共享目录访问;
调整目录权限(chmod / chown);
修改 SSH 配置来限定 SFTP 行为。

章节3、配置过程,独享目录+共享目录(可读写)

// 创建 Chroot 根目录,创建用户实际数据目录,设置 chroot 目录权限(必须由 root 拥有且不可写)

mkdir -p /sftp/user1
mkdir -p /sftp/user2

mkdir -p /data/user1
mkdir -p /data/user2
mkdir -p /data/share

chown root:root /sftp/user1 /sftp/user2
chmod 755 /sftp/user1 /sftp/user2

配置 sshd,实现 chroot jail,编辑 SSH 配置文件 /etc/ssh/sshd_config , 注释掉默认的 Subsystem 行,使该行语法失效。

# Subsystem sftp /usr/lib/openssh/sftp-server

移动到文件末尾,增加相关配置,增加sftp用户组sftp_users的配置,禁止登录系统,仅允许sftp

# 使用内部 sftp-server 实现 Chroot 功能
Subsystem sftp internal-sftp

# 为 SFTP 用户定义匹配组
Match Group sftp_users
    # 强制使用 internal-sftp
    ForceCommand internal-sftp
    # 禁止 TTY 和 X11 转发
    PermitTTY no
    X11Forwarding no
    # 设置 Chroot 根目录,%h 会被替换为用户的主目录
    ChrootDirectory %h
    # 允许用户的主目录内有读写权限
    AllowTcpForwarding no

注释:这里的 %h 是一个变量,它将使用 /etc/passwd 中定义的用户主目录(Home Directory)

继续配置,在系统里增加用户的组,创建不同用户并设置主目录和组

groupadd sftp_users

useradd -m -d /sftp/user1 -s /sbin/nologin -g sftp_users user1
passwd user1

useradd -m -d /sftp/user2 -s /sbin/nologin -g sftp_users user2
passwd user2

chown user1:sftp_users /data/user1
chown user2:sftp_users /data/user2
chmod 700 /data/user1
chmod 700 /data/user2

chown root:sftp_users /data/share
chmod 770 /data/share

注释:用户的 Home 目录必须设置为 Chroot Jail 的根目录

参数 -m: 创建用户主目录(即 /sftp/user1)

参数 -d /sftp/user1: 指定主目录为 Chroot 根目录

参数 -s /sbin/nologin: 禁止用户通过 SSH 登录 Shell,只能进行 SFTP

设置 Bind Mount 挂载点,在每个用户的 Chroot 根目录下创建挂载点(目标目录),将实际数据目录挂载到 Chroot 内部的入口

mkdir /sftp/user1/user1_files
mkdir /sftp/user1/share

mount --bind /data/user1 /sftp/user1/user1_files
mount --bind /data/share /sftp/user1/share

mkdir /sftp/user2/user2_files
mkdir /sftp/user2/share

mount --bind /data/user2 /sftp/user2/user2_files
mount --bind /data/share /sftp/user2/share

编辑 /etc/fstab 文件,使挂载在系统重启后仍然生效,编辑/etc/fstab 中添加以下四行

/data/user1      /sftp/user1/user1_files  none bind 0 0
/data/share      /sftp/user1/share        none bind 0 0

/data/user2      /sftp/user2/user2_files  none bind 0 0
/data/share      /sftp/user2/share        none bind 0 0

设置目录权限,需要确保用户对实际数据目录有正确的读写权限,设置用户私有目录的权限

chown user1:user1 /data/user1
chmod 700 /data/user1

chown user2:user2 /data/user2
chmod 700 /data/user2

设置共享目录的权限

groupadd sftp_users
usermod -aG sftp_users user1
usermod -aG sftp_users user2

# 设置 /data/share 目录
chown root:sftp_users /data/share
chmod 770 /data/share 

重启服务并测试

systemctl restart sshd

注释:用户登录后,其 SFTP 根目录就是 /sftp/userN,他们将只能看到 userN_filesshare 目录

章节4、配置过程,增加只读的共享目录

只读共享目录 /data/iso , 里面放的一些iso文件,这个一般用户,只读即可。

创建目录,并设置权限: 设置它为 root 拥有且不可写。

mkdir -p /data/iso

chown root:sftp_users /data/iso
chmod 750 /data/iso                  # 确保所有用户可读、可执行(进入目录)

在 Chroot 内部创建挂载点

mkdir /sftp/user1/iso_ro
mkdir /sftp/user2/iso_ro

执行只读 Bind Mount

systemctl daemon-reload
mount --bind /data/iso /sftp/user1/iso_ro -o ro
mount --bind /data/iso /sftp/user2/iso_ro -o ro

持久化 Bind Mount(系统重启后仍然生效),编辑 /etc/fstab 文件,添加以下两行

/data/iso      /sftp/user1/iso_ro       none bind,ro 0 0
/data/iso      /sftp/user2/iso_ro       none bind,ro 0 0

注释:bind,ro 确保了挂载的持久性和只读属性

总结:

私有目录 (/data/user1, /data/user2):通过 chown 和 chmod 700 实现独占读写。

共享目录 (/data/share):通过 sftp_share 组和 chmod 2770 实现组内读写。

只读目录 (/data/iso):通过 mount --bind -o ro 实现只读访问。

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

通过公网服务器映射家里的nextcloud的webdav

前缀、文档修改记录

20251006 初始化编辑此文章,完稿,暂未解决,求助
20251008 更新文档

章节1、需求描述

家中服务器

运行 Nextcloud (Docker),没有公网 IP,通过 frpc(TCP 模式) 将 80 端口映射到公网服务器

公网服务器

运行 frps,部署 nginx + HTTPS 证书,nginx 对外暴露的是 HTTPS,nginx 反代到 frp 转发来的 nextcloud HTTP

现象:

Web(浏览器)访问正常nextcloud。WebDAV 的 HTTPS 访问(例如通过 https://nas.mydomain.com/remote.php/dav/files/...)不通。

章节2、故障排查1 – Nginx反代的时候,少了对webdav的参数支持

WebDAV 不仅用 GET / POST,还会用 PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK,这些方法如果被 nginx 屏蔽或未转发,会直接导致 WebDAV 客户端报错(例如 Windows 或 macOS Finder 会直接显示“连接失败”)。

proxy_methods 指令,因为那是 第三方模块(ngx_http_proxy_methods_module) 的语法,不在标准版 nginx 中。

只要不写 proxy_methods 和 limit_except,nginx 默认会转发所有 HTTP 方法,包括 PROPFIND。

那我这个错误,应该不是这个因素导致的。

章节3、 故障排查2 – Nextcloud的配置文件

我配置文件的路径是,/data/config/config.php,确保反代后返回的链接是 HTTPS。

指定信任来源: trusted_proxies 参数是一个数组,用于明确列出 Nextcloud 应该信任的 反向代理服务器的 IP 地址 或 IP 地址段(CIDR 格式)。

正确配置 trusted_proxies 后,Nextcloud 才能从反向代理设置的特定 HTTP 头(默认为 X-Forwarded-For)中提取出真正的 客户端 IP 地址

  'trusted_proxies' => 
  array (
    0 => '192.168.1.10', // 你的反向代理服务器的 IPv4 地址
    1 => '2001:db8::1',  // IPv6 地址示例
    2 => '172.16.0.0/12',// IP 地址段 (CIDR) 示例,例如 Docker 网络的范围
  ),
  // ... 其他配置 ...

'overwriteprotocol' => 'https',
'overwrite.cli.url' => 'https://nas.mydomain.com',

在这个参数中,增加我服务器的域名,增加服务器的IP,重启一下docker/nextcloud实例。

章节4、故障排查3 – frp的TCP多路复用

启用 TCP 多路复用,应该在配置文件中,tcp_mux = true , 不过,我这里frp 0.65.0 版本

# tcp_mux = true  # 默认就是 true,可以不写

章节5、故障排查4 – nextcloud的应用密码

Nextcloud 的 WebDAV 默认不接受普通用户密码(如果开启了双重认证、OIDC、或 brute-force protection)。

在 Nextcloud 网页端:

点击右上角头像 → “安全”; 在“设备与会话”→“创建新应用密码”; 复制生成的密码

增加了,尝试,也没有用,应该也不是这个问题。

章节6、故障排查5 – nginx的配置

对于nginx,增加http2的配置,我这里版本是1.28.0,HTTP/2 是这样启用的

listen 443 ssl;
http2 on;

完全兼容 HTTP/1.1 回退,增加上来。尴尬,也没啥用。

章节7、故障排查6 – frp的参数

我这里配的frp,走的TCP,这个可能是不对的,frps和frpc之间的tcp通道是经过TLS加密的,这样的话,可能是存在TLS in TLS的情况。

如果是这样的情况,那就直接先docker重新拉一个纯HTTP方式的nextcloud容器看看,直接映射用ftp的TCP方式映射本地的http去公网试试。

用纯HTTP倒是没啥问题。

章节8、故障排查7 – 修改注册表

Windows 需要修改注册表才能支持非微软 WebDAV 服务器

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

0 禁用基本认证

1 只允许 HTTPS 基本认证

2 允许 HTTP/HTTPS 基本认证(推荐至少为 1)
net stop WebClient
net start WebClient

章节9、故障排查8 – 配置架构变化

从原先的
家中服务器:运行 Nextcloud (Docker),没有公网 IP,通过 frpc(TCP 模式) 将 80 端口映射到公网服务器
公网服务器:运行 frps,部署 nginx + HTTPS 证书,nginx 对外暴露的是 HTTPS,nginx 反代到 frp 转发来的 nextcloud HTTP

调整为
家中服务器:运行 Nextcloud (Docker)/TCP/80,没有公网 IP,通过加载证书的Nginx反代本地80到本机的TCP/SSL/443,通过 frpc(TCP 模式) 将 443 端口映射到公网服务器
公网服务器:运行 frps,通过刚刚frpc上指定的TCP/SSL/公网端口访问

即相当与HTTPS 场景的直通配置(TLS passthrough),避免经过frp隧道的时候的TLS in TLS的问题,这个也是我一开始怀疑的点。

章节10、故障排查9 – 测试 WebDAV 端点(不带认证)

curl -i http://localhost/remote.php/dav/

表示 WebDAV 接口存在,只是需要登录。

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨

Windows 11 系统,挂载SAMBA报错

前缀、文档修改记录

20251002 初始化编辑此文章,完稿

章节1、需求描述

Windows 11系统,挂载Linux的SAMBA,但是错误提示为“A specified logon session does not exist. It may already have been terminated.”

错误的原因是这次安装的Windows 11 系统很新,有的安全设置等级高,需要修改一下。

章节2、 修改方式

2.1 修改步骤1

打开控制面板。

点击 程序 → 启用或关闭 Windows 功能。

在列表中找到并勾选 “SMB 1.0/CIFS 文件共享支持”。

2.2 修改步骤2

按下 Win + R 键打开“运行”对话框,输入 secpol.msc 并按回车,打开本地安全策略。

导航到:本地策略 → 安全选项。

在右侧找到并双击设置项:“网络安全: LAN 管理器身份验证级别”(Network security: LAN Manager authentication level)。

将其值修改为:“发送 LM 和 NTLM – 使用 NTLMv2 会话安全(如果协商)”

2.3 重启一下系统,即可。

附录1、视频操作演示

附录2、@Dasmz

博客内,所有教程为手打原创教程,如果技术教程对您有所帮助,欢迎打赏作者。技术层面,闻道有先后,如有疏漏、错误,欢迎指正。技术博客的内容,一般具有一定的环境依赖,具有一定的年代依赖,酌情参考其中的内容,请勿完全照搬照抄。

对于博客内已提及的专业知识,如果需要技术指导,欢迎联系我,仅需支付工时费

Twitter: Dasmz

Youtube: @DasmzStudio

Telegram: @Dasmz

Donate
云乞讨