CentOS 搭建 SFTP 服务器(二)

CentOS 搭建 SFTP 服务器

适用系统:CentOS 7 / 8 / 9(及 Rocky Linux、AlmaLinux)


注:本文章是CentOS 搭建 SFTP 服务器(一)的进阶,如实操请先搭建SFTP服务器

步骤2.7:同组的不同权限用户访问共享目录(选配)

需求:同组内的不同用户,需要访问同一个 SFTP 目录,但拥有不同的权限(如只读、读写等)

在标准的 OpenSSH SFTP + chroot 架构下,原生不支持细粒度的文件级权限控制 (比如"用户 A 可写,用户 B 只读"),但可以通过 Linux 文件系统权限(ACL)+ 合理的目录结构设计 来实现。


2.7.1 目标场景示例
  • 用户 uploader:可上传/修改文件(读写)
  • 用户 viewer:只能下载/查看文件(只读)
  • 两者都属于 sftpusers
  • 共享目录:/sftp/shared

要求:

  • 两人登录后都能看到 /shared(或根目录就是共享目录)
  • 权限隔离,互不影响
  • 仍限制在 chroot 环境中(不能访问系统其他部分)

2.7.2 使用 统一 chroot 根 + ACL 权限控制

注意:由于 OpenSSH 的 ChrootDirectory 要求目录必须由 root 拥有,不能直接让多个用户共用同一个 chroot 根并写入

所以我们采用 "伪共享" 方式:每个用户有自己的 chroot 目录,但通过 bind mount符号链接(受限) 指向同一个物理共享目录。

符号链接在 chroot 中通常无效 (出于安全),所以推荐使用 bind mount


2.7.3 Bind Mount 共享目录(最可靠)
步骤 1:创建共享数据目录(不在 chroot 结构内)
bash 复制代码
sudo mkdir -p /sftp-data/shared
sudo chown root:sftpusers /sftp-data/shared
sudo chmod 750 /sftp-data/shared

所有实际文件存在这里,这是真正的共享存储位置


步骤 2:创建用户并加入组
bash 复制代码
# 组在之前已创建成功
sudo groupadd sftpusers
# 创建用户
sudo useradd -g sftpusers -d /sftp/uploader -s /sbin/nologin uploader
sudo useradd -g sftpusers -d /sftp/viewer   -s /sbin/nologin viewer
# 设置密码(密码要连续输入两次,成功会提示:passwd: all authentication tokens updated successfully.)
sudo passwd uploader
sudo passwd viewer

输入的密码是有的 ,被隐藏了,防止密码泄露


步骤 3:为每个用户创建独立的 chroot 目录
bash 复制代码
# 创建 uploader 的 jail
sudo mkdir -p /sftp/uploader
sudo chown root:root /sftp/uploader
sudo chmod 755 /sftp/uploader

# 创建 viewer 的 jail
sudo mkdir -p /sftp/viewer
sudo chown root:root /sftp/viewer
sudo chmod 755 /sftp/viewer

这满足 OpenSSH 对 chroot 目录的要求(root 拥有)。


步骤 4:使用 bind mount 将共享目录挂载到各用户 jail 内
bash 复制代码
# 为 uploader 挂载(可读写)
sudo mkdir /sftp/uploader/files
sudo mount --bind /sftp-data/shared /sftp/uploader/files

# 为 viewer 挂载(只读!)
sudo mkdir /sftp/viewer/files
sudo mount -o bind,ro /sftp-data/shared /sftp/viewer/files

命令分解

部分 说明
sudo 以 root 权限执行(挂载操作需要管理员权限)
mount Linux 挂载文件系统的命令
-o 表示"options"(挂载选项)
remount,ro 两个挂载选项,用逗号分隔: • remount:重新挂载已挂载的文件系统 • ro:read-only(只读)
/sftp/viewer/files 要重新挂载的目标挂载点(目录)

mount --bind 让两个路径指向同一份数据,但可以分别设置挂载选项(如只读)。


步骤 5:设置文件系统 ACL(精细控制谁可写)

即使挂载为读写,通过 ACL 控制具体用户的写权限:

bash 复制代码
# 允许 uploader 写入共享目录
sudo setfacl -m u:uploader:rwx /sftp-data/shared

# viewer 默认只有组权限(只读),无需额外设置
# 如果组是 r-x,则 viewer 只能读

验证 ACL:

bash 复制代码
getfacl /sftp-data/shared

示例结果:

复制代码
getfacl: Removing leading '/' from absolute path names
# file: sftp-data/shared
# owner: root
# group: sftpusers
user::rwx
user:uploader:rwx
group::r-x
mask::rwx
other::---

