Katharà - emulare una rete
In questa pagina 9
Perché serve un emulatore
Una rete vera è complicata: tanti dispositivi (computer, router, switch), tante interfacce (Ethernet, Wi-Fi), tanti protocolli in funzione insieme, e collegamenti fisici che formano topologie anche intricate. Fare esperimenti sulla rete di un'azienda o dell'università è impossibile (ci girano servizi che non si possono interrompere) e comprare l'attrezzatura per provare anche una cosa semplice, come far passare un pacchetto da un host a un altro attraverso due router, costa e richiede spazio. La soluzione è un emulatore di rete (network emulator).
Definizione (simulazione e emulazione). Un simulatore riproduce le prestazioni di un sistema reale (ritardi, perdite di pacchetti) con un modello. Un emulatore riproduce le funzionalità (configurazioni, architetture, protocolli): i programmi che girano sono quelli veri, ma poca attenzione è data alle prestazioni.
Esempio. Su Katharà un ping tra due container risponde in meno di 1 ms perché i container sono sulla stessa macchina: i tempi non sono quelli di un collegamento vero, e infatti nel laboratorio non si misurano ritardi ma si controlla se i pacchetti arrivano e per dove passano.
Katharà (Kathará) è l'emulatore usato nel corso: realizza il vecchio Netkit con Python e Docker. Ogni dispositivo emulato (host, router, server, ...) è un container, cioè un'unità standard di software che contiene programma e dipendenze e gira allo stesso modo su qualunque computer. Ogni container nasce da un'immagine, e ne esistono diverse: Base (DNS, web server, strumenti di rete), Quagga e FRRouting (protocolli di instradamento standard; FRR aggiunge EVPN e MPLS), Open vSwitch (switch OpenFlow), Behavioral Model (switch P4). Nei laboratori si usano l'immagine di base e, per RIP, kathara/frr (vedi RIP in KatharàLaboratorio 5 (LAB5), con FRRouting (FRR) in Katharà. Un router è una macchina che esegue un demone di instradamento: FRR contiene zebra (gestisce la tabella) e demoni per RIP, OSPF, BGP; si attivano nel file /etc/frr/daemons (ripd=yes) e si configurano in /etc/frr/frr.conf o dalla shell vtysh. RIPv2 (distance vector, metrica in numero di salti, messaggi multicast UDP 520 verso 224.0.0.9) si abilita con router rip e network <prefisso>; redistribute connected annuncia anche le reti collegate. Due laboratori: tre router in fila (kathara-lab_frr) e una rete stub di cinque router (kathara-lab_rip) con rotta predefinita verso l'esterno iniettata in RIP con route 0.0.0.0/0.RIP in Katharà →). Parecchi container vivono dentro la stessa macchina fisica (la host machine, il computer che si ha davanti) e si parlano attraverso reti virtuali.
Definizione (dispositivo emulato e dominio di collisione). Ogni dispositivo ha: una console (una finestra di terminale), una memoria, un filesystem proprio e zero, una o più interfacce di rete (
eth0,eth1, ...). Ogni interfaccia si collega a un dominio di collisione (collision domain) virtuale, indicato con una lettera o un nome (A, B, MYNET...), e ogni dominio di collisione può collegare più interfacce.
Esempio. Se pc1.eth0 e pc2.eth0 sono collegate al dominio A, i due host stanno sulla stessa rete locale e si vedono direttamente, come se fossero attaccati allo stesso hub. Per questo, in Katharà, non si aggiungono hub o switch: basta mettere più interfacce sullo stesso dominio.
Un dominio di collisione corrisponde a una rete IP (per esempio 10.0.0.0/24): le interfacce collegate allo stesso dominio devono avere indirizzi della stessa rete per comunicare direttamente (due indirizzi sono nella stessa rete se, applicando la maschera, danno lo stesso indirizzo di rete: vedi sotto, Livello di rete e indirizzamento IPIl livello di rete (network layer) porta i datagrammi da host a host attraverso i router: incapsula (framing), sceglie il percorso (routing) e sposta il pacchetto da un ingresso a un'uscita del router (forwarding); in Internet lascia ai livelli superiori controllo d'errore, di flusso e di congestione. Un indirizzo IPv4 è di 32 bit, diviso in prefisso (rete, $n$ bit) e suffisso (host, $32-n$ bit). L'indirizzamento a classi (A, B, C, D, E) è obsoleto; oggi si usa quello senza classi (CIDR): data una notazione $a.b.c.d/n$ si ricavano $N=2^{32-n}$ indirizzi, indirizzo di rete (suffisso tutto 0) e di broadcast (suffisso tutto 1), oppure con la netmask: rete $=$ indirizzo AND maschera, broadcast $=$ indirizzo OR (NOT maschera).Livello di rete e indirizzamento IP →); dispositivi in domini diversi comunicano solo se c'è un router in mezzo (vedi Routing statico in KatharàLaboratorio 2 (LAB2). Due LAN (195.11.14.0/24 e 200.1.1.0/24) sono unite da due router r1 e r2 collegati da una rete 100.0.0.8/30. Una interfaccia attiva inserisce da sola nella tabella di instradamento solo la rete direttamente collegata: per le altre servono rotte inserite a mano. I PC usano una rotta predefinita (route add default gw 195.11.14.1), i router rotte statiche (route add -net 195.11.14.0/24 gw 100.0.0.9 dev eth1). Senza la rotta di ritorno su r2 le richieste di ping arrivano ma le risposte no: la raggiungibilità vale solo se c'è un percorso in entrambi i versi. A configurazione finita ping da pc1 a pc2 risponde con ttl=62 (64 meno 2 router).Routing statico in Katharà →).
I comandi di Katharà
Katharà ha tre famiglie di comandi, tutti invocabili come kathara <comando> (le versioni a sola lettera, come lstart, sono scorciatoie del laboratorio).
| Famiglia | Comando | Che cosa fa |
|---|---|---|
| v-commands (una sola macchina) | vstart |
avvia un nuovo dispositivo con interfacce a piacere |
vconfig |
collega altre interfacce a un dispositivo già acceso | |
vclean |
ferma un dispositivo | |
| l-commands (un intero laboratorio) | lstart |
avvia tutti i dispositivi del laboratorio |
lclean |
ferma tutti i dispositivi del laboratorio | |
lrestart |
ferma e riavvia (si usa per azzerare, per esempio, le cache ARP) | |
linfo |
informazioni sul laboratorio | |
lcrash |
ferma i dispositivi di colpo, senza attendere (usato nel laboratorio sull'ARP) | |
| globali (gestione) | check |
controlla che l'ambiente funzioni |
connect |
apre la console di una macchina già in esecuzione | |
list |
elenca le macchine in esecuzione dell'utente | |
settings |
mostra e modifica le impostazioni | |
wipe |
cancella tutte le macchine e tutti i collegamenti |
I v-commands servono per prove rapide con una macchina sola; gli l-commands per i laboratori con più macchine, che sono quelli che userai più spesso.
kathara check # verifica che l'installazione funzioni
kathara vstart -n pc1 --eth 0:A # avvia il dispositivo pc1 con eth0 sul dominio A
kathara vclean -n pc1 # ferma pc1La prima riga lancia dei test automatici sull'ambiente. La seconda crea un dispositivo chiamato pc1 (-n = name) con l'interfaccia eth0 (--eth 0:A significa "interfaccia numero 0 sul dominio A") e apre una finestra di terminale su di esso. La terza lo ferma.
Nel laboratorio d'esame e di università, il terminale della host machine prepara l'ambiente con source ./kathara.sh, poi si entra nella cartella del laboratorio con cd e si lanciano lstart / lclean. Alla fine, lwipe cancella ogni residuo (macchine e reti virtuali): è il comando da dare per "distruggere" il laboratorio dopo lclean.
Condividere file con la macchina fisica
Ci sono due modi per scambiare file tra il computer vero e i dispositivi:
- la cartella
/shareddentro ogni dispositivo punta alla cartellashareddel laboratorio. È abilitata di default e permette lettura e scrittura; - la cartella
/hosthomedentro ogni dispositivo punta alla home dell'utente del computer vero. È disabilitata di default (si abilita conkathara settings), anch'essa in lettura e scrittura.
Esempio. Per salvare le catture di pacchetti in un file leggibile da Wireshark si scrive tcpdump -i eth0 -w /hosthome/capture.pcap: il file compare nella home dell'utente, fuori dal container.
Com'è fatto un laboratorio
Definizione (laboratorio Katharà). Un laboratorio è una cartella che contiene: un file
lab.confcon la topologia; per ogni dispositivo un file<nome>.startup(comandi eseguiti dentro il dispositivo subito dopo l'avvio); eventualmente una sottocartella<nome>/per ogni dispositivo, il cui contenuto viene copiato nella radice/del filesystem di quel dispositivo.
Esempio. Il file pc1/foo/file.txt diventa /foo/file.txt dentro pc1. Nel laboratorio del firewall la cartella vpc/var/www/index.html mette la pagina web nel server vpc, e r1/etc/shadow fissa la password dell'utente root di r1.
Katharà avvia un dispositivo per ogni macchina nominata in lab.conf e per ogni sottocartella presente.
lab.conf
Contiene righe macchina[argomento]=valore:
- se l'argomento è un numero,
valoreè il dominio di collisione a cui collegare l'interfacciaeth<numero>; - se non è un numero, è il nome di un'opzione e
valoreil suo argomento.
pc1[0]=A
pc2[0]=A
pc2[1]=B
pc3[0]=BSi legge così: pc1 ha una sola interfaccia, eth0 sul dominio A; pc2 ne ha due, eth0 su A ed eth1 su B (quindi pc2 sta in mezzo e può fare da router); pc3 ha eth0 sul dominio B. Le righe vuote e le variabili LAB_DESCRIPTION, LAB_VERSION, ... in testa servono solo come informazioni.
Esempi di opzioni (argomento non numerico) che incontrerai nei laboratori:
Le virgolette attorno al nome del dominio sono facoltative: pc1[0]="A" e pc1[0]=A sono uguali.
I file .startup
Sono script di shell, eseguiti dentro il dispositivo all'accensione. L'uso tipico è configurare le interfacce e avviare i servizi.
ifconfig eth0 10.0.0.1/24 up # assegna l'indirizzo e attiva l'interfaccia
/etc/init.d/zebra start # avvia un servizio (qui un demone di routing)In lab.conf e nei .startup sta quindi tutta la descrizione del laboratorio: copiando la cartella su un altro computer si ottiene la stessa rete.
ifconfig: configurare un'interfaccia
Formula (sintassi di
ifconfig).ifconfig <interfaccia> <indirizzo> netmask <maschera> broadcast <indirizzo di broadcast> [mtu <byte>] up. Equivale aifconfig eth0 <indirizzo>/<lunghezza> up: la maschera può essere scritta come lunghezza del prefisso.
Esempio. Nella rete 10.0.0.0/24, la riga ifconfig eth0 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255 up equivale a ifconfig eth0 10.0.0.1/24 up: l'indirizzo broadcast è quello con tutti nella parte host, cioè (vedi Subnetting e supernettingIl subnetting divide un blocco di indirizzi in sottoblocchi più piccoli allungando la maschera ($n_{\text{sub}}=n_{\text{rete}}+s$, con $2^s$ sottoreti); il supernetting (aggregazione CIDR) fa l'opposto, accorciando il prefisso per unire blocchi contigui in uno più grande. Regole di progetto: ogni sottorete ha un numero di indirizzi potenza di 2 ($M=2^k\ge$ host richiesti $+2$), prefisso $n=32-k$, indirizzo iniziale multiplo di $M$; si assegnano prima le sottoreti più grandi. Per aggregare $2^j$ blocchi di prefisso $n$ servono blocchi contigui il cui primo indirizzo sia multiplo della dimensione dell'aggregato, e il nuovo prefisso è $n-j$.Subnetting e supernetting →).
Il significato di ogni parte:
eth0è l'interfaccia da configurare;10.0.0.1è il suo indirizzo IP;netmask 255.255.255.0dice che i primi bit sono la parte di rete: l'interfaccia fa parte di10.0.0.0/24. In binario la maschera è (Basi di numerazione e conversioni - binario, ottale ed esadecimaleUn numero in base $r$ vale $\sum a_i r^i$ (cifre $a_i\in{0,\dots,r-1}$). Conversioni: base $r\to$ decimale con la somma pesata; decimale $\to$ base $r$ per divisioni successive (parte intera, resti letti dal basso) e moltiplicazioni successive (parte frazionaria, parti intere lette dall'alto); binario $\leftrightarrow$ ottale/esadecimale a gruppi di 3/4 bit. Somma, differenza e prodotto binari seguono le regole decimali con cifre 0 e 1; la differenza ha prestiti, il prodotto somma prodotti parziali traslati.Basi di numerazione e conversioni - binario, ottale ed esadecimale →): i bit a sono quelli di rete. L'indirizzo di rete si ottiene con un AND bit a bit tra indirizzo e maschera (Algebra di Boole e porte logicheVariabili booleane, operatori AND, OR, NOT e derivati (NAND, NOR, XOR, XNOR) con tabelle di verità; assiomi e teoremi dell'algebra di Boole, De Morgan; porte logiche e completezza di NAND e NOR; semplificazione algebrica con esempio.Algebra di Boole e porte logiche →):10.0.0.1AND255.255.255.010.0.0.0. Il broadcast si ottiene mettendo a tutti i bit dell'host, cioè rete OR (NOT maschera):10.0.0.0OR0.0.0.25510.0.0.255. Gli indirizzi della rete sono , di cui riservati (rete e broadcast), quindi per gli host; Quando si aggiunge solo l'indirizzo senza maschera, Linux sceglie la maschera della classe dell'indirizzo, e se la rete è sub-nettata (per esempio/30) si sbaglia: va sempre scritta;broadcast 10.0.0.255è l'indirizzo di broadcast della rete;upattiva l'interfaccia. Quando si attiva, Linux inserisce da solo nella tabella di instradamento la rete direttamente collegata (10.0.0.0/24sueth0): è la ragione per cui due host sulla stessa rete si raggiungono senza altre configurazioni.
Si può cambiare anche l'MTU (maximum transfer unit, la dimensione massima del campo dati di un frame):
ifconfig eth0 10.0.0.5 mtu 4000 upQuesta riga attiva eth0 con indirizzo 10.0.0.5 e MTU di byte (la maschera non è scritta: per 10.x.x.x viene scelta quella di classe A, , e conviene specificarla come sopra). È la risposta all'esercizio 1 del foglio facoltativo di LAB1.
Il laboratorio "Two Hosts"
Due host sulla stessa rete: pc1 con 10.0.0.1/24 e pc2 con 10.0.0.2/24, entrambi sul dominio di collisione A.
Passo 1: creare le macchine. Con i v-commands (due comandi in due terminali della macchina fisica):
kathara vstart -n pc1 --eth 0:A
kathara vstart -n pc2 --eth 0:AIl secondo comando può stampare Error response from daemon: network with name netkit_nt_A already exists: non è un errore vero, dice solo che il dominio A esiste già (l'ha creato pc1) e pc2 si collega a quello. Si apre una finestra di terminale per ciascun dispositivo.
Passo 2: configurare le interfacce.
pc1:~# ifconfig eth0 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255 up
pc2:~# ifconfig eth0 10.0.0.2 netmask 255.255.255.0 broadcast 10.0.0.255 upPasso 3: ping. Da pc1:
pc1:~# ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=2.65 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.357 ms
...
5 packets transmitted, 5 received, 0% packet loss, time 4078msping manda messaggi ICMP echo request e aspetta gli echo reply: IPv4 non ha un meccanismo per segnalare errori né per chiedere informazioni sugli host, e il protocollo ICMP (Internet Control Message Protocol) è stato progettato per colmare queste due mancanze. Se l'altro host è vivo risponde con un echo reply. Nell'uscita:
56(84) bytes of data: byte di dati ICMP, che con l'intestazione ICMP ( byte) e quella IP ( byte) fanno byte di datagramma IP;icmp_seq: numero progressivo della richiesta;ttl=64: il time to live con cui è partita la risposta. Resta perché i due host stanno sulla stessa rete e non attraversano router; quando c'è un router in mezzo, ogni router sottrae (vedi Routing statico in KatharàLaboratorio 2 (LAB2). Due LAN (195.11.14.0/24 e 200.1.1.0/24) sono unite da due router r1 e r2 collegati da una rete 100.0.0.8/30. Una interfaccia attiva inserisce da sola nella tabella di instradamento solo la rete direttamente collegata: per le altre servono rotte inserite a mano. I PC usano una rotta predefinita (route add default gw 195.11.14.1), i router rotte statiche (route add -net 195.11.14.0/24 gw 100.0.0.9 dev eth1). Senza la rotta di ritorno su r2 le richieste di ping arrivano ma le risposte no: la raggiungibilità vale solo se c'è un percorso in entrambi i versi. A configurazione finitapingda pc1 a pc2 risponde con ttl=62 (64 meno 2 router).Routing statico in Katharà →: dopo due router);time=2.65 ms: il tempo di andata e ritorno (RTT). Il primo è più alto perché comprende la risoluzione ARP, di cui parla il passo 4;- l'ultima riga riporta pacchetti inviati, ricevuti e perdite.
Si interrompe con ; per limitare il numero di richieste si usa ping -c 1 10.0.0.2 (una sola) o -w (secondi di attesa massima).
Passo 4: guardare i pacchetti con tcpdump. tcpdump è un packet sniffer: cattura tutti i pacchetti che passano su un'interfaccia.
pc2:~# tcpdump -i eth0
19:27:17.899782 arp who-has 10.0.0.2 tell 10.0.0.1
19:27:18.002578 arp reply 10.0.0.2 is-at fe:fd:0a:00:00:02
19:27:18.004384 IP 10.0.0.1 > 10.0.0.2: icmp 64: echo request seq 1
19:27:18.005806 IP 10.0.0.2 > 10.0.0.1: icmp 64: echo reply seq 1
19:27:18.920463 IP 10.0.0.1 > 10.0.0.2: icmp 64: echo request seq 2
19:27:18.920605 IP 10.0.0.2 > 10.0.0.1: icmp 64: echo reply seq 2(da lanciare su pc2 mentre pc1 fa ping). Si leggono nell'ordine:
- ARP request (
who-has 10.0.0.2 tell 10.0.0.1):pc1sa solo l'indirizzo IP dipc2, ma per spedire il frame Ethernet serve il suo indirizzo MAC, e lo chiede in broadcast a tutta la rete. Per i dettagli vedi Protocollo ARPUn host ha tre «nomi»: nome DNS, indirizzo IP (rete) e indirizzo MAC (collegamento). Per spedire un datagramma IP in un frame serve il MAC del prossimo nodo, che si ottiene da quel nodo con ARP: richiesta in broadcast (MAC destinazione FF:FF:FF:FF:FF:FF, contiene IP e MAC del mittente e l'IP cercato) e risposta unicast con il MAC richiesto, memorizzata nella cache ARP. ARP risolve sempre il prossimo salto (host di destinazione o router), non la destinazione finale. Un broadcast non esce dalla sottorete: il proxy ARP del router risponde con il proprio MAC.Protocollo ARP → e, per l'ARP lungo un percorso con router, Routing statico in KatharàLaboratorio 2 (LAB2). Due LAN (195.11.14.0/24 e 200.1.1.0/24) sono unite da due router r1 e r2 collegati da una rete 100.0.0.8/30. Una interfaccia attiva inserisce da sola nella tabella di instradamento solo la rete direttamente collegata: per le altre servono rotte inserite a mano. I PC usano una rotta predefinita (route add default gw 195.11.14.1), i router rotte statiche (route add -net 195.11.14.0/24 gw 100.0.0.9 dev eth1). Senza la rotta di ritorno su r2 le richieste di ping arrivano ma le risposte no: la raggiungibilità vale solo se c'è un percorso in entrambi i versi. A configurazione finitapingda pc1 a pc2 risponde con ttl=62 (64 meno 2 router).Routing statico in Katharà →; - ARP reply (
is-at fe:fd:0a:00:00:02):pc2risponde in unicast con il proprio MAC; - echo request e echo reply, che sono i pacchetti ICMP veri e propri, una coppia per ogni
icmp_seq.
L'ARP compare solo la prima volta: dopo, pc1 ha il MAC di pc2 nella cache. Opzioni utili di tcpdump:
| Opzione | Significato |
|---|---|
-i eth0 |
interfaccia su cui ascoltare |
-w file.pcap |
salva i pacchetti in un file invece di stamparli |
-r file.pcap |
rilegge un file salvato |
-n |
niente risoluzione dei nomi (mostra indirizzi IP numerici) |
-nn |
anche niente nomi di protocollo/porta |
-t |
non stampa gli orari: in Katharà i tempi non sono significativi |
-e |
mostra l'intestazione del livello collegamento (indirizzi MAC) |
-c N |
si ferma dopo pacchetti |
Passo 5: guardare i pacchetti con un'interfaccia grafica. Si salva la cattura in un file nella cartella condivisa con la macchina fisica:
pc2:~# tcpdump -i eth0 -w /hosthome/capture.pcape si apre il file capture.pcap sul computer vero con Wireshark, un analizzatore di pacchetti (packet dissector) che permette di entrare in ogni pacchetto, guardare ogni campo di ogni intestazione ai vari livelli della pila ISO/OSI e il contenuto utile (payload).
Gli indirizzi MAC di Katharà
Nelle uscite riportate dalle slide gli indirizzi MAC hanno una forma regolare: fe:fd seguito dai quattro byte dell'indirizzo IP, in esadecimale. Per esempio 10.0.0.2 ha MAC fe:fd:0a:00:00:02 (perché ), 200.1.1.7 ha FE:FD:C8:01:01:07 () e 195.11.14.5 ha FE:FD:C3:0B:0E:05 (, , ). Per convertire ogni byte decimale in esadecimale si divide per (Basi di numerazione e conversioni - binario, ottale ed esadecimaleUn numero in base $r$ vale $\sum a_i r^i$ (cifre $a_i\in{0,\dots,r-1}$). Conversioni: base $r\to$ decimale con la somma pesata; decimale $\to$ base $r$ per divisioni successive (parte intera, resti letti dal basso) e moltiplicazioni successive (parte frazionaria, parti intere lette dall'alto); binario $\leftrightarrow$ ottale/esadecimale a gruppi di 3/4 bit. Somma, differenza e prodotto binari seguono le regole decimali con cifre 0 e 1; la differenza ha prestiti, il prodotto somma prodotti parziali traslati.Basi di numerazione e conversioni - binario, ottale ed esadecimale →): quoziente e resto sono le due cifre. Per : , e si scrive C, resta , quindi C8; per si ha C3; per , con che si scrive A, si ha 0A. È una scelta dell'emulatore, utile perché permette di capire a quale interfaccia appartiene un MAC senza un elenco; in una rete vera il MAC è assegnato dal costruttore e non c'entra con l'IP.
Esercizi del foglio facoltativo di LAB1
Esercizio 1. Comando per attivare eth0 con indirizzo 10.0.0.5 e MTU byte: ifconfig eth0 10.0.0.5 netmask 255.255.255.0 mtu 4000 up (è la riga già spiegata sopra).
Esercizio 2. Che cosa succede facendo ping verso un indirizzo che non esiste?
- se l'indirizzo è nella stessa rete (per esempio
10.0.0.99): nessuno risponde all'ARP who-has, il kernel dopo alcuni tentativi rinuncia epingstampaDestination Host Unreachable(contcpdumpsi vedono solo ARP request senza risposta); - se l'indirizzo è fuori dalla rete e non c'è né una rotta né un gateway predefinito (per esempio
192.168.5.5):pingstampa subitoconnect: Network is unreachable, senza mandare nulla in rete, perché il kernel non sa da che interfaccia farlo uscire.
Come decide il kernel: la tabella di instradamento di pc1 contiene una sola voce, la rete collegata 10.0.0.0/24 su eth0. Per 10.0.0.99: 10.0.0.99 AND 255.255.255.0 10.0.0.0, la voce corrisponde, quindi il pacchetto parte e serve il MAC (ARP) che nessuno fornisce. Per 192.168.5.5: AND con la stessa maschera 192.168.5.0, diverso da 10.0.0.0; nessuna voce corrisponde e non c'è una rotta di default, quindi non si può neppure provare. Lo stesso accade con una maschera sbagliata: se pc1 è 10.0.0.1/25 (rete 10.0.0.0/25, host da .1 a .126) e pc2 è 10.0.0.200, allora 10.0.0.200 AND 255.255.255.128 10.0.0.128, che non è la rete di pc1: pc1 risponde Network is unreachable per un host che sembra vicino (Subnetting e supernettingIl subnetting divide un blocco di indirizzi in sottoblocchi più piccoli allungando la maschera ($n_{\text{sub}}=n_{\text{rete}}+s$, con $2^s$ sottoreti); il supernetting (aggregazione CIDR) fa l'opposto, accorciando il prefisso per unire blocchi contigui in uno più grande. Regole di progetto: ogni sottorete ha un numero di indirizzi potenza di 2 ($M=2^k\ge$ host richiesti $+2$), prefisso $n=32-k$, indirizzo iniziale multiplo di $M$; si assegnano prima le sottoreti più grandi. Per aggregare $2^j$ blocchi di prefisso $n$ servono blocchi contigui il cui primo indirizzo sia multiplo della dimensione dell'aggregato, e il nuovo prefisso è $n-j$.Subnetting e supernetting →).
Esercizio 3. Si lancia tcpdump su pc2, si fa il ping da pc1 e si apre la cattura in Wireshark: l'ARP request ha come MAC sorgente quello di pc1 e come destinazione ff:ff:ff:ff:ff:ff (broadcast); l'ARP reply porta in chiaro il MAC di pc2. Con la regola di Katharà, 10.0.0.1 ha MAC fe:fd:0a:00:00:01 e 10.0.0.2 ha fe:fd:0a:00:00:02 (gli indirizzi reali vanno letti dalla cattura).
Esercizio 4. Si avviano anche pc3 e pc4 su un dominio di collisione diverso (per esempio B) e si prova ping da pc1 a pc4. Non funziona: i due domini sono reti virtuali separate e non c'è nessun router che le colleghi. Se pc4 è in un'altra rete IP, il ping dà Network is unreachable; se per caso fosse nella stessa rete IP, l'ARP who-has non attraverserebbe mai il confine tra i domini e darebbe Destination Host Unreachable.
Errori tipici
- Dimenticare
up: l'interfaccia resta spenta e non compare nella tabella di instradamento. - Sbagliare la maschera: dà reti diverse sullo stesso dominio e quindi
Network is unreachable. - Mettere due macchine su domini diversi e aspettarsi che si vedano: serve un router.
- Concludere dai tempi di
pingqualcosa sulle prestazioni: Katharà emula le funzioni, non i ritardi. - Dimenticare di fermare il laboratorio con
lcleanelwipe: restano container e reti virtuali.
Versione ripasso
- Emulatore, non simulatore. Il simulatore riproduce le prestazioni (ritardi, perdite) con un modello; l'emulatore riproduce le funzionalità (configurazioni, architetture, protocolli) con i programmi veri. Su Katharà i tempi di
ping(sotto 1 ms) non sono quelli di un collegamento vero: si controlla se i pacchetti arrivano e per dove passano. - Architettura. Katharà (ex Netkit, Python + Docker): ogni dispositivo (host, router, server) è un container nato da un'immagine: base (DNS, web server, strumenti di rete), Quagga e FRRouting (
kathara/frr, per RIP in KatharàLaboratorio 5 (LAB5), con FRRouting (FRR) in Katharà. Un router è una macchina che esegue un demone di instradamento: FRR contienezebra(gestisce la tabella) e demoni per RIP, OSPF, BGP; si attivano nel file/etc/frr/daemons(ripd=yes) e si configurano in/etc/frr/frr.confo dalla shellvtysh. RIPv2 (distance vector, metrica in numero di salti, messaggi multicast UDP 520 verso 224.0.0.9) si abilita conrouter ripenetwork <prefisso>;redistribute connectedannuncia anche le reti collegate. Due laboratori: tre router in fila (kathara-lab_frr) e una rete stub di cinque router (kathara-lab_rip) con rotta predefinita verso l'esterno iniettata in RIP conroute 0.0.0.0/0.RIP in Katharà →), Open vSwitch, Behavioral Model. - Dominio di collisione. Ogni interfaccia (
eth0,eth1, ...) si collega a un dominio virtuale con un nome (A, B, MYNET). Più interfacce sullo stesso dominio si vedono direttamente, come allo stesso hub: per questo non si aggiungono hub o switch. Un dominio corrisponde a una rete IP (es.10.0.0.0/24); domini diversi comunicano solo con un router in mezzo (Routing statico in KatharàLaboratorio 2 (LAB2). Due LAN (195.11.14.0/24 e 200.1.1.0/24) sono unite da due router r1 e r2 collegati da una rete 100.0.0.8/30. Una interfaccia attiva inserisce da sola nella tabella di instradamento solo la rete direttamente collegata: per le altre servono rotte inserite a mano. I PC usano una rotta predefinita (route add default gw 195.11.14.1), i router rotte statiche (route add -net 195.11.14.0/24 gw 100.0.0.9 dev eth1). Senza la rotta di ritorno su r2 le richieste di ping arrivano ma le risposte no: la raggiungibilità vale solo se c'è un percorso in entrambi i versi. A configurazione finitapingda pc1 a pc2 risponde con ttl=62 (64 meno 2 router).Routing statico in Katharà →). - Comandi. v-commands (una macchina):
vstart,vconfig,vclean. l-commands (laboratorio):lstart,lclean,lrestart(azzera anche le cache ARP),linfo,lcrash. Globali:check,connect,list,settings,wipe. In aula:source ./kathara.sh,cdnel laboratorio,lstart...lclean, poilwipeper cancellare i residui.
kathara check # verifica che l'installazione funzioni
kathara vstart -n pc1 --eth 0:A # avvia pc1 con eth0 sul dominio A
kathara vclean -n pc1 # ferma pc1- Condivisione file.
/sharedè la cartella del laboratorio (attiva di default)./hosthomeè la home dell'utente, disabilitata di default (si abilita conkathara settings). Esempio:tcpdump -i eth0 -w /hosthome/capture.pcapsalva la cattura nella home, fuori dal container. - Laboratorio. Una cartella con:
lab.conf(topologia); un<nome>.startupper macchina, script eseguito all'avvio; una cartella<nome>/il cui contenuto va nella radice/della macchina (pc1/foo/file.txtdiventa/foo/file.txt). Copiando la cartella si ottiene la stessa rete. lab.conf. Righemacchina[N]=dominio: seNè un numero, l'interfacciaethNva sul dominio; altrimenti è un'opzione:image,num_terms(finestre di terminale),bridged(collegamento alla rete fisica),sysctl(parametro del kernel),ipv6. Esempio:pc1[0]=A,pc2[0]=A,pc2[1]=B,pc3[0]=B:pc2sta in mezzo e può fare da router.ifconfig.ifconfig eth0 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255 [mtu N] upequivale aifconfig eth0 10.0.0.1/24 up. La maschera va sempre scritta: senza, Linux usa quella di classe, sbagliata per reti sub-nettate (es./30, Subnetting e supernettingIl subnetting divide un blocco di indirizzi in sottoblocchi più piccoli allungando la maschera ($n_{\text{sub}}=n_{\text{rete}}+s$, con $2^s$ sottoreti); il supernetting (aggregazione CIDR) fa l'opposto, accorciando il prefisso per unire blocchi contigui in uno più grande. Regole di progetto: ogni sottorete ha un numero di indirizzi potenza di 2 ($M=2^k\ge$ host richiesti $+2$), prefisso $n=32-k$, indirizzo iniziale multiplo di $M$; si assegnano prima le sottoreti più grandi. Per aggregare $2^j$ blocchi di prefisso $n$ servono blocchi contigui il cui primo indirizzo sia multiplo della dimensione dell'aggregato, e il nuovo prefisso è $n-j$.Subnetting e supernetting →). Indirizzo di broadcast di10.0.0.0/24: . Conupil kernel inserisce da solo la rete direttamente collegata nella tabella di instradamento: per questo due host sulla stessa rete si raggiungono senza altro.- MTU.
ifconfig eth0 10.0.0.5 mtu 4000 upimposta 4000 byte di campo dati massimo (per10.x.x.xla maschera di default è quella di classe A, , quindi conviene scriverla). È l'esercizio 1 di LAB1.
pc1:~# ifconfig eth0 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255 up # indirizzo, maschera, broadcast, attivazione
pc1:~# ping 10.0.0.2 # echo request ICMP e attesa degli echo reply
pc2:~# tcpdump -tenni eth0 # cattura senza orari, con MAC, senza risoluzione nomi- Ping.
56(84) bytes: 56 byte di dati ICMP, più 8 di intestazione ICMP e 20 di IP, fanno 84 byte di datagramma.icmp_seq: numero della richiesta.ttl=64: resta 64 perché non ci sono router; ogni router attraversato sottrae 1 (62 dopo due router).time=…: RTT; il primo è più alto perché include la risoluzione ARP. Opzioni:-c N(N richieste),-w s(attesa massima). Interruzione con Ctrl+C. - Cosa si vede con
tcpdump. Prima un ARP requestwho-has 10.0.0.2 tell 10.0.0.1in broadcast (serve il MAC per il frame Ethernet), poi un ARP replyis-atin unicast, poi le coppie echo request e echo reply. Dalla seconda volta l'ARP non compare, perché c'è la cache (Protocollo ARPUn host ha tre «nomi»: nome DNS, indirizzo IP (rete) e indirizzo MAC (collegamento). Per spedire un datagramma IP in un frame serve il MAC del prossimo nodo, che si ottiene da quel nodo con ARP: richiesta in broadcast (MAC destinazione FF:FF:FF:FF:FF:FF, contiene IP e MAC del mittente e l'IP cercato) e risposta unicast con il MAC richiesto, memorizzata nella cache ARP. ARP risolve sempre il prossimo salto (host di destinazione o router), non la destinazione finale. Un broadcast non esce dalla sottorete: il proxy ARP del router risponde con il proprio MAC.Protocollo ARP →). - Opzioni
tcpdump.-iinterfaccia,-w file.pcapsalva,-rrilegge,-nniente nomi IP,-nnanche niente nomi di porta,-tniente orari (non significativi in Katharà),-emostra i MAC,-c Nsi ferma dopo N pacchetti. Il file si apre con Wireshark. - MAC di Katharà.
fe:fdseguito dai quattro byte dell'IP in esadecimale:10.0.0.2fe:fd:0a:00:00:02(perché );195.11.14.5FE:FD:C3:0B:0E:05. Scelta dell'emulatore: in una rete vera il MAC è del costruttore e non ha relazione con l'IP. - Esercizi LAB1.
- (2) Ping a indirizzo inesistente: nella stessa rete (es.
10.0.0.99) l'ARP resta senza risposta epingstampaDestination Host Unreachable; fuori dalla rete e senza rotta (es.192.168.5.5)pingstampa subitoconnect: Network is unreachablee non manda nulla. - (3) L'ARP request ha destinazione
ff:ff:ff:ff:ff:ff(broadcast) e porta il MAC di chi chiede; la reply porta il MAC cercato. - (4)
pc3epc4su un dominio B diverso non sono raggiungibili dapc1: nessun router. Se fossero nella stessa rete IP, l'ARP non attraverserebbe il confine tra domini.
- (2) Ping a indirizzo inesistente: nella stessa rete (es.
- Errori tipici: dimenticare
up(l'interfaccia resta spenta e fuori dalla tabella); sbagliare la maschera (reti diverse sullo stesso dominio, quindiNetwork is unreachable); mettere le macchine su domini diversi senza router; giudicare le prestazioni dai tempi diping(Katharà emula le funzioni, non i ritardi); dimenticarelcleanelwipe. Il laboratorio di attacco ARP è in Attacco man-in-the-middleLaboratorio 7 (LAB7). Telnet trasmette utente e password in chiaro: chi può leggere il traffico le ruba. Con un hub (scenario 1) basta untcpdumpsull'attaccante, perché l'hub ripete ogni frame su tutte le porte. Con uno switch (scenario 2) l'attaccante non vede nulla: serve un attacco man-in-the-middle con avvelenamento della cache ARP (ARP spoofing): l'attaccante invia di continuo risposte ARP false, dicendo al client che l'IP del router corrisponde al proprio MAC e al router che l'IP del client corrisponde al proprio MAC; poi inoltra i pacchetti e legge tutto. Wireshark, con Follow TCP stream, ricostruisce la sessione telnet e le credenziali.Attacco man-in-the-middle →.