# VPN (Wireguard / OpenVPN / IPSec)

# OpenVPN nach Hause

##### Serverseite

hier bei mir dient die Fritz!Box 7050 als OpenVPN Server(via Firmaware-Mod von [http://www.freetz.org](http://www.freetz.org "http://www.freetz.org")). Die Konfiguration sieht so aus:

<div id="bkmrk-%23-dev-tun0-dev-node-">```
#
dev tun0
dev-node /dev/misc/net/tun
ifconfig 192.168.200.2 192.168.200.1
tun-mtu 1500
float
mssfix

#Pfad zum Key File
secret /var/tmp/secret.key

#Protokoll auf TCP und Port 1199
proto tcp-server
port 1199

#Protokollierung auf 4
verb 4

#daemon

#Routen setzen, bei route Subnetz des Clients eintragen
route 192.168.150.0 255.255.255.0

#Verbindung erhalten
ping 15
ping-restart 120
```

</div>##### Clientseite

als Client dient mein PC im Büro, das hat den Vorteil, das man in der Bürofirewall kein Loch aufreissen muss.

<div id="bkmrk-ifconfig-192.168.200"><div>```
ifconfig 192.168.200.1 192.168.200.2
dev tun
#dev-node /dev/misc/net/tun
tun-mtu 1500
mssfix
persist-tun
persist-key

#Remote Adresse des Servers angeben
#muss entsprechend geaendert werden
remote remoteserver.net

#Pfad zum Key File
secret /etc/openvpn/secret.key

#Protokoll auf TCP und Port 1199
proto tcp-client
port 1199

#Da die Verbindung alle 24 Stunden getrennt wird
#soll regelmÃäßig kontrolliert werden ob die Verbindung noch steht
ping 15
ping-restart 120

#Der DynDNS-Name soll alle 60 Sekunden neu aufgelöst werden
#da OpenVPN sonst ständig versucht die alte IP
#zu verbinden
resolv-retry 60

#Protokollierungseinstellung
#4 ist optimaler Modus
verb 4

#Daemon sollte erst eingeschaltet werden wenn die
#Konfiguration passt
daemon

#Routen setzen, bei route Subnetz der Server-Box eintragen
route 192.168.10.0 255.255.255.0
push "route 192.168.150.0 255.255.255.0"
```

</div></div>für die Konfiguration der Fritz!Box bin ich nach dieser Anleitung vorgegangen: [http://www.tecchannel.de/server/linux/435560/](http://www.tecchannel.de/server/linux/435560/ "http://www.tecchannel.de/server/linux/435560/")

Wenn alles klappt ist das Netz zuhause mit dem internen Netz des Clients (und umgekehrt) verbunden. Ist hinter dem Client kein Netz vorhanden sollte man vorher z.B. eine zusätzliche interne IP vergeben (z.B. 192.168.150.1).

# IPSec Roadwarrior-VPN via racoon

Dieses Dokument beschreibt die Konfiguration und den Betrieb eines VPN mit Preshared-Keys und Racoon unter Fedora Core 4.

<div id="bkmrk-falls-nicht-vorhande"><div>- <div>Falls nicht vorhanden, das Verzeichnis „/etc/racoon“ anlegen, hier werden alle Configfiles abgelegt</div>

</div></div>/etc/racoon/setkey.conf

<div id="bkmrk-%23%21%2Fsbin%2Fsetkey--f-%23-"><div>```
#!/sbin/setkey -f

# Flush the SAD and SPD
flush;
spdflush;

############################################################
# Roadwarrior <-> Gateway

# 123.123.123.123 = externe IP des Gateways
# 192.168.1.0/24  = internes Netz auf Gateway-Seite

# HOST to HOST
spdadd 123.123.123.123 0.0.0.0 any -P out ipsec
   esp/tunnel/123.123.123.123-0.0.0.0/require;
spdadd 0.0.0.0 123.123.123.123 any -P in ipsec
   esp/tunnel/0.0.0.0-123.123.123.123/require;

# HOST to LAN
spdadd 192.168.1.0/24 0.0.0.0 any -P out ipsec
   esp/tunnel/123.123.123.123-0.0.0.0/require;
spdadd 0.0.0.0 192.168.1.0/24 any -P in ipsec
   esp/tunnel/0.0.0.0-123.123.123.123/require;
############################################################
```

- <div>mit „chmod 0700 /etc/racoon/setkey.conf“ lesen/schreiben/ausführen für root setzen.</div>

</div></div>/etc/racoon/racoon.conf

<div id="bkmrk-path-include-%22%2Fetc%2Fr"><div>```
path include "/etc/racoon";
path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";

# Preshared Keys
remote anonymous {
        exchange_mode aggressive, main, base;
        #doi ipsec_doi;
        nat_traversal on;
        generate_policy on;
        passive on;
        #my_identifier address 212.34.164.18;
        peers_identifier user_fqdn;
        proposal {
                encryption_algorithm 3des;
                hash_algorithm md5;
                authentication_method pre_shared_key;
                dh_group modp1024;
        }
}

sainfo anonymous {
        pfs_group modp1024;
        encryption_algorithm 3des;
        authentication_algorithm hmac_md5;
        compression_algorithm deflate;
}
```

- <div>mit „chmod 0600 /etc/racoon/racoon.conf“ lesen/schreiben für root setzen.</div>

</div></div>/etc/racoon/psk.txt enthält die PresharedKeys in folgendem Format:

<div id="bkmrk-roadwarrior001%40gatew"><div>```
roadwarrior001@gateway.de MpfeEuwPEkov7ScUtKtmAa4FGWVda9jjtruesrkJKUx8sWC4u9
```

- <div>mit „chmod 0600 /etc/racoon/psk.txt“ lesen/schreiben für root setzen.</div>

</div></div>/etc/sysconfig/racoon

<div id="bkmrk-opts%3D%22-f-%2Fetc%2Fracoon"><div>```
OPTS="-f /etc/racoon/racoon.conf -l /var/log/racoon -v"
```

- <div>mit „chmod 0644 /etc/sysconfig/racoon“ die Berechtigungen setzen</div>

</div></div>/etc/init.d/racoon

<div id="bkmrk-%23%21%2Fbin%2Fbash-%23-%23-raco">```
<span class="co0">#!/bin/bash</span>
<span class="co0">#</span>
<span class="co0"># racoon             Start/Stop the racoon IKE daemon.</span>
<span class="co0">#</span>
<span class="co0"># chkconfig: 2345 90 60</span>
<span class="co0"># description: racoon is the IKE daemon of the KAME tools. Use it with \</span>
<span class="co0">#              the native Linux 2.6 IPsec-Stack</span>
 
<span class="co0"># processname: racoon</span>
<span class="co0"># config: /etc/racoon/racoon.conf</span>
<span class="co0"># pidfile: /var/run/racoon.pid</span>
 
<span class="co0"># Source function library.</span>
. <span class="sy0">/</span>etc<span class="sy0">/</span>init.d<span class="sy0">/</span>functions
 
<span class="re2">OPTS</span>=<span class="st0">""</span>
 
<span class="br0">[</span> <span class="re5">-f</span> <span class="sy0">/</span>etc<span class="sy0">/</span>sysconfig<span class="sy0">/</span>racoon <span class="br0">]</span> <span class="sy0">&&</span> . <span class="sy0">/</span>etc<span class="sy0">/</span>sysconfig<span class="sy0">/</span>racoon
 
<span class="re2">RETVAL</span>=<span class="nu0">0</span>
 
<span class="re2">prog</span>=<span class="st0">"racoon"</span>
 
start<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
  <span class="sy0">/</span>etc<span class="sy0">/</span>racoon<span class="sy0">/</span>setkey.conf
  <span class="kw3">echo</span> <span class="re5">-n</span> $<span class="st0">"Starting <span class="es2">$prog</span>: "</span>
  daemon racoon <span class="re1">$OPTS</span>
  <span class="re2">RETVAL</span>=<span class="re4">$?</span>
  <span class="kw3">echo</span>
  <span class="br0">[</span> <span class="re1">$RETVAL</span> <span class="re5">-eq</span> <span class="nu0">0</span> <span class="br0">]</span> <span class="sy0">&&</span> <span class="kw2">touch</span> <span class="sy0">/</span>var<span class="sy0">/</span>lock<span class="sy0">/</span>subsys<span class="sy0">/</span>racoon
  <span class="kw3">return</span> <span class="re1">$RETVAL</span>
<span class="br0">}</span>
 
stop<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
  <span class="kw3">echo</span> <span class="re5">-n</span> $<span class="st0">"Stopping <span class="es2">$prog</span>: "</span>
  killproc racoon
  <span class="re2">RETVAL</span>=<span class="re4">$?</span>
  <span class="kw3">echo</span>
  <span class="br0">[</span> <span class="re1">$RETVAL</span> <span class="re5">-eq</span> <span class="nu0">0</span> <span class="br0">]</span> <span class="sy0">&&</span> <span class="kw2">rm</span> <span class="re5">-f</span> <span class="sy0">/</span>var<span class="sy0">/</span>lock<span class="sy0">/</span>subsys<span class="sy0">/</span>racoon
  <span class="kw3">return</span> <span class="re1">$RETVAL</span>
<span class="br0">}</span>
 
rhstatus <span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
  status racoon
<span class="br0">}</span>
 
restart <span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
  stop
  start
<span class="br0">}</span>
 
reload <span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
  <span class="kw3">echo</span> <span class="re5">-n</span> $<span class="st0">"Reloading racoon daemon configuration: "</span>
  killproc racoon <span class="re5">-HUP</span>
  <span class="re2">RETVAL</span>=<span class="re4">$?</span>
  <span class="kw3">echo</span>
  <span class="kw3">return</span> <span class="re1">$RETVAL</span>
<span class="br0">}</span>
 
<span class="kw1">case</span> <span class="st0">"$1"</span> <span class="kw1">in</span>
  start<span class="br0">)</span>
    start
    <span class="sy0">;;</span>
  stop<span class="br0">)</span>
    stop
    <span class="sy0">;;</span>
  restart<span class="br0">)</span>
    restart
    <span class="sy0">;;</span>
  reload<span class="br0">)</span>
    reload
    <span class="sy0">;;</span>
  status<span class="br0">)</span>
    rhstatus
    <span class="sy0">;;</span>
  condrestart<span class="br0">)</span>
    <span class="br0">[</span> <span class="re5">-f</span> <span class="sy0">/</span>var<span class="sy0">/</span>lock<span class="sy0">/</span>subsys<span class="sy0">/</span>crond <span class="br0">]</span> <span class="sy0">&&</span> restart <span class="sy0">||</span> :
    <span class="sy0">;;</span>
  <span class="sy0">*</span><span class="br0">)</span>
    <span class="kw3">echo</span> $<span class="st0">"Usage: $0 {start|stop|status|reload|restart|condrestart}"</span>
    <span class="kw3">exit</span> <span class="nu0">1</span>
<span class="kw1">esac</span>
 
<span class="kw3">exit</span> <span class="re4">$?</span>
```

- <div>mit „chmod 0744 /etc/init.d/racoon“ die Berechtigungen setzen.</div>
- <div>ein „chkconfig –add racoon“ aktiviert das Script beim Booten</div>
- <div>mit „service racoon start“ die Security Policy Database (SPD) laden (setkey.conf) und den Racoon-Dämon starten</div>
- <div>geloggt wird nach /var/log/racoon</div>
- <div>Um den Debuglevel zu erhöhen ggf. in /etc/sysconfig/racoon die -v Option um weitere v ergänzen, z.B.</div>

```
OPTS="-f /etc/racoon/racoon.conf -l /var/log/racoon -vvv"
```

</div>

# Tunnelüberwachung via Script

Mit dem folgenden Script lässt sich bequem ein Tunnel überwachen und ggf. automatisch neu starten:

<div id="bkmrk-%23%21%2Fbin%2Fbash-%23-keepal"><div>```
<span class="co0">#!/bin/bash</span>
<span class="co0"># keepalive for ipsec</span>
<span class="co0"># quick'n'dirty hack</span>
 
<span class="co0"># Check darf 3x fehlschlagen, dann wird der Tunnel neu gestartet</span>
<span class="re2">failmax</span>=<span class="nu0">3</span>
 
<span class="co0"># Check alle 10 Sekunden durchführen</span>
<span class="re2">keepalive</span>=<span class="nu0">10</span>
 
<span class="co0"># eine interne IP der Gegenseite eintragen</span>
<span class="re2">CHECKIP</span>=<span class="st0">"192.168.10.10"</span>
 
<span class="co0"># hier den Tunnelnamen eintragen</span>
<span class="re2">CHECKNAME</span>=<span class="st0">"Aussenstelle1"</span>
 
<span class="co0"># don not edit anything beyond this point!</span>
<span class="co0">###########################################################</span>
 
<span class="re2">fail</span>=<span class="nu0">0</span>
 
<span class="re2">MESSAGE</span>=<span class="st0">""</span>
 
<span class="kw1">while</span> <span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span>; <span class="kw1">do</span>
        <span class="co0"># Achtung: der Ping-Befehl hat nicht in allen Versionen die -I Option (von welchem Device/IP aus soll der Ping kommen)</span>
        <span class="co0"># als -I eth0 das Interface mit der internen IP eintragen</span>
        <span class="kw1">if</span> <span class="kw2">ping</span> <span class="re5">-w</span> <span class="nu0">2</span> <span class="re5">-c</span> <span class="nu0">1</span> <span class="re5">-s</span> <span class="nu0">1</span> <span class="re5">-I</span> eth0 <span class="re1">$CHECKIP</span> <span class="nu0">2</span><span class="sy0">>&</span><span class="nu0">1</span> <span class="sy0">></span> <span class="sy0">/</span>dev<span class="sy0">/</span>null;
        <span class="kw1">then</span>
                <span class="re2">MESSAGE</span>=<span class="st0">"Tunnel <span class="es2">$CHECKNAME</span> OK (check <span class="es2">$RANDOM</span>)"</span>
                logger <span class="re5">-p</span> local2.info <span class="re5">-t</span> TUNNEL <span class="st0">"<span class="es2">$MESSAGE</span>"</span>
                <span class="re2">fail</span>=<span class="nu0">0</span>
        <span class="kw1">else</span>
                <span class="re2">fail</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="re1">$fail</span>+<span class="nu0">1</span><span class="sy0">|</span><span class="kw2">bc</span><span class="sy0">`</span>
                <span class="re2">MESSAGE</span>=<span class="st0">"Tunnel <span class="es2">$CHECKNAME</span> DOWN: <span class="es2">$fail</span> (check <span class="es2">$RANDOM</span>)"</span>
                logger <span class="re5">-p</span> local2.info <span class="re5">-t</span> TUNNEL <span class="st0">"<span class="es2">$MESSAGE</span>"</span>
        <span class="kw1">fi</span>
 
        <span class="kw1">if</span> <span class="br0">[</span> <span class="re1">$fail</span> <span class="re5">-gt</span> <span class="re1">$failmax</span> <span class="br0">]</span> ;
        <span class="kw1">then</span>
                <span class="re2">MESSAGE</span>=<span class="st0">"Maxfail (<span class="es2">$failmax</span>) reached: restarting Tunnel <span class="es2">$CHECKNAME</span> (check <span class="es2">$RANDOM</span>)"</span>
                logger <span class="re5">-p</span> local2.info <span class="re5">-t</span> TUNNEL <span class="st0">"<span class="es2">$MESSAGE</span>"</span>
 
                <span class="co0"># Fehler, Tunnel stoppen:</span>
                <span class="co0"># wenn als Software Racoon zum Einsatz kommt:</span>
                <span class="sy0">/</span>etc<span class="sy0">/</span>init.d<span class="sy0">/</span>racoon stop
                <span class="co0"># das hier bei OpenSwan einkommentieren und obiges raus (CHECKNAME muss mit dem Tunnelnamen in der ipsec.conf übereinstimmen)</span>
                <span class="co0">#ipsec auto --down $CHECKNAME</span>
                <span class="kw2">sleep</span> <span class="nu0">5</span>
 
                <span class="co0"># jetzt den Tunnel wieder starten:</span>
                <span class="co0"># wenn als Software Racoon zum Einsatz kommt:</span>
                <span class="sy0">/</span>etc<span class="sy0">/</span>init.d<span class="sy0">/</span>racoon start
                <span class="co0"># das hier bei OpenSwan einkommentieren und obiges raus (CHECKNAME muss mit dem Tunnelnamen in der ipsec.conf übereinstimmen)</span>
                <span class="co0">#ipsec auto --up $CHECKNAME</span>
                <span class="kw2">sleep</span> <span class="nu0">120</span>
                <span class="re2">fail</span>=<span class="nu0">0</span>
        <span class="kw1">fi</span>
        <span class="kw2">sleep</span> <span class="re1">$keepalive</span>
<span class="kw1">done</span>
```

</div></div>das (check $RANDOM) ist als Workaround für Syslog gedacht, dort würden sonst massig „last message repeatet xx times“ auftauchen.

das Script loggt in die Syslog-Facility local2. Folgender Eintrag ist für syslog vorzunehmen, um nach /var/log/tunnel.log zu loggen:

<div id="bkmrk-local2.%2A-%2Fvar%2Flog%2Ftu"><div>```
local2.*                        /var/log/tunnel.log
```

</div></div>dieser Eintrag ist für syslog-NG

<div id="bkmrk-source-s_sys-%7B-file-"><div>```
source s_sys {
    file ("/proc/kmsg" log_prefix("kernel: "));
    unix-stream("/dev/log");
    udp(ip(0.0.0.0) port(514));
    internal();
};

# /var/log/tunnel.log
filter f_tunnel { facility(local2); };
destination d_tunnel { file("/var/log/tunnel.log"); };
log { source(s_sys); filter(f_tunnel); destination(d_tunnel); };
```

</div></div>es kann natürlich auch jede andere Facility verwendet werden.

um das Script bei Reboot automatisch wieder zu starten folgenden Eintrag in /etc/rc.local vornehmen:

<div id="bkmrk-%2Fusr%2Flocal%2Fsbin%2Fprob"><div>```
/usr/local/sbin/probe.ipsec 2>&1 >> /dev/null &
```

</div></div>Das Init-Script für Racoon ist hier zu finden: [Roadwarrior-VPN via racoon](https://wiki.magenbrot.net/books/kryptographie/page/ipsec-roadwarrior-vpn-via-racoon "IPSec Roadwarrior-VPN via racoon")

Das Script ist für Racoon in dieser Form leider nicht optimal, da alle bestehenden Tunnel gekillt werden. Das Script ist nur sinnvoll für ein Gateway mit nur einem Tunnel.

# OpenVPN startet nicht (ca md too weak)

<p class="callout danger">Die folgende Lösung sollte nur ein kurzfristiger Workaround bleiben. Sicherer wäre es wenn auch der Serverteil aktualisiert und auf aktuelle Hashes und Cipher umgestellt wird!</p>

Problem: OpenVPN Tunnel mag nicht starten. Im Log kommt folgende Meldung:

```
(OpenSSL: error:140AB18E:SSL routines:SSL_CTX_use_certificate:ca md too weak)
```

Neue OpenVPN Versionen haben veraltete Hashes und Ciphers deaktiviert. Es laufen aber noch ältere OpenVPN-Server zu denen man sich jetzt nicht mehr verbinden kann.

Die älteren Ciphers lassen sich mit einem Konfigurationsschalter wieder aktivieren.

Bei OpenVPN Configs direkt diese Zeile eintragen:

```
tls-cipher "DEFAULT:@SECLEVEL=0"
```

Bei Verbindungen mit dem NetworkManager kommt diese Zeile in den \[vpn\]-Teil:

```
tls-cipher=DEFAULT:@SECLEVEL=0
```

Danach muss der NetworkManager neu gestartet werden (Achtung, alle Verbindungen werden unterbrochen). Achtung: Die Zeile verschwindet auch wieder aus der Config wenn in der GUI Änderungen vorgenommen wurden.