OpenVPN unter OpenWRT

Im Zeitalter von Ettercap, Aircrack und Co., sollte man sich bewusst sein, dass man Sicherheit nicht kaufen kann. Sicherheit ist ein Prozess, der niemals abgeschlossen sein wird! Notebookbesitzer sind hier besonders betroffen. Wer kennt das nicht, beim Kumpel oder in der Kneipe mal schnell ins WLAN. Egal ob verschlüsselt oder nicht, kann man sich wirklich sicher fühlen? WEP gesicherte Netzwerke lassen sich von versierten Leuten in Minuten knacken, Passwörter im eMail- oder VoIP-Verkehr ausspähen oder Gespräche gar aufzeichnen. Eigentlich sollte es schon lange Standard sein, dass Verbindungen mit TLS/SSL gesichert werden, doch viele Anbieter verzichten aus „Kostengründen“ darauf. Wer wenigstens ein Mindestmaß an Sicherheit in fremden Netzen haben will, sollte seine Kommunikation über VPN’s abwickeln.

VPN

Dabei wird ein verschlüsselter Tunnel durch alle Netze hindurch an den eigenen DSL-Anschluss aufgebaut, der die Verbindungen sicher durchschleust und Dienste und Dateien im eigenen Netz zur Verfügung stellen kann, oder einfach nur Zugriff aufs Internet gewährt. Dieser Artikel soll zeigen, dass es sich dabei nicht um ein Hexenwerk handelt und auch nicht nur von Fachleuten realisierbar ist. DSL-Anschluss, Flatrate, Router und ein wenig Zeit reichen aus, um ein VPN aufzubauen.

Es gibt mitlerweile eine Vielzahl von VPN-Lösungen, die teilweise für den normalen Gebrauch völlig überladen sind. Den besten Kompromiss aus Komfort und Funktionalität hat derzeit OpenVPN zu bieten. Einen groben Vergleich der Varianten stellt Jürgen Schmidt von heise Security in einem Webcast vor. OpenVPN ist kostenlos und sehr einfach zu implementieren. Als Basis für den VPN-Server dient in diesem Howto die Linux-Distribution OpenWRT. Das Erstellen der notwengigen Zertifikate wird unter Gentoo realisiert, kann aber auf nahezu alle Betriebssysteme angewandt werden (inklusive Windows).

Achtung: die Anleitung im weiteren Verlauf gilt nur für die Firmware „White Russian“. Für „Kamikaze“ sind diverse Änderungen notwendig!

Zuerst sollte der Router unter OpenWRT seinen Dienst tun. Eine Anleitung dazu findet man in einem früheren Artikel.

Danach meldet man sich am Router via SSH an und installiert die benötigte Software:

ipkg update
ipkg install openvpn
ipkg install libopenssl
ipkg install liblzo
ipkg install ntpclient

Bevor man mit der Konfiguration von OpenVPN beginnt, muss man die Zeitzone im Router setzen und einen regelmäßigen Abgleich mit einem Zeitserver automatisieren.

echo "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" > /etc/TZ
vi /etc/init.d/S60ntpclient
# datei mit folgendem Inhalt füllen
#!/bin/sh
/usr/sbin/ntpclient -c 1 -s -h pool.ntp.org &
# danach das Script ausführbar machen:
chmod +x /etc/init.d/S60ntpclient

Jetzt wird nach jedem Neustart die Zeit aktualisiert, um diesen Vorgang alle 10 Minuten zu wiederholen, ist ein Eintrag im Cron erforderlich:

vi /etc/crontab
# datei mit folgendem Inhalt füllen
*/10 * * * * /etc/init.d/S60ntpclient

Kurz prüfen, ob der Befehl „date“ auch wirklich das richtige Datum ausspuckt. Gegebenfalls einen Neustart mit „reboot“ machen. Jetzt kann man mit OpenVPN beginnen.
Zuerst legt man das Init-Script an.

