<- SL: JFS - Copertina - Una questione di Privacy ->

Protocolli


Protocolli Internet - Prima puntata

di Umberto Salsi


L'articolo

Si descrive la documentazione ufficiale di Internet nota come RFC, e si introducono i protocolli fondamentali IP e TCP. Viene affrontato anche il protocollo POP-3 per il download della posta. Si danno esempi didattici di impiego dei protocolli descritti. L'articolo è destinato al sysadm che vuole diagnosticare eventuali problemi sistemistici, al programmatore che cerchi una introduzione all'argomento e all'utente evoluto che voglia comprendere meglio le possibilità offerte da Internet.


Indice

Introduzione
RFC - La documentazione ufficiale
ASCII - Il geroglifico dell'era moderna
File di testo ASCII
RFC 791: il protocollo IP
RFC 793: il protocollo TCP
RFC 854: Il protocollo Telnet
RFC 1939: il protocollo POP-3
POP-3 e sicurezza
Conclusioni
Bibliografia
L'Autore

Introduzione

Stanchi di sentirvi ripetere la solita storia condensata delle origini di Internet? Ormai libri e riviste ce l'hanno riproposta in tutte le salse. Quelle che invece più raramente si trovano descritte sono le specifiche tecniche dei vari protocolli.

Lo scopo di questo articolo è di introdurre i principali protocolli di Internet e dimostrare come questa conoscenza possa tornare utile per diagnosticare problemi sistemistici, per risolvere problemi di configurazione del proprio computer, come introduzione per i programmatori e per capire meglio le possibilità e i limiti dello strumento. Mostreremo come interrogare manualmente un server via Telnet e come consultare la propria mailbox senza usare un client di posta.

RFC - La documentazione ufficiale

Il documento più antico che sono riuscito a trovare è l'RFC numero 3: risale all'aprile 1969, proprio mentre gli astronauti si apprestavano a sbarcare sulla Luna, e parla di un gruppetto di cinque persone autoproclamatesi Network Working Group. Stavano lavorando al progetto di una nuova tecnologia di rete, e avevano bisogno di uno strumento efficace per mettere nero su bianco le loro discussioni tecniche. Usare carta e penna doveva sembrare troppo primitivo, e del resto la videoscrittura e MS Word non erano ancora stati inventati. Gli unici documenti che potevano scrivere erano file di testo ASCII, e così fecero. Chiamarono questa raccolta Request For Comment (richiesta di commenti, www.rfc-editor.org), sottolineando l'aspetto collaborativo e aperto del loro lavoro, uno spirito che ha ancora qualche riscontro tra gli utenti di Internet di oggi (anche se è sempre più fuori moda).

Dunque file ASCII: è grazie a questa saggia scelta che ancora oggi possiamo leggere la documentazione prodotta oltre trent'anni fa. La numerazione di questi documenti ha raggiunto quota 3222 alla data in cui scrivo, e vengono affrontati un po' tutti i temi relativi alle reti informatiche, alle telecomunicazioni e naturalmente alla rete Internet vera e propria.

Trattandosi di un "lavori in corso permanente", i documenti RFC sono soggetti a frequenti aggiornamenti sotto la guida di vari gruppi di lavoro coordinati dall'IETF (Internet Engeenering Task Force, www.ietf.org).

Nel sito ufficiale degli RFC troverai un motore di ricerca per parole chiave, l'indice per titoli, l'indice per autori, l'indice degli RFC validi e di quelli obsoleti, i siti mirror da cui poter scaricare più velocemente i documenti, e istruzioni varie. Se poi vuoi partecipare, non ti resta che iscriverti ad una delle innumerevoli mailing list dell'IETF: non vengono richiesti titoli o documenti, ma competenza e collaborazione.

Alcuni termini un po' desueti che troverai negli RFC:

octet = un byte
datagram = un pacchetto di rete

Per maggiori dettagli sui vari organismi di Internet, sul loro funzionamento, sui metodi di elezione dei rappresentanti, sul processo di redazione e revisione dei documenti, ecc. puoi leggere l'RFC 2026.

ASCII - Il geroglifico dell'era moderna

La modernità nel settore informatico ci ha proposto gli strumenti WYSIWYG, la programmazione "Visual", le tastiere multietniche, i documenti multimediali e la realtà virtuale. Alle origini delle tecnologie informatiche, invece, ci sono i testi, le telescriventi e il codice ASCII. Due paroline su questo set di caratteri vale la pena spenderle prima di addentrarci sul codice ASCII esteso, sull'UNICODE e sull'UTF-8.

Dunque, all'origine erano le telescriventi: sostanzialmente si trattava di dispositivi seriali dotati di una tastiera e di una stampante. La comunicazione seriale era a sette bit più un bit di parità, usato per una diagnostica grossolana degli errori di comunicazione. Questo rudimentale strumento di comunicazione di uso generale venne presto adottato come interfaccia "evoluta" per i computer degli anni '60, al posto dei lettori e dei perforatori di schede, e prima dell'avvento dei videoterminali.

Il set di caratteri ASCII (pr. it.: "aschi") è limitato dai sette bit disponibili, e per via del fatto che l'ANSI, l'ente unificatore che ha approvato questo set, è un istituto statunitense. Dal set ASCII mancano infatti i caratteri accentati e altri simboli utilizzati qui in Europa, per non parlare poi dei paesi dell'est e di quelli asiatici. Comunque, in ASCII vengono espressi tutti i linguaggi di programmazione attuali, e in ASCII si esprimono i protocolli testuali di Internet. Anche là dove le soluzioni più moderne hanno permesso l'introduzione di nuovi alfabeti e nuovi simboli, l'ASCII rimane comunque un minimo comun denominatore da conoscere.

Dopo averne così tanto parlato, vediamo finalmente questo ASCII che faccia ha:

  0 16 32 48 64 80 96 112
0 NUL DLE SP 0 @ P ` p
1 SOH DC1 ! 1 A Q a q
2 STX DC2 " 2 B R b r
3 ETX DC3 # 3 C S c s
4 EOT DC4 $ 4 D T d t
5 ENQ NAK % 5 E U e u
6 ACK SYN & 6 F V f v
7 BEL ETB ' 7 G W g w
8 BS CAN ( 8 H X h x
9 HT EM ) 9 I Y i y
10 LF SUB * : J Z j z
11 VT ESC + ; K [ k {
12 FF FS , < L \ l |
13 CR GS - = M ] m }
14 SO RS . > N ^ n ~
15 SI US / ? O _ o DEL
Tabella 1. Codici ASCII.

Osserviamo che la tabella ha 8 colonne per 16 righe, per un totale di 128 caselle e altrettanti simboli: è esattamente quello che ci dobbiamo aspettare con un codice a 7 bit: infatti 27=128. Il codice decimale di un simbolo si ottiene sommando i numeri in grigio al cui incrocio si trova il simbolo. Ad esempio, il codice ASCII decimale della lettera A è 1+64=65.

Non tutti i simboli producono la scrittura di un carattere sulla carta (o sullo schermo): alcuni codici sono speciali e sono detti codici di controllo. I codici di controllo sono indicati con una sigla a due o tre lettere in corsivo, e occupano le prime 32 posizioni e l'ultima. Non tutti questi codici hanno conservato il significato originario che avevano nelle telescriventi, ma alcuni di essi lo mantengono ancora; vediamo i principali tuttora usati:

NUL (0) - Il codice di controllo nullo non aveva effetto sulle telescriventi. La libreria standard del C, a fondamento del sistema UNIX e quindi anche di GNU/Linux, lo usa per marcare la fine delle stringhe nella loro rappresentazione in memoria.

BEL (7) - Il codice di controllo che nelle telescriventi azionava il campanello per produrre un sonoro "diiiinnnng". Oggi produce uno stridulo bip emesso dal buzzer piezoelettrico incorporato nei cabinet dei computer. In entrambi i casi serve per attirare l'attenzione dell'operatore su qualche evento inconsueto.

BS (8) - Il back space produceva lo spostamento della testina di stampa della telescrivente a sinistra di un carattere; spesso veniva utilizzato per eseguire il grassetto stampando una lettera, il BS, e quindi di nuovo la stessa lettera sopra la stampata precedente. Incredibile ma vero, viene usato ancora oggi con lo stesso significato: prova a dare il comando man ls | cat -vt: tutti quei ^H sono i caratteri BS usati per rendere il grassetto della man page!

HT (9) - L'horizontal tabulation comandava lo spostamento della testina di stampa all'inizio del successivo campo, esattamente quello che fa oggi sui nostri terminali. La larghezza dei campi è di solito 8 caratteri.

FF (12) - Il form feed produceva lo scorrimento della carta in modulo continuo fino a portare la testina di stampa sulla prima riga del foglio seguente. Oggi produce la cancellazione dello schermo e il posizionamento del cursore in alto a sinistra.

CR (13) - Il carriage return forzava la testina di stampa a scorrere fino al margine sinistro, posizionandosi quindi in corrispondenza del primo carattere della riga. Idem sui videoterminali moderni.

LF (10) - Il line feed faceva compiere uno scatto al rullo di scorrimento della carta, sicché la testina di stampa veniva a trovarsi sulla riga successiva.

ESC (27) - Il codice di escape ha un po' il ruolo di jolly, e precede tipicamente una sequenza di caratteri che vengono interpretati in modo speciale dalla telescrivente piuttosto che essere stampati. Le sequenze di escape, così come vengono chiamate ancora oggi, sono largamente utilizzate per comandare terminali, stampanti, e come codici generati dalla pressione di certi tasti speciali.

SP (32) - Lo space non è un carattere di controllo, ma semplicemente lo spazio. Si tratta di un carattere "stampabile" come gli altri, con la particolarità di non lasciare alcuna traccia sulla carta o sullo schermo, avendo il solo effetto di spostare la testina di stampa o il cursore.

Per completare questa rapida carrellata sull'ASCII, ricordo le denominazioni più accreditate di alcuni caratteri che si incontrano meno frequentemente ma che appaiono spesso nella documentazione:

# - cancelletto, diesis, number.
& - "e" commerciale, ampersand.
' - accento acuto, apice.
- - meno, minus, hypen.
/ - barra obliqua, slash.
: - duepunti, colon.
; - puntoevirgola, semicolon.
< - minore di, less than.
> - maggiore di, greater than.
@ - chiocciola, chiocciolina, at.
[ - parentesi quadra aperta, left square bracket.
] - parentesi quadra chiusa, right square bracket.
\ - barra obliqua inversa, back slash.
^ - accento circonflesso.
_ - sottolinea, underscore.
` - accento grave, apice inverso.
{ - parentesi graffa aperta, left curly brace.
} - parentesi graffa chiusa, right curly brace.
| - barra verticale, vertical bar.
~ - tilde.

