www.Newbie-Net.de

NetBSD DSL-Router

NetBSD als DSL-Router mit Paketfilter und NAT

Autoren: Karsten Kruse und Ulrich Heilmann.

Inhalt

Vorwort

Im folgenden werde ich (eigentlich wir, der Einfachheit halber aber ich) erklären wie man einen Rechner mit NetBSD [1] als DSL-Router einrichtet. Ziel ist es einem Netzwerk einen problemlosen Zugriff auf das Internet zu ermöglichen. Als Betriebsystem habe ich mich aufgrund meiner guten Erfahrungen für NetBSD in der neuesten Version entschieden. In meinem Fall ist das NetBSD 2.0 für die i386 Architektur. Das ganze sollte aber auch mit einer anderen Architektur funktionieren. Für die Installation und grundlegende Konfiguration von NetBSD verweise ich auf die Anleitung [2] von Hans-Michael Gerhards.

Netzwerkeinrichtung

Beginnen wir damit, unseren Rechner in das lokale Netzwerk einzubinden. Ich werde kurz anreißen wie unser Netzwerk im großen und ganzen funktionieren soll. Danach müssen wir herausfinden welche Netzwerkkarte mit unserem LAN verbunden werden soll um sie dann einzurichten und zu testen.

Der Plan

Unseren Rechner nur mit dem LAN zu verbinden würde reichen, wenn wir nicht auch als Gateway ins Internet fungieren wollten. So aber brauchen wir mindestens zwei physikalische Verbindungen, eine ins LAN und eine in das Internet. Üblicherweise wird die physikalische Verbindung in das Internet über ein Modem, eine ISDN-Karte oder eine weitere Ethernetkarte, an der das DSL-Modem angeschlossen wird, realisiert.

Ich möchte mich auf den Weg mit einer Ethernetkarte konzentrieren. Mein ISP (Internet Service Provider) ist T-Online und bietet mir T-DSL an. Im Kern ist das ein Punkt-zu-Punkt Protokoll (PPP) das über Ethernet realisiert wird. Mein ISP nennt das T-DSL (was T-Onlines Marketingname für ADSL Technik ist), der bessere Name ist aber PPPoE (Point to Point over Ethernet).

Im weiteren Verlauf werden wir PPPoE einrichten, doch vorher werden wir uns um die Ethernetverbindung in unser eigenes LAN kümmern.

Die Hardware

Da wir später eine DSL-Verbindung über ein externes DSL-Modem herstellen wollen, ist jetzt schon klar das wir zwei Ethernetkarten in unserem System benötigen. Eine wird mit dem DSL-Modem verbunden, die andere mit einem Hub oder Switch, damit wir mit unserem LAN kommunizieren können. (Sollte man eine 10MBit und eine 100MBit Netzwerkkarte haben, dann nimmt man natürlich die 10MBit Karte für die Verbindung zum DSL-Modem).

Soweit, so gut.

Als erstes verschafft man sich einen Überblick welche Netzwerkkarten eingebaut sind. Dazu sehen wir einfach in der Ausgabe von dmesg nach, welche Netzwerkkarten beim Booten erkannt wurden und wie das entsprechende Device heißt. Am besten kombiniert man die Ausgabe von dmesg mit grep, dadurch bekommen wir ganz bequem genau die Informationen die wir benötigen.

 user@host:~> dmesg | grep Ethernet
 ex0 at pci0 dev 9 function 0: 3Com 3c905C-TX 10/100 Ethernet with mngmt (rev. 0x74)
 ex1 at pci0 dev 11 function 0: 3Com 3c905-TX 10/100 Ethernet (rev. 0x0)

Wir sehen das zwei Netzwerkkarten installiert sind ex0 und ex1, das beide Karten von der Firma 3Com sind und das sie 10MBit und 100MBit unterstützen.

