Protocolli di trasferimento file: da Kermit a rsync
Kermit compie 45 anni e riceve una nuova release: la storia del trasferimento file, dalle linee rumorose all'FTP dietro NAT, fino al successo di rsync e SFTP.
Perché i protocolli di trasferimento file hanno continuato a cambiare
Ogni protocollo di trasferimento file è stato progettato per gestire il tipo di errore tipico del proprio decennio. Kermit partiva dal presupposto che la linea avrebbe corrotto i byte. XMODEM e ZMODEM partivano dal presupposto che la connessione fosse lenta e che ogni minuto avesse un costo. FTP (file transfer protocol) partiva dal presupposto che la rete intermedia fosse affidabile. SSH partiva dal presupposto che fosse ostile. È quest'ultima ipotesi ad aver prevalso. Per questo oggi un VPS offre SFTP e rsync su SSH, con poche altre possibilità.
È utile esaminare questo argomento ora. C-Kermit 11.0.506 è stato rilasciato il 3 agosto 2026. È la prima release non beta dal rilascio di C-Kermit 9.0.302, avvenuto il 20 agosto 2011, e il protocollo che implementa è stato progettato nel maggio 1981. Quarantacinque anni sono un periodo sufficiente per vedere nascere un'intera categoria, assistere alla sua standardizzazione, vederla compromessa dalla rete su cui veniva eseguita e infine integrata in SSH.
Kermit, 1981: progettato per linee che alteravano i byte
Kermit è stato creato nel maggio 1981 presso il Columbia University Computer Center da Frank da Cruz e Bill Catchings. Il nome deriva da Kermit the Frog. Secondo il racconto di da Cruz, mentre il gruppo cercava un nome sulla parete c'era un calendario dei Muppets, e nessuno si aspettava che il programma si sarebbe diffuso.
Il problema risolto da Kermit non era la velocità. Il percorso tra un terminale e un mainframe non era un canale in grado di trasportare byte arbitrari. Era un dispositivo a caratteri con vincoli specifici. Poteva usare 7 bit. Poteva funzionare in half duplex. Poteva ignorare i caratteri di controllo oppure interpretarne uno come comando. L'invio non modificato di un file binario non funzionava.
Per questo il progetto ha adottato quei vincoli alla lettera. La cronologia ufficiale di Kermit Project li elenca:
- pacchetti brevi, perché la maggior parte dei mainframe non riusciva a gestire lunghi burst di dati in ingresso da un terminale
- half duplex con stop-and-wait, perché i mainframe IBM non supportavano la comunicazione full duplex
- codifiche stampabili per i caratteri di controllo e per i caratteri a 8 bit, perché nessuno dei due poteva attraversare il driver del terminale del mainframe
- un checksum su ogni pacchetto, a cui risponde il ricevitore, in modo che un pacchetto corrotto richieda una sola ritrasmissione e non l'intero file
Il terzo punto è quello più interessante. Kermit invia una codifica del file compatibile con il testo, non il file stesso. Un byte di controllo diventa un carattere prefisso seguito da un carattere stampabile, mentre un byte con il bit alto impostato può essere codificato nello stesso modo su un collegamento a 7 bit. Qualsiasi componente intermedio che comprende soltanto testo stampabile riceve testo stampabile. Il costo è l'aumento delle dimensioni: un file binario occupa più spazio durante il trasferimento. Rispetto a un front end di mainframe che altrimenti avrebbe alterato completamente il trasferimento, era il compromesso corretto.
Un'altra proprietà insolita di Kermit è il suo ambito. XMODEM trasferiva un file tra due macchine che avevano già la stessa definizione di file. Kermit è stato scritto come denominatore comune tra sistemi che non erano d'accordo, con set di caratteri diversi, strutture dei record diverse e interpretazioni diverse di ciò che indica la fine di una riga di testo. È il mondo descritto in il lungo passaggio dai mainframe ai server cloud, e Kermit rappresenta il modo in cui si gestiva l'interoperabilità prima che fosse il livello di rete a occuparsene.
Columbia ha interrotto il finanziamento nel 2011 e ha rilasciato C-Kermit con la licenza BSD rivista a 3 clausole. Frank da Cruz è rimasto nel progetto per 44 anni, dalla progettazione del 1981 fino al 2025. La release 2026 è mantenuta dal progetto OpenKermit, con John Goerzen impegnato a modernizzare una codebase C più vecchia della maggior parte delle persone che oggi la leggono.
XMODEM e ZMODEM: quando il costo della connessione telefonica ha determinato il design
Ward Christensen scrisse MODEM.ASM nel 1977 e il protocollo che introduceva è XMODEM. Nel 1978 lui e Randy Suess misero online CBBS, il primo bulletin board system pubblico. Christensen è morto l'11 ottobre 2024.
XMODEM è quasi il protocollo più semplice possibile. I dati vengono trasferiti in blocchi da 128 byte. Ogni blocco contiene un checksum di un byte, ottenuto dalla somma dei 128 byte di dati modulo 256. Il ricevitore conferma ogni blocco oppure ne richiede la ritrasmissione. Questa struttura è dovuta a ragioni economiche. Su una linea dial-up si paga il tempo di connessione, quindi un errore sulla linea dovrebbe costare un solo blocco, non l'intero trasferimento.
La debolezza è contenuta nella stessa descrizione. XMODEM attende una conferma dopo ogni 128 byte. Chuck Forsberg lo spiegò chiaramente nelle specifiche di ZMODEM: "La ridotta lunghezza dei blocchi penalizza il throughput quando il protocollo viene usato con sistemi timesharing, reti a commutazione di pacchetto e circuiti satellitari." È la latenza, non la larghezza di banda, a rendere inefficiente il protocollo stop-and-wait. Ogni round trip produce un intervallo senza traffico su una linea il cui tempo viene addebitato.
YMODEM arrivò in seguito e Ward Christensen coniò il nome nel 1985. Il suo contributo fu il trasferimento batch. Prima dei dati, il mittente comunica il nome e la dimensione del file. In questo modo è possibile trasferire più file nella stessa sessione e il ricevitore sa dove termina ciascuno.
ZMODEM è la risposta di Chuck Forsberg, sviluppata presso Omen Technology. Le specifiche sono alla revisione del 14 ottobre 1988 e dichiarano che "ZMODEM è stato sviluppato per il pubblico dominio nell'ambito di un contratto con Telenet". Telenet gestiva una rete pubblica per la trasmissione dati a commutazione di pacchetto e quel contratto si riflette nel design. ZMODEM esegue l'escape dei caratteri di controllo della rete, in modo che una rete a commutazione di pacchetto intermedia non li consumi. Indica l'inizio di ogni frame con una sequenza univoca di caratteri invece di dedurre i limiti del frame dal silenzio. In questo modo recupera dagli errori di linea senza attendere la scadenza di un timeout. Dispone inoltre di una ripresa esplicita, quindi un trasferimento interrotto riparte dal punto in cui si era fermato.
Soprattutto, smette di attendere. La descrizione nelle specifiche afferma che "ZMODEM, in pratica, usa l'intero file come finestra". Il mittente trasmette in streaming e si ferma soltanto quando il ricevitore segnala un problema. È la stessa intuizione codificata da TCP nella sua finestra, raggiunta dalla direzione opposta da chi osservava un modem restare inattivo.
Perché le due connessioni di FTP sono diventate rapidamente obsolete
FTP è più vecchio di tutti questi strumenti. La RFC 114, “A File Transfer Protocol”, è datata 16 aprile 1971 ed è stata scritta da A. Bhushan.
Il dettaglio importante è che la RFC 114 prese in considerazione il design con due connessioni e lo scartò. Bhushan valutò “l’uso di due collegamenti full-duplex, uno per le informazioni di controllo e l’altro per i dati”, quindi concluse: “Raccomandiamo di usare una singola connessione full-duplex per lo scambio di dati e informazioni di controllo”. La separazione arrivò in seguito. La RFC 354, datata 8 luglio 1972, stabilisce che “dati e file vengono trasferiti soltanto tramite la connessione dati”, mentre i comandi viaggiano su una connessione Telnet separata. La RFC 959, dell’ottobre 1985, scritta da Postel e Reynolds, è la versione ancora implementata da tutti.
La RFC 959 definì anche le porte. La porta dati predefinita del server è “la porta adiacente alla porta della connessione di controllo, cioè L-1”, quindi la porta 20 quando la connessione di controllo usa la porta 21.
La parte che non ha resistito è questa. Nella modalità FTP originale, è il server ad aprire la connessione dati verso il client. Un client dietro NAT (network address translation) non ha un indirizzo raggiungibile dal server, mentre un client dietro un firewall non accetta connessioni in ingresso. Di conseguenza, la connessione dati non arriva e il trasferimento si blocca non appena viene richiesta una directory o un file. La soluzione è stata PASV, che la RFC 959 definisce come una richiesta al server “di mettersi in ascolto su una porta dati, diversa dalla porta dati predefinita, e attendere una connessione invece di avviarne una alla ricezione di un comando di trasferimento”. Il server risponde con l’indirizzo e la porta a cui connettersi:
PASV
227 Entering Passive Mode (203,0,113,10,195,80)La risposta indica l’host 203.0.113.10 e la porta 195 moltiplicato per 256 più 80, cioè 50000. Rileggendo la risposta, il problema strutturale diventa evidente. L’endpoint della seconda connessione viene annunciato nel payload della prima. Un dispositivo NAT o un firewall non può inoltrare quella connessione senza analizzare il canale di controllo e aprire la porta indicata. Linux include un connection tracking helper che esegue esattamente questa operazione. L’helper funziona soltanto finché la connessione di controllo è in chiaro. Di conseguenza, proteggere FTP con TLS (transport layer security) rende cieco il middlebox che permetteva a FTP di funzionare.
Questa è la lezione di FTP in una frase. FTP ha reso la rete parte integrante del protocollo. Un protocollo che richiede alla rete di comprenderlo non può sopravvivere in una rete che smette di fidarsi del suo contenuto.
La conclusione è documentata. Firefox ha rimosso il supporto a FTP nella versione 90, a luglio 2021. Chrome ha rimosso il codice FTP in Chrome 95, a ottobre 2021.
rcp e i r-command: attendibilità basata sul nome host
4.2BSD, rilasciato nel 1983 da Berkeley con finanziamenti DARPA, introdusse rcp, rsh e rlogin. Erano progettati per un campus con macchine Unix sulla stessa rete, e il modello di autenticazione lo dimostra. Un host dichiarava quale utente stava effettuando la richiesta. Se /etc/hosts.equiv o il ~/.rhosts dell'utente indicavano che l'host era attendibile, la dichiarazione veniva accettata e non veniva richiesta alcuna password.
È importante descrivere chiaramente il meccanismo, perché spiega la scomparsa di questi comandi. L'attendibilità si basava su un indirizzo e su una dichiarazione. Entrambi viaggiavano sulla rete in testo in chiaro, quindi chiunque si trovasse sul percorso poteva leggerli e falsificarli. Questo modello era adatto all'ambiente descritto in il percorso da Unix a Linux, in cui la rete era un edificio. Ha smesso di essere adeguato nel momento in cui la rete è diventata Internet.
rcp aveva un'interfaccia ben progettata. Origine, destinazione, fine. Non era necessario aprire una sessione, negoziare una modalità di trasferimento o predisporre una seconda connessione. Si comporta come cp con i due punti nel percorso. Quell'interfaccia è sopravvissuta al relativo protocollo di quattro decenni.
SSH assorbe l’intera categoria
Nel 1995 Tatu Ylonen, allora ricercatore presso la Helsinki University of Technology, scrisse SSH in risposta a un attacco di sniffing delle password sulla rete dell’università. Nel luglio 1995 lo pubblicò come software libero con il relativo codice sorgente. Alla fine di quell’anno si stimavano circa 20,000 utenti in 50 paesi e, nel dicembre 1995, fondò SSH Communications Security per proseguirne lo sviluppo.
Nelle versioni successive la licenza divenne più restrittiva, quindi gli sviluppatori di OpenBSD crearono un fork dell’ultima versione distribuita con una licenza libera, ssh 1.2.12. L’importazione iniziale risale al 26 settembre 1999 e OpenSSH 1.2.2 fu distribuito con OpenBSD 2.6 il 1 dicembre 1999. Questo fork è un esempio compatto di perché i termini delle licenze open source contano nella pratica, perché l’implementazione SSH utilizzata oggi dalla quasi totalità degli utenti discende dall’unica versione la cui licenza ne consentiva ancora l’uso.
Quando SSH divenne disponibile, il trasferimento dei file smise di essere un problema separato. Un flusso autenticato e cifrato con più canali fornisce già ciò che i protocolli precedenti dovevano implementare autonomamente: integrità, ordinamento e un secondo percorso dati che non richiede una seconda connessione TCP. Se questi meccanismi non ti sono familiari, inizia da una spiegazione di cosa sia realmente SSH prima di proseguire.
Da SSH nacquero due strumenti. scp era il protocollo di comunicazione di rcp eseguito all’interno di una sessione SSH, per questo ne ereditò esattamente l’interfaccia a riga di comando. SFTP è un progetto diverso: un vero protocollo per il trasferimento dei file, con elenchi delle directory, attributi dei file e accesso casuale, trasportato su un canale SSH. SFTP non è mai diventato un RFC. La bozza IETF draft-ietf-secsh-filexfer raggiunse la versione 13 il 18 luglio 2006 e poi scadde. OpenSSH implementa la versione 3 di quella bozza. Il protocollo di trasferimento sicuro dei file più utilizzato al mondo è una revisione numerata di una bozza abbandonata, e funziona.
Anche il protocollo scp legacy è stato ritirato. OpenSSH 8.8, rilasciato il 26 settembre 2021, avvertiva che "una versione futura di OpenSSH passerà scp(1) dall’uso del protocollo scp/rcp legacy all’uso predefinito di SFTP". OpenSSH 9.0, rilasciato l’8 aprile 2022, lo fece: "Questa versione modifica scp(1), che passa dall’uso del protocollo scp/rcp legacy all’uso predefinito del protocollo SFTP."
Il motivo spiega un elemento della tradizione tecnica. Il vecchio protocollo scp espandeva i caratteri jolly nei nomi dei file remoti passandoli alla shell remota. Per questo gli utenti impararono a racchiudere tra virgolette doppie ogni metacarattere presente in un percorso remoto. Le note della versione 8.8 specificano che scp tramite SFTP "non richiede più questa gestione delle virgolette, complessa e soggetta a errori". Di conseguenza, su un server aggiornato, scp è un client SFTP che utilizza l’interfaccia a riga di comando di rcp. L’interfaccia del 1983 è sopravvissuta. Il protocollo di comunicazione del 1983 no.
rsync, 1996: inviare le differenze, non il file
Andrew Tridgell e Paul Mackerras annunciarono rsync il 19 giugno 1996 presso l'Australian National University, insieme al rapporto tecnico TR-CS-96-05, "The rsync algorithm".
Ogni protocollo precedente si chiedeva come trasferire un file senza corromperlo. rsync si chiedeva quale parte del file fosse già disponibile sull'altro lato. Il rapporto descrive lo scenario come "un collegamento di comunicazione bidirezionale a bassa larghezza di banda e alta latenza" e l'obiettivo come l'identificazione delle "parti del file sorgente identiche ad alcune parti del file di destinazione", in modo da trasferire soltanto le parti non corrispondenti.
Vale la pena comprendere il meccanismo, perché spiega il comportamento di rsync. Il ricevitore suddivide la copia esistente in blocchi di dimensione fissa e calcola due checksum per ogni blocco: uno debole ed economico, l'altro forte e più costoso. Invia quindi questo elenco al mittente. Il mittente sposta una finestra sul proprio file, un byte alla volta, e aggiorna incrementalmente il checksum debole. È questo che rende possibile una scansione byte per byte con un costo accettabile. Una corrispondenza debole viene poi verificata confrontando il checksum forte. Le corrispondenze confermate diventano riferimenti ai blocchi. Tutto il resto viene inviato come byte letterali. Il ricevitore ricostruisce il file usando i riferimenti ai blocchi già disponibili e i byte letterali appena ricevuti.
Se si inserisce un byte all'inizio di un file di grandi dimensioni, un semplice strumento per il calcolo delle differenze deve inviare l'intero file, perché ogni offset è cambiato. La finestra mobile individua gli stessi blocchi nei nuovi offset, quindi rsync invia un byte più le informazioni di gestione. Questa caratteristica spiega perché rsync sia ancora lo strumento corretto per una directory che verrà copiata più di una volta.
Due comportamenti sorprendono spesso gli utenti, ed entrambi sono descritti nel manuale. Primo, rsync non calcola i checksum dei file per decidere se analizzarli. Per impostazione predefinita, "individua i file che devono essere trasferiti usando un algoritmo di controllo rapido che cerca i file la cui dimensione o il cui orario di ultima modifica sono cambiati". Un file il cui contenuto è cambiato, ma la cui dimensione e il cui timestamp sono rimasti identici, viene ignorato. --checksum modifica questo comportamento e fa sì che entrambi i lati leggano completamente ogni file candidato. Secondo, l'algoritmo delta è disabilitato per impostazione predefinita quando entrambi i percorsi sono locali, perché leggere e calcolare i checksum di due copie sulla stessa macchina costa più che copiare i byte. Il vantaggio esiste soltanto quando il collegamento è il collo di bottiglia.
Cosa si usa davvero su un VPS e perché
In breve: SFTP per pochi file, rsync su SSH per una directory che copierai di nuovo.
Entrambi usano SSH, quindi ereditano la verifica della chiave host e la cifratura senza configurazione aggiuntiva. Sono cinquant'anni di lavoro compressi in un'impostazione predefinita. I progettisti di Kermit dovevano prevedere che la linea potesse corrompere i dati, quindi integrarono checksum e ritrasmissione nel protocollo. Oggi se ne occupa TCP. Christensen e Forsberg dovevano prevedere che ogni byte avesse un costo, quindi integrarono la ripresa dei trasferimenti e lo streaming. Oggi se ne occupa l'algoritmo delta di rsync, in modo più efficace. Gli autori di FTP presupponevano una rete di host cooperanti, ed è l'unico di questi presupposti che si è rivelato falso in un modo che nessun intervento sul protocollo avrebbe potuto correggere.
Cosa permettono ancora di verificare gli checksum
Nel corso di questa storia, il termine "checksum" ha svolto tre funzioni diverse, che non sono intercambiabili.
I checksum per pacchetto di Kermit e XMODEM rilevavano la corruzione dei dati durante la trasmissione. Oggi se ne occupano il checksum TCP e la correzione degli errori a livello di collegamento. Per questo nessuno strumento moderno per il trasferimento dei file richiede di gestire direttamente questo aspetto.
I checksum a blocchi di rsync non rispondono alla domanda "questi dati sono corretti?". Rispondono alla domanda "questo blocco è già disponibile?". In questo contesto, un checksum robusto è una chiave di ricerca, non una garanzia sull'origine del file.
La terza funzione è ancora a tuo carico. Un checksum pubblicato insieme a un file di release risponde a una domanda a cui TLS non può rispondere. TLS dimostra che hai comunicato con il server corretto. Non dimostra che su quel server fosse presente il file corretto e non offre alcuna garanzia per un file scaricato da un mirror. Per questo vale ancora la pena dedicare trenta secondi ai checksum e alle firme delle release. È un'abitudine facile da acquisire: verifica il checksum di ogni download che installi.
Tutto il resto di questa storia è stato risolto dal livello sottostante. Questo aspetto no, perché non è mai stato un problema di rete.
FAQ
FTP è ancora sicuro da usare su un VPS?
No. FTP in chiaro trasmette le credenziali e il contenuto dei file senza cifratura, quindi chiunque si trovi sul percorso di rete può leggerli. Inoltre dipende da un firewall in grado di analizzare il canale di controllo, cosa che non è più possibile non appena si cifra quel canale con TLS. I browser lo hanno già abbandonato: Firefox ha rimosso il supporto a FTP nella versione 90, a luglio 2021, e Chrome ha rimosso il relativo codice nella versione 95, a ottobre 2021. Usare SFTP su SSH richiede una sola porta e nessun dispositivo intermedio che debba riconoscere il protocollo.
Perché FTP richiede una modalità passiva?
Perché nella modalità originale di FTP è il server ad aprire la connessione dati verso il client. RFC 959 assegna per impostazione predefinita la porta dati del server alla "porta adiacente alla porta della connessione di controllo, cioè L-1", quindi alla porta 20 quando il controllo usa la porta 21. Un client dietro NAT (network address translation) non dispone di un indirizzo raggiungibile dal server, quindi quella connessione non arriva e il trasferimento resta bloccato. PASV inverte la direzione: il server resta in ascolto e risponde con un indirizzo e una porta all'interno di una risposta 227 Entering Passive Mode, ai quali il client si connette.
scp usa ancora un protocollo proprietario?
Non da OpenSSH 9.0, rilasciato l'8 aprile 2022, che "passa scp(1) dall'uso del protocollo scp/rcp legacy all'uso predefinito del protocollo SFTP". OpenSSH 8.8 aveva annunciato la modifica a settembre 2021. La differenza visibile riguarda il quoting. Il vecchio protocollo espandeva i caratteri jolly remoti passandoli alla shell remota, mentre quello basato su SFTP non lo fa. Di conseguenza, i percorsi che dipendevano da quell'espansione della shell ora si comportano in modo diverso.
Quando rsync è preferibile a scp su un VPS?
Quando si deve copiare lo stesso albero più di una volta. rsync trasmette solo le parti di ogni file che la destinazione non possiede già, quindi la seconda copia è molto più economica della prima. Per un singolo file che la destinazione non ha mai ricevuto, scp e rsync trasferiscono all'incirca lo stesso numero di byte e scp è più semplice. Per impostazione predefinita, rsync determina cosa esaminare in base alle dimensioni e all'ora di modifica. Pertanto, se il contenuto di un file è cambiato ma le dimensioni e il timestamp sono rimasti invariati, serve --checksum prima che rsync possa rilevare la modifica.
Perché Kermit codificava i file come testo stampabile invece di inviare byte grezzi?
Perché era destinato a una linea terminale verso un mainframe, non a un canale di byte. Questi collegamenti potevano essere a 7 bit e il driver del terminale del mainframe interpretava i caratteri di controllo invece di inoltrarli. Kermit codificava i byte di controllo e quelli con il bit alto impostato come caratteri stampabili, in modo che nulla nel percorso potesse reagire a essi. La codifica aumenta le dimensioni dei file binari durante la trasmissione, ma era un compromesso corretto rispetto a un trasferimento che altrimenti sarebbe arrivato corrotto.