weidner/archives/2012/07/

Anycast (2)

Nachdem ich im letzten Artikel allgemein auf IP-Anycast-Dienste eingegangen bin, geht es diesmal um ein Skript, mit dem ich IP-Adressen am Loopback-Interface automatisch beim Systemstart aktivieren und bequem einzeln aus- und eingeschalten kann. Diese IP-Adressen am Loopback-Interface kann ich nicht nur für Anycast-Adressen verwenden, sondern auch als eindeutige Router-Adressen, die unabhängig von der Netztopologie sind.

Das Skript kümmert sich nicht um das Bekanntmachen der Anycast-Adressen im Netz. Dafür ist, mit entsprechender Konfiguration ein Routing-Dämon auf dem gleichen Rechner zuständig. Das hier beschriebene Skript konfiguriert lediglich vorher festgelegte Adressen auf dem Loopback-Netzwerkinterface.

Bei der Konzeption des Skripts habe ich mich am Initd-Skript des openvpn Packages bei Debian Linux orientiert, mit dem es möglich ist, beliebige konfigurierte VPNs einzeln oder insgesamt zu aktivieren/deaktivieren.

Die zugelassenen Adressen werden hier als Dateien mit Name $adresse.conf im Verzeichnis /etc/loopback-addr/ angelegt. Im einfachsten Fall (für Adresse 10.1.2.3) wie folgt:

$ sudo touch /etc/loopback-addr/10.1.2.3.conf

Mehr ist zu diesen Dateien im Moment nicht zu sagen. Ihre Existenz reicht aus.

Im Skript wird für jede Adresse bei jeder möglichen Aktion (start, stop, status) geprüft, ob eine betreffende Datei existiert:

if test -e ${CONFDIR}/$1.conf; then
    # ... Aktion ausführen
else
    echo -n " ($1 not configured for loopback)" >&2
    STATUS=1
fi

Das Skript prüft für jede mögliche Aktion (start, stop, status), ob die betreffende Adresse konfiguriert ist und führt die Aktion dann aus. Die möglichen Aktionen selbst sind recht einfach. Sie greifen auf eine Funktion addr_active() zurück, deren Rückgabewert angibt, ob die betreffende Adresse bereits aktiviert ist:

address_active () {
    ip addr show dev lo|grep -qE "inet6? $1/[0-9]+ scope global"
}

Zum Aktivieren einer Adresse haben wir damit folgenden Code:

start () {
    if test -e ${CONFDIR}/$1.conf; then
        if address_active $1; then
            echo -n " [$1 already active]"
        else
            ip addr add $1/32 dev lo
            echo -n " [$1]"
        fi
    else
        echo -n " ($1 not configured for loopback)" >&2
        STATUS=1
    fi
}

Beim Aufruf von start 10.1.2.3 testet das Skript zunächst auf das Vorhandensein der zugehörigen Konfigurationsdatei und fügt die Adresse schließlich mit ip addr add 10.1.2.3/32 dev lo hinzu, wenn diese noch nicht an das Loopback-Interface gebunden ist.

Für die Aktionen stop und status sieht der Code ähnlich aus. Bei stop wäre die Aktion ip del addr 10.1.2.3/32 dev lo und bei status wird gar nichts eingestellt, sondern lediglich eine Ausgabe für den Bildschirm erzeugt.

Dieses Skript kann ich so, wie es ist nach /etc/init.d/ kopieren und mit

$ sudo update-rc.d loopback-addr defaults

im Boot-Prozess verankern.

Debian Package

Um die Installation zu vereinfachen, baue ich mir ein Debian-Package für das Skript, so dass ich es mit einem Befehlsaufruf installieren und im Boot-Prozess einfügen kann. Außerdem kann ich es so über ein lokales Debian-Repository leichter verteilen.

Für den Bau des Debian-Packages nehme ich equivs. Dafür brauche ich nur noch eine Steuerdatei und zwei kurze Skripts für den Aufruf von update-rc.d.

Die Steuerdatei für equivs (loopback-address-control) sieht so aus:

Section: misc
Priority: optional
Standards-Version: 3.6.2
Package: loopback-addr
Depends: coreutils, grep, iproute
Recommends: quagga
Suggests: mon
Files: loopback-addr /etc/init.d/loopback-addr
File: /etc/loopback-addr/README 644
 To have an loopback address automatically started at system boot time,
 add a file named <addr>.conf to this directory.
 .
 For instance to add address 10.1.2.3, you could do:
 .
   $ sudo touch /etc/loopback-addr/10.1.2.3.conf
 .
 Then you may activate this address at the loopback interface with
 .
   $ sudo /etc/init.d/loopback-addr start 10.1.2.3
 .
 or stop it with
 .
   $ sudo /etc/init.d/loopback-addr stop 10.1.2.3
 .
 It will be automatically activated at boot time.
Postinst: postinst
Prerm: prerm
Description: Manage loopback addresses at the local network interface
 Use this package to manage loopback ip addresses if you want to provide
 services at these addresses and have them configured at startup.
 .
 You will also need a means to make these addresses known to the network.
 A routing daemon like the ones in the quagga package would do the trick.

Das Nach-Installations-Skript (postinst):

#!/bin/sh
update-rc.d loopback-addr defaults

Und das Vor-Deinstallations-Skript (prerm):

#!/bin/sh
/etc/init.d/loopback-addr stop
update-rc.d -f loopback-addr remove

Nun kann ich mir ein Debian-Package mit folgenden Befehlen erzeugen und einspielen:

$ equivs-build loopback-addr-control
$ sudo dpkg -i loopback-addr_1.0_all.deb

Zur bequemen Benutzung habe ich alles in der Tar-Datei loopback-addr.tar.gz zusammengefasst.

Achtung! Versionsabhängig

Beim Programm equivs-build, mit dem ich das Debian-Package erzeuge, gab es eine Änderung zwischen Version 2.0.8 (z.B in Debian 6 Squeeze oder Ubuntu 10.04) und der Version 2.0.9 (in Ubuntu 12.04). In der alten Version muss die Files: Zeile wie folgt lauten:

Files: loopback-addr /etc/init.d/loopback-addr

Hier war es möglich, der Datei einen anderen Namen zu geben.

Bei der neuen Version muss es heissen:

Files: loopback-addr /etc/init.d/

Im zweiten Feld muss das Verzeichnis stehen, so wie es auch im Handbuch steht. Andernfalls wird ein Verzeichnis /etc/init.d/loopback-addr/ angelegt und die Datei dorthin kopiert.

Posted 2012-07-25
Tags: