NetBSD als DSL-Router mit Paketfilter und NAT
Autoren: Karsten Kruse und Ulrich Heilmann.
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.
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.
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.
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.
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.
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.
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.
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 :).
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.
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).
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.
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.
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).
Als Abschluß hier noch ein paar Tipps und Tricks die das Leben mit dem NetBSD Router um einiges angenehmer machen können.
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.
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
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.
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
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.
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.