Hier noch ein weiteres Beispiel:

 user@host:~> dmesg | grep Ethernet
 Device Name: 8139 10/100 Ethernet (0x8139)
 Realtek Semiconductor 8139 10/100 Ethernet (ethernet network, revision 0x10)\
 at ? dev 10 function 0 (tag 0x80005000, intrtag 0x80005000, intrswiz 0,\
 intrpin 0x1, i/o on, mem on, no quirks): RealTek 8139 10/100BaseTX

 rtk0: Ethernet address 00:e0:7d:81:f9:b1

 Device Name: 8139 10/100 Ethernet (0x8139)
 Realtek Semiconductor 8139 10/100 Ethernet (ethernet network, revision 0x10)\
 at ? dev 11 function 0 (tag 0x80005800, intrtag 0x80005800, intrswiz 0,\
 intrpin 0x1, i/o on, mem on, no quirks): RealTek 8139 10/100BaseTX

 rtk1: Ethernet address 00:40:ca:2d:f1:c6

Hier sehen wir zwei Realtek Karten, rtk0 und rtk1 die beide 10/100Mbit Ethernet unterstützen.

Okay, zurück zu unseren 3Com Karten. Wir wählen einfach die Karte ex0 für das LAN und nehmen ex1 für die Verbindung zum Modem. Als nächstes weisen wir ex0 eine Adresse aus dem privaten Adressraum zu und aktivieren die Karte, falls das während der Installation noch nicht erledigt wurde.

Adressvergabe

Um die Karte einzurichten erstellen wir eine Datei mit dem Namen /etc/ifconfig.DEVICE. DEVICE wurde in meinem Fall mit ex0 ersetzt, also /etc/ifconfig.ex0. In diese Datei werden die Einstellungen der Karte verewigt, in meinem Fall sieht das so aus:

 192.168.1.10 netmask 0xffffff00 media auto

192.168.1.10 ist die IP-Adresse aus dem privaten Adressraum. Dann kommt die Netzwerkmaske in hexadezimaler Schreibweise, sie entspricht 255.255.255.0 und sollte für ein normales privates Netzwerk gut passen. Schließlich geben wir den Medientyp (10base2, 10baseT usw.) an, in unserem Fall wird er automatisch gewählt. Wenn Netzwerkarten verwendet werden die nur 10MBit schnell sind, sollte man media 10baseT verwenden, da es sonst zu Problemen kommen kann und die Karte nicht automatisch beim booten konfiguriert wird.

Das ist alles. Wenn wir den Rechner neu starten sollte automatisch ex0 mit unseren Einstellungen aktiviert werden. Testen können wir das mit dem Kommando ifconfig ex0. Die Ausgabe sieht in etwa so aus:

 ex0: flags=8863 >UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST< mtu 1500
 capabilities=7
 enabled=0
 address: 00:04:76:1b:65:ee
 media: Ethernet autoselect (100baseTX full-duplex)
 status: active
 inet 192.168.1.100 netmask 0xffffff00 broadcast 192.168.1.255
 inet6 fe80::204:76ff:fe1b:65ee%ex0 prefixlen 64 scopeid 0x1

Es sollte nun möglich sein andere Rechner im LAN mit deren IP anzupingen. Wenn dem nicht so ist, müssen wir uns nochmal die Konfiguration genau ansehen.

SecureShell für die Remoteadministration

Um die Administration über das Netzwerk zu erlauben wird der SecureShell-Demon gestartet. Bevor wir ihn benutzen können, müssen wir ihn in der globalen Konfigurationsdatei /etc/rc.conf eintragen, das erledigt folgender Befehl:

 echo "sshd=YES" >> /etc/rc.conf

Beim nächsten Start werden automatisch Hostschlüssel erstellt und der Dienst gestartet.

DSL schmerzlos einrichten

Wir haben unser LAN gemeistert, kommen wir zu DSL. Nachdem wir den Kernel auf seine PPPoE-Fähigkeiten hin untersucht haben richten wir die PPPoE-Verbindung ein. Ich werde das vorgehen für eine Flatrate beschreiben, das heißt der Rechner wird direkt nachdem die Verbindung ausgegangen ist eine neue herstellen.

Kernel prüfen

