Jak wykryć lub zarejestrować przerwane przesyłanie za pomocą serwera OpenSSH SFTP?

9

Mam ten problem, gdy nasz klient skraca dane obcięte przez SFTP. Nie jestem pewien, czy problem jest po naszej stronie, czy jego. Włączyłem rejestrowanie SFTP, ale nie pozwala mi to wykryć, czy przesyłanie zostało przerwane.

Na przykład, jeśli uruchomię klienta sftp i uderzę ^Cw środek przesyłania, serwer po prostu powie coś takiego close "/data/README.md" bytes read 0 written 5366, co jest nie do odróżnienia od nieprzerwanego przesyłania.

Wydaje mi się, że coś w stylu .partprefiksu zadziałałoby, ale patrząc na inne posty dotyczące awarii serwera, nie sądzę, że jest to możliwe w przypadku serwera sftp OpenSSH.

Czy mogę więc wykryć, czy przesyłanie pliku zostało przerwane?

surjikal
źródło

Odpowiedzi:

8

Zakładam, że przez „klienta sftp” odnosisz się do klienta OpenSSH SFTP. „Problem” polega na tym, że po naciśnięciu Ctrl+Czatrzymuje przesyłanie i czysto zamyka plik zdalny, tak jakby przesyłanie zostało całkowicie zakończone (zwróć uwagę, że jest to prawidłowe zachowanie i wielu innych klientów SFTP zachowuje się tak samo). Tak więc serwer nie ma absolutnie żadnego sposobu, aby stwierdzić, że przesyłanie zostało przerwane.


Ściśle mówiąc, tak, ponieważ klient OpenSSH przesyła wskazówkę dotyczącą rozmiaru do serwera podczas tworzenia pliku. Ale serwer OpenSSH nie używa ani nawet nie rejestruje tych informacji. Chociaż zmodyfikowanie kodu w celu zarejestrowania rozmiaru byłoby dość proste, jeśli jest to opcja dla ciebie.

Zobacz process_openw 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);

Zmień logitinstrukcję na:

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

Pamiętaj, że przesłanie wskazówki dotyczącej rozmiaru jest opcjonalne. Chociaż niektórzy klienci SFTP go wyślą (np. OpenSSH lub WinSCP), inni nie (np. PSFTP, FileZilla lub LFTP). W takim przypadku otrzymasz 0 w a->size.


Gdyby klient naprawdę przerwał przesyłanie (bez czystego zamknięcia zdalnego pliku, np. Kiedy sftpzostał zabity), byłbyś w stanie odróżnić go od „wymuszonego” prefiksu do „zamknięcia” zapisu:

wymuszone zamknięcie bajtów „/data/README.md” odczytano 0 zapisano 5366

Martin Prikryl
źródło
1
Wow, stworzyłeś WinSCP? Wielkie kolesie. Dzięki za odpowiedź, zrobię to.
surjikal