步骤 6:持久化 bind mount(重启不失效)

编辑 /etc/fstab,添加:

复制代码
vi /etc/fstab
fstab 复制代码
/sftp-data/shared  /sftp/uploader/files  none  bind  0 0
/sftp-data/shared  /sftp/viewer/files    none  bind,ro  0 0

bind,ro 表示只读绑定。

然后测试挂载:

bash 复制代码
sudo mount -a

2.7.4 最终效果
用户 登录后路径 权限 能否上传?
uploader /files/ 读写 可上传、删除
viewer /files/ 只读 上传会报 "Permission denied"

两人看到的是同一份文件内容,但操作权限不同。


2.7.5 安全与注意事项
  1. SELinux 处理(CentOS/RHEL):

    bash 复制代码
    sudo setsebool -P ssh_chroot_rw_homedirs on
    sudo restorecon -R /sftp /sftp-data
  2. 不要用符号链接:SFTP 在 chroot 中默认禁用符号链接解析(安全机制)。

  3. 避免直接共享 chroot 根:因为根目录必须属主 root,无法赋写权限。

  4. 审计日志 :通过 /var/log/secure 可追踪谁上传/下载了什么文件。


2.7.6 替代方案(仅读写区分,选配(2.7.1~2.7.5)/2.7.6)

如果不需要"只读",只是多个用户都能读写同一个目录,则更简单:

  • 所有用户共用同一个 chroot 目录(如 /sftp/shared

  • 设置目录属组为 sftpusers,权限 775

  • 所有用户加入 sftpusers

  • chroot 目录必须由 root 拥有 → 所以仍需子目录:

    步骤 1:重建共享 chroot 结构
    复制代码
    # 删除旧的 per-user jails(可选)
    sudo rm -rf /sftp/uploader /sftp/viewer
    
    # 创建共用 jail
    sudo mkdir -p /sftp/shared/upload
    # 必须 root 所有!
    sudo chown root:root /sftp/shared
    sudo chown root:sftpusers /sftp/shared/upload
    sudo chmod 755 /sftp/shared
    sudo chmod 775 /sftp/shared/upload
步骤 2:修改 /etc/ssh/sshd_config
复制代码
# 注释或删除原来的 Match 块
# Match Group sftpusers
#     ChrootDirectory /sftp/%u
#     ...

# 改为:
Match Group sftpusers
    ChrootDirectory /sftp/shared
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
步骤 3:重载 SSH
复制代码
sudo sshd -t && sudo systemctl reload sshd

然后所有用户 ChrootDirectory /sftp/shared,即可共同读写 upload/(因为 sftpusers 组有 rwx),但无法实现只读/读写区分!

适合完全共享场景。


2.7.8 总结
需求 推荐方案
多用户 完全隔离 ChrootDirectory /sftp/%u(标准做法)
多用户 共享且都可读写 共用 chroot + 组权限(775)
多用户 共享但权限不同(如只读/读写) Bind mount + ACL + 只读挂载

相关博客
FTP、FTPS 和 SFTP 的区别
CentOS 搭建 SFTP 服务器(一)
CentOS 搭建 SFTP 服务器(二)
CentOS 搭建 SFTP 服务器(三)
FTP服务器安装与配置(超详细)

相关推荐
..Move...2 小时前
云原生运维企业级实战项目:CentOS Stream 8 下 Nginx 高可用集群部署
运维·云原生·centos
lhyzws2 小时前
CENTOS上的网络安全工具(三十三) Portainer Kafka-Clickhouse部署(2)
linux·运维·centos
爬山算法2 小时前
Netty(9)如何实现基于Netty的UDP客户端和服务器?
服务器·网络协议·udp
艾莉丝努力练剑2 小时前
【Linux进程(一)】深入理解计算机系统核心:从冯·诺依曼体系结构到操作系统(OS)
java·linux·运维·服务器·git·编辑器·操作系统核心
宋军涛2 小时前
记一次服务器异常宕机导致的系统异常
运维·服务器
草莓熊Lotso3 小时前
C++11 核心特性实战:列表初始化 + 右值引用与移动语义(附完整代码)
java·服务器·开发语言·汇编·c++·人工智能·经验分享
草莓熊Lotso4 小时前
GCC/G++ 编译器完全指南:从编译流程到进阶用法(附实操案例)
linux·运维·服务器·网络·c++·人工智能·自动化
鸠摩智首席音效师10 小时前
linux 系统中 Shutting Down, Restarting, Halting 有什么区别 ?
linux·运维·服务器