我有一个通过 SFTP 接收文件集合的应用程序。我需要知道该会话何时结束,以便我可以按组处理这批文件。
目前,我正在使用强力解决方案,即在最后一次文件更改后等待一小时作为传输完成的信号。还有什么比超时更优雅/更可靠的吗?
[编辑] 添加对 larsks 评论的回应。
在这个环境中,我只能控制接收端。我无法强迫发送方做任何事情(包括发送标志文件或控制文件顺序),只能批量发送文件。幸运的是,他们同意使用 SFTP。
答案1
如果您使用的是 OpenSSH(或使用 PAM 的其他 SFTP 服务器),请设置自定义 PAM“会话”模块,该模块将在会话打开时触发或关闭。
该标准pam_exec.so
可用于以下目的:
# Skip the next 1 module if the condition fails
session [success=ignore default=1] pam_succeed_if.so quiet user = BatchUpload
session optional pam_exec.so type=close_session /bin/systemctl --no-block start BatchJob.service
(请不要在 PAM 上下文中直接运行整个作业。如果您有 systemd,请将您的处理“分离”为 systemd 服务运行。如果您没有 systemd – 请使用 Fedora 的 oddjobd,或者让 PAM 成为touch
cronjob 可以查看的标志文件,或者将消息发布到某种形式的消息队列等。)
对于 OpenSSH,只要您不使用ChrootDirectory
(尽管在您的情况下您可能正在使用),SFTP 子系统就可以重定向到运行实际的包装器脚本,sftp-server
然后执行您想要的任何类型的自定义任务。
Subsystem sftp-server /usr/local/sbin/sftp-server-wrapper.sh
SSH 子系统只是命令别名,在用户上下文中运行,不需要任何额外的权限,因此脚本需要使用 sudo/doas 才能使用 systemctl。
答案2
您可以通过在 SSHLog 中设置命令触发器来解决这个问题(我是贡献者)。
https://github.com/sshlog/agent/
这是一个可以完成您想要的操作的示例配置:
events:
- event: upload_complete
triggers: [ 'command_finish']
filters:
command_name: 'scp'
username: 'upload_user'
command_exit_code: '= 0'
actions:
- action: do_the_thing
plugin: run_command_action
command: /usr/local/bin/process_batch
args: ["arg1", "arg2"]
因此,只要“scp”命令执行完毕,就会触发此操作,同时要求 usrename 为“upload_user”。
或者,您也可以监听“connection_close”事件(即,如果上传用户正在传输多个文件,而您想等待所有文件完成)。
此处的操作将以 root 身份触发您的脚本。