基于atmoz/sftp的Docker SFTP服务器:会话结束后触发脚本可行吗?
实现SFTP会话结束后自动处理上传文件的方法
以下是几种基于atmoz/sftp Docker镜像的可行实现方案:
方案一:通过PAM会话钩子触发脚本
利用OpenSSH的PAM模块,在SFTP会话关闭时执行处理脚本,是最贴合需求的原生方式:
- 构建自定义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
- 运行自定义容器
挂载宿主机目录持久化用户数据、处理结果和日志:
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进程状态,当进程终止时对对应用户的文件进行处理:
- 构建自定义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
- 运行容器
同方案一的挂载逻辑,确保宿主机目录权限正确。
注意事项
- 确保处理脚本拥有访问上传目录、处理目录的权限,可通过调整用户组或
chmod实现 - 处理逻辑需避免重复操作,例如移动文件后原目录清空,或给已处理文件添加标记
- 建议保留详细日志,便于排查处理失败或未触发的问题
内容的提问来源于stack exchange,提问作者Skeeve
相关产品推荐
相关产品推荐

