原文地址: https://mp.weixin.qq.com/s/sbMEoUOwFYKQtpuX80sPdA
今天收到安全部门的需求,看 sftp 能不能和 ssh 端口分开运行,这里分享下如何做。
SFTP 是 OpenSSH 自带的内置子系统,底层完全依赖 sshd 进程,无法单独拆成独立服务。今天分享的思路是在同一台机器上运行两个独立的 sshd 进程实例,通过不同配置文件实现端口和功能完全隔离。
·原生 sshd 服务使用22端口仅提供 SSH 终端登录,关闭 SFTP 文件传输能力
·独立 sftpd 服务(本质仍是 sshd 二进制),自定义端口(如 2233),仅提供 SFTP 文件传输,禁止 SSH 终端登录,仅允许指定用户组访问
1.创建 SFTP 专用的 sshd 配置文件
$ cp /etc/ssh/sshd_config /etc/ssh/sftpd_config 2.编辑 /etc/ssh/sftpd_config,核心修改两项:
# SFTP 服务独立端口
Port 2233
# 独立 PID 文件,避免与原生 sshd 进程冲突
PidFile /var/run/sftpd.pid 3.创建 systemd 服务单元
$ cp /usr/lib/systemd/system/sshd.service /etc/systemd/system/sftpd.service 编辑 /etc/systemd/system/sftpd.service,关键修改点如下:
[Unit]
Description=SFTP server daemon
# 依赖网络与密钥生成服务,在原生 sshd 之后启动
After=network.target sshd-keygen.service auditd.service sshd.service
Wants=sshd-keygen.service
[Service]
Type=simple
EnvironmentFile=/etc/sysconfig/sshd
# 核心:启动时指定 SFTP 专用配置文件
ExecStart=/usr/sbin/sshd -D -f /etc/ssh/sftpd_config $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target 4.放行端口(如有SELinux + 防火墙)
# SELinux 给新端口打上 ssh 服务标签
semanage port -a -t ssh_port_t -p tcp 2233
# 防火墙放行端口
firewall-cmd --add-port=2233/tcp --permanent
firewall-cmd --reload 5.原生 SSH 服务(22 端口)禁用 SFTP 能力
编辑 /etc/ssh/sshd_config,注释掉默认的 SFTP 子系统:
# Subsystem sftp /usr/libexec/openssh/sftp-server 重启原生 sshd 生效:
systemctl restart sshd 6.SFTP 专属服务(2233 端口)仅允许 SFTP,禁止终端登录
编辑 /etc/ssh/sftpd_config,做以下权限限制:
# 注释默认子系统,改用性能更好、支持目录隔离的 internal-sftp
# Subsystem sftp /usr/libexec/openssh/sftp-server
Subsystem sftp internal-sftp -l INFO -f AUTH
# 仅允许 sftponly 用户组登录,其他用户一律拒绝
AllowGroups sftponly
# 匹配 SFTP 用户组,强制禁用终端登录,只能使用 SFTP
Match Group sftponly
ForceCommand internal-sftp
# 禁用所有 SSH 高级功能,收紧权限
AllowTcpForwarding no
X11Forwarding no
PermitTunnel no 重载 systemd 并启动 SFTP 服务:
systemctl daemon-reload
systemctl start sftpd
systemctl enable sftpd 7.创建 SFTP 专属用户
创建 SFTP 专属用户组:
groupadd sftponly 创建用户,设置登录 shell 为 /bin/false(从系统层面禁止终端登录):
useradd sftptestuser -g sftponly -s /bin/false
passwd sftptestuser 8.测试
SFTP 连接 2233 端口:
sftp -P 2233 sftptestuser@服务器IP 
SSH 连接 2233 端口(认证通过后立即断开,无终端权限):
ssh -p 2233 sftptestuser@服务器IP 
目录 Chroot 隔离:通过 ChrootDirectory 参数限制 SFTP 用户只能访问自己的工作目录,防止越权访问系统文件。
密钥登录:生产环境禁用密码认证,改用 SSH 密钥登录,大幅提升安全性。
日志审计分离:配置独立的日志输出路径,单独记录 SFTP 文件操作日志,满足合规审计要求。
每个用户独立 Chroot 根:
系统实际路径 | 属主:属组 | 权限 | 作用 |
|---|---|---|---|
/sftpdata/chroot/sftptestuser | root:root | 755 | 用户 sftptestuser 的 Chroot 根目录,用户只读不可写 |
/sftpdata/chroot/sftptestuser/upload | sftptestuser:sftponly | 755 | 用户可读写的上传目录 |
1.创建目录并赋权
# 1. 创建目录结构(以 testuser1 为例,新增用户按同样格式复用)
mkdir -p /sftpdata/chroot/sftptestuser/upload
# 2. Chroot 根目录必须 root 所有,权限755(强制要求)
chown root:root /sftpdata/chroot/sftptestuser
chmod 755 /sftpdata/chroot/sftptestuser
# 3. 上传子目录交给用户,赋予写权限
chown sftptestuser:sftponly /sftpdata/chroot/sftptestuser/upload
chmod 755 /sftpdata/chroot/sftptestuser/upload 2.修改 SFTP 专属配置文件/etc/ssh/sftpd_config
# 注释掉默认外部子系统,使用内置internal-sftp(Chroot必备)
# Subsystem sftp /usr/libexec/openssh/sftp-server
Subsystem sftp internal-sftp -l INFO -f AUTH
# 仅允许sftponly组登录
AllowGroups sftponly
# 匹配SFTP用户组,统一应用监禁与权限规则
Match Group sftponly
# 核心:指定Chroot根目录,%u为变量自动匹配登录用户名,新增用户只需创建对应目录即可自动适配
ChrootDirectory /sftpdata/chroot/%u
# 强制使用sftp,禁止终端登录
ForceCommand internal-sftp
# 禁用所有SSH转发功能,收紧安全边界
AllowTcpForwarding no
X11Forwarding no
PermitTunnel no
PermitTTY no 3.SELinux 安全上下文配置
# 1. 给整个chroot目录添加SFTP读写安全上下文
semanage fcontext -a -t ssh_chroot_rw_content_t "/sftpdata/chroot(/.*)?"
# 2. 生效标签(递归应用)
restorecon -Rv /sftpdata/chroot
# 3. 验证标签是否生效,输出中包含 ssh_chroot_rw_content_t 即为正常。
ls -Z /sftpdata/chroot/sftptestuser 4.用户家目录适配(可选)
/etc/passwd 中用户的家目录路径,是Chroot 监禁后的相对路径,不是系统绝对路径。
如果希望用户登录后直接进入可上传的 upload 目录,执行:
usermod -d /upload sftptestuser 登录后用户视角:当前目录为 /upload,可直接上传文件
系统实际路径:/sftpdata/chroot/sftptest/upload
若不修改,用户登录后默认在 Chroot 根目录 /(只读,无法直接上传),需要手动 cd upload 才能写入。
5.验证配置与重启服务
# 无任何输出即为配置语法正确,有报错会直接提示行号。
sshd -t -f /etc/ssh/sftpd_config
# 重启sftp服务
systemctl restart sftpd 6.验证
sftp -P 2233 sftptestuser@服务器IP 登录后执行以下操作验证监禁效果:
pwd:查看当前路径,应为 / 或 /upload
cd / 后 ls:只能看到 Chroot 内的目录,看不到系统的 /etc /root 等目录
put 本地文件:只能在 upload 目录下成功上传,根目录上传会报权限错误

好了,今天的分享就到这里了,希望对大家有所帮助。如果觉得还不错的话,各位看官动动小手点赞加关注,点击下面的链接可以直接进入本公众号,查看历史文章,谢谢大家^_^
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。