vi /etc/init.d/S46openvpn
# datei mit folgendem Inhalt füllen
#!/bin/sh
openvpn --verb 5 --config /etc/openvpn/openvpn.conf \
--dh /etc/openvpn/dh1024.pem --key /etc/openvpn/server.key \
--cert /etc/openvpn/server.crt --ca /etc/openvpn/ca.crt &

Danach muss man das Script ausführbar machen:

chmod +x /etc/init.d/S46openvpn

Um eine Verbindung ins VPN von aussen zuzulassen, ist es notwendig die Firewall aufzubohren.

vi /etc/firewall.user
# datei mit folgendem Inhalt füllen
### OpenVPN
WAN_IP=`ifconfig ppp0 | grep 'inet' | cut -d ":" -f2 | cut -d " " -f1`
iptables -A input_rule -i $WAN -p tcp --dport 25 -j ACCEPT
iptables -t nat -I POSTROUTING -o $WAN -j SNAT --to $WAN_IP
iptables -A forwarding_rule -i tun0 -o $WAN -j ACCEPT
iptables -A forwarding_rule -m state --state ESTABLISHED,RELATED -j ACCEPT

In diesem Beispiel verwende ich Port 25, wenn man einen SMTP Server im gleichen Netz betreibt, sollte man einen anderen Port wählen. Viele öffentliche WLAN’s beschränken jedoch das surfen auf die Ports 25 (SMTP), 80 (HTTP), 443 (HTTPS).

Im nächsten Schritt kann man sich die Zertifikate vornehmen. Das ist eigentlich auch der Knackpunkt der Installation. Meine Erfahrung hat gezeigt, dass das manuelle Erstellen zu Problemen führen kann, desshalb empfehle ich „easy-rsa“. Auf einem Gentoo System zu finden unter „/usr/share/openvpn/easy-rsa“. Die Windows-Installation von OpenVPN speichert die Scripte unter „C:\Programme\OpenVPN\easy-rsa“. Eine Anleitung unter Windows findet man hier. Die Konfiguration unter Gentoo funktioniert wie folgt. Zuerst installiert man OpenVPN und erstellt ein Verzeichnis, in welchem die Dateien abgelegt werden.

emerge net-misc/openvpn -av
cd
mkdir openvpn_wrt
cd openvpn_wrt

Nach dem Setzen der Variablen muss man noch zwei Dateien in den Arbeitsordner kopieren und kann dann mit dem Bauen der Zertifikate beginnen.

source /usr/share/openvpn/easy-rsa/vars
/usr/share/openvpn/easy-rsa/clean-all
cp /usr/share/openvpn/easy-rsa/pkitool .
cp /usr/share/openvpn/easy-rsa/openssl.cnf .

Zuerst wird ein Privat Key (ca.key) erstellt. Dabei muss man ein paar Fragen beantworten. Hier ein Beispiel:

/usr/share/openvpn/easy-rsa/build-ca
# Ausgabe
Generating a 1024 bit RSA private key
.........++++++
................++++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:DE
State or Province Name (full name) [CA]:B-W
Locality Name (eg, city) [SanFrancisco]:Freiburg
Organization Name (eg, company) [Fort-Funston]:Privat
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:Benjamin Knaus
Email Address [me@myhost.mydomain]:benjamin@bknaus.de

Danach erzeugt man den Key des Servers (server.key) wie folgt:

/usr/share/openvpn/easy-rsa/build-key-server server
# Ausgabe
Generating a 1024 bit RSA private key
..........................................................++++++
...................++++++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:DE
State or Province Name (full name) [CA]:B-W
Locality Name (eg, city) [SanFrancisco]:Freiburg
Organization Name (eg, company) [Fort-Funston]:Privat
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [server]:
Email Address [me@myhost.mydomain]:benjamin@bknaus.de
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:passwort
An optional company name []:
Using configuration from /root/openvpn_wrt/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'DE'
stateOrProvinceName   :PRINTABLE:'B-W'
localityName          :PRINTABLE:'Freiburg'
organizationName      :PRINTABLE:'Privat'
commonName            :PRINTABLE:'server'
emailAddress          :IA5STRING:'benjamin@bknaus.de'
Certificate is to be certified until Dec  6 13:05:27 2016 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Und den Key des ersten Client. Dieser Schritt kann je nach Anzahl der Clients wiederholt werden. Dabei nur den letzten Parameter anpassen (hier ist es „benjamin“):

