iodine – IPv4 über DNS tunneln

Ich habe schon öfter über Dinge geschrieben die unterwegs nützlich sind um Zugriff aufs Internet zu bekommen. Ein Tool habe ich bereits seit langem installiert, jedoch jetzt kürzlich das erste Mal praktisch genutzt: iodine.

Zugiodine ermöglicht es einem IPv4 Traffic über DNS zu tunneln. Das ist immer dann praktisch wenn der Internetzugriff per Firewall gesperrt, DNS aber erlaubt ist.

Die Hürden für ein iodine Setup sind erst einmal groß. Um den Server zu installieren bedarf es nicht nur eines entsprechenden Hosts auf dem das Paket installiert werden kann, sondern man muss auch in seinem DNS Einstellungen machen können. Bei mir funktioniert das folgende Setup:

Auf dem gewünschten Server habe ich das iodine Paket aus den Paketquellen installiert:

aptitude install iodine

Anschließend habe ich in der Konfigurationsdatei /etc/default/iodine die folgenden Einstellungen hinterlegt:

START_IODINED="true"
IODINED_ARGS="10.9.0.123 iodine.example.net -c"
IODINED_PASSWORD="MYSECRETPASSWORD"

Nun zum DNS. Dort benötigt man zwei Einträge. Angenommen der Host auf dem iodine installiert ist hat die IP 1.2.3.4, dann bekommt dieser zuerst einen ganz normalen IN A Eintrag. host.example.net zeigt auf 1.2.3.4. Das  ist nichts besonderes sondern so einen Eintrag setzt man ja eigentlich immer.

IN A

Der zweite Eintrag ist nun der abweichende. Wie in den IODINED_ARGS angegeben benötigen wir den DNS-Eintrag iodine.example.net. Dieser bekommt aber keinen IN A Eintrag, sondern als Nameserver den host.example.net eingetragen.

IN NS

Wenn der Server eingerichtet ist, kann man sich an den Client machen. Ich nutze den Network-Manager und dafür gibt es ein praktisches Plugin. Auf dem Client:

aptitude install network-manager-iodine-gnome

Anschließend kann man den nm-connection-editor starten und dort eine neue Verbindung vom Typ VPN – Iodine VPN Tunnel  hinzufügen. Als Verbindungsname wählt man das was man will, als Toplevel Domain trägt man iodine.example.net ein, und das auf dem Server unter IODINED_PASSWORD gesetzte Passwort speichert man auch optional ab. Fertig.

Schnell ist die Anbindung nicht, das ist technisch bedingt, aber sie ist stabil, selbst wenn man von dem Hotspot alle X Minuten per DHCP eine neue IP bekommt bricht der Tunnel nicht ab. Klasse!

HowTo: Mailserver, DNS und SPF Records

SPF steht fuer Sender Policy Framework und ist ein Spamschutzverfahren bei dem im DNS ein TXT Record hinterlegt wird. Der Record enthaelt zusaetzliche Informationen zum Mailserver. Ein empfangender Mailserver kann dann unter Zuhilfenahme eines SPF Records ueberpruefen ob der Server der diese Email versendet ueberhaupt legitimiert ist selbiges zu tun.

Einen einfachen SPF Record Generator gibt es unter der folgenden Adresse:

TXT Records koennen unter Linux mit dem Tool dig abgefragt werden:

user@host:~$ dig +short TXT jan-von.de
"v=spf1 a a:vonde.eu a:s2.pregos.info ip4:188.40.81.89"
user@host:~$

Mit den folgenden Schritten kann man unter Debian in Postfix selber einen SPF Check implementieren:

  1. Paket installieren:
    user@host:~$ aptitude install postfix postfix-policyd-spf-perl
  2. Die Ueberpruefung als smtpd_recipient_restrictions in der /etc/postfix/main.cf hinzufuegen. Dabei darauf achten, dass nur der neue Eintrag hinten angefuegt und nichts geloescht wird:
    smtpd_recipient_restrictions = [...], check_policy_service unix:private/policy
  3. Die Policy Engine in der /etc/postfix/master.cf hinzufuegen:
    policy unix - n n - - spawn
      user=nobody argv=/usr/bin/perl /usr/sbin/postfix-policyd-spf-perl
  4. Postfix neu starten:
    user@host:~$ service postfix restart

Diese Schritte habe ich aus dem Eintrag Implementing SPF checks in Postfix von www.debiantutorials.com. Hier in meinen Blog ueberfuehrt, damit ich die Infos auch noch habe sollte die andere Seite mal Offline gehen…

