IpCop
(→IPCop) |
(→ipsec-watch) |
||
Zeile 47: | Zeile 47: | ||
# Werte zuruecksetzen | # Werte zuruecksetzen | ||
CONN_STATE="-" | CONN_STATE="-" | ||
− | |||
− | |||
# vergleichen, falls noch wenigstens 1 Verbindung steht | # vergleichen, falls noch wenigstens 1 Verbindung steht | ||
Zeile 60: | Zeile 58: | ||
CONN_RIGHT=${RAW_STATE#*\@} # alles bis zum @ entfernen | CONN_RIGHT=${RAW_STATE#*\@} # alles bis zum @ entfernen | ||
CONN_RIGHT_IP=${CONN_RIGHT%:*} # alles ab : entfernen | CONN_RIGHT_IP=${CONN_RIGHT%:*} # alles ab : entfernen | ||
+ | if [ "$RIGHT_IP" != "$CONN_RIGHT_IP" ] ; then | ||
+ | logger -p local0.warning -t ipcop "ipsec-watch restarting $CONN_NAME $RIGHT_IP $CONN_RIGHT_IP(IP changed)" | ||
+ | /usr/local/bin/ipsecctrl S $CONN_NR | ||
+ | fi | ||
else | else | ||
# RAW_STATE = %trap:0 || %hold:0 (oder war das bei hold anders?) | # RAW_STATE = %trap:0 || %hold:0 (oder war das bei hold anders?) | ||
− | |||
CONN_STATE=${RAW_STATE#%} # % am Anfang entfernen | CONN_STATE=${RAW_STATE#%} # % am Anfang entfernen | ||
CONN_STATE=${CONN_STATE%:*} # alles ab : entfernen | CONN_STATE=${CONN_STATE%:*} # alles ab : entfernen | ||
+ | logger -p local0.warning -t ipcop "ipsec-watch restarting $CONN_NAME $RIGHT_IP (state = $CONN_STATE) $RAW_STATE" | ||
+ | /usr/local/bin/ipsecctrl S $CONN_NR | ||
fi | fi | ||
fi | fi | ||
Zeile 70: | Zeile 73: | ||
fi | fi | ||
− | if [ "$CONN_STATE" == " | + | if [ "$CONN_STATE" == "-" ] ; then |
− | + | logger -p local0.warning -t ipcop "ipsec-watch restarting $CONN_NAME (connection down)" | |
− | + | /usr/local/bin/ipsecctrl S $CONN_NR | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | /usr/local/bin/ipsecctrl S $CONN_NR | + | |
fi | fi | ||
Version vom 3. August 2010, 20:45 Uhr
IPCop ist eine Linuxdistribution für Router und Firewalls und ist erhältlich unter http://www.ipcop.org/ . Weitere allg. Informationen unter http://de.wikipedia.org/wiki/IPCop
ipsec-watch
Im praktischen Einsatz ergab sich das Problem, daß dead-peer-detection bei den IPsec-VPN-Verbindungen nicht funktionierte. Zum Teil liegt das vermutlich auch an der Art des Internetzugangs.
Der 1. Router befindet sich hinter einem Kabelmodem, welches als Bridge arbeitet und dem IPCop die öffentliche IP durchreicht.
Der 2. Router befindet sich hinter einer FritzBox und hat eine private IP an RED.
Beide Router haben eine dynamische IP, die aber erst nach 14 Tagen geändert wird. (Kabel Deutschland)
Der 3. Router wählt sich via DSL-Modem selbst ein und erhält jeden Tag eine neue IP. (T-Com)
Nach der DSL-Neueinwahl mit Änderung der IP-Adresse werden die VPN-Verbindungen nicht neu initialisiert. Die genaue Ursache ist noch nicht ermittelt.
Da es sich um Netz-zu-Netz-VPNs handelt ist ein Monitoring via ping von den IPCops selbst nicht möglich. Ein externes Monitoring einer Maschine im Netz informiert per Mail über eine fehlende Verbindung. Ggf. kann von dort aus auch ein gezielter Neustart einzelner Verbindungen mit dedizierten ssh-Keys eingerichtet werden. Ziel ist es jedoch, daß die IPCops selbst den Fehler zu korrigieren.
Als Workaround wurde ein Shellskript geschrieben, welches regelmäßig kontrolliert, ob die Verbindungen in einem definierten Zustand sind und diese ggf. neu startet. Das Skript vergleicht die in der Konfigurationsdatei hinterlegten Verbindungen mit der Ausgabe von "ipsec eroute" ( -> $EROUTE). Der einzige als "garantiert bestehende Verbindung" bekannte Zustand ist "tun0x*@<IP>:0", wobei die IP der aktuell gültigen IP der Gegenstelle entsprechen muß. Letztere wird wiederum mit "host" aus dem FQDN der zugehörigen Verbindung aus der Config (Feld_12 -> $RIGHT) ermittelt. Die zugehörige Verbindung ergibt sich aus der Config (Feld_13 -> $RIGHTSUBNET_CFG) und $EROUTE (Feld_4 -> $RIGHTSUBNET), jeweils ab dem "/" um die in unterschiedlicher Schreibweise angegebene Subnetzmaske gekürzt. Feld_1 in der Config ist der jeweilige Verbindungsname (bzw. Nr.) für ipsecctrl. Damit kann die jeweilige Verbindung gezielt neugestartet werden.
Als fehlerhaft bekannt sind die Zustände:
- "tun" + alte <IP>
- "trap"
- ggf. "hold"
#!/bin/bash CONFIG='/var/ipcop/vpn/config' EROUTE=$( ipsec eroute ) # pruefe alle aktiven Verbindungen ($2=on) aus CONFIG while read CONN_NR CONN_NAME RIGHT RIGHTSUBNET_CFG; do # IP-Adresse aus Config-FQDN der Gegenstelle ermitteln read F1 F2 F3 RIGHT_IP F4 <<< $( host -t a $RIGHT ) # ToDo: vorher pruefen, ob in CONFIG eine IP statt FQDN eingetragen wurde # dann eruebrigt sich die Namensaufloesung # BASH#IP-Validierung funktioniert nicht, =~ wird nicht akzeptiert # Werte zuruecksetzen CONN_STATE="-" # vergleichen, falls noch wenigstens 1 Verbindung steht if [ "$EROUTE" != "" ]; then # EROUTE zeilenweise verarbeiten while read P_COUNT LEFTSUBNET A1 RIGHTSUBNET A2 RAW_STATE; do if [ "${RIGHTSUBNET_CFG%/*}" == "${RIGHTSUBNET%/*}" ] ; then CONN_STATE=${RAW_STATE%%0x*} # alles ab 0x entfernen if [ "$CONN_STATE" == "tun" ]; then # RAW_STATE = tun0x<NR>@<IP>:0 CONN_RIGHT=${RAW_STATE#*\@} # alles bis zum @ entfernen CONN_RIGHT_IP=${CONN_RIGHT%:*} # alles ab : entfernen if [ "$RIGHT_IP" != "$CONN_RIGHT_IP" ] ; then logger -p local0.warning -t ipcop "ipsec-watch restarting $CONN_NAME $RIGHT_IP $CONN_RIGHT_IP(IP changed)" /usr/local/bin/ipsecctrl S $CONN_NR fi else # RAW_STATE = %trap:0 || %hold:0 (oder war das bei hold anders?) CONN_STATE=${RAW_STATE#%} # % am Anfang entfernen CONN_STATE=${CONN_STATE%:*} # alles ab : entfernen logger -p local0.warning -t ipcop "ipsec-watch restarting $CONN_NAME $RIGHT_IP (state = $CONN_STATE) $RAW_STATE" /usr/local/bin/ipsecctrl S $CONN_NR fi fi done <<< "$EROUTE" fi if [ "$CONN_STATE" == "-" ] ; then logger -p local0.warning -t ipcop "ipsec-watch restarting $CONN_NAME (connection down)" /usr/local/bin/ipsecctrl S $CONN_NR fi done <<< "$( awk -F , '($2 == "on") {printf "%s %s %s %s\n", $1, $3, $12, $13}' $CONFIG )"
Eintrag in der crontab (fcrontab -e):
*/2 * * * * [ -x "/usr/local/bin/ipsec-watch" ] && /usr/local/bin/ipsec-watch >/dev/null 2>&1
schaut alle 2 Minuten nach dem Rechten. (ursprünglich aller 5 Minuten)
Festgestellt wurde, daß der (2.) Router mit der privaten IP an RED nach der DSL-Neueinwahl des 3. Routers die geänderte IP-Adresse nach 5 Minuten noch nicht bemerkt hat. Die Verbindung wurde erst mit dem 2. Neustart wieder aktiviert, also erst nach 10 Minuten. Der 1. Router war bereits nach dem 1. Versuch wieder im Normalzustand.
Zustand der VPNs nach der DSL-Neueinwahl: 1. Check (+5min):
- 1 -> 2: nicht betroffen (wird nicht neugestartet)
- 1 <- 2: nicht betroffen (wird nicht neugestartet)
- 1 -> 3: Verbindung weg (kein eroute-Eintrag)
- 1 <- 3: trap
- 2 -> 3: tun -> alte IP
- 2 <- 3: trap
2. Check (+10min):
- 2 -> 3: Verbindung weg (kein eroute-Eintrag)
- 2 <- 3: trap