/usr/share/openvpn/easy-rsa/build-key benjamin
# Ausgabe
Generating a 1024 bit RSA private key
.............++++++
.....++++++
writing new private key to 'benjamin.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:DE
State or Province Name (full name) [CA]:B-W
Locality Name (eg, city) [SanFrancisco]:Freiburg
Organization Name (eg, company) [Fort-Funston]:Privat
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [benjamin]:
Email Address [me@myhost.mydomain]:benjamin@bknaus.de
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:passwort
An optional company name []:
Using configuration from /root/openvpn_wrt/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'DE'
stateOrProvinceName   :PRINTABLE:'B-W'
localityName          :PRINTABLE:'Freiburg'
organizationName      :PRINTABLE:'Privat'
commonName            :PRINTABLE:'benjamin'
emailAddress          :IA5STRING:'benjamin@bknaus.de'
Certificate is to be certified until Dec  6 13:07:30 2016 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Zuletzt erzeugt man noch die Datei zum Schlüsselaustausch.

/usr/share/openvpn/easy-rsa/build-dh

Im Unterordner „keys“ findet man jetzt alle notwendigen Dateien. Mann sollte sie sicher aufbewahren, und vor fremden Zugriff schützen. Die Dateien sind wie folgt zu verteilen:
Für den Server (OpenWRT):

  • ca.crt
  • dh1024.pem
  • server.crt
  • server.key

Für den Client:

  • ca.crt
  • benjamin.crt
  • benjamin.key

„benjamin“ ist natürlich durch den Namen des Benutzers zu ersetzen. Um die Dateien auf den VPN-Server zu bekommen, kann man entweder „openssh-sftp-server“ installieren, oder folgenden Befehl verwenden:

scp ./keys/ca.crt root@192.168.1.1:/etc/openvpn/

Das ganze muss man jetzt für alle Dateien wiederholen und dabei jedesmal das Passwort eingeben.
Zuletzt legt man noch die Konfigurationsdatein für Server und Client an. Die des Servers schaut so aus:

vi /etc/openvpn/openvpn.conf
# Inhalt
port 25
proto tcp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 10.0.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway"
push "dhcp-option DNS 192.168.1.1"
max-clients 2
keepalive 10 120
auth SHA1
cipher AES-256-CBC
verb 3

Die Konfigurationsdatei des Client schaut wie folgt aus:

vi /etc/openvpn/benjamin.ovpn
# Inhalt
client
dev tun
proto tcp
remote name.dyndns.org 25
ca ca.crt
cert benjamin.crt
key benjamin.key
auth SHA1
cipher AES-256-CBC
verb 3

Um den Tunnel verwenden zu können, startet man den Router neu und prüft, ob das VPN gestartet wurde

root@OpenWrt:~# ps aux | grep openvpn
486 root       1704 S   openvpn --verb 5 --config /etc/openvpn/openvpn.conf ...

Jetzt muss man den Client starten. Unter Linux wechselt man in den Ordner, in dem man die Konfigurationsdatei und die Zertifikate abgelegt hat und tippt folgenden Befehl ein:

openvpn benjamin.ovpn
# VPN wird aufgebaut und zeigt folgendes an
Sun Dec 10 12:13:12 2006 OpenVPN 2.0.6 i686-pc-linux-gnu [SSL] [LZO] [EPOLL] built on Sep  7...
Sun Dec 10 12:13:12 2006 IMPORTANT: OpenVPN's default port number is now 1194, based on an o...
Sun Dec 10 12:13:12 2006 WARNING: No server certificate verification method has been enabled...
Sun Dec 10 12:13:12 2006 Control Channel MTU parms [ L:1559 D:140 EF:40 EB:0 ET:0 EL:0 ]
...
Sun Dec 10 12:13:14 2006 /sbin/route add -net 192.168.1.0 netmask 255.255.255.0 gw 10.0.0.5
Sun Dec 10 12:13:14 2006 /sbin/route add -net 10.0.0.1 netmask 255.255.255.255 gw 10.0.0.5
Sun Dec 10 12:13:14 2006 Initialization Sequence Completed

Damit ist das VPN aufgebaut … viel Spass damit ;)

Pimp My WRT54G

WRT54GWer einen Router unter Linux betreiben will und kein Vermögen für Hardware und Stromrechnung aufbringen kann, findet mit dem WRT54G von Linksys in Verbindung mit OpenWRT eine geniale Alternative. Den Router bekommt man für zirka 65€ bei Fachhändler um die Ecke oder bei Amazon. Die Originalfirmware wird den meisten Benutzern ausreichen, wer allerdings mehr aus seiner Hardware rauskitzeln will, bekommt hier eine auf Linux basierende Firmware mit vielen Features. Wem z.B. die Sendeleistung seines herkömmlichen WLAN-Routers nicht ausreicht, kann mit OpenWRT die TX-Power auf bis zu 251 mW hochschrauben, in Deutschland zulässig sind allerdings maximal 100 mW! Das Einspielen einer neuen Firmware geschieht auf eigenes Risiko und führt zum Garantieverlust! Man benötigt lediglich tftp, welches z.B mit Knoppix erledigt werden kann. Dazu wechselt man ins gleiche Verzeichnis wie die OpenWRT Firmware und tippt folgende Kommandos ein:

tftp 192.168.1.1
tftp> binary
tftp> rexmt 1
tftp> timeout 60
tftp> trace
Packet tracing on.

Die Folgende Zeile schon mal eintippen (admin = zuletzt verwendetes Passwort), aber noch nicht ENTER drücken … Stromstecker ziehen, wieder rein machen … kurz warten bis alle LED’s vom Switch aus sind und dann ENTER drücken …

tftp> put openwrt-xxx-x.x-xxx.bin admin

Jetzt muss man einige Minuten warten, bis der Router zum ersten mal gebootet hat. Danach kann man sich über Telnet einloggen:

telnet 192.168.1.1
passwd
exit
ssh root@192.168.1.1

Wenn ihr folgendes zu sehen bekommt, hab ihr es geschafft:

BusyBox v1.00 (2005.11.23-21:46+0000) Built-in shell (ash)

Enter 'help' for a list of built-in commands.
  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M

 WHITE RUSSIAN (RC4) -------------------------------
  * 2 oz Vodka   Mix the Vodka and Kahlua together
  * 1 oz Kahlua  over ice, then float the cream or
  * 1/2oz cream  milk on the top.
 ---------------------------------------------------
root@OpenWrt:~#

Als nächstes kann man eine ADSL Verbindung via PPPoE einrichten:

nvram set wan_ifname=ppp0
nvram set wan_proto=pppoe
nvram set ppp_mtu=1492
nvram set ppp_username=benutzer@provider.de
nvram set ppp_passwd=zugangspasswort
nvram commit
reboot

Wer prüfen will, ob eine Internetanbindung besteht kommt hiermit weiter:

ifconfig ppp0
ping google.de (abbrechen mit strg+c)

Um sein WLAN zu konfigurieren sollte man zuerst ein Update der Paketlisten machen und danach die erforderlichen Programme (nas, wl) über das Internet installieren:

ipkg update
ipkg install nas
ipkg install wl

Wenn beide Pakete eingespielt sind, geht es an die Konfiguration. Die derzeit sinnvollste Verschlüsselungsart im Privatbereich ist WPA/AES:

nvram set wl0_mode=ap
nvram set wl0_ssid=irgendwas
nvram set wl0_infra=1
nvram set wl0_closed=0
nvram set wl0_channel=2
nvram set wl0_akm=psk
nvram set wl0_crypto=aes
nvram set wl0_wpa_psk=irgendeinschluessel
### Sendeleistung erhöhen (zulässig in D sind nur 100 !)
nvram set txpwr=251
nvram commit
reboot

Danach sollte man noch einen Nameserver angeben, das folgende Beispiel zeigt zwei von Versatel. Natürlich kann man auch die eines anderen Providers angeben:

echo "nameserver 62.72.64.237" > /etc/resol.conf
echo "nameserver 62.72.64.241" >> /etc/resol.conf

Jetzt gehts an die Firewall … dazu löscht man erstmal das Firewall-Scipt, welches auf den ROM verlinkt und kopiert es an die vorherige Stelle. Jetzt kann man das Script editieren und damit an seine eigenen Bedürfnisse anpassen:

rm /etc/firewall.user
cp /rom/etc/firewall.user /etc/firewall.user
vim /etc/firewall.user

Die Grundkonfiguration ist schon gehärtet und verwirft alle nicht angeforderten Pakete am WAN Port. Wer seinen Router über SSH erreichen will, muss seine Firewall aufbohren. eMule lässt sich über Portforwarding optimieren. Der Inhalt der Datei sollte dann wie folgt ausschauen:

#!/bin/sh
. /etc/functions.sh

WAN=$(nvram get wan_ifname)
LAN=$(nvram get lan_ifname)

iptables -F input_rule
iptables -F output_rule
iptables -F forwarding_rule
iptables -t nat -F prerouting_rule
iptables -t nat -F postrouting_rule

### SSH am WAN Interface
iptables -t nat -A prerouting_rule -i $WAN -p tcp --dport 22 -j ACCEPT
iptables        -A input_rule      -i $WAN -p tcp --dport 22 -j ACCEPT

### Port forwarding
# aMule auf 192.168.1.2
iptables -t nat -A prerouting_rule -i $WAN -p tcp --dport 4662 -j DNAT --to 192.168.1.2
iptables        -A forwarding_rule -i $WAN -p tcp --dport 4662 -d 192.168.1.2 -j ACCEPT
iptables -t nat -A prerouting_rule -i $WAN -p udp --dport 4672 -j DNAT --to 192.168.1.2
iptables        -A forwarding_rule -i $WAN -p udp --dport 4672 -d 192.168.1.2 -j ACCEPT

Nach dem editieren der firewall.user kann man jetzt noch eine kleine Optimierung durchführen. Dazu muss man das init Script der Firewall öffnen und die Zeilen 43 und 44 auskommentieren. Danach sollten die IPTables durch einen Neustart auf den aktuellen Stand gebracht werden:

vim /etc/init.d/S45firewall
/etc/init.d/S45firewall restart

Wer sein Heimnetz über das Internet fernadministrieren will, oder einen eigenen Server betreibt, kommt mit dynamischen DNS weiter. Zuerst gilt es einen Account unter dyndns.org anzulegen. Danach muss man die entsprechende Software auf dem Linksys installieren:

ipkg install ez-ipupdate

Danach sollte man ein init Script anlegen, welches die IP bei DynDns auf dem aktuellsten Stand hällt.

vi /etc/init.d/S70ez-ipupdate

#!/bin/sh
case "$1" in
start)
/usr/sbin/ez-ipupdate -d /tmp/ez-ipupdate.pid -S dyndns -u benutzername:passwort -h benutzername.dyndns.org -i ppp0
;;
stop)
kill -9 `cat /tmp/ez-ipupdate.pid`
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac

Zuletzt setzt man noch die Berechtigungen auf ausführbar:

chmod +x /etc/init.d/S70ez-ipupdate
reboot

That’s it ;)