Als erstes testen wir ob PPPoE überhaupt von unserem Kernel unterstützt wird (das sollte eigentlich bei allen aktuellen Kernel der Fall sein).

 user@host~> ifconfig -C
 bridge vlan gif gre tun pppoe

Sieht wohl so aus :).

DSL einrichten

Jetzt legen wir (genau wie für die Netzwerkkarte) in /etc eine Konfigurationsdatei an. Da wir eine PPPoE-Verbindung aufbauen wollen heißt diese ifconfig.pppoe0 :

 # Um das Device zu erstellen
 create
 # Um das Interface das von PPPoE benutzt wird zu aktivieren
 ! /sbin/ifconfig ex1 up
 # Wir benutzen $int für ex1
 ! /sbin/pppoectl -e ex1 $int
 # Authentifizierung konfigurieren
 ! /sbin/pppoectl $int myauthproto=pap\
 'myauthname=00098598892143657257940060001@t-online.de'\
 'myauthsecret=mypassword' hisauthproto=none

 # Das PPPoE-Interface selbst konfigurieren. Da wir nicht sicher sind welche
 # Adresse wir bekommen, lassen wir unser gegenüber die Adressen aussuchen...
 0.0.0.0 0.0.0.1 up
 # eof

Diese Konfiguration sollte eigentlich selbsterklärend sein. Man muß nur myauthname auf die eigene t-online Kennung ändern und bei myauthsecret das eigene Passwort eingeben. Da wir hier unser Passwort angegeben haben, sollte besser keiner außer Root ifconfig.pppoe0 lesen können. Mit

 root@host~> chmod 600 /etc/ifconfig.pppoe0

setzen wir die Rechte von ifconfig.pppoe0 auf nur lesen und schreiben für den Besitzer.

Als nächstes setzten wir in /etc/rc.conf die Variable ifwatchd=YES. Der ifwatchd sorgt dafür das die Verbindung automatisch beim Booten aufgebaut wird. Außerdem stellt er bei jeder 24 stündigen Zwangstrennung die Verbindung wieder neu her.

Status Abfrage

Okay, jetzt sind wir drin oder doch nicht? Mit pppoectl -d pppoe0 können wir uns den Status der Verbindung anschauen. Die erste Zeile sollte dann so aussehen pppoe0: state = session. Alternativ können wir auch die Ausgabe von ifconfig anschauen. Wenn wir eine IP haben, steht die Verbindung.

 user@host~> ifconfig pppoe0
 pppoe0: flags=8851 <UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST>
         inet 217.225.199.153 -> 217.15.9.127 netmask 0xff000000
         inet6 fe80::204:76ff:fe1b:65ee%pppoe0 -> prefixlen 64 scopeid 0x8

Bei inet sehen wir unsere IP 217.225.199.153 und die unserer Gegenstelle 217.15.9.127 (das ist der Netzknoten in der nächsten Vermittlungsstelle).

Der Weg ins Internet

Nun kümmern wir uns darum, das die Defaultroute automatisch eingestellt wird, da unsere Daten sonst nicht den Weg ins Internet finden. Hierfür erstellen wir in /etc/ppp/ip-up folgenden Eintrag:

 #!/bin/sh
 /sbin/route add default $5

Wenn die Verbindung abgebaut wird, soll die Defaultroute auch wieder sauber gelöscht werden.

Eintrag in /etc/ppp/ip-down:

 #!/bin/sh
 /sbin/route delete default $5

Falls das Verzeichnis /etc/ppp nicht vorhanden sein sollte, kann man es einfach mit mkdir /etc/ppp anlegen.

Nun müssen wir die Scripte ip-up und ip-down noch ausführbar machen. chmod +x /etc/ppp/ip-up und chmod +x /etc/ppp/ip-down erledigt das für uns.

DNS / Die Namensauflösung

Mit dem DNS (Domain Name System) ist es schon lustig. "Hä, DNS?", wirst du dich vielleicht fragen und das ist genau das was ich meine. Alle nutzen es, aber die wenigsten kennen es.

Wenn wir eine Webseite aufrufen wollen z.B. www.Newbie-Net.net, dann wird unser Browser als erstes versuchen, über den nächsten DNS-Server die IP-Adresse des Servers herauszufinden. (Dies muß er tun, da die IP-Adresse sozusagen unsere Anschrift im Internet ist und eine www-Adresse nur so etwas wie die Beschreibung der Anschrift...). Als nächstes verbindet sich der Browser zu dem Webserver mit der vorher ermittelten IP und holt uns die Seite vom Newbie-Net.

Was hat das mit uns zu tun? Ganz einfach, wenn wir unserem Router nicht mitteilen welche DNS-Server er nutzen soll, kann er uns auch nicht auf die richtigen Webseiten führen. Um das zu erreichen, tragen wir einfach zwei der unten stehenden IP-Adressen in die Datei /etc/resolv.conf ein:

 nameserver 217.146.142.73
 nameserver 62.225.248.240
 nameserver 145.253.2.11
 nameserver 62.153.158.62
 nameserver 194.25.134.203
 nameserver 195.145.119.62

Bei allen anderen Rechnern die ins Internet wollen, sind ebenfalls zwei IPs als DNS-Server einzutragen.

NAT und Firewall

Da wir von unserem Internetprovider nur eine IP zugewiesen bekommen, aber mit mehr als einem Computer im Internet surfen wollen, müssen wir ein bischen tricksen. Der Trick bei der Sache heißt NAT und steht für "Network Address Translation". Wie der Name schon sagt, werden hierbei die Netzwerkadressen (IP-Adressen) übersetzt. In unserem Fall so, das mehrere interne/private IP-Adressen über eine externe/öffentliche IP-Adresse Kontakt mit dem Internet aufnehmen können (Das nennt man N:1 NAT, die Linuxer sagen Masquerading). Nebenbei erstellen wir uns noch eine einfache Firwall mit ipf.

Um das zu erreichen müssen wir in /etc/rc.conf folgendes eintragen um ipnat und ipf beim booten zu aktivieren:

 ipnat=YES
 ipfilter=YES

Dann sollten wir in /etc eine Konfigurationsdatei für das IP-NAT anlegen. Diese heißt ipnat.conf und sieht für unsere Bedürfnisse so aus:

 # NAT
 map pppoe0 192.168.1.0/24 -> 0/32 proxy port ftp ftp/tcp mssclamp 1412
 map pppoe0 192.168.1.0/24 -> 0/32 portmap tcp/udp auto mssclamp 1412
 map pppoe0 192.168.1.0/24 -> 0/32 mssclamp 1412