aptitude mit search pattern; Systeme ohne DNS; Apache Satisfy Direktive; bash Bedeutung der Klammern

  1. Loeschen von Paketen mittels aptitude und search pattern um mehrere Pakete gleichzeitig zu loeschen, aber nicht alle hintereinander einzugeben. Das kann man mit ~n. Hier ein klassisches Beispiel wo ich das anwende. Rausfinden welcher Kernel gerade laeuft, rausfinden was es alles an alten Kernel Images auf dem System gibt, loeschen aller linux-image-2.6.32-3*:
    $ uname -a
    $ sudo aptitude search linux-image | grep "^i"
    $ sudo aptitude purge ~nlinux-image-2.6.32-3
  2. Manchmal hat man Systeme, bei denen kein DNS verfuegbar ist. Das fuehrt dann dazu, dass einige Sachen extrem lange dauern, weil Sie versuchen irgendetwas ueber DNS aufzuloesen und dann erst weiter machen wenn es einen Timeout gibt. Als erstes sollte man dann pruefen, dass der eigene Hostname in der /etc/hosts korrekt auf localhost gemappt ist. Oft rgibt es dann auch noch Sinn in der /etc/ssh/sshd_config den folgenden Schalter zu aktivieren:
    UseDNS no
  3. Manchmal moechte man bei einem Apache Webserver etwas fuer einen bestimmten IP Bereich direkt freigeben, und ansonsten soll ein Passwort eingegeben werden. Jeweils das eine von beiden ist einfach realisiert. Wenn man beides moechte, braucht man die Satisfy Direktive. Klassisches Beispiel dafuer:
            <Location "/foo">
                    Order deny,allow
                    Deny from all
                    AuthName "Foo Login"
                    AuthUserFile /path/to/.htpasswd
                    AuthType Basic
                    Require valid-user
                    Allow from 192.168
                    Satisfy Any
                    ProxyPass http://localhost:8080/foo/ timeout=6000
                    ProxyPassReverse http://localhost:8080/foo/
            </Location>
  4. bash Klammern. Immer wieder spannend, deswegen hier mal eben aus meinem Kopf heraus festgehalten wie ich mit ihnen arbeite:
    • () = Subshell. Benutze ich zum Beispiel beim anlegen von Sicherheitskopien mit:

       $ mv foo.txt foo.txt-$(date -I)
    • [] in Schleifen = Ruft das Programm „[“ auf, oder auch „test“. In einer if [ ! -d „/tmp“ ]; echo „directory /tmp does not exist.“; fi Schleife wird bei dem [ das Programm mit dem Namen „[“ aufgerufen. Liegt zum Beispiel unter /usr/bin/[ und hat auch eine eigene manpage.
    • [[]] in Schleifen = Bash eigene Funktion. Darin kann man dann auch Regex verwenden. Beispiel

      $ FOO=1234
      $ if [[ $FOO =~ ^[0-9]*$ ]]; then echo "OK"; else echo "NO"; fi
      OK
      $ FOO=1234a
      $ if [[ $FOO =~ ^[0-9]*$ ]]; then echo "OK"; else echo "NO"; fi
      NO
      $
    • {} = Variablen und Listen. Ich nutze das um in Skripten Variablen besser ersichtlich zu machen, zum Beispiel

      /bin/bash
      FOO=foo.txt
      mv ${FOO} ${FOO}_$(date -I)

      Ausserdem fuer Listen, zum Beispiel wenn man mehrere Ordner mit Unterordnern anlegen moechte:

      mkdir -p /tmp/foo/bar/{one,two,three,four}/

      Nicht zu vergessen die ganzen build-in Shell Funktionen bei den Klammern, z.B. hier, da, dort, guckstu, minneminne

check_rogue – Nagios Plugin zum erkennen von rogue DHCP

Bereits vor einiger Zeit schrieb ich darueber, dass wir bei uns im Wohnheim Probleme mit einem rogue DHCP hatten. Vorlon schrieb in einem Comment, das auch das SANS Diary das Problem beschreibt. Auch Heise war das ganze inzwischen einen Artikel wert! Wir haben bei uns im Internettutorium verschiedene Gegenmassnamen ergriffen, die fuer andere evtl. auch von Interesse sein koennen, deswegen an dieser Stelle mal kurz festgehalten:

Sperrung via iptables

Bei uns in der Firewall wird die gesamte Range in der die „boesen“ DNS-Server stehen auf Port 53 gesperrt. Der Zugriff wird geloggt, und stuendlich checken wir die Logfiles, ob es einen Zugriff gab. Wenn ja, dann gibts ne Mail.

Die iptables-Regeln im Firewall Skript lauten wie folgt:

iptables -F ukr_dns
iptables -X ukr_dns
iptables -N ukr_dns
iptables -A ukr_dns -j LOG -m limit --limit 90/h --log-prefix "FW: MALDNS "
iptables -A ukr_dns -j REJECT
iptables -I FORWARD -p udp --dport 53 -d 85.255.112.0/255.255.255.0 -j ukr_dns
iptables -I FORWARD -p tcp --dport 53 -d 85.255.112.0/255.255.255.0 -j ukr_dns

Der dazugehoerige crontab-Einzeiler-Eintrag lautet wie folgt:

0 *     * * *    root    /bin/grep MALDNS /var/log/syslog | grep -v CRON | \
mail -e -s "MALDNS-Report /bin/date -I" vir-reports@mydomain.tld

check auf rogue DHCP mit Nagios

neben dieser mehr schadensbegrenzenden Massname wenn bereits etwas passiert ist, ueberpruefen wir unser Netz auf rogue DHCP Server mit einem Nagios-Skript. Das Skript ist ein Wrapper zu dhcp_probe.
Leider ist dhcp_probe nicht direkt fuer Debian Linux verfuegbar. Das bedeutet im Klartext, dass ein bisschen Handarbeit angesagt ist, zumal es auch unter Debian Linux erst nach einer Modifikation von libnet funktioniert.

Als erstes muss man natuerlich die benoetigten *-dev Pakete installieren und wenn nicht bereits passiert auch die build-essential

aptitude install libpcap-dev build-essential

Das installieren vom libnet-dev Paket aus apt wuerde das compilieren von dhcp_probe nicht zu einem Erfolg bewegen, da die in Debian etch enthaltene Version eine wichtige Funktion nicht mitbringt. Siehe dazu auch den entsprechenden Eintrag in der INSTALL.dhcp_probe. Deswegen lautet der naechste Schritt libnet herunterzuladen, entpacken und entsprechend zu patchen.

wget http://www.packetfactory.net/libnet/dist/libnet.tar.gz
tar -xzvf libnet.tar.gz

Wie in der bereits verlinkten INSTALL.dhcp_probe unter Punkt 2. beschrieben nun die beiden Dateien ./src/libnet_cq.c und ./include/libnet/libnet-functions.h bearbeiten, den entsprechenden Code unten einfuegen. Der Dreisatz aus ./configure, make sowie make install als root fuehrt einen dann zum gewuenschten Ergebnis.
Ab dieser Stelle ist nun auch ein compilieren von dhcp_probe von Erfolg gekroent.

wget http://www.net.princeton.edu/software/dhcp_probe/dhcp_probe-1.2.2.tar.gz

entpacken, compilieren und installieren. Wenn man bis zu diesem Punkt ohne Fehler gekommen ist, ist schon der grossteil der Arbeit geschafft. Es fehlt noch dhcp_probe zu konfigurieren. Eine Beispiel-Konfigurationsdatei liegt dem Quelltext mit bei. Einfach aus dem entpackten Verzeichnis heraus ein

cp extras/dhcp_probe.cf.sample /etc/dhcp_probe.cf

machen und durchlesen. Der wichtigste Eintrag ist der Punkt legal_server, bei dem evtl. intendiert vorhandene Server angegeben werden sollten. Uebrigens ein guter Punkt bei dem man testen kann, ob dhcp_probe auch gut funktioniert.

Wenn all diese Vorraussetzungen erfuellt sind, kommt es endlich zu dem Nagios wrapper Skript fuer dhcp_probe. Die folgende Datei /usr/lib/nagios/plugins/ ablegen:

Nun noch fix in Nagios ein command und definiert:

/etc/nagios2/commands.cfg

define command{
        command_name    check_rogue
        command_line    $USER1$/check_rogue
        }

und schon kann ich den Check auf dem Client einrichten, auf dem das Skript liegt und dhcp_probe installiert ist. Bei uns sieht das ganze dann so aus:

nag_rogue_ok

nag_rogue_detected

Ja, ich weiss, das das Plugin nicht schoen geschrieben ist, aber es tut seinen zweck. Und an dieser Stelle nochmal herzlichen Dank an Matthias, Alex und Sebastian bei der Hilfe das ganze zu entdecken und zu beheben etc. :-)