File di testo ASCII

La stessa sequenza di caratteri da inviare a una telescrivente per ottenere un certo testo stampato può essere salvata in un file, che pertanto viene detto file di testo ASCII. In questo caso l'ottavo bit, che nella trasmissione alla telescrivente portava il bit di parità, non serve più, e viene forzato a zero. Per mettere bene in evidenza questa differenza, gli altri file che usano tutti gli otto bit per byte sono invece talvolta detti file binari, sebbene la precisazione possa apparire ridondante.

Nei file di testo ASCII, lo spreco di un bit per ogni byte ha alimentato la fantasia dei progettisti di computer degli anni '80, sicché è nata una pletora di set detti ASCII estesi, che includevano 256 simboli. Ecco allora comparire caratteri semigrafici, cornicette, cuoricini e faccine varie, ma anche lettere accentate e altri simboli alfabetici. Vedremo come alcune norme ISO abbiano cercato di porre ordine tra i set ASCII estesi, mentre l'UNICODE e l'UTF-8 abbiano poi permesso di superare anche il limite degli 8 bit per carattere.

Sfortunatamente, neppure per quello che riguarda i testi ASCII c'è una perfetta concordanza di vedute. La principale differenza tra i file di testo che adottano il codice ASCII sta nella diversa convenzione usata per marcare la fine riga:

CR+LF telescriventi, MS-DOS e derivati, e i principali protocolli testuali di Internet
LF Unix, GNU/Linux e sistemi operativi affini, RFC
CR MacOS
Tabella 2. Convenzioni per il fine-riga.

Osserviamo che la convenzione storicamente più corretta prevede l'invio del CR seguito dal LF: il primo codice riporta il carrello di stampa sul margine sinistro, mentre il secondo codice fa avanzare di una riga il rullo della carta. L'effetto netto è il posizionamento della testina di stampa all'inizio della prossima riga. Coerenti con questa impostazione sono rimasti l'MS-DOS e i sistemi operativi di Microsoft, ma anche la maggior parte dei protocolli testuali di Internet (FTP, SMTP, POP-3, HTTP, ecc.).

MacOS usa il solo CR, mentre Unix e affini usano il solo LF: questa scelta, almeno nel caso di Unix e affini, è derivata da considerazioni di pura efficienza: essendo Unix un sistema molto orientato al trattamento di testi, il rilevamento del fine-riga e dell'a-capo sono più veloci se il test coinvolge un solo carattere.

E' facile immaginare come eseguire tutte le conversioni tra i vari formati. Quando si tratta di produrre programmi che "parlano" direttamente i protocolli Internet, bisogna ricordarsi di questo aspetto subdolo.

Un'altra convenzione al centro di frequenti micro-dibattiti riguarda il carattere HT: quanto la vogliamo fare larga la tabulazione? Questo carattere viene impiegato con scopi speciali nel formato delle intestazioni dei messaggi email (RFC 822), ma per quanto riguarda il dibattito sulla larghezza del campo, noi ce ne disinteresseremo.

RFC 791: il protocollo IP

Correva l'anno 1981 quando Jon Postel, recentemente scomparso, firmava la specifiche definitive del tuttora valido protocollo di Internet, per conto del DARPA. Si tratta di un protocollo a pacchetti composti da una intestazione e da un corpo. L'intestazione prevede, essenzialmente, di specificare un numero di nodo mittente e un numero di nodo destinatario del pacchetto; è inoltre previsto un campo per specificare il protocollo di livello superiore veicolato e la lunghezza del pacchetto in byte; c'è anche un campo che riporta una semplice somma di controllo della intestazione per rilevare eventuali errori di trasmissione su quella che è la parte più importante del pacchetto. Il documento è abbastanza chiaro e conciso: ne raccomando senz'altro la lettura, anche se noi ci interesseremo soprattutto al protocollo TCP basato su IP.

Il pacchetto, una volta "lanciato" nella rete, si propaga seguendo cammini spesso imprevedibili a priori, instradato ad ogni nodo della rete da un qualche algoritmo di routing che cerca di farlo pervenire a destinazione nel modo più efficiente possibile. Quando il percorso più diretto verso la destinazione non è praticabile, gli algoritmi di routing possono prevedere l'instradamento attraverso canali alternativi. Se neppure questa soluzione è attuabile, il pacchetto viene scartato. Il protocollo ICMP (v. RFC 792) viene in soccorso in questi casi: il nodo che ha riscontrato il problema ha la possibilità di segnalare l'accaduto al mittente inviandogli un altro pacchetto IP...

 0                   1                   2                   3   
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |Type of Service|          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |Flags|      Fragment Offset    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live |    Protocol   |         Header Checksum       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Destination Address                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                             data                              |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figura 1. Struttura semplificata del pacchetto IP.

La Figura 1 schematizza la struttura del pacchetto IP, la collocazione e la lunghezza dei vari campi. Ho evidenziato in grassetto i campi che più ci interessano ai fini della nostra discussione; per i dettagli conviene fare riferimento al documento RFC 791. Da questo schema si possono desumere molte informazioni importanti: ad esempio, analizzando la lunghezza dei vari campi, scopriamo che:

La filosofia sottostante al metodo di propagazione dei pacchetti IP prevede che ogni nodo della rete "faccia del suo meglio" per instradare il pacchetto, ma questo servizio non può essere dato per scontato. I nostri dati impacchettati dentro al pacchetto IP vengono insomma affidati alla sorte, come il classico messaggio nella bottiglia lanciato in mare nella speranza che correnti favorevoli pensino a recapitarlo a destinazione.

RFC 793: il protocollo TCP

Il protocollo TCP nasce senza essere necessariamente legato a IP: ecco perché a volte lo si trova scritto "TCP/IP" (si legge: TCP su IP), ad indicare che il protocollo di trasporto usato è IP. La Figura 2 illustra la struttura del pacchetto TCP/IP.

 0                   1                   2                   3   
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|          header del pacchetto IP come da figura 1             |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |           |U|A|P|R|S|F|                               |
| Offset| Reserved  |R|C|S|S|Y|I|            Window             |
|       |           |G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                             data                              |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figura 2. Struttura semplificata del pacchetto TCP/IP.

La prima parte del pacchetto contiene la solita intestazione IP come vista nella Figura 1, dove il campo Protocol assumerà il valore 6 assegnato al TCP. La sezione dati del pacchetto IP viene occupata dalle informazioni proprie del TCP della figura 2. Notiamo che i numeri di porta sono a 16 bit, per un totale di 65536 porte. Notiamo anche che è presente un ulteriore checksum a 16 bit, che questa volta copre l'intestazione TCP e la sezione dati del pacchetto TCP. L'intestazione TCP occupa 20 byte per cui, tolti i 20 byte dell'intestazione IP, rimangono 65495 byte disponibili per i dati.

Comunque, quello che interessa è che il TCP realizza un livello di astrazione in più rispetto all'IP: con TCP, infatti, si realizzano canali di comunicazione semi-permanenti tra due nodi della rete. Ogni canale si stabilisce in una fase di contrattazione, cui segue una fase di comunicazione, e si conclude con la chiusura del canale. Il protocollo assicura l'affidabilità del collegamento, eseguendo i controlli necessari ed eventualmente richiedendo la ritrasmissione delle informazioni corrotte o non pervenute.

Ai due estremi del canale vengono assegnati i numeri di porta TCP, che permettono di individuare il canale stesso. La figura qui sotto dovrebbe chiarire il concetto.

                    1234              80                    
+----------------+ /                    \ +----------------+
|                |/                      \|                |
|    Host A      O------------------------O     Host B     |
|                |                        |                |
+----------------+                        +----------------+
Figura 3. Canale TCP tra gli host A e B.

I numeri di porta convenzionali ai quali rispondono i server sono riportati nell'RFC 1700, e sono disponibili anche nel file /etc/services.

Nell'esempio della Figura 3, l'host con numero di nodo A stabilisce un collegamento TCP con l'host con numero di nodo B; alle estremità del canale le porte assegnate sono rispettivamente 1234 e 80. Nel linguaggio dei programmatori, la combinazione del numero di nodo A (32 bit) e del numero di porta 1234 (16 bit) forma un socket Internet. Similmente, all'altra estremità del canale si crea un altro socket Internet caratterizzato dal numero di nodo B e dalla porta 80. Questi due socket formano un socket pair (coppia di socket). Un socket pair è quindi costituito da quattro numeri, e caratterizza univocamente un canale TCP. Un dato socket pair è garantito essere univoco in Internet, e alle due estremità i sistemi operativi fanno corrispondere tipicamente un processo: quello che ha aperto il canale e quindi che ha richiesto il collegamento è il client, mentre l'altro è il server.

Nella figura, possiamo immaginare che A sia il client e che B sia il server. In questo caso, la porta 80 è quella convenzionalmente riservata al server WEB, per cui in questo caso al socket A:1234 potrebbe corrispondere il processo di un browser WEB che sta interrogando un server Apache che gira sul socket B:80. Osserviamo che su di una macchina ci possono essere diversi socket uguali: per esempio, su B avremo parecchi processi di Apache che gestiscono altrettante comunicazioni su socket caratterizzati dalle coordinate B:80. Quello che distingue i diversi canali di comunicazione, e che impedisce di mescolare i pacchetti TCP provenienti da fonti diverse, è il concetto di socket pair.

