Score:2

Detect when an SSH or SFTP connection has closed

sy flag

I have an application that receives a collection of files by SFTP. I need to know when that session has finished so I can process the batch of files in a group.

Currently, I'm using the brute force solution of waiting an hour after the last file change as a signal that the transfer is done. Is there anything more elegant/reliable than a timeout?

[edit] Adding in response to larsks comment.

In this environment, I only control the receiving end. I can not force the senders to do anything (including sending a flag file or controlling file order) except send the files as a batch. I'm lucky they agreed to use SFTP.

pt flag
A simple solution is to transfer a flag file after everything else has been sent: when your application sees the flag file, it knows the transfer is complete.
alsoeric avatar
sy flag
I've used that trick when I control both ends. in this case, I only control the receiving end. updated the question to clarify
djdomi avatar
za flag
you can maybe watch syslog?
Score:2
fr flag

If you are using OpenSSH (or another SFTP server that uses PAM), set up a custom PAM 'session' module that will be triggered whenever the session is opened or closed.

The standard pam_exec.so can be used for this purpose:

# 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

(Please don't actually run the entire job directly within the context of PAM. If you have systemd, run your processing "detached" as a systemd service. If you don't have systemd – use Fedora's oddjobd, or have PAM touch a flag file for a cronjob to see, or post a message to some form of message queue, etc.)


For OpenSSH, as long as you're not using ChrootDirectory (though in your case you probably are), the SFTP subsystem can be redirected to a wrapper script that runs the real sftp-server followed by any kind of custom task you want.

Subsystem sftp-server /usr/local/sbin/sftp-server-wrapper.sh

SSH subsystems are just command aliases, running in the user's context without any additional privileges, so the script would need to use sudo/doas in order to use systemctl.

Score:2
hr flag

You could solve this by setting up a command trigger in SSHLog (I'm a contributor).
https://github.com/sshlog/agent/

Here's a sample config that should accomplish what you want:

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"]

So this will trigger whenever the "scp" command has finished executing, also requiring that the usrename is "upload_user".

You could, alternatively, listen for the 'connection_close' event (i.e., if the upload user is transferring more than one file and you want to wait for them all to finish).

The action here will trigger your script as root.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.