Questo HOWTO descrive come preparare un laboratorio di macchine diskless (senza hard-disk), avviando i pc via rete e rendendo cosi’ un laboratorio pienamente riconfigurabile.
Note legali
Copyright
(C)opyright 2003 Alessandro Illiano, Alotto, <[email protected]>. Non si intende infrangere nessun copyright con questa opera, realizzata a scopo prettamente educativo e senza fini di lucro. Questo documento è copiabile in ogni sua parte, mantenendo il copyright. Questo documento è altresì distribuibile liberamente, mantenendo SEMPRE questa sezione. La distribuzione e l’utilizzo di questo documento, inoltre, sono vincolati dai termini indicati nella versione 2 (o da qualunque versione successiva) della GNU General Public License pubblicata dalla Free Software Foundation.
Questo documento viene distribuito con l’intento di essere utile, ma SENZA ALCUNA GARANZIA, compreso quella implicita di FUNZIONALITA’ o di UTILITA’ PER UN PARTICOLARE UTILIZZO. Vedere la GNU General Public License per ulteriori dettagli.
Feedback
Inviate per favore domande, commenti e suggerimenti ad [email protected] (Alessandro Illiano). Sono più che disposto ad aiutare chiunque abbia problemi direttamente collegati con questo HOWTO e gradirò qualunque suggerimento riguardante cambiamenti/modifiche e/o miglioramenti.
Tuttavia, avendo configurato il mio laboratorio in maniera per me soddisfacente, questo HOWTO non sarà significativamente migliorato senza suggerimenti da parte dei lettori. Grazie
Perchè questo how-to
Ho scritto questo HOWTO perché mi e’ stato proposto di effettuare un progetto di laboratorio riconfigurabile via rete durante lo stage alla Yacme s.r.l. (www.yacme.com).
Ringraziamenti
Ringrazio di cuore la Yacme s.r.l (www.yacme.com) che mi ha dato l’idea e la possibilità di realizzare questo progetto. GRAZIE!!!!!
Ringrazio, inoltre, tutti coloro che hanno contribuito minimamente alla stesura del testo dell’HOWTO, in particolar modo Pier Luigi Fiorini (grazie gigi) e Luca Bolcioni (grazie Luca ). Preciso che anche Robert Nemkin e Al Dev hanno inconsapevolmente contribuito a questa stesura.
Infine vorrei ringraziare Nigi Riccardo e Claudio Carloni che mi hanno accompagnato “nell’avventura” di Bologna :P .
Introduzione al boot via rete e all’Etherboot
Cosa è il boot via rete
Il boot via rete è una vecchia idea; l’idea di base è che il computer abbia un qualche codice di bootstrap nella memoria non volatile, cioè un chip ROM o un floppy, che gli permetterà di contattare un server per ottenere i file di sistema attraverso un collegamento di rete.
Come funziona
Perché sia possibile un boot attraverso la rete il computer deve ricevere:
- un’identità, (SERVER DHCP)
- un’immagine del sistema operativo (SERVER TFTP)
- un file system funzionante. (SERVER NFS)
Consideriamo un computer diskless (DC) che abbia una floppy per il boot via rete. Potrebbe essere uno di vari DC identici, come possiamo distinguere questo computer dagli altri? C’è una informazione che è unica per quel computer (in realtà per il suo adattatore di rete) ed è il suo indirizzo Ethernet (MAC Address). Ogni adattatore Ethernet nel mondo ha un indirizzo Ethernet univoco di 48 bit; ciò perché ad ogni costruttore di hardware Ethernet sono stati assegnati dei blocchi di indirizzi. Per convenzione tali indirizzi sono scritti con cifre esadecimali, con i due punti che separano ogni gruppo di due cifre; ad esempio: 00:60:08:C7:A3:D8.
I protocolli usati per ottenere un indirizzo IP, dato un indirizzo Ethernet, sono chiamati Boot Protocol (BOOTP) e Dynamic Host Configuration Protocol (DHCP, protocollo di configurazione dinamica dell’host). DHCP è una evoluzione di BOOTP. Nella nostra configurazione utilizziamo il DHCP SERVER.
Un esempio di scambio DHCP funziona così:
DC : Salve, il mio indirizzo hardware è 00:60:08:C7:A3:D8, per favore dammi il mio indirizzo IP.
server DHCP : (guardando nel database degli indirizzi) Il tuo nome è 486, il tuo indirizzo IP è 172.16.0.51, il tuo server è 172.16.1.1, il file da cui effettuare il boot è tftpboot/172.16.0.51/vmlinuz.prova (più qualche altra informazione).
Da notare che il file dal quale il DC deve effettuare il bootstrap è contenuto nella directory tftpboot/172.16.0.51/vmlinux.prova dove 172.16.0.51 indica l’indirizzo IP della macchina.
Ci si potrebbe chiedere come ha fatto il DC a trovare l’indirizzo del server DHCP la prima volta. La risposta è che non l’ha fatto; la richiesta DHCP è stata diffusa in broadcast sulla rete locale e qualsiasi server DHCP in grado di rispondere lo ha fatto.
Dopo aver ottenuto un indirizzo IP, il DC deve scaricare l’immagine di un sistema operativo ed eseguirlo. Qui viene usato un altro protocollo Internet chiamato Trivial File Transfer Protocol (TFTP – protocollo elementare per il trasferimento file). Il TFTP è una specie di versione ridotta dell’FTP (non c’è autenticazione e funziona sullo User Datagram Protocol (UDP) invece che sul Transmission Control Protocol (TCP)). È stato scelto l’UDP al posto del TCP a causa della semplicità; l’implementazione dell’UDP sul DC può essere abbastanza piccola da permettere di farne facilmente entrare il codice in una ROM. Visto che l’UDP è un codice orientato ai blocchi, al contrario di uno orientato al protocollo, il trasferimento avviene blocco per blocco, in questo modo:
DC: Dammi il blocco 1 di /tftpboot/172.16.0.51/vmlinuz.prova
server TFTP: Eccolo.
DC: Dammi il blocco 2.
…e così via, finché non viene trasferito l’intero file. L’handshaking è basato su una semplice conferma di ogni blocco e la perdita di pacchetti è gestita ritrasmettendo dopo un timeout. Quando sono stati ricevuti tutti i pacchetti la ROM di boot della rete passa il controllo all’entry point dell’immagine del sistema operativo.
Concludendo, per poter eseguire un sistema operativo deve essere fornito un filesystem principale. Il protocollo usato da Linux e da altri Unix di solito è il Network File System (NFS – file system di rete), sebbene siano possibili altre scelte. In questo caso il codice non deve risiedere nella ROM ma può essere parte del sistema operativo che si è appena scaricato. Comunque il sistema operativo deve essere capace di girare con un file system principale che sia un NFS invece che un vero disco. Linux ha le variabili di configurazione necessarie per compilare una versione che possa farlo.
Il bootstrap via rete in pratica
Configurazione del laboratorio
La macchina prescelta come SERVER dovrà assumere le seguenti funzioni:
- SERVER DHCP (per attribuire una identità ai client)
- SERVER TFTP (per fornire una immagine del kernel ai client)
- SERVER NFS (per dare un filesystem funzionante ai client)
I client, invece, devono essere istruiti attraverso un floppy di boot (nel nostro caso); questo si può creare con ‘etherboot’ (http://www.etherboot.org), che è un software in grado di creare immagini ROM, e quindi capace di far “bootstrappare” le macchine attraverso la rete.
Preciso, inoltre, che per il nostro laboratorio sono state utilizzate le seguenti distribuzioni:
- Per il SERVER: RedHat 7.3
- Per il CLIENT: Slackware 9.0
Inutile dire che ogni configurazione verrà eseguita solo dal lato SERVER (i client saranno avviati da un floppy di boot e quindi non hanno bisogno di configurazioni fatta eccezione per LA CREAZIONE DEL FLOPPY DI AVVIO, che vedremo più avanti).
Configurazione del server
Installazione e configurazione del DHCP server
Abbiamo visto dunque qual è il compito di un server DHCP. Ma adesso passiamo alla parte pratica.
Installazione e configurazione dal lato server
– Innanzitutto bisogna installare il pacchetto relativo al DHCP (nel nostro caso il pacchetto è dhcp-2.0pl5-8
– Il file sul quale bisogna agire è /etc/dhcpd.conf, il quale contiene la configurazione del servizio DHCP. Se dopo aver installato il pacchetto relativo al dhcp-server (cambia da distribuzione a distribuzione) il file non dovesse essere presente basta editarlo (con un editor a vostra scelta) nel percorso citato sopra.
– La configurazione del file è la seguente:
#dhcpd.confb # default-lease-time 600; max-lease-time 7200; # use-host-decl-names on; # subnet 172.16.0.0 netmask 255.255.0.0 { filename “vmlinuz.prova”; range 172.16.0.51 172.16.0.100; option broadcast-address 172.16.0.255; option routers 172.16.0.10; option tftp-server-name 172.16.1.1; }
Bisogna specificare che questa è la configurazione generica di dhcpd.conf, infatti potremmo configurare al meglio questo file specificando i parametri per ogni nostra macchina nel seguente modo:
#dhcpd.conf # default-lease-time 600; max-lease-time 7200; # subnet 172.16.0.0 netmask 255.255.0.0 host 486 { hardware ethernet 00:10:A7:13:6F:25; fixed-address 172.16.0.51; filename vmlinuz.prova”; }
e così via per ogni altro client.
Bisogna dare delle spiegazioni, però;
- filename “vmlinuz.prova”; indica il percorso dell’immagine del kernel (che ancora abbiamo da creare — quindi per il momento potete pure lasciare vuoto il campo, e riempirlo solo a creazione effettuata). Il percorso dell’immagine dipende dalla configurazione del server TFTP (che vedremo piu’ avanti — fate attenzione quindi alla configurazione di questo parametro);
- hardware ethernet 00:10:A7:13:6F:25; qua va inserito il MAC Adress della scheda di rete del CLIENT;
- default-lease-time 600; max-lease-time 7200; questi parametri indicano rispettivamente il tempo predefinito e il tempo massimo per la scadenza tra nodo e indirizzo IP assegnato;
- use-host-decl-names on;
- subnet 172.16.0.0 netmask 255.255.0.0; indicano rispettivamente la sottorete e la maschera di rete
- range 172.16.0.51 172.16.0.100; indica l’intervallo di indirizzi IP uilizzabili in modo dinamico. Piu intervalli separati possono essere indicati utilizzando piu volte questo tipo di parametro
- option broadcast-address 172.16.0.255; permette di definire l’indirizzo di broadcast
- option routers 172.16.0.10; permette di indicare l’indirizzo IP del nostro gateway (facoltativo se non si utilizza una connessione a internet)
- option tftp-server-name 172.16.1.1; permette di impostare l’indirizzo IP del nostro TFTP SERVER
Ricordo che ci sono opzioni che sono state tralasciate in questa guida, quindi per ogni altro dubbio consultare il manuale della configurazione del dhcpd.conf (man dhcpd.conf).
CONTROLLARE SE IL SERVIZIO DI DHCPD PARTE ALL’AVVIO
Installazione e configurazione del TFTP server
Installazione e configurazione dal lato server
- Innanzitutto bisogna installare il pacchetto relativo al TFTP (nel nostro caso il pacchetto è tftp-0.28-2.
- Il file sul quale bisogna agire è /etc/xinet.d/tftp, il quale contiene la configurazione del servizio TFTP.
La configurazione del file e’ la seguente:
service TFTP { socket-type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s tftpboot disable = no per_source = 11 cps = 100 2 }
A questo punto è possibile riavviare il servizio
IMPORTANTE: la stringa “server_args = -s tftpboot” indica la directory del server nella quale si trova il client all’avvio, quindi e’ importante specificare nella configurazione del DHCP server (dhcpd.conf) il percorso dell’immagine del kernel (parametro —> ‘filename “vmlinuz.prova”;’) relativamente a questa directory (/tftpboot) .
La mia situazione è la seguente:
server_args = -s tftpboot (TFTP): il client quindi di default si trovera’ nella directory /tftpboot/
filename vmlinuz.prova”; (DHCP): indica il percorso del’immagine del kernel a partire dalla directory specificata nella stringa “server_args = -s tftpboot”;
Quindi se tralasciamo l’opzione -s tftpboot nel filename dobbiamo specificare /tftpboot/vmlinuz.prova
altrimenti possiamo inserire l’opzione -s tftpboot e già di defaults il client si troverà nella directory desiderata e per questo basta scrivere vmlinuz.prova.
Ricordo che ci sono opzioni che sono state tralasciate in questa guida, quindi per ogni altro dubbio consultare il manuale della configurazione di in.tftpd (man in.tftpd).
CONTROLLARE SE IL SERVIZIO DI TFTP PARTE ALL’AVVIO
Installazione e configurazione del NFS server
Installazione e configurazione dal lato server
- Innanzitutto bisogna installare il pacchetto relativo all’nfs (nel nostro caso il pacchetto è nfs-utils-0.3.3-5.
- Controllare se è stato compilato il kernel con il supporto per l’NFS; per vedere ciò basta fare un
cat /proc/filesystem
- Controllare se il kernel consente di gestire la funzionalità di server NFS;
cat /proc/net/rpc/nfsd
- Dalla parte dell’elaboratore server è necessario che oltre al Portmapper siano in funzione alcuni demoni, avviati secondo l’ordine seguente: rpc.mountd, rpc.nfsd, rpc.statd, rpc.lockd;
rpcinfo -p
Se tutto è apposto editare il file /etc/exports che consente di condividere delle directory con i client
/tftpboot 172.16.0.51 (rw, no_root_squash)
oppure per condividere la directory con tutti i client della mia rete:
/tftpboot 172.16.0.* (rw, no_root_squash)
Se vogliamo possiamo anche configurare i files /etc/hosts.allow e /etc/hosts.deny per consentire o proibire l’accesso a determinati client.
Dobbiamo riavviare il servizio
Infine controllate con showmount -e se si condividono le directory desiderate.
Devo precisare che l’opzione “no_root_squash” non effettua la trasformazione dell’UID root e ciò é necessario quando si utilizzano client NFS senza disco fisso (il nostro caso).
Ricordo che ci sono opzioni che sono state tralasciate in questa guida, quindi per ogni altro dubbio consultare il manuale della configurazione di /etc/exports (man exports).
CONTROLLARE SE IL SERVIZIO DI NFS PARTE ALL’AVVIO
Configurazione dei client
Creazione dell’immagine del kernel
Per preparare a dovere la configurazione per i client è necessario compilare il kernel (make menuconfig o make xconfig a vostro piacere) nel seguente modo:
- Abilitare la scheda di rete presente sul pc e compilarla staticamente all’interno del kernel
- Sotto Networking options abilitare:
- IP: kernel level autoconfiguration
- IP: DHCP support
- Sotto Filesystems
- Sotto Network File systems abilitare:
- NFS file system support
- Root file system on NFS
- Sotto Network File systems abilitare:
Ricompilare il kernel con il seguente comando: make dep && make bzImage
A questo punto e’ possibile creare l’immagine del kernel
mknbi-linux --output=vmlinuz.prova --rootdir=/172.16.0.51 --ip=172.16.0.51:172.16.1.1:172.16.0.10:255.255.0.0:486 arch/i386/boot/bzImage
mknbi-linux possiamo scaricarlo da http://etherboot.sourceforge.net/.
Analizziamo il comando:
- –output=vmlinuz.prova è il nome dell’immagine del kernel che stiamo per creare
- –rootdir=/172.16.0.51 è la directory (nel SERVER) del filesystem del client
- –ip=172.16.0.51:172.16.1.1:172.16.0.10:255.255.0.0:486
questo parametro è strutturato secondo la seguente maschera:
- –ip=client:server:gateway:netmask:nome client arch/i386/boot/bzImage indica la directory dove si trova la bzImage creata con la compilazione del kernel
- Adesso ci ritroveremo nella directory da dove abbiamo lanciato il comando un file di nome vmlinuz.prova che sarà la nostra immagine del kernel da passare ai client nella directory /tftpboot/
- Per ogni dubbio consulare il manuale di mknbi-linux (man mknbi-linux)
Creazione del floppy di avvio
Dobbiamo scaricare Etherboot (da http://www.etherboot.org) e, dopo averlo installato, seguire le istruzioni:
Per creare un floppy di boot nella distribuzione viene fornito uno speciale blocco di boot. Questo piccolo programma di 512 byte carica in memoria i blocchi del disco che lo seguono nel floppy e inizia l’esecuzione. Quindi, per fare un floppy di boot, uno deve solo concatenare il blocco di boot con il binario Etherboot contenente il driver per una scheda di rete, in questo modo:
# cat floppyload.bin 3c509.lzrom > /dev/fd0
- 3c509.lzrom indica il driver per la scheda di rete presente nel pc (client) che e’ disponibile in etherboot;
- floppyload.bin indica il pacchetto per il boot che si trova all’interno di etherboot.
Quindi, ricapitolando, arrivati a questo punto, dovremmo avere (nel SERVER):
- una directory chiamata /tftpboot/
- all’interno di questa, le directory associate agli ip dei client; nel mio caso ho:
/tftpboot/172.16.0.51/
/tftpboot/???.??.?.??/
…e cosi’ via per ogni client
- inoltre all’interno di /tftpboot/ ci deve essere l’immagine del kernel (vmlinuz.prova) preparata con il comando ‘ mknbi-linux’
- i servizi di server DHCP, TFTP e NFS attivi all’avvio.
Se tutto ciò é presente possiamo provare ad avviare il client attraverso il boot da floppy (quello creato con etherboot) e vedere se carica l’immagine del kernel che sta sul server DHCP.
Qua riceveremo un errore del tipo VFS: cannot mount root filesystem perchè, giustamente, ancora non abbiamo creato la root filesystem del client all’interno della propria directory (/tftpboot/172.16.0.51/rootfilesystem).
Quindi basta creare la rootfilesystem ed il gioco é fatto.
Creazione della root file system
Io ho scelto di creare la rootfilesystem con i pacchetti di Slackware 9.0 .
Se volete seguirmi ho creato uno script che automatizza la creazione del filesystem (ricordo che le distribuzioni utilizzate sono: RedHat 7.3 per il server e Slackware 9.0 per i client), purche’ siano scaricati e copiati su cd almeno i seguenti pacchetti:
aaa_base-9.0.0-noarch-1.tgz
apmd-3.0.2-i386-1.tgz
bash-2.05b-i386-2.tgz
bin-8.5.0-i386-1.tgz
binutils-2.13.90.0.18-i386-1.tgz
bootp-2.4.3-i386-1.tgz
bzip2-1.0.2-i386-4.tgz
cpio-2.5-i386-1.tgz
cxxlibs-5.0.2-i386-1.tgz
db1-1.85-i386-1.tgz
db2-2.4.14-i386-1.tgz
db3-3.3.11-i386-3.tgz
dcron-2.3.3-i386-4.tgz
devfsd-1.3.25-i386-2.tgz
devs-2.3.1-i386-13.tgz
dhcp-3.0pl2-i386-1.tgz
e2fsprogs-1.32-i386-2.tgz
elflibs-9.0.3-i386-1.tgz
etc-5.0-noarch-11.tgz
fileutils-4.1-i386-2.tgz
findutils-4.1.7-i386-1.tgz
floppy-5.4-i386-3.tgz
gawk-3.1.1-i386-2.tgz
gdbm-1.8.0-i386-3.tgz
glibc-2.3.1-i386-3.tgz
glibc-i18n-2.3.1-noarch-1.tgz
glibc-solibs-2.3.1-i386-3.tgz
glibc-zoneinfo-2.3.1-noarch-2.tgz
grep-2.5-i386-2.tgz
gzip-1.3.3-i386-2.tgz
iptables-1.2.7a-i386-2.tgz
kbd-1.08-i386-2.tgz
less-381-i386-1.tgz
lftp-2.6.5-i386-1.tgz
libtermcap-1.2.3-i386-5.tgz
links-0.98-i386-2.tgz
modutils-2.4.22-i386-1.tgz
nc-1.10-i386-1.tgz
ncftp-3.1.5-i386-1.tgz
ncurses-5.3-i386-1.tgz
nfs-utils-1.0.1-i386-1.tgz
nmap-3.00-i386-1.tgz
openssh-3.5p1-i386-2.tgz
openssl-0.9.7a-i386-2.tgz
openssl-solibs-0.9.7a-i386-2.tgz
perl-5.8.0-i386-3.tgz
pkgtools-9.0.0-i386-1.tgz
popt-1.7-i386-1.tgz
portmap-4.0-i386-2.tgz
procps-3.1.6-i386-1.tgz
python-2.2.2-i386-3.tgz
readline-4.3-i386-2.tgz
sed-4.0.5-i386-2.tgz
shadow-4.0.3-i386-6.tgz
sh-utils-2.0-i386-1.tgz
slang-1.4.5-i386-2.tgz
svgalib-1.4.3-i386-2.tgz
sysklogd-1.4.1-i386-7.tgz
sysvinit-2.84-i386-25.tgz
tar-1.13.25-i386-1.tgz
textutils-2.0-i386-1.tgz
util-linux-2.11z-i386-1.tgz
vim-6.1-i386-7.tgz
wget-1.8.2-i386-2.tgz
yptools-2.8-i386-2.tgz
zlib-1.1.4-i386-3.tgz
Se avete messo su cd i pacchetti e avete montato il cd nel SERVER potete lanciare il mio script che vi creerà il file system del client all’interno della sua directory (/tftpboot/172.16.0.51);
E’ estremamente importante che lo script venga lanciato dalla directory /tftpboot/172.16.0.51/ dove 172.16.0.51 indica l’indirizzo IP del client che il server DHCP assegna a lui in automatico al bootstrap. Inoltre, lo script va invocato specificando il mount-point del cd-rom.
Esempio: ./nomescript /mnt/cdrom
Questo è lo SCRIPT:
################################################################################################### # Questo script e' stato realizzato da Alessandro Illiano per la Yacme s.r.l. ed e' distribuito con licenza GPL. # ################################################################################################### #!/bin/bash # mntpoint=$1 # # Controllo dei parametri if [ -z $mntpoint ]; then echo "Non hai specificato il mount point del CD-ROM!" echo -n "Mount point del CD-ROM: " read x if [ -z $x ] || [ ! -d $x ]; then echo "Directory errata!" exit 1 else mntpoint=$x fi fi # # Chiede se si vuole cancellare tutto echo -n "Vuoi cancellare il contenuto di `pwd`? [S/N] " read x if [ "$x" = "S" ] || [ "$x" = "s" ]; then rm -rf * find . -not -name '.' -not -name '..' -type f -exec 'rm -rf {}' \; fi # # Scompatta i file nel CD-ROM for i in ${mntpoint}/*.tgz; do tar -xvzf $i done # # Toglie .new dal nome del file for i in `find . -name '*.new'`;do nome=`echo $i | sed -e "s,.new,,"` mv -f $i $nome done # # Sposta le librerie mv -f lib/incoming/* lib/ # # Crea i riferimenti mancanti in ld.so.conf cat >> etc/ld.so.conf << EOF /lib /usr/lib EOF # # Crea la cache di ldconfig ldconfig -r `pwd` # # Collegamento della shell cd bin/ ln -sf bash2 sh cd .. # # Cambia la shell di root cp etc/passwd pippo cat pippo | sed -e "s,bash,bash2," > etc/passwd rm -f pippo # # Collegamento del comando mount cd sbin ln -s ../bin/mount mount cd .. # # Creazione della directory proc mkdir -p proc chmod 555 proc # # Un po' di pulizia mv -f etc-incoming/* etc/ rm -rf install rm -rf etc-incoming # # Creazione etc/fstab cat > etc/fstab << EOF /dev/nfs / nfs defaults 0 0 none /proc proc defaults 0 0 EOF