跳到主要内容Linux 服务器配置 SFTP 完整指南与安全实践 | 极客日志Shell / Bash
Linux 服务器配置 SFTP 完整指南与安全实践
Linux 服务器配置 SFTP 涉及安装 OpenSSH、创建受限用户组及目录权限设置。核心在于使用 ChrootDirectory 限制用户访问范围,确保根目录属主为 root 且不可写,上传目录由用户拥有。需修改 sshd_config 启用 internal-sftp 并禁用端口转发等不安全选项。安全强化包括 SSH 公钥认证、防火墙配置、Fail2Ban 防护及日志审计。提供详细步骤、常见错误排查及一键部署脚本,帮助实现安全可控的文件传输。
AiEngineer2 浏览 SFTP(SSH File Transfer Protocol) 是一种基于 SSH 的安全文件传输协议。
相比传统 FTP,它有如下优势:
- 只使用单一端口(通常 22),无需额外开放端口
- 全程加密传输,保证数据在网络中不被截获
- 可以直接复用 SSH 用户体系,无需额外账户管理
- 支持 Chroot 目录隔离、操作日志审计、密钥认证 等企业级安全机制
SFTP 已成为企业和个人服务器最常用、最安全的文件上传方式之一。
二、安装与启动 OpenSSH
SFTP 依赖 OpenSSH Server,大部分 Linux 系统已自带。
如果未安装,可以执行:
Ubuntu / Debian
sudo apt update
sudo apt install -y openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh
sudo systemctl status ssh
CentOS / 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。
创建受限用户组和用户:
sudo groupadd sftpusers
sudo useradd -g sftpusers -s /usr/sbin/nologin sftpuser
sudo passwd sftpuser
-s /usr/sbin/nologin:禁止用户获得 shell 登录权限
-g sftpusers:将用户加入 SFTP 专用组
-m 参数用于同时创建 home 目录,但如果你打算用 /sftp 作为 Chroot 根目录,其实可以省略
四、目录结构与权限(关键坑点)
- Chroot 根目录必须由 root 拥有
- 根目录不可被非 root 用户写入
- 用户写入必须在根目录下的子目录
推荐目录结构
创建目录并设置权限
sudo mkdir -p /sftp/uploads
sudo chown root:root /sftp
sudo chmod 755 /sftp
sudo chown sftpuser:sftpusers /sftp/uploads
sudo chmod 700 /sftp/uploads
注意:常见坑点包括 /sftp 被非 root 拥有导致登录失败 bad ownership or modes for chroot directory;忘记创建可写子目录导致无法上传文件;子目录权限错误等。
五、修改 SSH 配置
sudo nano /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
sudo systemctl restart sshd
七、测试 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 "你的公钥内容" | sudo tee /home/sftpuser/.ssh/authorized_keys
sudo chmod 700 /home/sftpuser/.ssh
sudo chmod 600 /home/sftpuser/.ssh/authorized_keys
sudo chown -R sftpuser:sftpusers /home/sftpuser/.ssh
PasswordAuthentication no
PubkeyAuthentication yes
2. 磁盘配额
sudo apt install quota
sudo edquota -u sftpuser
3. 日志与审计
sudo apt install auditd
sudo auditctl -w /sftp/uploads -p war -k sftp_watch
4. 系统和 OpenSSH 更新
sudo apt update && sudo apt upgrade -y
sudo apt install unattended-upgrades
5. 防火墙配置
sudo ufw allow 22/tcp
sudo ufw enable
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
6. Fail2Ban 防暴力破解
sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
九、企业级拓展
| 场景 | 推荐做法 |
|---|
| 多用户隔离 | 每个用户独立子目录: /sftp/user1/uploads |
| 审计与监控 | 使用 ELK / Graylog 收集 SFTP 日志 |
| 容器化部署 | 在 Docker / Podman 中运行 SFTP 服务 |
| 自动化管理 | 使用 Ansible / Terraform 批量配置 |
| 负载均衡 | 使用 HAProxy 或 Nginx 进行 SFTP 负载分发 |
多用户隔离示例
sudo mkdir -p /sftp/user1/uploads
sudo mkdir -p /sftp/user2/uploads
sudo chown user1:sftpusers /sftp/user1/uploads
sudo chown user2:sftpusers /sftp/user2/uploads
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
USERNAME=${1:-sftpuser}
PASSWORD=$2
SFTP_ROOT="/sftp"
UPLOAD_DIR="$SFTP_ROOT/uploads"
echo "=== SFTP 自动部署脚本 ==="
echo "[1/7] 检查并安装 OpenSSH..."
if command -v apt &> /dev/null; then
apt update && apt install -y openssh-server
systemctl enable ssh && systemctl start ssh
elif command -v yum &> /dev/null; then
yum install -y openssh-server
systemctl enable sshd && systemctl start sshd
fi
echo "[2/7] 创建 SFTP 用户组和用户..."
groupadd -f sftpusers
if id "$USERNAME" &>/dev/null; then
echo "用户 $USERNAME 已存在"
else
useradd -g sftpusers -s /usr/sbin/nologin "$USERNAME"
if [ -n "$PASSWORD" ]; then
echo "$USERNAME:$PASSWORD" | chpasswd
else
echo "请为用户 $USERNAME 设置密码:"
passwd "$USERNAME"
fi
fi
echo "[3/7] 创建目录并设置权限..."
mkdir -p "$UPLOAD_DIR"
chown root:root "$SFTP_ROOT"
chmod 755 "$SFTP_ROOT"
chown "$USERNAME:sftpusers" "$UPLOAD_DIR"
chmod 700 "$UPLOAD_DIR"
echo "[4/7] 备份 SSH 配置..."
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup.$(date +%Y%m%d_%H%M%S)
echo "[5/7] 配置 SSH..."
if ! grep -q "Subsystem sftp internal-sftp" /etc/ssh/sshd_config; then
echo "Subsystem sftp internal-sftp" >> /etc/ssh/sshd_config
fi
if ! grep -q "Match Group sftpusers" /etc/ssh/sshd_config; then
cat >> /etc/ssh/sshd_config <<EOF
Match Group sftpusers
ChrootDirectory $SFTP_ROOT
ForceCommand internal-sftp -d /uploads
AllowTcpForwarding no
X11Forwarding no
PermitTunnel no
EOF
fi
echo "[6/7] 验证 SSH 配置..."
if sshd -t; then
echo "配置验证成功"
else
echo "配置验证失败,请检查"
exit 1
fi
echo "[7/7] 重启 SSH 服务..."
if systemctl restart ssh 2>/dev/null || systemctl restart sshd 2>/dev/null; then
echo "SSH 服务重启成功"
else
echo "SSH 服务重启失败"
exit 1
fi
echo ""
echo "✅ SFTP 部署完成!"
echo "用户名:$USERNAME"
echo "登录命令:sftp $USERNAME@$(hostname -I | awk '{print $1}')"
echo "上传目录:/uploads"
使用方法:
sudo nano sftp_setup.sh
sudo chmod +x sftp_setup.sh
sudo bash sftp_setup.sh sftpuser "your_password"
sudo bash sftp_setup.sh sftpuser
十二、总结
- 安全传输:SFTP 基于 SSH,端口单一、全程加密
- 目录隔离:Chroot + ForceCommand 强制限制
- 上传目录:根目录必须 root 拥有,用户操作在子目录
- 权限坑点:切勿给 Chroot 根目录写权限,否则登录失败
- 企业管理:结合公钥认证、日志审计、磁盘配额,实现安全、可控文件传输
- 自动化部署:使用一键脚本快速配置,避免手动操作错误
📚 延伸阅读
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
- JSON美化和格式化
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online