Die ipf-Firewall bezieht ihre Konfiguration aus /etc/ipf.conf die etwa so aussehen sollte:

 # +-----------+   +-----------+   +---------------+
 # | DSL-Modem |---| ipf+ipnat |---| Internes Netz |
 # +-----------+   +-----------+   +---------------+

 # Kaputte oder gefärliche Pakete werden geblockt
 block in log quick from any to any with ipopts
 block in log quick proto tcp from any to any with short
 block in log quick from any to any with frag
 block in log quick from any to any with opt lsrr
 block in log quick from any to any with opt ssrr

 # Loopback wird erlaubt
 pass out quick on lo0 from any to any
 pass in  quick on lo0 from any to any

 # Lokales Netzwerk ist erlaubt
 pass out quick on rtk0 from any to any
 pass in  quick on rtk0 from any to any

 # Wir halten den Status aller Verbindungen von innen nach aussen
 pass out quick on pppoe0 proto tcp from any to any flags S keep state keep frags
 pass out quick on pppoe0 proto udp from any to any keep state keep frags
 pass out quick on pppoe0 proto icmp from any to any keep state keep frags

 # Gefälschte oder unwahrscheinliche Pakete kommen nicht rein
 block in log body quick on pppoe0 from 192.168.0.0/16 to any
 block in log body quick on pppoe0 from 172.16.0.0/12 to any
 block in log body quick on pppoe0 from 10.0.0.0/8 to any
 block in log body quick on pppoe0 from 127.0.0.0/8 to any
 block in log body quick on pppoe0 from 0.0.0.0/8 to any
 block in log body quick on pppoe0 from 169.254.0.0/16 to any
 block in log body quick on pppoe0 from 192.0.2.0/24 to any
 block in log body quick on pppoe0 from 204.152.64.0/23 to any
 block in log body quick on pppoe0 from 224.0.0.0/3 to any

 block out log body quick on pppoe0 from any to 192.168.0.0/16
 block out log body quick on pppoe0 from any to 172.16.0.0/12
 block out log body quick on pppoe0 from any to 10.0.0.0/8
 block out log body quick on pppoe0 from any to 127.0.0.0/8
 block out log body quick on pppoe0 from any to 0.0.0.0/8
 block out log body quick on pppoe0 from any to 169.254.0.0/16
 block out log body quick on pppoe0 from any to 192.0.2.0/24
 block out log body quick on pppoe0 from any to 204.152.64.0/23
 block out log body quick on pppoe0 from any to 224.0.0.0/3

 # Erlaube Ping, ident und ssh von aussen
 #
 # ping
 pass in log quick on pppoe0 proto icmp from any to any icmp-type echo keep state
 # ssh
 pass in log quick on pppoe0 proto tcp from any to any port = \
          22 flags S keep state keep frags
 # auth/ident
 pass in log quick on pppoe0 proto tcp from any to any port = \
          113 flags S keep state keep frags

 # Alle anderen geblockten Pakete werden geloggt (ipflog)
 block in log quick from any to any
 block out log quick from any to any

Wichtig ist das rtk0 und rtk1 durch die Namen der eigenen Netzwerkinterfaces ersetzt werden.

Zum Schluß fügen wir noch folgende Einträge in die Datei /etc/sysctl.conf ein:

 # Beachte die MTU des Interfaces wenn MSS berechnet wird
 net.inet.tcp.mss_ifmtu=1

 # Damit können wir einige Hosts mit schlechtem Setup erreichen
 net.inet.tcp.rfc1323=0

 # Erlaube Paketweiterleitung
 net.inet.ip.forwarding=1

Danach rebooten wir den Rechner (neu starten wie bei Windows? Muß man nicht, aber so sieht man am einfachsten ob man bisher irgendwelche Fehler gemacht hat).

Tipps & Tricks

Als Abschluß hier noch ein paar Tipps und Tricks die das Leben mit dem NetBSD Router um einiges angenehmer machen können.

Dateisystem tunen

Man kann in der /etc/fstab einen Eintrag für softdep vornehmen. Das stellt die Integrität des Datenträgers sicher und macht ihn dadurch sozusagen absturzfester. Zusätzlich bekommt man "ordered writes". Das alles kostet zwar ein paar KB RAM pro Dateisystem aber bringt Geschwindigkeitsvorteile.

Die Einträge in der Datei /etc/fstab sehen etwa so aus:

 /dev/wd0a  /           ffs     rw           1 1
 /dev/wd0b  none        swap    sw           0 0
 /dev/wd0e  /usr        ffs     rw           1 2

Um softdep zu erlauben ändern wir die Mountoptionen für alle Dateisysteme des Typs ffs:

 /dev/wd0a  /           ffs     rw,softdep   1 1
 /dev/wd0b  none        swap    sw           0 0
 /dev/wd0e  /usr        ffs     rw,softdep   1 2

Fertig. Nach einem Reboot werden die Dateisysteme mit der neuen Option gemountet. Das Kommando mount sollte das auch anzeigen.

Systemzeit

Wir sollten uns auch noch darum kümmern, daß die Uhrzeit und das Datum ersteinmal stimmen da es ziemlich lästig werden kann, wenn dem nicht so ist. (Außerdem wundert man sich dann nicht mehr, weshalb man Logfiles aus dem Jahr 1999 hat ;).

 user@host~> date
 user@host~> ntpdate Zeitserver

Das Kommando date zeigt uns erst einmal die aktuellen Datumseinstellungen, welche wir dann mit ntpdate Zeitserver auf den neuesten Stand bringen. Wer sich erstmal anschauen will welche Zeit er da geliefert bekommt, kann mit ntpdate -q zeitserver einfach eine Anfrage an einen Zeitserver stellen. In diesem Query können wir dann in der zweiten Zeile gleich als erstes das aktuelle Datum und die Uhrzeit sehen:

 server 130.133.1.10, stratum 1, offset 0.484536, delay 0.10205
 26 Feb 22:05:10 ntpdate[237]: adjust time server 130.133.1.10 offset 0.484536 sec

Als Zeitserver kann man in Deutschland einen der folgenden angeben:

 ptbtime1.ptb.de
 ptbtime2.ptb.de
 time.fu-berlin.de

Wohnt man in Österreich kann man einen dieser Server hier nutzen:

 time.uni-ak.ac.at (193.170.136.254)
 timeback.uni-ak.ac.at

T-DSL Zwangstrennung

Da diese Anleitung für einen Router mit T-DSL ist, leiden wir natürlich auch unter dessen Zwängen. Um es genau zu sagen, die Zwangstrennung alle 24 Stunden. Wie es Murphies Law so will, passiert dies meistens während eines wichtigen Downloads. Um dem zuvorzukommen, richten wir uns einen Cronjob ein, um dies irgendwann morgends früh automatisch zu erledigen. Dazu habe ich mir ein kleines Script geschrieben, das die Verbindung sauber trennt und nach einer kurzen Pause wieder aufbaut:

 #!/bin/sh
 #
 # online bleiben per cron-job
 #
 ifconfig pppoe0 down
 sleep 5
 ifconfig pppoe0 up

Dieses Script habe ich bei mir in /root/bin als connect.sh abgelegt (ausführbar machen wie bei ip-up nicht vergessen!). Jetzt müssen wir nur noch den Eintrag für Cron erstellen. Als root öffnet man mit crontab -e die crontab und fügt den folgenden Eintrag hinzu:

 # daily reconnect
 30      4       *       *       *       /root/bin/connect.sh

Dadurch wird an jedem Tag in der Woche um 04:30 Uhr das Script connect.sh in /root/bin ausgeführt. Die Verbindung wird getrennt und nach 5 Sekunden wieder aufgebaut.

Logging für PPPoE

Falls man daran interessiert ist, wann man online bzw. offline gegangen ist und auch noch die letzte IP wissen will, kann man noch folgende Einträge in ip-up bzw. ip-down vornehmen:

In ip-up:

 echo "online  `date` $4" >> /tmp/internet.log

In ip-down:

 echo "offline `date`" >> /tmp/internet.log

Privater IP-Adressraum

Für private Netzwerke (alle Netze die nicht öffentlich zugänglich sind) sollte man (nach RFC 1918 [3]) eine Adresse aus den folgenden drei Bereichen wählen. Diese sind für die private Nutzung reserviert und werden im Internet nicht geroutet.

 1. Netzwerk: 10.0.0.0    - 10.255.255.255  / 255.0.0.0
 2. Netzwerk: 172.16.0.0  - 172.31.0.0      / 255.255.0.0
 3. Netzwerk: 192.168.0.0 - 192.168.255.255 / 255.255.255.0

Im ersten Netzwerk können 16 Mio. IP-Adressen vergeben werden, im zweiten Netzwerk 65000 und in dem dritten kann man noch 256 IPs vergeben, was normalerweise mehr als genug ist. Die Einteilung der IP-Bereiche sind identisch mit denen der Netzwerkklassen (Class A, B, C). Die Einteilung in Klassen ist jedoch veraltet und wurde durch CIDR (RFC 1817 [4]) ersetzt.

Nachwort

Wer Hilfe benötigt kann sich gern auf der Mailingliste oder im IRC Channel melden. Kommentare und Anregungen auch gern über die Mailingliste oder im IRC.

Quellen