【运维实战】企业级SFTP 文件服务 · 一键自动化部署方案 (适配AnolisOS /openEuler /CentOS)

企业 SFTP 服务一键部署:基于 OpenSSH 实现部门隔离与国产化适配

在国产操作系统替代浪潮中,如何快速搭建安全、可控的文件共享服务?本文分享一套自动化部署方案,实现"开箱即用"的 SFTP 服务。

一、业务背景:国产化替代下的文件共享难题

随着信创产业加速落地,越来越多的政府、金融、能源企业将原有 CentOS 迁移至国产 Linux 发行版,如 Anolis OS、openEuler、Rocky Linux、AlmaLinux 等。在这些环境中,常见的商业文件共享软件(如 Serv-U、WS_FTP)要么授权昂贵,要么对国产系统支持不佳。而传统的 FTP 协议明文传输、防火墙配置复杂,已逐渐被企业安全策略淘汰。

SFTP(SSH File Transfer Protocol) 凭借其基于 SSH 的加密通道、简单开放端口(22)、天然支持 Linux 权限模型等优势,成为内部文件共享的首选方案。然而,手工配置 SFTP 的 Chroot 隔离、多部门用户管理、SELinux 策略等步骤繁琐且易错,急需一套自动化工具。

二、需求分析与痛点识别

在与多家企业运维团队沟通后,我们归纳出以下核心需求与痛点:

需求点 具体描述 手工配置痛点
部门隔离 不同部门(行政、市场、设计、研发)的文件互相不可见 需逐一配置 ChrootDirectory,修改 Match Group 块
用户权限精细 同一部门内用户可共享可写目录,且用户仅能 SFTP 不能 SSH 需设置 shell 为 /sbin/nologin,配置家目录与属主
快速批量创建 一次性创建数十个用户并分配密码 手工 useradd + chpasswd 效率极低,密码管理混乱
国产系统兼容 在 Anolis OS、openEuler 等系统上无报错运行 不同发行版的 SELinux 布尔值名称、服务管理存在差异
可重复执行 部署脚本应幂等,支持后续增加用户或重置 缺乏标准化,二次维护成本高

基于以上痛点,我们设计了一套 一键式 SFTP 部署脚本,并已在阜阳云动科技内部及多家客户环境验证。

三、方案设计:打造"一键式"SFTP 服务端部署脚本

