在某些情况下, 我们希望将 SFTP 用户限制在某个特定目录内, 出于安全考虑。OpenSSH 提供了 Chroot Jail 机制来实现这一功能。
⚠️ 需要注意。在 chroot 环境下, SFTP 用户不能直接写入 /
。因此要么强制他们进入一个可写的子目录, 要么提前建立合适的目录结构。
实现方式有两种:
- 针对多个用户, 可以将他们限制在各自的 home 目录, 并把 home 目录设置到自定义路径
- 针对单个用户, 可以在
sshd_config
中直接指定目录
本文主要介绍如何为多个用户设置
如何为多个用户进行设置
创建用户组
首先, 创建一个专门的 sftp 用户组
groupadd sftprestricted
创建目录
创建存放用户目录的路径
mkdir /location/to/your/HomeFolder
创建用户
创建新用户并将其直接加入 sftprestricted
组, 同时指定 home 目录为刚才创建的目录, 并禁用 shell 登录
useradd -d /location/to/your/HomeFolder -m USERNAME -g sftprestricted -s /sbin/nologin
说明
-s /bin/false
或/sbin/nologin
用于禁止用户直接通过 SSH 获取 shell- 在禁用 shell 之前不要使用
ssh-copy-id
来复制公钥, 因为 chroot 权限限制会导致authorized_keys
无法使用
设置权限
由于 OpenSSH 对 chroot jail 有严格要求:
- 用户 home 目录必须归 root 所有
- 用户不能对其 home 根目录直接写入
因此, 需要调整目录权限
chown root:root /location/to/your/HomeFolder
chmod 755 /location/to/your/HomeFolder
如果要允许用户写入, 需要在其 home 目录下再创建一个子目录, 例如 /location/to/your/HomeFolder/data
, 并设置权限
子目录权限可根据需要设置为 755
或 750
mkdir /location/to/your/HomeFolder/data
chown USERNAME:sftprestricted /location/to/your/HomeFolder/data
chmod 755 /ftpusers/HomeFolder/data
这样, 用户登录后只能在 data
子目录中进行读写
启用 internal-sftp
编辑 /etc/ssh/sshd_config
, 将 sftp-server
替换为 internal-sftp
# override default of no subsystems
# Subsystem sftp /usr/libexec/openssh/sftp-server
Subsystem sftp internal-sftp
UsePAM yes
这样, sftp 服务会作为 SSH 内置子系统运行, 而不会再启动独立的 sftp 进程。
从功能上看, sftp-server
与 internal-sftp
基本相同, 且由同一份源码构建。
设置 Chroot Jail
编辑 /etc/ssh/sshd_config
, 在末尾添加
# SFTP Chroot Jail
Match Group sftprestricted
ChrootDirectory %h
ForceCommand internal-sftp
PasswordAuthentication no
PubkeyAuthentication yes
PermitTunnel no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
说明
ChrootDirectory %h
: 将用户限制在其 home 目录ForceCommand internal-sftp
: 确保用户只能使用 SFTP, 不会执行.bashrc
或其他命令- 同时禁止隧道、转发、X11 等, 强制使用公钥认证
配置密钥认证 (推荐)
最佳实践是使用 密钥认证 来进行 SSH/SFTP 连接
默认情况下, OpenSSH 会检查 /home/%u/.ssh/authorized_keys
来读取公钥
由于 home 目录权限限制, ~/.ssh/authorized_keys
在 chroot jail 中无法正常使用, 因此需要为 SFTP 用户指定一个独立的密钥存放目录, 例如 /etc/ssh/user_keys/
创建目录和密钥文件
先创建存放密钥的目录, 并为用户生成对应的 authorized_keys
文件, 并将户名附加到文件名中
mkdir /etc/ssh/user_keys
vim /etc/ssh/user_keys/authorized_keys_USERNAME
修改权限
为文件设置适当权限, 确保只有目标用户可以读取密钥
chown USERNAME:sftprestricted /etc/ssh/user_keys/authorized_keys_USERNAME
chmod 640 /etc/ssh/user_keys/authorized_keys_USERNAME
为用户组指定密钥文件位置
编辑 /etc/ssh/sshd_config
, 在末尾添加以下配置, 指定自定义密钥文件路径
# SSH Key authentication for SFTP users using chroot
Match Group sftprestricted
AuthorizedKeysFile /etc/ssh/user_keys/authorized_keys_%u
为特定用户指定密钥文件位置
如果需要针对单个用户设置, 可以使用 Match User
Match User USERNAME
AuthorizedKeysFile /etc/ssh/user_keys/authorized_keys_%u
允许用户写入根目录 (可选)
如果希望用户直接写入 chroot 的根目录, 可以通过 -d
强制他们进入某个子目录
# SFTP Chroot Jail
Match Group sftprestricted
ChrootDirectory %h
ForceCommand internal-sftp -d /subdirectory
PasswordAuthentication no
PubkeyAuthentication yes
PermitTunnel no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
其中 /subdirectory
必须归用户所有, 并设置正确权限
重启 SSH 服务
配置完成后, 重启 SSH 服务并检查状态。在保持当前终端会话不关闭的情况下, 建议再开一个新终端测试 SSH 登录是否正常。
systemctl restart sshd
systemctl status sshd
调试与问题排查
首先, 仔细检查权限设置, 因为权限问题是最常见的原因。
- chroot 根目录必须由 root 拥有, 并且不可写
- 用户写入目录必须是子目录
使用详细模式调试 SFTP
sftp -vvv username@host.local
查看 SSH 日志
可以在 /etc/ssh/sshd_config
中临时开启调试日志, 调试完成后记得恢复默认配置
# Logging
# SyslogFacility AUTH
SyslogFacility AUTHPRIV
LogLevel DEBUG
修改后重启 SSH 服务并检查状态
systemctl restart sshd
systemctl status sshd
然后查看 sshd
服务日志, 确认是否有权限或其他错误。日志文件路径因系统而异, 一般在 /var/log/secure
或 /var/log/auth.log
tail -f /var/log/secure
原文
Restrict SFTP user to a specific folder
Limit SFTP user access to specified directory