Nella Figura 4 qui sotto, il computer A crea un secondo canale TCP con B, sempre sulla porta 80. In questo caso esistono due socket pair distinti, perché differiscono per il numero di porta dell'host A.

                    1234              80                    
+----------------+ /                    \ +----------------+
|                |/                      \|                |
|                O------------------------O                |
|    Host A      |                        |     Host B     |
|                O------------------------O                |
|                |\                      /|                |
+----------------+ \                    / +----------------+
                    1235              80                    
Figura 4. Doppio canale TCP tra gli host A e B.

Si possono visualizzare i socket attivi sul proprio computer con il comando netstat:

    # netstat --ip
    Active Internet connections (w/o servers)
    Proto Local Address           Foreign Address         State
    tcp   ppp-118-146.26-151:1495 twister1.libero.it:nntp ESTABLISHED
    tcp   ppp-118-146.26-151:1501 195.210.93.172:http     ESTABLISHED
    tcp   ppp-118-146.26-151:1502 195.210.93.172:http     ESTABLISHED
    tcp   ppp-118-146.26-151:1503 195.210.93.172:http     ESTABLISHED
    tcp   ppp-118-146.26-151:1506 195.210.93.172:http     ESTABLISHED
    tcp   ppp-118-146.26-151:1507 195.210.93.172:http     ESTABLISHED

Da questo output si arguisce che stavo scaricando i newsgroup, mentre intanto scorazzavo nel WEB. Ho evidenziato in grassetto il socket pair usato per i newsgroup: durante il collegamento la mia macchina usava il socket ppp-118-146.26-151:1495, mentre il socket all'altro estremo era twister1.libero.it:nntp. Il comando netstat ha sostituito i numeri di nodo con il nome, e ha anche sostituito i numeri delle porte con quelli dati dalla tabella delle porte note, che si trova nel file /etc/services.

Il comando netstat ha poi alcune opzioni molto utili: l'opzione -n del comando permette di vedere i numeri al posto dei nomi; l'opzione -p mostra i processi associati ai socket del nostro computer. Se il tuo computer, ormai permanentemente on-line, presenta qualche socket "misterioso", quest'ultima opzione permette di scovare il processo responsabile. Sempre che il comando netstat stesso non sia già stato manomesso...

Notiamo, en passant, che per il WEB il mio browser ha aperto ben 5 canali TCP per altrettanti socket pair: uno di questi canali serviva probabilmente per scaricare la pagina HTML, mentre gli altri servivano per scaricare in contemporanea varie immagini ed elementi accessori della pagina.

L'ultima colonna dell'output del comando netstat presenta lo stato del canale TCP, come spiegato nella man page del comando.

RFC 854: Il protocollo Telnet

Un altro documento a firma Jon Postel: un protocollo che supporta terminali a carattere via connessione TCP. Via Telnet possiamo aprire un terminale su di un computer remoto e operare esattamente come se fossimo collegati direttamente a quel computer con un classico video-terminale seriale. Disponendo di un sistema a finestre, si possono aprire vari terminali con uno o più computer remoti.

La gestione di un terminale seriale comporta la conoscenza delle sequenze di escape specifiche del tipo di terminale di volta in volta utilizzato, costringendo i server ad includere il supporto per ciascuno di essi. Il Telnet, invece, introduce il concetto di Network Virtual Terminal, che supporta un set minimale ma sufficiente di funzionalità standard. Inoltre, Telnet permette anche la negoziazione dinamica di parecchie caratteristiche addizionali, come il supporto per il colore o il dimensionamento variabile della finestra.

Ai giorni nostri il protocollo Telnet viene utilizzato per fare il login sempre più raramente, dato che la trasmissione non è criptata, e quindi la password e tutta la comunicazione seguente può essere facilmente intercettata. Sebbene il protocollo sia stato arricchito nel tempo di varie estensioni per rimediare a questo inconveniente, la tendenza attuale è quella di utilizzare SSH (www.ssh.com) o la sua versione open source OpenSSH (www.openssh.org).

Nell'ambito di questo articolo faremo abbondante uso di Telnet come programma client per "parlare" direttamente con i vari server. Infatti il server Telnet risponde alla porta TCP numero 23, ma la maggior parte dei programmi client permettono di specificare anche una porta alternativa:

    $ telnet nomehost numeroporta

dove numeroporta può essere indifferentemente il numero della porta oppure il suo nome, come deducibile dal file /etc/services. Con questo comando il client realizza una comunicazione diretta bidirezionale con il server: quello che premo sulla tastiera viene inviato al server, mentre quello che il server invia a me appare sullo schermo.

Due ultime considerazioni sulla modalità di comunicazione adottata dal client Telnet:

In ambiente Windows suggerisco di usare programmi come PuTTY o Teraterm, che sono decisamente più completi e sofisticati. Una ricerca in Internet dovrebbe ritornare immediatamente i siti da cui scaricare questi programmi.

Armati di questo strumento fondamentale, possiamo ora affrontare gli altri protocolli Internet fondamentali, cercando di presentarli in ordine crescente di complessità.