3.1 技术选型

  • 底层服务 :OpenSSH 自带的 internal-sftp(无需额外安装 vsftpd 或 proftpd)
  • 隔离机制 :Chroot 目录 + 专用系统组(sftp-*
  • 自动化工具:Bash 脚本,兼容 systemd、firewalld、SELinux
  • 密码策略 :初始明文密码在脚本中定义,首次登录强制修改(生产环境建议结合 chage

3.2 目录结构设计

复制代码
/srv/sftp/                     # SFTP 根目录(所有部门)
├── admin/                     # 行政部
│   └── files/                 # 可写子目录(用户实际家目录)
├── market/                    # 市场部
│   └── files/
├── design/                    # 设计部
│   └── files/
└── develop/                   # 研发部
    └── files/
  • Chroot 原理 :用户登录后,/ 被映射为 /srv/sftp/部门名,因此用户只能看到 /files 目录。
  • 权限设计
    • 部门根目录(如 /srv/sftp/admin)属主 root:root,权限 755 → 用户无法在此创建文件。
    • 可写子目录 /files 属主 root:sftp-admin,权限 775 → 用户可读写,同组用户可共享。

3.3 用户与组映射

脚本内置了 4 个部门、10 个虚拟用户(可根据实际修改):

  • 行政部:admin01, admin02
  • 市场部:market01, market02, market03
  • 设计部:design01, design02
  • 研发部:develop01, develop02, develop03

每个用户属于对应部门组,家目录指向 /部门根目录/files,Shell 禁用。

3.4 核心安全加固

  • 禁止 root 登录(PermitRootLogin no
  • 仅允许密码认证(可后续开启密钥)
  • 禁用 TCP 转发、X11 转发
  • 配置 SELinux 布尔值:ssh_sysadm_loginsftp_enable_homedirssshd_enable_password_auth

四、脚本核心代码节选(完整版见文末)

由于篇幅限制,以下展示脚本中最关键的几个函数:

4.1 部门目录与组创建

bash 复制代码
create_dept_structure() {
    DEPTS=("admin" "market" "design" "develop")
    for dept in "${DEPTS[@]}"; do
        groupadd "sftp-$dept" || true
        DEPT_ROOT="$SFTP_ROOT/$dept"
        mkdir -p "$DEPT_ROOT"
        chown root:root "$DEPT_ROOT"
        chmod 755 "$DEPT_ROOT"
        
        FILES_DIR="$DEPT_ROOT/files"
        mkdir -p "$FILES_DIR"
        chown "root:sftp-$dept" "$FILES_DIR"
        chmod 775 "$FILES_DIR"
    done
}

4.2 批量用户创建

bash 复制代码
declare -A USERS=(
    ["admin01"]="admin01@pwd"
    ["market01"]="market01@pwd"
    # ...
)
declare -A DEPARTMENTS=(
    ["admin01"]="admin"
    ["market01"]="market"
    # ...
)

create_sftp_users() {
    for user in "${!USERS[@]}"; do
        dept="${DEPARTMENTS[$user]}"
        group="sftp-$dept"
        useradd -g "$group" -d "$SFTP_ROOT/$dept/files" -s /sbin/nologin -M "$user"
        echo "$user:${USERS[$user]}" | chpasswd
    done
}

4.3 sshd_config 动态配置

bash 复制代码
cat >> /etc/ssh/sshd_config << EOF
Subsystem sftp internal-sftp

Match Group sftp-admin
    ChrootDirectory /srv/sftp/admin
    ForceCommand internal-sftp -d /files
    AllowTcpForwarding no
    X11Forwarding no
# ... 其他部门类似
EOF

4.4 SELinux 策略适配

bash 复制代码
if [ "$(getenforce)" = "Enforcing" ]; then
    setsebool -P ssh_sysadm_login on
    setsebool -P sftp_enable_homedirs on
    setsebool -P sshd_enable_password_auth on
fi

五、部署效果演示(成功输出摘要)

在一台 Anolis OS 8.9 服务器上执行脚本后,输出摘要如下:

复制代码
[root@MiWiFi-RA70-srv ~]# ./install-sftp.sh
╔══════════════════════════════════════════════════════════════╗
║           企业级 SFTP 一键部署脚本 (Chroot 隔离版)           ║
║               基于 OpenSSH - 支持 RHEL 8/9 及衍生版          ║
╚══════════════════════════════════════════════════════════════╝

[STEP 0] 检查系统权限...
2026-04-16 03:26:10 - 系统权限检查通过
  └─ [✓] root 权限验证成功
[STEP 1] 检测系统类型和版本...
2026-04-16 03:26:10 - 检测到系统: Anolis OS 8.10 (rpm_based)
  └─ [✓] 检测到系统: Anolis OS 8.10
  └─ [✓] 包管理器: dnf
[STEP 2] 安装 OpenSSH 服务器...
  └─ [✓] OpenSSH 服务已就绪
2026-04-16 03:26:13 - OpenSSH 服务安装/检查完成
[STEP 3] 创建部门组和目录结构...
2026-04-16 03:26:13 - 创建组 sftp-admin
2026-04-16 03:26:13 - 部门目录创建: /srv/sftp/admin
2026-04-16 03:26:13 - 创建组 sftp-market
2026-04-16 03:26:13 - 部门目录创建: /srv/sftp/market
2026-04-16 03:26:13 - 创建组 sftp-design
2026-04-16 03:26:13 - 部门目录创建: /srv/sftp/design
2026-04-16 03:26:13 - 创建组 sftp-develop
2026-04-16 03:26:13 - 部门目录创建: /srv/sftp/develop
  └─ [✓] 部门组和目录结构创建完成
[STEP 4] 创建 SFTP 用户并设置密码...
2026-04-16 03:26:13 - 创建用户 admin01 (部门: admin)
2026-04-16 03:26:13 - 设置密码 for admin01
2026-04-16 03:26:14 - 创建用户 admin02 (部门: admin)
2026-04-16 03:26:14 - 设置密码 for admin02
2026-04-16 03:26:14 - 创建用户 market01 (部门: market)
2026-04-16 03:26:14 - 设置密码 for market01
2026-04-16 03:26:14 - 创建用户 market02 (部门: market)
2026-04-16 03:26:14 - 设置密码 for market02
2026-04-16 03:26:14 - 创建用户 market03 (部门: market)
2026-04-16 03:26:14 - 设置密码 for market03
2026-04-16 03:26:14 - 创建用户 develop03 (部门: develop)
2026-04-16 03:26:14 - 设置密码 for develop03
2026-04-16 03:26:14 - 创建用户 develop02 (部门: develop)
2026-04-16 03:26:14 - 设置密码 for develop02
2026-04-16 03:26:14 - 创建用户 develop01 (部门: develop)
2026-04-16 03:26:15 - 设置密码 for develop01
2026-04-16 03:26:15 - 创建用户 design02 (部门: design)
2026-04-16 03:26:15 - 设置密码 for design02
2026-04-16 03:26:15 - 创建用户 design01 (部门: design)
2026-04-16 03:26:15 - 设置密码 for design01
  └─ [✓] SFTP 用户创建完成
[STEP 5] 备份原始 SSH 配置文件...
  └─ [✓] 已备份至 /etc/ssh/sshd_config.bak_20260416
2026-04-16 03:26:15 - SSH 配置文件备份完成
[STEP 6] 配置 SSH 守护进程 (SFTP + Chroot)...
  └─ [✓] sshd_config 语法正确
2026-04-16 03:26:15 - sshd_config 配置完成
[STEP 7] 配置防火墙规则...
  └─ [WARN] firewalld 未运行,请手动确保端口 22 开放
2026-04-16 03:26:15 - 防火墙配置完成
[STEP 8] 配置 SELinux 策略...
  └─ [INFO] SELinux 未处于强制模式,跳过
2026-04-16 03:26:15 - SELinux 配置完成
[STEP 9] 重启 SSH 服务...
  └─ [✓] SSH 服务重启成功
2026-04-16 03:26:17 - SSH 服务重启完成
[STEP 10] 验证 SFTP 服务配置...
  ├─ [✓] SSH 服务状态: active
  ├─ [✓] 端口 22 监听: 是
  └─ [✓] SFTP 子系统可用(internal-sftp)
2026-04-16 03:26:17 - SFTP 服务验证完成

╔══════════════════════════════════════════════════════════════╗
║                    SFTP 服务部署完成信息                     ║
╚══════════════════════════════════════════════════════════════╝

  ● 系统版本: Anolis OS 8.10
  ● SFTP 服务: OpenSSH option
  ● 根目录: /srv/sftp

┌────────────────────────────────────────────────────────────┐
│                    用户账号信息                            │
├────────────────────────────────────────────────────────────┤
用户名    密码          登录后路径
─────────────────────────────────────────────────────────────────
admin01      admin01@pwd     /files (在部门根目录下)
admin02      admin02@pwd     /files (在部门根目录下)
design01     design01@pwd    /files (在部门根目录下)
design02     design02@pwd    /files (在部门根目录下)
develop01    develop01@pwd   /files (在部门根目录下)
develop02    develop02@pwd   /files (在部门根目录下)
develop03    develop03@pwd   /files (在部门根目录下)
market01     market01@pwd    /files (在部门根目录下)
market02     market02@pwd    /files (在部门根目录下)
market03     market03@pwd    /files (在部门根目录下)
└────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────┐
│                    网络访问信息                            │
├────────────────────────────────────────────────────────────┤
│ SFTP 地址: sftp://192.168.31.33:22                        │
│ 客户端: FileZilla, WinSCP, 命令行 sftp user@IP                  │
└────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────┐
│                    服务管理                                │
├────────────────────────────────────────────────────────────┤
│ systemctl start|stop|restart|status sshd                  │
└────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────┐
│                    目录结构                                │
├────────────────────────────────────────────────────────────┤
│ /srv/sftp/admin/files   - 行政部可写区域                  │
│ /srv/sftp/market/files  - 市场部可写区域                  │
│ /srv/sftp/design/files  - 设计部可写区域                  │
│ /srv/sftp/develop/files - 研发部可写区域                  │
└────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────┐
│                    安全提醒                                │
├────────────────────────────────────────────────────────────┤
│ 1. 所有用户已禁用 shell,仅允许 SFTP 登录                  │
│ 2. 用户被 chroot 到部门根目录,无法访问系统文件           │
│ 3. 定期修改用户密码:passwd <用户名>                       │
│ 4. 查看登录日志:journalctl -u sshd -f                     │
└────────────────────────────────────────────────────────────┘

✅ 企业级 SFTP 服务部署完成!
安装日志: /var/log/sftp_deploy_20260416_032610.log

验证测试 :使用 sftp market01@服务器IP 登录,执行 pwd 显示 /files,尝试 ls / 只能看到 files 目录,无法访问系统文件,隔离生效。

六、后期维护建议(由阜阳云动科技提供)

脚本部署完成后,日常运维仍需关注以下几点:

6.1 用户增删改

  • 新增用户 :手动编辑脚本中的 USERSDEPARTMENTS 数组,重新执行脚本(已有用户会跳过,新用户被创建)。
  • 删除用户userdel -r 用户名,同时清理 USERS 数组避免误重建。
  • 重置密码passwd 用户名echo "新密码" | chpasswd

6.2 磁盘空间与日志

  • 定期清理 /srv/sftp/*/files 中的过期文件,可配合 tmpwatchcron 任务。
  • SFTP 传输日志:journalctl -u sshd -f | grep "sftp"
  • 审计用户登录:last | grep sftp

6.3 安全加固进阶

  • 禁用密码,改用密钥认证 :修改 /etc/ssh/sshd_configPasswordAuthentication no,并为每个用户配置 AuthorizedKeysFile
  • 限制用户传输速率 :在 Match Group 块中添加 SftpRateLimit(需 OpenSSH 9.0+,或使用 tc 限流)。
  • IP 白名单 :通过 sshd_configAllowUsersMatch Address 实现。

6.4 备份与恢复

  • 备份目录:tar czf sftp_backup.tar.gz /srv/sftp /etc/ssh/sshd_config
  • 恢复时先解压目录,再重启 sshd,注意检查 SELinux 上下文:restorecon -Rv /srv/sftp

6.5 跨部门文件共享

当前设计部门之间天然隔离。若需跨部门读写(如设计部向市场部交付素材),可考虑:

  • 创建公共组 sftp-share,在某个部门下建立子目录,属组改为 sftp-share
  • 或使用软链接(注意 Chroot 环境内软链接不能指向外部,需使用 mount --bind)。

脚本完整版获取 :关注账号,回复 SFTP一键部署 即可下载。
技术支持:如遇国产系统兼容性问题(统信 UOS、麒麟等),欢迎联系我们获取适配版本。

阜阳云动科技有限公司,专注于系统运维、服务器网络、安全及 AI 大模型落地。我们坚信:好的运维工具,应该让复杂变简单

相关推荐
杨浦老苏2 小时前
Docker容器管理面板Dockhand
运维·docker·群晖
diygwcom2 小时前
jeecg验证码在centos报错
linux·运维·centos
努力的搬砖人.2 小时前
配置 Docker 镜像加速器
运维·docker·容器
坚持就完事了2 小时前
Linux中的tar命令
linux·运维·服务器
晚枫歌F2 小时前
同步异步阻塞非阻塞
运维·服务器
江湖有缘2 小时前
实时监控所有端口,Docker 部署 WatchYourPorts 保姆级教程
运维·docker·容器
Cyber4K2 小时前
【DevOps专项】Git 部署及使用方法
运维·git·devops
数据雕塑家2 小时前
Linux磁盘性能测试完全指南:使用FIO深入评估存储系统
linux·运维·服务器
csdn_aspnet2 小时前
告别重复造轮子:Codex写脚本,运维/DevOps场景下,用Codex批量生成Shell/Python自动化脚本
运维·python·ai·自动化·devops·codex·辅助编程