Comment détecter ou enregistrer des téléchargements interrompus avec le serveur OpenSSH SFTP?

9

J'ai ce problème où un de nos clients a été des données tronquées SFTP-ing. Je ne sais pas si le problème est de notre côté ou du sien. J'ai activé la journalisation SFTP mais cela ne me permet pas de détecter si un téléchargement a été interrompu.

Par exemple, si je lance le client sftp et que je frappe ^Cau milieu du téléchargement, le serveur dit simplement quelque chose comme close "/data/README.md" bytes read 0 written 5366, qui ne se distingue pas d'un téléchargement ininterrompu.

Je suppose que quelque chose comme un .partpréfixe fonctionnerait, mais en regardant d'autres messages sur la défaillance du serveur, je ne pense pas que ce soit possible avec le serveur sftp d'OpenSSH.

Alors, existe-t-il un moyen pour moi de détecter si un téléchargement de fichier a été interrompu?

surjikal
la source

Réponses:

8

Je suppose que par «client sftp», vous faites référence à un client OpenSSH SFTP. Le "problème" est que lorsque vous appuyez sur Ctrl+C, il arrête le téléchargement et ferme proprement le fichier distant, comme si le téléchargement était complètement terminé (notez que c'est un comportement correct et que de nombreux autres clients SFTP se comportent de la même manière). Le serveur n'a donc absolument aucun moyen de dire que le téléchargement a été interrompu.


Eh bien à proprement parler, car le client OpenSSH envoie un indice de taille au serveur lors de la création du fichier. Mais le serveur OpenSSH n'utilise ni n'enregistre même ces informations. Bien qu'il soit assez simple de modifier son code pour enregistrer la taille, si c'est une option pour vous.

Voir process_opendans sftp-server.c:

a = get_attrib();
flags = flags_from_portable(pflags);
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
logit("open \"%s\" flags %s mode 0%o",
    name, string_from_portable(pflags), mode);

Remplacez l' logitinstruction par:

logit("open \"%s\" flags %s mode 0%o size %llu",
    name, string_from_portable(pflags), mode, (unsigned long long)a->size);

Notez que l'envoi de l'indice de taille est facultatif. Alors que certains clients SFTP l'enverront (par exemple OpenSSH ou WinSCP), d'autres pas (par exemple PSFTP, FileZilla ou LFTP). Dans un tel cas, vous obtiendrez 0 po a->size.


Si le client avait vraiment abandonné le téléchargement (sans fermer proprement le fichier distant, par exemple lorsqu'il sftpest tué), vous seriez en mesure de le dire du préfixe "forcé" à l'enregistrement "close":

fermeture forcée "/data/README.md" octets lus 0 écrits 5366

Martin Prikryl
la source
1
Wow, vous avez fait winSCP ?? Big ups mec. Merci pour la réponse, je vais le faire.
surjikal