首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >ssh和sftp分开独立运行方案

ssh和sftp分开独立运行方案

作者头像
保持热爱奔赴山海
发布2026-08-11 22:22:12
发布2026-08-11 22:22:12
790
举报
文章被收录于专栏:DevOpsDevOps

原文地址: 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 配置文件

代码语言:txt
复制
$ cp /etc/ssh/sshd_config /etc/ssh/sftpd_config            

2.编辑 /etc/ssh/sftpd_config,核心修改两项:

代码语言:txt
复制
# SFTP 服务独立端口            
Port 2233            
# 独立 PID 文件,避免与原生 sshd 进程冲突            
PidFile /var/run/sftpd.pid            

3.创建 systemd 服务单元

代码语言:txt
复制
$ cp /usr/lib/systemd/system/sshd.service /etc/systemd/system/sftpd.service            

编辑 /etc/systemd/system/sftpd.service,关键修改点如下:

代码语言:txt
复制
[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 + 防火墙)

代码语言:txt
复制
# 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 子系统:

代码语言:txt
复制
# Subsystem sftp /usr/libexec/openssh/sftp-server            

重启原生 sshd 生效:

代码语言:txt
复制
systemctl restart sshd            

6.SFTP 专属服务(2233 端口)仅允许 SFTP,禁止终端登录

编辑 /etc/ssh/sftpd_config,做以下权限限制:

代码语言:txt
复制
# 注释默认子系统,改用性能更好、支持目录隔离的 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 服务:

代码语言:txt
复制
systemctl daemon-reload            
systemctl start sftpd            
systemctl enable sftpd            

7.创建 SFTP 专属用户

创建 SFTP 专属用户组:

代码语言:txt
复制
groupadd sftponly            

创建用户,设置登录 shell 为 /bin/false(从系统层面禁止终端登录):

代码语言:txt
复制
useradd sftptestuser -g sftponly -s /bin/false            
passwd sftptestuser            

8.测试

SFTP 连接 2233 端口:

代码语言:txt
复制
sftp -P 2233 sftptestuser@服务器IP            

图片
图片

SSH 连接 2233 端口(认证通过后立即断开,无终端权限):

代码语言:txt
复制
ssh -p 2233 sftptestuser@服务器IP            

图片
图片

生产环境补充优化

优化内容

目录 Chroot 隔离:通过 ChrootDirectory 参数限制 SFTP 用户只能访问自己的工作目录,防止越权访问系统文件。

  1. ChrootDirectory 指定的目录,以及它的所有上级目录,必须由 root 用户拥有
  2. 权限最大只能是 755,绝对不能给普通用户写权限。
  3. 用户若需写入文件,必须在 Chroot 根目录内新建子目录,给用户赋予子目录的写权限

密钥登录:生产环境禁用密码认证,改用 SSH 密钥登录,大幅提升安全性。

日志审计分离:配置独立的日志输出路径,单独记录 SFTP 文件操作日志,满足合规审计要求。

实现示例

每个用户独立 Chroot 根:

系统实际路径

属主:属组

权限

作用

/sftpdata/chroot/sftptestuser

root:root

755

用户 sftptestuser 的 Chroot 根目录,用户只读不可写

/sftpdata/chroot/sftptestuser/upload

sftptestuser:sftponly

755

用户可读写的上传目录

1.创建目录并赋权

代码语言:txt
复制
# 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

代码语言:txt
复制
# 注释掉默认外部子系统,使用内置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 安全上下文配置

代码语言:txt
复制
# 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 目录,执行:

代码语言:txt
复制
usermod -d /upload sftptestuser            

登录后用户视角:当前目录为 /upload,可直接上传文件

系统实际路径:/sftpdata/chroot/sftptest/upload

若不修改,用户登录后默认在 Chroot 根目录 /(只读,无法直接上传),需要手动 cd upload 才能写入。

5.验证配置与重启服务

代码语言:txt
复制
# 无任何输出即为配置语法正确,有报错会直接提示行号。            
sshd -t -f /etc/ssh/sftpd_config            

# 重启sftp服务            
systemctl restart sftpd            

6.验证

代码语言:txt
复制
sftp -P 2233 sftptestuser@服务器IP            

登录后执行以下操作验证监禁效果:

pwd:查看当前路径,应为 / 或 /upload

cd / 后 ls:只能看到 Chroot 内的目录,看不到系统的 /etc /root 等目录

put 本地文件:只能在 upload 目录下成功上传,根目录上传会报权限错误

图片
图片

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

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 方案:
  • 实现过程:
  • 生产环境补充优化
    • 优化内容
    • 实现示例
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档