Aus aktuellem Anlass musste ich eine Firewall von der Windowsseite her umgehen, um einem FreeBSD gegenueber einen Port oeffnen zu koennen. Dazu schien die einfachste Loesung (ausser den Admin zu fragen), ein VPN aufzubauen. Und da OpenVPN ohne Admin-Rechte auf Client-Seite schwierig ist, bleiben nur die Windows-Bordmittel zum Aufbau eines VPNs. Hierzu gibt es als Server unter FreeBSD zwei Alternativprogramme: mpd oder poptop. Ich habe mich fuer das Letztere entschieden, da ich damit schon einmal erfolgreich eine PPTP-Verbindung aufzubauen in der Lage war. Dieses Mal habe ich mir die Zeit genommen, auch zu beschreiben wie ich das gemacht habe -- schon, damit ich es nicht wieder vergesse :)

Wozu das Ganze und was ueberhaupt

Die Ausgangssituation war folgende: Ich hatte ein Programm und das sollte auf einem anderen Rechner, einer Windowsmaschine hinter einer halbwegs restriktiven Firewall laufen. Leider basierte mein Programm darauf, dass es einen TCP-Socket aufmacht und ich mich auf diesen Verbinden kann. Natuerlich koennte ich den Admin der naechsten Firewall fragen, ob er fuer mich das Tuerchen aufmachen wuerde. Aber damit rechnete ich dann doch eher nicht. Also sah ich meine Chance darin, dass das Windows eine ausgehende Verbindung initiieren muesse - und zwar einen PPTP-Tunnel zu meiner Maschine. Interessant wird das ganze noch mehr, wenn ich bedenke, dass dese Maschine ein FreeBSD auf meinem Notebook ist. Und im WLAN der Uni Rostock steht. Durchaus interessant, das Ganze.

Das Angebot an Serversoftware

Das Angebot an serverseitigen Loesungen fuer einen PPTP-Einwahlserver umfasst (neben Microsoft-eigenen und Cisco-Loesungen) auch die beiden offenen Projekte mpd und poptop. Ich habe mich (ohne besondere Gruende) mit dem Letztgenannten eingelassen. Die Installation aus /usr/ports/net/poptop/ verlief erwartungsgemaess unspektakulaer. Dann kam die Einrichtung. Konkret betrifft diese die Dateien /usr/local/etc/pptpd.conf und /etc/ppp/ppp.conf nebst ein paar Hilfsdateien. Aber mehr dazu weiter unten, zunaechst noch ein paar generelle Erlaeuterungen.

Was genau ist so ein VPN?

VPN, das steht fuer "Virtual Private Network" und kann fuer die unterschiedlichsten Zwecke eingesetzt werden. Eigentlich immer dann, wenn ein lokal aussehendes Netzwerk ueber eine weite Strecke (z.B. durch das Internet) realisiert werden soll. Bekannte Einsatzzwecke sind solche wie das Verbinden mit einem Firmennetzwerk oder aber der Aufbau eines VPNs, damit man auch ausserhalb eines LANs und ohne dabei das Internet an sich zu benutzen geknackte Spiele ueber Netzwerk mit anderen spielen kann.

Einrichtung I: Grundvoraussetzungen

Bevor es losgehen kann, hier meine Grundvoraussetzungen:

Nachdem nun auch meine Motivation klar ist, kann es ja technischer werden.

Einrichtung II: Die Konfigruationsdateien

Hier soll es nun "in medias res" gehen und die Konfiguration angegangen werden. Diese Besteht zunaechst aus vier Dateien.

/usr/local/etc/pptpd.conf

[ad001@glas ~] cat /usr/local/etc/pptpd.conf
debug
nobsdcomp
proxyarp
localip 172.16.0.1
remoteip 172.16.0.100-110
pidfile /var/run/pptpd.pid
+chapms-v2
mppe-40
mppe-128
mppe-128
mppe-stateless

[ad001@glas ~]

Was soll nun dies bedeuten? Zunaechst lege ich fest, dass ich mehr Ausgaben haben will - mit debug aktiviere ich das senden von zusaetzlichen Informationen an syslogd. Mit dem Eintrag localip lege ich fest, welche IP-Adresse der VPN-Server "von innen" also in der VPN-Verbindung haben wird; remoteip legt die ausgegebenen IP-Adressen fest. Diese sind hier als der Berich von 172.16.0.100 bis 172.16.0.110 gewaehlt. Die uebrigen Eintraege erlaube ich mir zu ueberspringen, PoPToP kann wesentlich mehr als ich ihm abverlange.. das spiegelt sich hier wieder. Schlimmer noch wird das bei ppp ;)

/etc/ppp/ppp.conf

[ad001@glas ~] sudo cat /etc/ppp/ppp.conf
loop:
    set timeout 0
    set log phase chat connect lcp ipcp command
    set device localhost:pptp
    set dial
    set login
    set ifaddr 172.16.0.1 172.16.0.100-172.16.0.110 255.255.0.0
    add default HISADDR
    set server /tmp/loop "" 0177

loop-in:
    set timeout 0
    set log phase lcp ipcp command
    allow mode direct

pptp:
    load loop
    disable pap
    enable passwdauth
    disable ipv6cp
    enable proxy
    accept dns
    enable MSChapV2
    enable mppe
    disable deflate pred1
    deny deflate pred1
    set dns 24.26.163.24
    set device !/etc/ppp/secure

[ad001@glas ~]

Wenn die Einwahl stattgefunden hat, dann muss die Verbindung abgewickelt werden -- dazu wird ppp genutzt. Und auch ppp muss dafuer konfiguriert werden. Und hier ist der erste und groesste Teil dieser Konfiguration. Um bei der Knappheit wie oben zu bleiben, werde ich auch hier nur ein paar wichtige Details erlaeutern. Das eine ist die Definition der lokalen und der vergebenen IP-Adressen im Abschnitt "loop" -- diese muss natuerlich mit der Angabe in der pptpd.conf uebereinstimmen. Ferner ist noch zu bemerken, dass in der Sektion "pptp" festgelegt wird, dass eine Passwort (und nicht etwa zertifikatsbasierte o.ae.) Authentifikation vorgenommen werden soll. Schliesslich wird noch eine DNS-Server fuer diese Verbdinung definiert, der auch den Clients weitergegeben werden wird.

/etc/ppp/ppp.secret

#nutzer	\t	passwort
donald	entenhausen

In dieser Datei sind schlicht und ergreifend die Nutzer-Passwort-Zuordnungen im Klartext gespeichert. Das ist nicht wirklich toll, das mindeste, was man tun sollte um ein kleines bisschen Sicherheit zu gewaehrleisten, ist, diese Datei nur fuer root lesbar zu machen.

/etc/ppp/secure

[ad001@glas ~] cat /etc/ppp/secure
#!/bin/sh
exec /usr/sbin/ppp -direct loop-in

[ad001@glas ~]

Diese Datei wird von der letzten Zeile der ppp.conf als Device spezifiziert und macht nichts weiter, als eine umleitung in die Sektion "loop-in" zu bieten.

Einrichtung III: Rest

Die ganz grundlegenden Sachen sind geschafft, das ganze sollte nun schon funktionieren. Aber wer moechte, dass der PPTPd nicht nur einzelne Male mittels /usr/local/etc/rc.d/pptpd onestart zum Laufen zu bewegen ist, der kann sich natuerlich noch ein pptpd_enable="YES" in seine /etc/rc.conf einfuegen.

Weiterhin bestehendes Problem und seine Loesung

Der Test mit einem Client lief problemlos, dann kamen zwei. Aber funktionstuechtig war weiterhin nur einer -- naemlich derjenige, der seinen Tunnel zuerst angelegt hatte. Warum? Man schaue sich ein ifconfig an, welches zum Zeitpunkt einer einzelnen hergestellten Verbindung wie folgt ausschaut:

[ad001@glas ~] ifconfig tun0
tun0: flags=8051 metric 0 mtu 1498
        inet 172.16.0.1 --> 172.16.0.102 netmask 0xffff0000
        Opened by PID 2518
Und da ist auch nur dieser eine Tunnel. Alles ist gut, es gibt keinerlei Probleme. Wenn man aber nun noch einen zweiten Tunnel aufbaut, sieht es wie folgt aus:
[ad001@glas /usr/home/ad001]$ ifconfig
[...]
tun0: flags=8051 metric 0 mtu 1498
        inet 172.16.0.1 --> 172.16.0.102 netmask 0xffff0000
        Opened by PID 2518
tun1: flags=8051 metric 0 mtu 1398
        inet 172.16.0.1 --> 172.16.0.104 netmask 0xffff0000
        Opened by PID 2615

Was ist hier das Problem? Noch gar nichts. Sieht alles noch funktionstuechtig aus. Aber ein Ping von der 172.16.0.104 wird trotzdem scheitern. Warum? Schauen wir einmal in die Routingtabelle:
[ad001@glas /usr/home/ad001]$ netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
172.16.0.152       172.16.0.4         UGH         0        0   tun0
172.16.0.154       172.16.0.4         UGH         0        0   tun0
[...]

Da haben wir das Problem vor uns: Die "rueckroute" fuer die pings stimmt nicht -- die Antwort fuer das Ping vom zweiten eingewaehlten Rechenr wird durch den falschen Tunnel geschickt. Aber, Problem erkannt, Problem gebannt, dem kann man Abhilfe schaffen, indem wir route das interface mit angeben:
[ad001@glas /usr/home/ad001]$ sudo route delete 172.16.0.104
delete host 172.16.0.104
[ad001@glas /usr/home/ad001]$ sudo route add -host 172.16.0.104 -interface tun1
add host 172.16.0.104: gateway tun1

Und nun fliessen die Pings in und von allen Richtungen :)

Stichworte:


Impressum