CentOS 搭建 SFTP 服务器
适用系统:CentOS 7 / 8 / 9(及 Rocky Linux、AlmaLinux)
注:本文章是CentOS 搭建 SFTP 服务器(一)的进阶,如实操请先搭建SFTP服务器
第三阶段:高级安全加固(选配)
以下功能可根据实际需求选择启用,不影响基础 SFTP 使用。
选配 3.1:处理 SELinux(CentOS 特有)
适用场景:若第二阶段测试失败,且系统启用了 SELinux(默认开启)。
方法 A(推荐):启用布尔值
bash
# 允许 chroot 内 SFTP 用户写入
sudo setsebool -P ssh_chroot_rw_homedirs on
方法 B(备选):修复文件上下文
bash
# 安装管理工具(如未安装)
sudo yum install -y policycoreutils-python-utils
# 设置正确 SELinux 类型
sudo semanage fcontext -a -t ssh_home_t "/sftp(/.*)?"
sudo restorecon -Rv /sftp
验证:
bash
ls -Z /sftp/sftpuser
# 应显示 context 包含 ssh_home_t
选配 3.2:启用日志审计
在 /etc/ssh/sshd_config 中添加(可在全局或 Match 块内):
vi /etc/ssh/sshd_config
添加内容如下:
conf
LogLevel VERBOSE
重启 SSH:
bash
sudo systemctl restart sshd
查看日志:
bash
sudo grep sftpuser /var/log/secure
# 可看到登录、文件传输记录
例:确认 uploader用户 是否成功通过 SFTP 登录?
sudo grep -i 'uploader' /var/log/secure
内容如下(我先登出再登录,最后查询):
# 登出与登录信息
Dec 14 11:59:54 VM-16-12-centos sshd[26045]: pam_unix(sshd:session): session closed for user uploader
Dec 14 12:00:01 VM-16-12-centos sudo: root : TTY=pts/1 ; PWD=/root ; USER=root ; COMMAND=/bin/grep -i uploader /var/log/secure
Dec 14 12:00:11 VM-16-12-centos sshd[29421]: Accepted password for uploader from 112.**.**.86 port 1**3 ssh2
Dec 14 12:00:11 VM-16-12-centos sshd[29421]: pam_unix(sshd:session): session opened for user uploader by (uid=0)
Dec 14 12:00:11 VM-16-12-centos sshd[29421]: Changed root directory to "/sftp/uploader" [postauth]
Dec 14 12:00:11 VM-16-12-centos sshd[29421]: Starting session: forced-command (config) 'internal-sftp' for uploader from 112.19.68.86 port 1203 id 0 [postauth]
# 系统记录的 sudo 审计日志
Dec 14 12:00:17 VM-16-12-centos sudo: root : TTY=pts/1 ; PWD=/root ; USER=root ; COMMAND=/bin/grep -i uploader /var/log/secure
选配 3.3:使用 SSH 密钥认证(替代密码或双用)
更安全,但配置稍复杂(因 chroot 限制)。
3.3.1.SSH 密钥生成方式(客户端操作)
密钥应在用户自己的电脑(客户端) 上生成,不要在服务器上生成私钥!
方法 1:使用 ssh-keygen(推荐)
# 生成 Ed25519 密钥(更安全、更快)
ssh-keygen -t ed25519 -f ~/.ssh/id_sftpuser -C "sftpuser@sftp"
# 或 RSA(兼容性更好)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_sftpuser -C "sftpuser@sftp"
命令执行后,全敲回车就会生成密钥文件
- 私钥:id_sftpuser(绝不上传到服务器!)
- 公钥:id_sftpuser.pub(需要上传到服务器)
方法 2:使用工具(如 PuTTYgen、VS Code Remote、Termius 等)
导出 OpenSSH 格式的公钥(以 ssh-ed25519 AAAAC3... 开头)
这是我在Windows上生成的密钥文件
ssh-keygen -t ed25519 -f "$HOME\.ssh\id_sftpuser" -C "sftpuser@sftp"

将公钥(id_sftpuser.pub)上传至服务器
3.3.2.在 chroot 外 创建密钥目录(由 root 控制)
bash
# 创建sftpuser用户的密钥存放目录
sudo mkdir -p /etc/ssh/sftp-keys/sftpuser
# 复制生成的公钥到对应的密钥目录中
sudo cp /root/id_sftpuser.pub /etc/ssh/sftp-keys/sftpuser/authorized_keys
# 有目录和文件必须由 root 拥有,且不可被其他用户写
sudo chown root:root /etc/ssh/sftp-keys/sftpuser/authorized_keys
sudo chmod 600 /etc/ssh/sftp-keys/sftpuser/authorized_keys

