在 Linux 服务器上配置 SFTP 的完整指南(2025 最新安全实践)
适用对象:需要在 Linux 服务器上为团队、客户或应用安全传输文件的开发者与系统管理员
适用系统:Ubuntu / Debian / CentOS / Rocky / AlmaLinux / RHEL 等
更新时间:2025 年 10 月
一、为什么选择 SFTP?
SFTP(SSH File Transfer Protocol) 是一种基于 SSH 的安全文件传输协议。
相比传统 FTP,它有如下优势:
- 只使用单一端口(通常 22),无需额外开放端口
- 全程加密传输,保证数据在网络中不被截获
- 可以直接复用 SSH 用户体系,无需额外账户管理
- 支持 Chroot 目录隔离、操作日志审计、密钥认证 等企业级安全机制
SFTP 已成为企业和个人服务器最常用、最安全的文件上传方式之一。
二、安装与启动 OpenSSH
SFTP 依赖 OpenSSH Server,大部分 Linux 系统已自带。
如果未安装,可以执行:
Ubuntu / Debian
sudoapt update sudoaptinstall -y openssh-server sudo systemctl enablesshsudo systemctl start sshsudo systemctl status sshCentOS / RHEL / Rocky / AlmaLinux
sudo yum install -y openssh-server sudo systemctl enable sshd sudo systemctl start sshd sudo systemctl status sshd 🔹 验证 SSH 服务是否启动正常,是确保 SFTP 可用的第一步。
三、创建 SFTP 用户和组
为了安全,建议不要让普通 SSH 用户直接使用 SFTP。
创建受限用户组和用户:
sudogroupadd sftpusers sudouseradd -g sftpusers -s /usr/sbin/nologin sftpuser sudopasswd sftpuser 💡 说明:
-s /usr/sbin/nologin:禁止用户获得 shell 登录权限-g sftpusers:将用户加入 SFTP 专用组-m参数用于同时创建 home 目录,但如果你打算用/sftp作为 Chroot 根目录,其实可以省略
四、目录结构与权限(关键坑点)
OpenSSH 要求:
- Chroot 根目录必须由 root 拥有
- 根目录不可被非 root 用户写入
- 用户写入必须在根目录下的子目录
推荐目录结构
/sftp └── uploads 创建目录并设置权限
sudomkdir -p /sftp/uploads sudochown root:root /sftp sudochmod755 /sftp sudochown sftpuser:sftpusers /sftp/uploads sudochmod700 /sftp/uploads ⚠️ 常见坑点:
/sftp被非 root 拥有 → 登录失败bad ownership or modes for chroot directory- 忘记创建可写子目录 → 登录后无法上传文件,报
permission denied - 子目录权限错误 → 上传失败
五、修改 SSH 配置
编辑 /etc/ssh/sshd_config:
sudonano /etc/ssh/sshd_config 确保存在以下内容:
Subsystem sftp internal-sftp PasswordAuthentication yes ChallengeResponseAuthentication no UsePAM yes在文件底部添加:
Match Group sftpusers ChrootDirectory /sftp ForceCommand internal-sftp -d /uploads AllowTcpForwarding no X11Forwarding no PermitTunnel no 配置说明
| 配置项 | 作用 |
|---|---|
Subsystem sftp internal-sftp | 使用内置 SFTP 服务 |
ChrootDirectory /sftp | 限制用户在 /sftp 根目录活动 |
ForceCommand internal-sftp -d /uploads | 禁止 shell 命令,并登录直接进入 /uploads |
AllowTcpForwarding no | 禁止端口转发 |
PermitTunnel no | 禁止隧道连接 |
X11Forwarding no | 禁止图形界面转发 |
🔹 没有 -d /uploads 会导致登录后看到空目录,需要手动 cd uploads
六、重启 SSH 服务
sudo systemctl restart ssh# Ubuntu / Debiansudo systemctl restart sshd # CentOS / RHEL七、测试 SFTP
本地客户端命令:
sftp -P 22 sftpuser@your_server_ip 交互模式:
sftp>pwd Remote working directory: /uploads sftp>ls sftp> put test.txt sftp> get test.txt 🔹 上传失败报 permission denied 时,大概率是子目录权限问题或 Chroot 根目录非 root 拥有
八、安全强化
1. 使用 SSH 公钥认证
ssh-keygen -t ed25519 mkdir -p /home/sftpuser/.ssh echo"你的公钥内容"|sudotee /home/sftpuser/.ssh/authorized_keys sudochmod700 /home/sftpuser/.ssh sudochmod600 /home/sftpuser/.ssh/authorized_keys sudochown -R sftpuser:sftpusers /home/sftpuser/.ssh 禁用密码登录:
PasswordAuthentication no PubkeyAuthentication yes重启 SSH 服务。
2. 磁盘配额
sudoaptinstallquotasudo edquota -u sftpuser 3. 日志与审计
sudoaptinstall auditd sudo auditctl -w /sftp/uploads -p war -k sftp_watch 4. 系统和 OpenSSH 更新
sudoapt update &&sudoapt upgrade -y sudoaptinstall unattended-upgrades 5. 防火墙配置
# UFW (Ubuntu/Debian)sudo ufw allow 22/tcp sudo ufw enable# FirewallD (CentOS/RHEL)sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --reload 6. Fail2Ban 防暴力破解
sudoaptinstall fail2ban sudo systemctl enable fail2ban sudo systemctl start fail2ban 九、企业级拓展
| 场景 | 推荐做法 |
|---|---|
| 多用户隔离 | 每个用户独立子目录: /sftp/user1/uploads |
| 审计与监控 | 使用 ELK / Graylog 收集 SFTP 日志 |
| 容器化部署 | 在 Docker / Podman 中运行 SFTP 服务 |
| 自动化管理 | 使用 Ansible / Terraform 批量配置 |
| 负载均衡 | 使用 HAProxy 或 Nginx 进行 SFTP 负载分发 |
多用户隔离示例
# 为每个用户创建独立目录sudomkdir -p /sftp/user1/uploads sudomkdir -p /sftp/user2/uploads sudochown user1:sftpusers /sftp/user1/uploads sudochown user2:sftpusers /sftp/user2/uploads # 在 sshd_config 中为每个用户设置独立 Chroot Match User user1 ChrootDirectory /sftp/user1 ForceCommand internal-sftp -d /uploads Match User user2 ChrootDirectory /sftp/user2 ForceCommand internal-sftp -d /uploads 十、常见错误总结
| 报错 | 原因 | 解决方法 |
|---|---|---|
bad ownership or modes for chroot directory | Chroot 根目录非 root 拥有 | sudo chown root:root /sftp |
subsystem request failed on channel 0 | 未启用 internal-sftp | 添加 Subsystem sftp internal-sftp |
| 登录成功但无法写入 | 上传目录权限不正确 | 确认 /sftp/uploads 权限为 700 或 755 |
Permission denied (publickey,password) | 密钥或密码认证失败 | 检查公钥配置或密码设置 |
Connection closed by remote host | SSH 配置语法错误 | 运行 sudo sshd -t 检查配置 |
十一、一键部署脚本
为了方便快速部署,这里提供一个自动化脚本:
#!/bin/bash# SFTP 一键部署脚本# 使用方法: sudo bash sftp_setup.sh <username> <password>USERNAME=${1:-sftpuser}PASSWORD=$2SFTP_ROOT="/sftp"UPLOAD_DIR="$SFTP_ROOT/uploads"echo"=== SFTP 自动部署脚本 ==="# 1. 安装 OpenSSHecho"[1/7] 检查并安装 OpenSSH..."ifcommand -v apt&> /dev/null;thenapt update &&aptinstall -y openssh-server systemctl enablessh&& systemctl start sshelifcommand -v yum &> /dev/null;then yum install -y openssh-server systemctl enable sshd && systemctl start sshd fi# 2. 创建用户组和用户echo"[2/7] 创建 SFTP 用户组和用户..."groupadd -f sftpusers ifid"$USERNAME"&>/dev/null;thenecho"用户 $USERNAME 已存在"elseuseradd -g sftpusers -s /usr/sbin/nologin "$USERNAME"if[ -n "$PASSWORD"];thenecho"$USERNAME:$PASSWORD"| chpasswd elseecho"请为用户 $USERNAME 设置密码:"passwd"$USERNAME"fifi# 3. 创建目录结构echo"[3/7] 创建目录并设置权限..."mkdir -p "$UPLOAD_DIR"chown root:root "$SFTP_ROOT"chmod755"$SFTP_ROOT"chown"$USERNAME:sftpusers""$UPLOAD_DIR"chmod700"$UPLOAD_DIR"# 4. 备份原配置echo"[4/7] 备份 SSH 配置..."cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup.$(date +%Y%m%d_%H%M%S)# 5. 修改 SSH 配置echo"[5/7] 配置 SSH..."if!grep -q "Subsystem sftp internal-sftp" /etc/ssh/sshd_config;thenecho"Subsystem sftp internal-sftp">> /etc/ssh/sshd_config fiif!grep -q "Match Group sftpusers" /etc/ssh/sshd_config;thencat>> /etc/ssh/sshd_config <<EOF Match Group sftpusers ChrootDirectory $SFTP_ROOT ForceCommand internal-sftp -d /uploads AllowTcpForwarding no X11Forwarding no PermitTunnel no EOFfi# 6. 验证配置echo"[6/7] 验证 SSH 配置..."if sshd -t;thenecho"配置验证成功"elseecho"配置验证失败,请检查"exit1fi# 7. 重启服务echo"[7/7] 重启 SSH 服务..."if systemctl restart ssh2>/dev/null || systemctl restart sshd 2>/dev/null;thenecho"SSH 服务重启成功"elseecho"SSH 服务重启失败"exit1fiecho""echo"✅ SFTP 部署完成!"echo"用户名: $USERNAME"echo"登录命令: sftp $USERNAME@$(hostname -I |awk'{print $1}')"echo"上传目录: /uploads"使用方法:
# 保存脚本sudonano sftp_setup.sh # 添加执行权限sudochmod +x sftp_setup.sh # 运行脚本(自动设置密码)sudobash sftp_setup.sh sftpuser "your_password"# 或运行后手动输入密码sudobash sftp_setup.sh sftpuser 十二、总结
- 安全传输:SFTP 基于 SSH,端口单一、全程加密
- 目录隔离:Chroot + ForceCommand 强制限制
- 上传目录:根目录必须 root 拥有,用户操作在子目录
- 权限坑点:切勿给 Chroot 根目录写权限,否则登录失败
- 企业管理:结合公钥认证、日志审计、磁盘配额,实现安全、可控文件传输
- 自动化部署:使用一键脚本快速配置,避免手动操作错误