Sistemi Liberi
User-Mode Linux e la rete
User-Mode Linux e la rete
di Stefano Sasso
L'articolo...
Nei precedenti articoli su User-Mode Linux abbiamo visto come
compilare un kernel UML e come effettuare l'installazione di un
sistema Debian in un'istanza UML. In questa puntata prenderemo in
considerazione un modo di utilizzare la rete da un'istanza UML
diverso da quello già affrontato; quindi vedremo come sia
possibile emulare una rete con vari host GNU/Linux utilizzando
più istanze User-Mode connesse tra loro. Questo può
permetterci di testare vari servizi (o regole di firewall) se non
disponiamo di una rete o se non vogliamo comprometterla con i
nostri esperimenti.
|
Condivisione del root_fs
Prima di addentrarci nelle possibili configurazioni di rete con
User-Mode Linux affrontiamo un problema che sorge quando si ha la
necessità di avere più macchine virtuali che devono
avere lo stesso filesystem iniziale. In poche parole vedremo un
modo per evitare che per avere più cloni di un filesystem
base lo stesso venga copiato brutalmente, occupando così un
notevole spazio su disco.
Dato che il filesystem di una macchina virtuale è a tutti
gli effetti un file, più accessi concorrenti a tale file lo
renderebbero inconsistente. Quindi non è possibile lanciare
più macchine virtuali che siano agganciate allo stesso
root_fs
La soluzione a questi problemi si presenta usando file gestiti
con il meccanismo Copy-On-Write (COW).
La tecnica COW consente di avere un backing file, accessibile in
sola lettura e condiviso da tutte le macchina virtuali, e
più file COW, ciascuno per ogni macchina virtuale (che
rappresentano quindi il root_fs per tali macchine) che contiene
solo le modifiche apportate al backing file.
Il comando necessario per avviare una macchina virtuale ed
inizializzarne il relativo COW-file è questo:
# ./linux-um ubd0=<cow_file>,</uml/root_fs>
|
per cui potremmo avviare due diverse macchine virtuali con
# ./linux-um ubd0=pc1.cow,root_fs
# ./linux-um ubd0=pc2.cow,root_fs
|
La rete e User-Mode Linux
Come prerequisito occorre che il supporto per la rete virtuale
sia stato abilitato in fase di compilazione del kernel (vedi primo
articolo della serie) e che siano installate le uml_utilities. Come
abbiamo visto invece nel secondo articolo, per "equipaggiare" una
macchina virtuale con una scheda di rete virtuale dobbiamo passare
il parametro eth<n> al kernel User-Mode. I valori associati a
questo parametro andranno a determinare il tipo di scheda di rete
virtuale che vogliamo usare. I tipi possibili sono:
- ethertap, TUN/TAP: connettività virtuale tra
macchina virtuale e macchina host tramite interfaccia tap
- switch-daemon: connettività solo con le altre
macchine virtuali, anche se è possibile usare una macchina
virtuale come gateway verso l'host
- slip, slirp: se non sono disponibili ethertap o TUN/TAP
o non si dispongono i privilegi di super user
- pcap: interfaccia in modalità read-only, utile se
vogliamo usare una macchina virtuale come IDS o come sniffer
Nell'articolo precedente abbiamo visto come connettere una macchina
virtuale all'host utilizzando il driver TUN/TAP, questa volta ci
soffermeremo sul driver switch-daemon.
Creazione di un hub/switch virtuale
Prima di connettere tra loro le nostre macchine virtuali
è necessario creare un hub o uno switch virtuale, al quale
le macchine virtuali si connetteranno (sempre virtualmente).
Questo si può fare con il comando uml_switch
[opzioni] e i suoi parametri possibili sono:
- -unix : indica il path del socket unix che identifica lo
switch
- -hub : fa funzionare lo switch come se fosse un hub,
ovvero invia i pacchetti in ingresso a tutte le sue interfacce
(necessario se si vuole sniffare il traffico della rete)
Ad esempio:
# uml_switch -unix /tmp/switch1
# uml_switch -hub -unix /tmp/hub1
|
Connessione della macchina virtuale all'hub/switch
È molto semplice connettere "fisicamente" la macchina
virtuale all'hub/switch di rete appena creato, basta modificare il
parametro eth<n> con cui si lancia il kernel User-Mode
eth<n>=daemon,,,/tmp/switch1 ricordandoci che comunque
è possibile aggiungere più interfaccie virtuali a
ogni istanza UML, ed è possibile creare più
hub/switch virtuali.
La nostra prima rete virtuale
Cominciamo a creare la nostra prima rete virtuale creando lo
switch al quale saranno connesse tutte le macchina virtuali
# uml_switch -unix /tmp/switch
|
Quindi facciamo partire le macchine virtuali
# ./linux ubd0=pc1.cow,root_fs eth0=daemon,,,/tmp/switch
# ./linux ubd0=pc2.cow,root_fs eth0=daemon,,,/tmp/switch
# ./linux ubd0=pc3.cow,root_fs eth0=daemon,,,/tmp/switch
# ./linux ubd0=pc4.cow,root_fs eth0=daemon,,,/tmp/switch
|
quindi possiamo configurare le interfaccie di rete sulle istanze
appena avviate
pc1# ifconfig eth0 192.168.0.1 netmask 255.255.255.0 up
|
pc2# ifconfig eth0 192.168.0.2 netmask 255.255.255.0 up
|
pc3# ifconfig eth0 192.168.0.3 netmask 255.255.255.0 up
|
pc4# ifconfig eth0 192.168.0.4 netmask 255.255.255.0 up
|
ed ora con un po' di ping verifichiamo i collegamenti.
Rete virtuale con routing verso l'host
Proviamo ora a creare una rete virtuale con un gateway verso
l'host.
Iniziamo creando e configurando l'interfaccia tap e le tabelle di
routing sul sistema host, poi creiamo lo switch virtuale:
# tunctl
set 'tap0' persistent and owned by uid 0
# ifconfig tap0 192.168.99.254 netmask 255.255.255.0 up
# ip route add 192.168.0.0/24 via 192.168.99.253
# uml_switch -unix /tmp/switch
|
Quindi facciamo partire le macchine virtuali
# ./linux ubd0=virtrouter.cow,root_fs eth0=daemon,,,/tmp/switch eth1=tuntap,tap0
# ./linux ubd0=pc1.cow,root_fs eth0=daemon,,,/tmp/switch
# ./linux ubd0=pc2.cow,root_fs eth0=daemon,,,/tmp/switch
|
quindi possiamo configurare le interfaccie di rete e le tabelle di
routing sulle istanze appena avviate
virtrouter# ifconfig eth0 192.168.0.254 netmask 255.255.255.0 up
virtrouter# ifconfig eth1 192.168.99.253 netmask 255.255.255.0 up
virtrouter# ip route add default via 192.168.99.254
virtrouter# sysctl net.ipv4.ip_forward=1
|
pc1# ifconfig eth0 192.168.0.1 netmask 255.255.255.0 up
pc1# ip route add default via 192.168.0.254
|
pc2# ifconfig eth0 192.168.0.2 netmask 255.255.255.0 up
pc2# ip route add default via 192.168.0.254
|
ed ora sempre con un po' di ping verifichiamo i collegamenti.
Come si può notare è molto facile creare e quindi
emulare situazioni di rete anche molto complesse.
Per chiunque voglia addentrarsi in quest'argomento consiglio
NetKit [1], un front-end a UML per le emulazioni di rete sviluppato
dall'Università di Roma 3 e dal LUG Roma 3.
[1] NetKit:
http://www.netkit.org/
L'autore
Stefano Sasso
(http://www.dscnet.org/stefano)
utilizza Linux dal 2000 e si diverte a programmare in Java, PHP,
Perl e Python. Frequenta il corso di laurea in Ingegneria
Informatica presso l'Università di Padova e a tempo perso
è consulente informatico su piattaforme Open Source.
|