giovedì, Novembre 21, 2024

Bootstrap remoto con macchine diskless HOWTO

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

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

Articoli correlati

Noleggia una Tesla per il tuo evento ICT!

Categorie