You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于atmoz/sftp的Docker SFTP服务器:会话结束后触发脚本可行吗?

实现SFTP会话结束后自动处理上传文件的方法

以下是几种基于atmoz/sftp Docker镜像的可行实现方案:

方案一:通过PAM会话钩子触发脚本

利用OpenSSH的PAM模块,在SFTP会话关闭时执行处理脚本,是最贴合需求的原生方式:

  1. 构建自定义Docker镜像
    创建Dockerfile:
FROM atmoz/sftp

# 安装PAM脚本依赖
RUN apt-get update && apt-get install -y libpam-script && rm -rf /var/lib/apt/lists/*

# 添加会话结束处理脚本
COPY post-sftp-session.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/post-sftp-session.sh

# 配置PAM钩子,会话关闭时触发脚本
RUN echo "session optional pam_script.so onexit=/usr/local/bin/post-sftp-session.sh" >> /etc/pam.d/sshd

编写post-sftp-session.sh处理脚本:

#!/bin/bash
# 仅处理SFTP会话关闭事件
if [ "$PAM_TYPE" = "close_session" ] && [ "$PAM_SERVICE" = "sshd" ]; then
    USER="$PAM_USER"
    UPLOAD_DIR="/home/$USER/upload" # 对应你创建用户时指定的上传目录
    PROCESS_DIR="/var/sftp-processed/$USER"

    # 若上传目录有文件则执行处理逻辑
    if [ -d "$UPLOAD_DIR" ] && [ "$(ls -A "$UPLOAD_DIR")" ]; then
        mkdir -p "$PROCESS_DIR"
        # 示例:移动文件到处理目录,可替换为解压、校验、通知等逻辑
        mv "$UPLOAD_DIR"/* "$PROCESS_DIR"/
        echo "$(date): 已处理用户$USER的上传文件" >> /var/log/sftp-handler.log
    fi
fi
  1. 运行自定义容器
    挂载宿主机目录持久化用户数据、处理结果和日志:
docker run -d \
    -p 22:22 \
    -v /host/path/sftp-users:/home \
    -v /host/path/sftp-processed:/var/sftp-processed \
    -v /host/path/sftp-logs:/var/log \
    my-custom-sftp \
    user1:pass1:1001:1001:/home/user1/upload

方案二:监控SFTP进程触发脚本

通过后台脚本监控sftp-server进程状态,当进程终止时对对应用户的文件进行处理:

  1. 构建自定义Docker镜像
    创建Dockerfile:
FROM atmoz/sftp

COPY session-monitor.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/session-monitor.sh

# 同时启动SSHD和监控脚本
CMD ["sh", "-c", "/usr/sbin/sshd -D & /usr/local/bin/session-monitor.sh"]

编写session-monitor.sh监控脚本:

#!/bin/bash
# 初始化用户列表文件
touch /tmp/previous-sftp-users.txt

while true; do
    # 获取当前活跃的SFTP用户
    ps aux | grep -v grep | grep sftp-server | awk '{print $1}' | sort -u > /tmp/current-sftp-users.txt
    
    # 对比找出已断开会话的用户
    comm -13 /tmp/current-sftp-users.txt /tmp/previous-sftp-users.txt | while read USER; do
        UPLOAD_DIR="/home/$USER/upload"
        PROCESS_DIR="/var/sftp-processed/$USER"
        
        if [ -d "$UPLOAD_DIR" ] && [ "$(ls -A "$UPLOAD_DIR")" ]; then
            mkdir -p "$PROCESS_DIR"
            mv "$UPLOAD_DIR"/* "$PROCESS_DIR"/
            echo "$(date): 已处理用户$USER的上传文件" >> /var/log/sftp-handler.log
        fi
    done
    
    # 更新用户列表
    cp /tmp/current-sftp-users.txt /tmp/previous-sftp-users.txt
    sleep 10 # 10秒轮询一次,可调整频率
done
  1. 运行容器
    同方案一的挂载逻辑,确保宿主机目录权限正确。

注意事项

  • 确保处理脚本拥有访问上传目录、处理目录的权限,可通过调整用户组或chmod实现
  • 处理逻辑需避免重复操作,例如移动文件后原目录清空,或给已处理文件添加标记
  • 建议保留详细日志,便于排查处理失败或未触发的问题

内容的提问来源于stack exchange,提问作者Skeeve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 01:50:24