1

I run a SSH server (a plain sshd) which receives files from multiple users in different timezones/DSTs via SFTP. These files are then polled and further processed by a set of worker jobs.

In order to prevent the files not being processed (a faulty or slow worker, etc.) I decided to implement a simple check would go over all the SFTP-mapped dirs and report all files older than X.

The problem is the SFTP-received files on the server apparently feature user's local timezone/DST in their timestamps for mtime and - to my surprise - even ctime. This results in the check failing to detect files which arrived with a positive timezone offset and immediately reporting files which arrived with a negative one.

I can't seem to find a way how to normalize the timestmap of the received files to the server's local timezone or UTC.

3 Answers 3

1

You can configure your sftp-server to refuse requests to change the timestamp of a file. Look in /etc/ssh/sshd_config for the current configuration line, which in my case was

Subsystem      sftp    /usr/libexec/openssh/sftp-server

Run the server with the -Q option to list which requests can be made:

/usr/libexec/openssh/sftp-server -Q requests

In my case this included setstat and fsetstat which presumably correspond to changing the times. Use the blacklist option -P to refuse these requests in the sshd_config file:

Subsystem       sftp    /usr/libexec/openssh/sftp-server -P setstat,fsetstat

Notify sshd to reread the configuration by killing it with signal SIGHUP.

When I then tried sftp to put a file to the server with option -p which preserves times, the file was copied, but its last-modification time stayed at "now". The client saw a warning, which you will have to educate your users about:

sftp> put -p localfile remotefile
Uploading localfile to remotefile
Couldn't fsetstat: Permission denied
0

One solution I see to this problem is that you touch files as soon as you receive them. This will modify the accessed and modified timestamps for those files.

Source: Touch manual

4
  • Is it 100% safe to touch them even though the file might be still transferring (slow line, a huge file, etc.)?
    – Yuri
    Commented Jun 5, 2020 at 7:46
  • @Yuri: That I have never tried. I'm sure it won't corrupt the file but I'm not sure if the timestamps will persist.
    – 7_R3X
    Commented Jun 5, 2020 at 8:15
  • There seems to be another problem. I recall there are SFTP clients which somehow set the timestamp as the last step of the transfer. So touching the file before it is completely transferred would be useless.
    – Yuri
    Commented Jun 5, 2020 at 8:22
  • @Yuri: SFTP, unfortunately, isn't my forte but, is there an option for SFTPD to run a script when a file transfer completes? You might have to look around a bit for this.
    – 7_R3X
    Commented Jun 5, 2020 at 8:30
0

If you do not have a very large number of files, you can use inotifywait to watch for new files arriving and fix their timestamp. (The default limit is 8192 files and directories. You can increase this, but it is probably not a good idea to go too far as it is expensive). For example, to look for files being closed after a write, or for a change in permissions or time attributes underneath directory /dir, recursively:

inotifywait -m -r -e close_write -e attrib /dir

This runs continuously and will output lines like

/dir/subdir ATTRIB filea
/dir/subdir CLOSE_WRITE,CLOSE filea

for changes to a file /dir/subdir/filea. You can write a shell script to reconstruct the filename $f (beware of names with spaces), and then use stat -c %Z $f to get its current modification time, and compare this with date +%s. If the absolute difference is more than a few seconds, you can use touch to change the file time (which will generate a new event, hence the need to ignore small differences in time).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .