Diskless Router

Eine Schule wollte ihre Klassenzimmer netzwerktechnisch voneinander trennen, die Anschaffung von Routern war zu teuer, allerdings standen hier noch viele alte PC-Systeme herum, die kurzerhand zu Diskless Systemen umgebaut wurden. Im folgenden wird beschrieben wie ich dies aufgesetzt habe. dabei bekommen die Diskless Systeme über die F-Tasten auch einiges an Testfunktionalitäten mit. Das ganze basiert auf Busybox und Kernel 2.4. unterscheidet sich prinzipiell aber nicht von Linux Kernel 2.6.

ÜBERSETZUNG DES LINUX KERNELS

Für die Diskless-Router gibt es zwei Komponenten, die über TFTP geladen werden – den Linux Kernel und den Init-Ramdisk. Hier wird das Erstellen des Kernels beschrieben.

Für alle Diskless-Routers existiert nur ein Kernel-Image und ein RAM-disk, welche gleich für alle Routers sind. Die Konfiguration (Hostname und IP-Adressen) sind in Konfigurationsdateien auf dem TFTP-Server abgelegt und nicht hardcodiert.

Die IP-Adresse für die äussere Schnittstelle (Richtung Backbone) wird beim Hochfahren über DHCP zugewiesen, die anderen Schnittstellen (Richtung Subnetz) werden durch das rc-Script aus dem inird konfiguriert.

Der kernel bzImage-2.4.xx-dhcp hat die IP-Autoconfiguration (IP_PNP) einkompiliert. Beim Hochfahren konfiguriert der Kernel die externe Schnittstelle über DHCP (kein dhcp-client Daemon ist notwendig).

###########################

Wichtige einkompilierte Eigenschaften:

– Netzwerktreibern: eepro100, e1000, tulip, 3com-vortex – IP-Autokonfiguration mit DHCP – keine Unterstützung für lokale Datenträger (HDD/FDD), Mouse, Sound, … – Init-Ramdisk Unterstützung – ext2fs Unterstützung (für initrd) – Kernel-keyboard Layout ist auf deutsch-qwertz gepatched

###########################

Die Ãœbersetzung des Kernels läuft ganz normal ab:

% tar xvjf linux-2.4.20.tar.bz2 % cd linux-2.40.20 % loadkeys -m /usr/share/keymaps/i386/qwertz/de-latin1-nodeadkeys.kmap.gz > drivers/char/defkeymap.c % make mrproper

# Jetzt die Konfigration anpassen

% make menuconfig # oder auch ‚make oldconfig‘ % make dep && make bzImage

Den fertigen Kernel in das TFTP-Verzeichnis kopieren (zuerst ein Backup des alten Kernels vornehmen!).

% cp arch/i386/boot/bzImage /tftpboot/bzImage-2.4.xx-dhcp

###########################

Die Ãœbersetzungsoptionen im Ãœberblick:

% egrep -v ‚^$|^#‘ .config


CONFIG_X86=y
CONFIG_UID16=y
CONFIG_EXPERIMENTAL=y
CONFIG_M486=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_X86_L1_CACHE_SHIFT=4
CONFIG_X86_USE_STRING_486=y
CONFIG_X86_ALIGNMENT_16=y
CONFIG_X86_PPRO_FENCE=y
CONFIG_X86_MCE=y
CONFIG_NOHIGHMEM=y
CONFIG_NET=y
CONFIG_PCI=y
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_ISA=y
CONFIG_PCI_NAMES=y
CONFIG_SYSVIPC=y
CONFIG_SYSCTL=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
CONFIG_PACKET=y
CONFIG_FILTER=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_SYN_COOKIES=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_NET_VENDOR_3COM=y
CONFIG_VORTEX=y
CONFIG_NET_PCI=y
CONFIG_TULIP=y
CONFIG_EEPRO100=y
CONFIG_E1000=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_RAMFS=y
CONFIG_PROC_FS=y
CONFIG_EXT2_FS=y
CONFIG_MSDOS_PARTITION=y
CONFIG_VGA_CONSOLE=y

ERSTELLUNG DES RAMDISKS

Der initrd enthält folgende Teile:

– busybox (eine Binary, die wichtige Unix-Befehle implementiert) – dhcp-relay – inetd – tcpd – tcpdump – Konfigurationsdateien und Skripten