3.3.3.修改 /etc/ssh/sshd_config 的 Match 块
vi /etc/ssh/sshd_config
添加如下内容:
conf
# 允许密码 or 公钥(二选一或两者都开)
PasswordAuthentication yes
# 指定公钥路径(在 chroot 之外)
AuthorizedKeysFile /etc/ssh/sftp-keys/%u/authorized_keys

3.3.4.重载 sshd
sudo sshd -t && sudo systemctl reload sshd
注意:密钥路径必须在 chroot 之外,且由 root 控制。

成功登录,后续只允许密钥登录 的话,也配置文件(/etc/ssh/sshd_config )中的PasswordAuthentication改为no,即可
PasswordAuthentication no
3.3.5.新用户流程与快速部署脚本
如果你配置了密钥登录,那新用户需要以下流程
- 创建用户,加入组,设置密码
- 生成用户的密钥,将公钥上传
新用户快速部署脚本(选做)
vi add-sftp-user.sh:
#!/bin/bash
# 初始化设置密码与密钥
USER=$1
PUBKEY=$2
sudo useradd -g sftpusers -d /sftp/$USER -s /sbin/nologin $USER
sudo passwd $USER # 设密码
sudo mkdir -p /etc/ssh/sftp-keys/$USER
sudo cp "$PUBKEY" /etc/ssh/sftp-keys/$USER/authorized_keys
sudo chown root:root /etc/ssh/sftp-keys/$USER/authorized_keys
sudo chmod 600 /etc/ssh/sftp-keys/$USER/authorized_keys
或
#!/bin/bash
# 初始化设置密钥,禁用密码
USER=$1
PUBKEY=$2
if [[ -z "$USER" || -z "$PUBKEY" ]]; then
echo "Usage: $0 <username> <public_key_file>"
exit 1
fi
# 创建用户(无密码 shell)
sudo useradd -g sftpusers -d /sftp/$USER -s /sbin/nologin $USER
# 部署公钥
sudo mkdir -p /etc/ssh/sftp-keys/$USER
sudo cp "$PUBKEY" /etc/ssh/sftp-keys/$USER/authorized_keys
sudo chown root:root /etc/ssh/sftp-keys/$USER/authorized_keys
sudo chmod 600 /etc/ssh/sftp-keys/$USER/authorized_keys
# 锁定密码(双重保险,确保无法用密码登录)
sudo passwd -l $USER
echo " User '$USER' created with key-only access."
使用(创建auditor用户)
./add-sftp-user.sh auditor /root/auditor.pub
参数1:用户名(auditor)
参数2:公钥在服务器上存放的位置(/root/auditor.pub)
选配 3.4:防暴力破解(fail2ban)
bash
sudo yum install -y fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
编辑 /etc/fail2ban/jail.local
vi /etc/fail2ban/jail.local
启用 SSH 监控:
ini
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/secure
maxretry = 3
bantime = 3600

启动:
bash
sudo systemctl enable --now fail2ban
选配 3.5:批量添加用户脚本
可参考3.3.5.新用户流程与快速部署脚本,如果你没配置密钥登录,就可以采用下面的脚本,进行批量用户的创建。
vi /usr/local/bin/add_sftp_user.sh
bash
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Usage: $0 <username>"
exit 1
fi
U=$1; G=sftpusers; D=/sftp
sudo useradd -g $G -d $D/$U -s /sbin/nologin $U
sudo passwd $U
sudo mkdir -p $D/$U/upload
sudo chown root:root $D/$U
sudo chmod 755 $D/$U
sudo chown $U:$G $D/$U/upload
sudo chmod 755 $D/$U/upload
echo "User $U created."
赋予权限并使用:创建用户client01
bash
sudo chmod +x /usr/local/bin/add_sftp_user.sh
sudo /usr/local/bin/add_sftp_user.sh client01
常见问题排查
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
Connection closed by remote host |
chroot 目录权限错误 | 确保 /sftp/user 属主为 root:root,权限 755 |
| 登录后立即断开 | SELinux 阻止 | 执行 setsebool -P ssh_chroot_rw_homedirs on |
Permission denied 无法写入 |
试图写根目录 | 告知用户只能使用 upload/ 子目录 |
Write failed: Broken pipe |
sshd_config 语法错误 | 运行 sudo sshd -t 检查 |
| 无法连接 22 端口 | 防火墙/安全组未放行 | 检查 firewalld 和云平台安全组 |
阶段路线图
| 阶段 | 内容 | 是否必做 |
|---|---|---|
| 第一阶段 | 安装并启动 SSH 服务 | 必做 |
| 第二阶段 | 创建用户、目录、配置 chroot SFTP | 必做 |
| 第三阶段 | SELinux、日志、密钥、fail2ban 等 | 选配 |
相关博客 :
FTP、FTPS 和 SFTP 的区别
CentOS 搭建 SFTP 服务器(一)
CentOS 搭建 SFTP 服务器(二)
CentOS 搭建 SFTP 服务器(三)
FTP服务器安装与配置(超详细)