RFC 1939: il protocollo POP-3

Il Post Office Protocol è un protocollo "popolare", perché lo usiamo tutti i giorni per scaricare la posta dalla nostra mailbox. Il nostro client di posta, qualunque esso sia, usa il POP-3 per collegarsi al server del nostro ISP, autenticarsi, richiedere la lista dei messaggi giacenti, scaricarli uno ad uno, e quindi eventualmente rimuoverli dalla mailbox per lasciare spazio ai messaggi futuri.

I progettisti del protocollo, nella loro infinita saggezza, hanno mantenuto il dialogo tra il client e il server puramente testuale: una volta stabilito il canale TCP tra la nostra macchina e il server remoto, il dialogo si articola in una serie di righe di testo che le due macchine si scambiano. Questo dialogo può dunque essere facilmente visualizzato e, all'occorrenza, riprodotto manualmente usando telnet come client.

I comandi del POP-3 si possono scrivere indifferentemente maiuscoli o minuscoli. Qui li scriverò sempre maiuscoli per metterli meglio in evidenza. Ecco dunque i principali comandi del protocollo POP-3:

USER nomeutente
PASS password
Una volta stabilita la connessione con il server ci troviamo nella fase di autenticazione. Questi comandi permettono di identificare l'utente con la tradizionale combinazione di nome e password: il nome identifica univocamente la mailbox dell'utente, mentre la password impedisce l'accesso a coloro che non ne hanno diritto.
APOP nomeutente digest
Come metodo alternativo di autenticazione dell'utente, il protocollo POP-3 prevede anche l'invio criptato della password, come vedremo più in dettaglio negli esempi. Questa funzionalità è prevista come opzionale, e solo alcuni server la supportano.
STAT
Ritorna il numero di messaggi presenti nella mailbox e la lunghezza totale in byte.
LIST
Ritorna l'elenco dei messaggi giacenti. L'elenco prevede una riga per ogni messaggio, e viene terminato con una riga contenente un solo punto. Ogni riga presenta il numero del messaggio e la sua lunghezza (indicativa) in bytes.
RETR n
Ritorna il messaggio numero n. Al termine del messaggio il server ritorna una riga contenente un solo punto; le righe del messaggio che dovessero contenere almeno un punto iniziale vengono fatte precedere da un altro punto per evitare ambiguità.
TOP n r
Ritorna l'intestazione del messaggio e le prime r righe del corpo del messaggio numero n. Questo comando è opzionale, ma pare che tutti i server lo abbiano implementato.
DELE n
Marca il messaggio numero n per essere cancellato una volta chiusa in modo regolare la connessione.
RSET
In caso di ripensamento, questo comando rimuove la marcatura dai messaggi marcati per la cancellazione con il comando DELE.
QUIT
Il server esegue la cancellazione dei messaggi marcati per cancellazione, e quindi chiude la connessione con il client.

Possiamo sperimentare tutto questo direttamente sulla nostra macchina, basta installare il pacchetto imap allegato a tutte le distribuzioni GNU/Linux. Non richiede alcuna configurazione. In alternativa, possiamo usare il server POP-3 del nostro ISP: fintanto che non useremo il comando DELE non c'è rischio di cancellare i nostri messaggi giacenti.

Nella sessione completa che riporto di seguito sono contenute alcune prove che ho svolto sul mio computer. Per cominciare ho creato due email campione usando il comando mail e le ho inviate a me stesso. Per vedere il protocollo POP-3 in azione, mi sono collegato via Telnet alla porta pop-3 (110) della mia stessa macchina, mi sono autenticato, e ho fatto alcune operazioni sulla mia mailbox. A questo punto dovresti essere in grado di capire cosa ho fatto. In particolare ho cancellato una delle due email: sapresti dire quale? La soluzione di questo intrigante enigma sarà svelata nella prossima puntata!

    $ echo "body messaggio 1" | mail salsi -s "oggetto 1"

    $ echo "body messaggio 2" | mail salsi -s "oggetto 2"

    $ telnet localhost pop-3
    Trying 127.0.0.1...
    Connected to localhost.localdomain.
    Escape character is '^]'.
    +OK POP3 localhost.localdomain v2000.69rh server ready
    user salsi
    +OK User name accepted, password please
    pass pippo
    +OK Mailbox open, 2 messages
    stat
    +OK 2 702
    list
    +OK Mailbox scan listing follows
    1 351
    2 351
    .
    retr 1
    +OK 351 octets
    Return-Path: 
    Received: (from salsi@localhost)
            by casa.lan (Sendmail/3.14) id fBLCt1b01993
            for salsi; Fri, 21 Dec 2001 13:55:01 +0100
    Date: Fri, 21 Dec 2001 13:55:01 +0100
    From: "U.Salsi" 
    Message-Id: <200112211255.fBLCt1b01993@casa.lan>
    To: salsi@casa.lan
    Subject: oggetto 1
    Status:   

    body messaggio 1
    .
    dele 1
    +OK Message deleted
    quit
    +OK Sayonara
    Connection closed by foreign host.

    $