Wichtige Debian-Entwicklungspakete:

– binutils – bison – gcc – flex – libc6-dev – make

###########################

Tools und Sourcen zur Erstellung des initrd sind in Verzeichnissen unter /root/diskless-image/ zu finden:

1) Skripten zur Erstellung das init-Ramdisks

./bin/doit ./bin/makedev # wird aus doit aufgeruft

2) Masterkopien der Scripts und Konfigurationsdateien, die durch auf den Init-Ramdisk kopiert werden:

./Master/bin/pingask ./Master/etc/* ./Master/rc

3) Konfigurationsdatei für die Ãœbersetzung von Busybox (und auch Backupkopie von .config aus dem Linux-Kernel).

./Config/busybox-Config.h ./Config/linux-2.4.xx-config

4) Mountpoint für die Erstellungs des initrd, angelegt und benutzt von Skript doit.

./mnt

5) Sourcen und Patches für die eingesetzte Software

./busybox-0.60.5/
./busybox-0.60.5.tar.bz2
./dhcp-3.0pl2/
./dhcp-3.0pl2.tar.gz
./libpcap-0.7.2
./libpcap-0.7.2.tar.gz
./netkit-base-0.17/
./netkit-base-0.17.diff.gz
# patch für inetd (ignore field 5 in inetd.conf)
./netkit-base-0.17.tar.gz ./tcp_wrappers_7.6/
./tcp_wrappers_7.6.diff.gz ./tcp_wrappers_7.6.tar.gz
./tcpdump-3.7.2 ./tcpdump-3.7.2.tar.gz

Für den TCP-Wrapper Patch sieh:

http://beyond.linuxfromscratch.org/view/cvs/basicnet/tcpwrappers.html

(This patch alters the original path and logging facility of the original tcpwrappers program.)

6) Das generierte initrd.gz

./initrd.gz

###########################

Alle Programme werden mit dem Skript doit übersetzt und im initrd.gz zusammengepackt. Vorher können die Konfiguration von Busybox (Config/busybox-Config.h) und die Dateien in ./Master/* angepasst werden.

Alle Programme werden statisch kompiliert und auch gestripped, weil die standardmässige maximale Grösse für ein initrd ist nur 4MB.

% cd /root/diskless-image % RECOMPILE=no bin/doit …output überprüfen… % cp /tftpboot/initrd-dhcp.gz /tftpboot/initrd-dhcp.gz.bck % cp initrd.gz /tftpboot/initrd-dhcp.gz

Die Variable RECOMPILE entscheidet, ob bin/doit die Programme neu entpackt und übersetzt („yes“ ist der Standardwert).

Für tiefere Änderungen in dem Build-Prozess muss das Skript bin/doit angepasst werden.

Änderungen in der Konfiguration der Diskless Routers sind im Verzeichnis ./Master und in /tftpboot/* vorzunehmen.

###########################

Wir nutzen kein /linuxrc (sieh linux/Documentation/initrd.txt für Details über /linuxrc), folgende Ãœbersicht ist also nicht mehr wichtig.

Wie linux-kernel das Skript /linuxrc beim Hochfahren startet und root-device mountet:

1) initrd=xxxx – final root device is NOT ramdisk, linuxrc is executed mit PID > 1

2) initrd=xxxx root=/dev/ram0 – final root device IS ramdisk, linuxrc is NOT executed

3) initrd=xxxx root=/dev/ram0 init=/linuxrc – final root device IS ramdisk, linuxrc IS executed mit PID = 1 (init)

linuxrc: exec /sbin/init => kernel panic after halt (attempt to kill init)

Busybox as init: after halt/reboot: „Oops, attempted to kill init.“

Skripten zur Erstellung des Init-Ramdisks

* doit – Erstellung des Init-Ramdisks initrd

#=————————————————————————=#

#!/bin/sh

# $Id: doit,v 1.3 2003/06/30 07:37:18 karel Exp karel $

# This scripts builds the init ramdisk. # The variable RECOMPILE decides whether to recompile the software # from scratch (using previously saved configuration) or just use # already built binaries.

WDIR=$HOME/diskless-image INITRD=$WDIR/initrd MNT=$WDIR/mnt MASTER=$WDIR/Master CONFIG=$WDIR/Config

# build from scratch? RECOMPILE=${RECOMPILE:=yes}

# install tcpdump? TCPDUMP=${TCPDUMP:=yes}

######### # Create the init-ramdisk file

dd if=/dev/zero of=$INITRD bs=4M count=1 # default max size is 4MB mke2fs -F -m0 $INITRD

# Mount it

[ -d $MNT ] || mkdir $MNT mount -t ext2 -o loop $INITRD $MNT && rmdir $MNT/lost+found # pretty useless with ramdisk

# Create the directory structure

cd $MNT mkdir -p bin dev etc proc sbin usr/bin usr/sbin var/log var/run

# Create the required device files

cd $MNT/dev && $WDIR/bin/makedev

### CFG & SCRIPTS ###
# Copy the configuration files and the rc-Script

cd $WDIR cp -v $MASTER/etc/inittab $MNT/etc cp -v $MASTER/rc $MNT cp -v $MASTER/bin/pingask $MNT/bin

cd $WDIR

### BUSYBOX ###
# Build the busybox binary according to the busybox-Config.h

if [ „$RECOMPILE“ == „yes“ ] ; then [ -d busybox-0.60.5 ] && rm -r busybox-0.60.5 tar xvjf busybox-0.60.5.tar.bz2 && cd $WDIR/busybox-0.60.5 && cp -v $CONFIG/busybox-Config.h Config.h && make LDFLAGS=-static || exit 2 fi

# Install the busybox binary and create the symlinks

cd $WDIR/busybox-0.60.5 && ./install.sh $MNT cd $WDIR

### DHCP-RELAY ###
# Build the dhcp-relay if [ „$RECOMPILE“ == „yes“ ]; then [ -d dhcp-3.0pl2 ] && rm -r dhcp-3.0pl2 tar xvzf dhcp-3.0pl2.tar.gz && cd $WDIR/dhcp-3.0pl2 && ./configure && make CC=“gcc -static“ || exit 2 strip work.linux-2.2/relay/dhcrelay fi

# Install the dhcrelay binary

cd $WDIR cp -v dhcp-3.0pl2/work.linux-2.2/relay/dhcrelay $MNT/sbin

### INETD ###
# Build inetd
if [ „$RECOMPILE“ == „yes“ ]; then tar xvzf netkit-base-0.17.tar.gz && cd netkit-base-0.17 && zcat ../netkit-base-0.17.diff.gz | patch -p0 && ./configure && make CC=“gcc -static“ SUB=inetd || exit 2 strip inetd/inetd fi

# Install inetd and copy the configuration on the init ramdisk cd $WDIR cp -v netkit-base-0.17/inetd/inetd $MNT/usr/sbin cp -v $MASTER/etc/inetd.conf $MNT/etc

### TCPD ###
# Build TCP-Wrapper tcpd

if [ „$RECOMPILE“ == „yes“ ]; then [ -d tcp_wrappers_7.6 ] && rm -f tcp_wrappers_7.6 tar xvzf tcp_wrappers_7.6.tar.gz && cd tcp_wrappers_7.6 && zcat ../tcp_wrappers_7.6.diff.gz | patch -p1 && make CC=“gcc -static“ REAL_DAEMON_DIR=/usr/sbin linux || exit 2 strip tcpd fi

# Install tcpd and copy the configuration

cd $WDIR cp -v tcp_wrappers_7.6/tcpd $MNT/usr/sbin cp -v $MASTER/etc/hosts.allow $MASTER/etc/hosts.deny $MNT/etc

### TCPDUMP ###
# Build tcpdump

if [ „$RECOMPILE“ == „yes“ ]; then [ -d libpcap-0.7.2 ] && rm -r libpcap-0.7.2 tar xvzf libpcap-0.7.2.tar.gz && cd libpcap-0.7.2 && ./configure && make CC=“gcc -static“ || exit 2 cd .. [ -d tcpdump-3.7.2 ] && rm -r tcpdump-3.7.2 tar xvzf tcpdump-3.7.2.tar.gz && cd tcpdump-3.7.2 && ./configure –prefix=/usr –disable-ipv6 –without-crypto –disable-smb && make CC=“gcc -static“ || exit 2 strip tcpdump fi

# Install tcpdump

if [ „$TCPDUMP“ == „yes“ ]; then cd $WDIR cp tcpdump-3.7.2/tcpdump $MNT/usr/sbin fi

### # Print disk-usage (there should remain some space for logs)

echo df -h $MNT

# Unmount and compress the init ramdisk

umount $MNT gzip -f $INITRD

echo The ramdisk $INITRD.gz is ready to use.

#=————————————————————————=#

* makedev – Erstellung der Device-Files in /dev (aufgeruft von doit)

#=————————————————————————=#

#!/bin/sh

# owner ids root=“0:0″ kmem=“0:0″ tty=“0:0″

makedev() { # Usage: makedev FILE c 1 8 $root 644 mknod -m $6 $1 $2 $3 $4 && chown $5 $1 }

# console makedev console c 5 1 $root 600 &&

# core ln -s /proc/kcore core &&

# file descriptors – link to proc (base for stdin/out/err) ln -s /proc/self/fd fd &&

# allways full device makedev full c 1 7 $root 666 &&

# kernel memory makedev kmem c 1 2 $kmem 640 &&

# system memory makedev mem c 1 1 $kmem 640 &&

# null makedev null c 1 3 $root 666 &&

# system ports makedev port c 1 4 $kmem 640 &&

# standard I/O streams (links to file descriptors in /proc) ln -s fd/2 stderr && ln -s fd/0 stdin && ln -s fd/1 stdout &&

# controlling terminal makedev tty c 5 0 $tty 666 &&

# virtual console terminals for i in 0 1 2 3 4 5 6; do makedev tty$i c 4 $i $root 600 done &&

# virtual console memory for i in 0 1 2 3 4 5 6; do makedev vcs$i c 7 $i $tty 640 && makedev vcsa$i c 7 $[$i+128] $tty 640 done &&

# zero makedev zero c 1 5 $root 666

#=————————————————————————=#

Skripten, die auf Diskless-Routers laufen

* rc Init-Skript (startet Dienste und konfiguriert Netzwerk)

#=————————————————————————=#

#!/bin/sh

# $Id: rc,v 1.1 2003/06/26 10:55:34 karel Exp karel $

### rc script called by init during system boot (see /etc/inittab)

### /proc should be mounted to get better results with BusyBox tools mount -t proc proc /proc

### Start daemons [ -x /sbin/klogd ] && /sbin/klogd # [ -x /sbin/syslogd ] && /sbin/syslogd -R loghost -L [ -x /sbin/syslogd ] && /sbin/syslogd

echo Stage one finished

### Load configuration of the other network interfaces from tftp server ### (the boot interface was configured via dhcp)

### Extract the IP of the boot server from the kernel buffer BOOTSERVER=dmesg | grep bootserver= | cut -f 1 -d , | cut -f 2 -d =

# Use it as TFTP Server unless TFTPSERVER set as kernel parameter TFTPSERVER=${TFTPSERVER:-„$BOOTSERVER“}

# Argument for dhcp-relay DHCPSERVER=${DHCPSERVER:-„$BOOTSERVER“}

HOSTNAME=hostname

# Name of the file where non-dhcp interfaces are listed IFACES=interfaces

echo Bootserver: $BOOTSERVER echo TFTP Server: $TFTPSERVER echo Hostname: $HOSTNAME

echo IP-Config: other network interfaces

IP=127.0.0.1 ifconfig lo $IP && echo „lo: IP=$IP“

tftp -g -r /$HOSTNAME/$IFACES -l $IFACES $TFTPSERVER &&

INTERFACES=grep -v ^# $IFACES;

for IFACE in $INTERFACES; do unset IP NETMASK BCAST

tftp -g -r /$HOSTNAME/$IFACE -l $IFACE $TFTPSERVER && echo „$IFACE: grep ^IP $IFACE“ && eval cat $IFACE && ifconfig $IFACE $IP netmask $NETMASK broadcast $BCAST up

# tftp always creates the local file rm $IFACE done

rm $IFACES

### Start dhcp-relay

[ -x /sbin/dhcrelay ] && /sbin/dhcrelay $DHCPSERVER

### Start inetd [ -x /usr/sbin/inetd ] && /usr/sbin/inetd

### Enable routing echo 1 > /proc/sys/net/ipv4/ip_forward

### Remove startup script(s) rm -f /rc* 2>&1

echo Stage two finished

#=————————————————————————=#

* pingask – „Safe“ ping (ping für Console 2, feste Parameter)

#=————————————————————————=#

#!/bin/sh

echo -n „Enter an IP address to ping: “ read IP IP=echo $IP | cut -f 1 -d " " ping -c 4 $IP

#=————————————————————————=#

DER BOOT PROZESS DER DISKLESS-ROUTER

1) Die Äussere Netzwerkkarte startet mit einem DHCP request und bekommt vom DHCP Server folgende relevante Parameter als die Antwort:

– eigene IP-Adresse, Netzmaske, Broadcast, default Gateway

– IP-Adresse des Boot-Servers

– Pfad der Boot-Datei, die aus dem TFTP Server geladen und ausgeführt werden soll (/tftpboot/pxelinux.0)

2) pxelinux.0 ist ein Linux Boot Loader. Er versucht folgende Datei auf dem TFTP-Server zu finden:

/tfttpboot/pxelinux.cfg/

Sie enthält ähnliche Informationen wie lilo.conf, d.h. sie bestimmt, welcher linux kernel und mit welchen Parametern gebootet werden soll. Beispiel:

— /tftpboot/pxelinux.cfg/AC11000B — default linux

label linux kernel /bzImage-2.4.20-dhcp append root=/dev/ram0 initrd=/initrd-dhcp.gz rw panic=60 ip=:::::eth1:dhcp TFTPSERVER= —

Die Pfade zum Kernel und Ramdisk enthalten nicht den Prefix „/tftpboot“ (wegen der Option „root-path“ in dhcpd.conf).

Hier die Beschreibung der Parameter (sieh auch kernel-parameters.txt und nfsroot.txt in /usr/src/linux/Documentation):

root=/dev/ram0 – das finale Root-Filesystem ist im ram(disk)

initrd=/initrd-dhcp.gz – beim Booten soll dieser ramdisk-file geladen werden

rw – root-disk sofort beim Booten read/write einhängen

panic=60 – reboot automatisch nach 60sec, wenn ein kernel panic passiert

ip= – welche Netzwerk-Schnittstelle und wie konfiguriert werden soll. Funktioniert nur für eine Schnittstelle (nur der letzte ip=… oder nfsaddr=… eingegebene Parameter wird genutzt).

TFTPSERVER=.. – nicht wirklich ein kernel Parameter – unbekannte Optionen in der Form variable=value werden an init übergeben und als Environment-Variablen exportiert. Diese Variable wird später von dem Skript /rc benutzt.

3) pxelinux.0 ladet den angezeigten Kernel in den Speicher und führt ihn mit den Parametern aus.

4) Der Kernel bootet, initialisiert die Hardware und konfiguriert noch einmal über DHCP die äussere Netzwerk-Schnittstelle (IP_PNP Feature). Von dem DHCP Server bekommt er erneut folgende relevante Parameter (diesmal wird keine Boot-Datei übergeben):

– eigene IP-Adresse, Netzmaske, Broadcast, default Gateway

– IP-Adresse des Boot-Servers

– seinen Hostnamen

– den Root-Pfad auf dem TFTP-Server

5) Dannach entpackt der Kernel die ramdisk-Datei im Speicher und hängt sie als sein Root-Filesystem ein. Wenn alles in Ordnung ist, startet mit dem PID=1 das init-Programm /sbin/init.

6) Das init-Programm startet weitere Programme nach der Konfiguration in /etc/inittab.

— # /etc/inittab

::sysinit:/rc

### uncomment next line to debug on console 7
#tty7::askfirst:/bin/sh # the variable TFTPBOOT must be set in pxelinux.cfg/xxx as „kernel“ parameter
::askfirst:/bin/ping -c 4 $TFTPSERVER
tty2::askfirst:/bin/pingask
tty3::askfirst:/sbin/ifconfig | more
tty4::askfirst:/sbin/route
tty5::askfirst:/bin/ps ax | more
tty6::respawn:/usr/bin/tail -f /var/log/messages
::ctrlaltdel:/sbin/reboot

Als erstes (Zeile sysinit) wird das Script /rc ausgeführt, welches:

– startet die Daemons klogd und syslogd

– aktiviert die anderen Netzwerkschnittstellen; die Konfiguration wird über TFTP aus dem Bootserver geholt, wo sie in den Verzeichnissen /tftpboot// liegt.

– startet die Daemons dhcp-relay und inetd (sieh auch den nächsten Punkt)

– aktiviert IP Forwarding

– löscht sich aus dem RAM-Disk

Auf den Consolen 1-5 werden die Programme ping, pingask, ifconfig, ps, route ausgeführt, wenn auf die Taste Enter gedrückt wird.

Auf der Console 6 werden die Meldungen aus der Log-Datei /var/log/messages angezeigt.

7) Der Daemon inetd erwartet Verbindungen auf dem TCP Port 1 und startet über den TCP-Wrapper tcpd den Shell /bin/sh im interaktiven Modus. TCP-Wrapper sperrt alle Verbindungen, die nicht von einer der IP-Adressen des Routers R-S01 kommen – sieh auch etc/hosts.allow und etc/hosts.deny.

— # /etc/inetd.conf

1 stream tcp nowait r00t /usr/sbin/tcpd /bin/sh -i —

Den Source von inetd.c habe ich gepatched, damit er das fünfte Feld in der inetd.conf ignoriert und Prozesse immer mit UID und GID gleich 0 startet. Der RAM-Disk entält nämlich keine C-Bibliotheken, die die Auflösung Name-UID ermöglichen (die Funktion getpwnam).

KONFIGURATION EINES NEUEN DISKLESS-ROUTERS AUF DEM R-S01

(angenommen die Verkabelung und die Hardware sind bereit)

A. Wichtige Pfade auf dem TFTP-SERVER:

/etc/dhcp3/* # Konfiguration des DHCP-Servers

/tftpboot/pxelinux.0 # PXE boot loader (~lilo) /tftpboot/pxelinux.cfg/* # Konfiguration für pxelinux (~lilo.conf)

/tftpboot/bzImage-2.4.xx-dhcp # Linux Kernel für die Disklesses /tftpboot/initrd-dhcp.gz # Ramdisk für die Disklesses

/tftpboot//* # Konfiguration für das rc-Skript /tftpboot//interfaces # Liste der inneren Schnittstellen /tftpboot//eth* # Konfiguration der inneren Schnittstellen

/root/diskless-image/* # Sourcen zur Erstellung des kernels und initrd

B. Konfigurationsanleitung

1) Die IP-Addresse und den Hostnamen für den Router in der DHCP-Konfiguration bestimmen (in dem richtigen Subnet-Block!):

— /etc/dhcp3/dhcpd.conf —

host { hardware ethernet ; fixed-address ; } —

Die Reihenfolge, in der die Intel-Karten initialisiert werden, muss nicht der Reihenfolge entsprechen, in der Linux die Schnittstellen konfiguriert (eth0, eth1, …)!

Die neue Konfiguration aktivieren:

% /etc/init.d/dhcp3-server restart

2) Die Konfiguration für den PXE-BootLoader erstellen:

% cd /tftpboot/pxelinux.cfg % vi gethostip -x

Beispiel (sieh auch booting.txt):

— default linux

label linux kernel /bzImage-2.4.20-dhcp append root=/dev/ram0 initrd=/initrd-dhcp.gz rw panic=60 ip=:::::eth1:dhcp TFTPSERVER= —

Noch einen symlink erstellen, damit man für spätere Änderungen die HEX-Adresse nicht mehr braucht.

% ln -s gethostip -x

3) Konfiguration für das rc-Script vorbereiten:

% mkdir /tftpboot/ % cd /tftpboot/

Hier zwei oder mehr Dateien nach folgendem Beispiel anlegen (interfaces und eth*). In der Datei interfaces darf nicht die Schnittstelle stehen, die über DHCP konfiguriert wird:

—interfaces— # interfaces to configure via „tftp“ eth0 eth2 eth3 —

—eth0— IP=xxx.xxx.xxx.xxx NETMASK=xxx.xxx.xxx.xxx BCAST=xxx.xxx.xxx.xxx —

Falls erforderllich, das rc-Skript unterstüzt auch IP-Aliasen (zB. eth0:0).

4) Den Diskless-Router rebooten und beten 😀