Alcune osservazioni sulla transazione precedente:

Avvertenza
Durante le prove con i server POP-3, potrebbe accadere che la connessione di rete cada improvvisamente per vari motivi, soprattutto se stiamo usando un modem. In questi casi il successivo collegamento POP-3 per accedere alla stessa mailbox potrebbe andare fallito. Questo perché il server protegge la mailbox dagli accessi concorrenti, e la nostra mailbox risulta ancora bloccata dalla connessione precedente, ufficialmente ancora attiva. In questo caso non rimane che attendere fiduciosi il timeout del server POP-3. Questo timeout potrebbe durare da qualche minuto fino anche a mezzora. Per le prove fatte sul proprio computer il problema non ricorre: tutti i collegamenti TCP vengono comunque sempre chiusi regolarmente.

Per finire, un piccolo trucco. Capita a volte di ritrovarsi in mailbox messaggi di dimensioni enormi che abbiamo difficoltà a scaricare. Ciononostante vorremmo almeno leggere di che si tratta, magari visualizzando la parte iniziale del messaggio incriminato, per poi decidere se tenerlo o eliminarlo. Per questo scopo è molto comodo il comando TOP opportunamente parametrizzato. Intanto, un bel LIST ci porta subito ad individuare il numero del messaggio in questione. Ottenuto questo numero, poniamo che sia il 12, procediamo con una sequenza di TOP ad intervalli di 10 righe in 10 righe:

    TOP 12 1
    (il server ritorna l'header e una riga del body)
    TOP 12 10
    (leggiamo le prime 10 righe del body)
    TOP 12 20
    (leggiamo le successive 10 righe del body)
    TOP 12 30
    ...
    DELE 12  (abbiamo optato per la distruzione!)
    QUIT  (confermiamo la scelta e chiudiamo la connessione)

Lo stesso principio, naturalmente, lo potremmo impiegare qualora sentissimo l'irrefrenabile necessità di dare un'occhiatina alla mailbox, ma non avessimo a disposizione un client completamente configurato.

POP-3 e sicurezza

Se hai mai provato un software come linsniff o un altro programma sniffer dei pacchetti di rete, avrai notato che è facile intercettare tutti i protocolli non criptati, incluso per esempio la fase di autenticazione di POP-3. La possibilità di intercettare le comunicazioni via Internet è presente a tutti i livelli della Grande Rete, a partire dalla nostra LAN aziendale o domestica, fino ad arrivare ai più remoti nodi di routing. Se infastidisce il fatto che i nostri messaggi vengano letti da persone estranee, è ancora più grave che qualcuno possa carpire la nostra password: sappiamo infatti che i messaggi nella mailbox si possono tranquillamente visionare senza cancellarli, e dunque la posta che noi leggiamo potrebbe avere già avuto un qualche lettore misterioso...

Il protocollo POP-3 prevede un meccanismo per l'invio criptato della password, ma questo sistema è previsto come feature opzionale da parte del protocollo. A vantaggio di coloro che possono avvalersi di server così avvedutamente predisposti, spieghiamo come il POP-3 supporta l'invio criptato della password. Faremo questo considerando un esempio di dialogo reale:

    $ telnet popmail.libero.it 110
    +OK POP3 PROXY server ready (6.0.012) <C1ADC15AA12@pop2.libero.it>
    APOP umberto-salsi 3c7450bfa9b8148d75c3df9677a606a1
    +OK authentication successful
    STAT
    +OK 0 0
    QUIT
    +OK POP3 server closing connection

Qui ho interrogato il server POP-3 del mio ISP per controllare la mia mailbox, verificando che è vuota. Ma la cosa importante è il metodo di autenticazione che ho usato: il comando APOP. Per cominciare, riconosco che il server supporta la trasmissione criptata della password per via della stringa tra parentesi angolari <C1ADC15AA12@pop2.libero.it> che il server presenta nel messaggio di benvenuto (la prima riga dal server): questa stringa viene detta timestamp. Ed ora il passaggio veramente interessante: apro un altro terminale virtuale dove faccio questo calcolo:

    $ echo -n "<C1ADC15AA12@pop2.libero.it>pippo" | md5sum
    3c7450bfa9b8148d75c3df9677a606a1  -

Qui ho calcolato il digest MD5 della stringa composta dal timestamp concatenato alla mia password, la classica "pippo" (qualche info in più sull'MD5 nel box). Il risultato del calcolo è un numero a 128 bit la cui rappresentazione in base esadecimale viene ritornata in output. Questa è proprio la stringa da inserire come digest nel comando APOP, insieme al mio nome utente. Un semplice copia-incolla sulla sessione telnet ancora aperta, ed ecco composto un comando APOP corretto.
N.B.: l'opzione -n del comando echo impedisce che questo comando invii l'a-capo automatico al termine dell'output generato; senza questa opzione otterremmo l'MD5 della stringa incluso il carattere di a-capo, che darebbe un risultato completamente sbagliato.

MD5 e digest
L'algoritmo MD5 fa parte della categoria delle funzioni di hash che ritornano un digest. In pratica si tratta di una funzione che accetta in input un messaggio costituito da un numero arbitrario di byte, e calcola in output una stringa di bit di lunghezza fissa detta hash. Inoltre l'argoritmo è studiato in modo che sia praticamente impossibile, dato questo hash, risalire al messaggio che lo ha generato, sia praticamente impossibile costruire un messaggio che dia un hash predefinito, e che gli hash di due messaggi simili non siano neppure lontanamente simili. Un algoritmo di hash che soddisfa questi requisiti viene detto digest. L'algoritmo MD5 è di dominio pubblico, e viene descritto nell'RFC 1321. L'MD5 è molto usato per verificare l'integrità dei file, nell'ambito degli algoritmi di crittazione e firma digitale, ma sono possibili altri utilizzi alternativi come quello illustrato in questo articolo.

A sua volta il server, che conosce la mia password, ripete lo stesso calcolo e verifica che la mia risposta sia corretta.

Un eventuale sniffatore che intercettasse questa comunicazione non potrebbe ripetere il login, perché il server cambia ogni volta il timestamp! Lo sniffatore, che non conosce la password, non ha dunque la possibilità di calcolare il digest corretto e non può quindi autenticarsi.

E' chiaro che se il meccanismo APOP risolve il problema dell'invio della password, non mette al riparo la nostra posta che viaggia in chiaro. Per risolvere veramente alla radice anche quest'ultimo problema bisogna far uso della criptazione e della firma digitale dei messaggi con programmi a chiave doppia, come PGP o GnuPG. Forse ne riparleremo.

Purtroppo il programma imap solitamente allegato alle distribuzioni GNU/Linux non supporta APOP. A beneficio dei sysadm che vogliono sperimentare con questa soluzione suggerisco il server qpopper di QUALCOMM, prelevabile da www.qualcomm.com. Si tratta di una implementazione gratuita e open source di POP-3 con supporto APOP, oltre che del metodo di autenticazione in chiaro tradizionale. Dare anche un'occhiatina al progetto gnu-pop3d reperibile su ftp.ndn.net/gnu-pop3d come sorgente, o su rpmfind.net come pacchetto RPM.

Per quanto riguarda i client in grado di supportare l'APOP eccone alcuni:

Conclusioni

Lo stretto legame esistente tra i protocolli di Internet e i sistemi operativi Unix e affini non è casuale, ma legato a scelte fatte a cavallo tra gli anni '70 e i primi anni '80, quando si dovette scegliere la piattaforma di sviluppo più efficace per la nuova tecnologia di rete. Uno degli aspetti più interessanti di questa scelta è che i protocolli principali usati ancora oggi sono essenzialmente testuali, facilitando l'apprendimento, la sperimentazione didattica, ma anche la diagnostica sistemistica e lo sviluppo software. Inoltre abbiamo visto che la documentazione tecnica degli RFC è molto ricca di informazioni e particolarmente utile per tutti coloro che affrontano le tecnologie Internet.

Non nascondo che l'argomento che sto trattando è molto vasto e complesso, per cui non mi illudo di essere stato esaustivo, nè tantomeno infallibile. Ecco perché ho già predisposto una pagina WEB all'indirizzo http://digilander.iol.it/salsi/erratacorrige dove ospitare le inevitabili correzioni e le integrazioni che si dovessero rendere necessarie. Ovviamente, si tratta di una vile manovra scaramantica.

Nella prossima puntata affronteremo altri e ancor più interessanti RFC: parleremo del formato delle email, parleremo dei messaggi multimediali, del protocollo per l'invio della posta elettronica, del protocollo dei newsgroups e condiremo il tutto con altri trucchi e suggerimenti.

Tenete in caldo il vostro programma telnet: ci servirà ancora!

Bibliografia

www.rfc-editor.org - Sito ufficiale dove vengono pubblicati e archiviati i documenti RFC.
RFC 791 - Specifiche del protocollo IP.
RFC 792 - Specifiche del protocollo ICMP.
RFC 793 - Specifiche del protocollo TCP.
RFC 854 - Specifiche del protocollo Telnet.
RFC 1321 - Specifiche dell'algoritmo MD5.
RFC 2026 - Organismi di Internet e processo di redazione dei documenti.
RFC 1700 - Numeri assegnati ai protocolli IP e alle porte TCP.
RFC 1939 - Specifiche del protocollo POP-3.
RFC 2324 - Specifiche del protocollo Coffee Pot.
www.ietf.org - Sito dell'IETF.



L'autore

Umberto Salsi <umberto-salsi@libero.it> ha scritto il suo primo programma nel 1981: un potente ciclo FOR stampava su schermo i numeri da 1 a 10000. Folgorato da questo successo, da allora non ha più smesso di seviziare computer nel software e nell'hardware, e di queste pratiche ne ha fatto il suo lavoro e il suo hobby. Nel 1992 scopre Internet e il mondo delle reti telematiche. Nel 1996 incontra GNU/Linux, ed è un'altra infatuazione.


<- SL: JFS - Copertina - Una questione di Privacy ->