Was ich möchte: mit OpenS/WAN auf meinem Debian-System einen Tunnelendpunkt für das iPhone-VPN herstellen. Mein Debian-Server (Debian squeeze) steht im Internet mit einer offiziellen IP-Adresse. Ziel ist es aus verschiedenen Netzen abhörsicher eine Verbindung in das Internet aufzubauen.

Was brauche ich dafür:

  • xl2tpd
  • openswan

Installation xl2tpd

apt-get install xl2tpd

installiert neben dem xl2tpd auch den ppp-daemon ppp.

Konfiguration xl2tpd

Inhalt der Datei /etc/xl2tpd/xl2tpd.conf:

[global]                               ; Global parameters:
port = 1701                            ; * Bind to port 1701
ipsec saref = yes

[lns default] ; Our fallthrough LNS definition
ip range = 10.0.4.2 ; * Allocate from this IP range
local ip = 10.0.4.1 ; * Our local IP to use
length bit = yes ; * Use length bit in payload?
require chap = yes ; * Require CHAP auth. by peer
refuse pap = yes ; * Refuse PAP authentication
require authentication = yes ; * Require peer to authenticate
name = myServer ; * Report this as our hostname
ppp debug = yes ; * Turn on PPP debugging
pppoptfile = /etc/ppp/options.l2tpd ; * ppp options file

Konfiguration von ppp

Inhalt der Datei /etc/ppp/options.l2tpd

ipcp-accept-local
ipcp-accept-remote
noccp
ms-dns 203.0.113.60
ms-dns 203.0.113.61
auth
name l2tpd
crtscts
idle 1800
mtu 1400
mru 1400
nodefaultroute
debug
lock
connect-delay 5000

Bei ms-dns sind entsprechend die richtigen DNS-Server einzutragen!

Inhalt der Datei /etc/ppp/chap-secrets:

# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
username         l2tpd   password              *

username und password sind entsprechend anzupassen.

Die Angabe l2tpd in der Spalte server der Datei /etc/pap/chap-secrets muß mit der Angabe name l2tpd der Datei /etc/ppp/options.l2tpd übereinstimmen.

Installation von openswan

# apt-get install openswan

Konfiguration von openswan

Inhalt der Datei /etc/ipsec.conf:

version 2.0     # conforms to second version of ipsec.conf specification

# basic configuration
config setup
        nat_traversal=yes
        oe=off
        protostack=netkey
        uniqueids=no

conn road_warrior
        rekey=no
        authby=secret
        pfs=no
        keyingtries=3
        dpddelay=30
        dpdtimeout=120
        dpdaction=clear
        compress=yes
        #
        left=198.51.100.208
        leftprotoport=17/1701
        leftnexthop=198.51.100.1
        #
        right=%any
        rightprotoport=17/%any
        rightsubnet=vhost:%no,%priv
        #
        auto=add

Inhalte der Datei /etc/ipsec.secrets:

198.51.100.208 %any: PSK "veryverysecret"

Der Preshared key (PSK) veryverysecret ist entsprechend anzupassen.

Starten/Stoppen der Daemons

Die Daemonen für IPSec (OpenS/WAN) und die Layer2-Verbindung können folgendermaßen neu gestartet werden:

# invoke-rc.d ipsec restart
# invoke-rc.d xl2tpd restart

Zusätzliche Konfigurationsschritte

Damit das Routen der Pakete von der ppp-Schnittstelle auf das eth-Interface funktioniert, muss das Routing aktiviert werden:

# echo 1 > /proc/sys/net/ipv4/ip_forward

Um diese Einstellung permanent zu machen muss sie in der Datei /etc/sysctl.conf eingetragen werden:

…
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.conf.default.forwarding=1
…

oder

…
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
…

Da wir im Tunnel private Adressen verwenden, müssen die noch entsprechend geNATet werden:

# iptables -A POSTROUTING -t nat -o eth0 -s 10.0.4.2 -d 0/0 -j MASQUERADE

Diese Einstellung für das NAT ist für die permanente Verwendung in der Datei /etc/rc.local zu verewigen:

…
# NAT for iPhone VPN
/sbin/iptables -A POSTROUTING -t nat -o eth0 -s 10.0.4.2 -d 0/0 -j MASQUERADE
…

Einstellungen auf dem iPhone

Server: IP-Adresse (oder DNS-Name) des VPN-Servers (in meinem Beispiel 198.51.100.180)
Account: username (aus /etc/ppp/chap-secrets)
Kennwort: password (aus /etc/ppp/chap-secrets)
Shared-Secrets: veryverysecret (aus /etc/ipsec.secrets)

iPhone-VPN

Probleme

Reaktivierung der Verbindung nach Abbruch

Nach Abbruch der Verbindung (durch deaktivieren von VPN am iPhone oder durch ein Timeout) kann dann nicht sofort wieder eine Verbindung aufgebaut werden. Nach einer Wartezeit (oder 2-3 Versuchen) funktioniert der Verbindungsaufbau wieder.
Info von http://just-another-tech-blog.blogspot.de/2011/02/l2tp-vpn-fur-iphone-mit-debian-lenny.html

Update von Openswan verursacht Fehler

Nach dem Update auf Version openswan 1:2.6.37-3+deb7u1 funktioniert der VPN-Tunnel nicht mehr. Es erscheint unter anderem folgende Fehlermeldung im Log:
May 26 21:28:11 e2 pluto[32709]: "road_warrior"[3] 178.191.58.99 #3: message ignored because it contains an unknown or unexpected payload type (ISAKMP_NEXT_SAK) at the outermost level
Ein Downgrade von openswan bringt Linderung, ist aber problematisch, da möglicherweise wieder Bugs aktiviert werden!
Überprüfung der Version (unter Debian/Ubuntu):

# dpkg -l | grep openswan
ii  openswan                                      1:2.6.37-3+deb7u1             amd64        Internet Key Exchange daemon

Downgrade auf eine funktionierende Version von Openswan:

apt-get install openswan=1:2.6.37-3

Ich habe aktuell das Paket openswan auf hold gesetzt:

# echo "openswan hold"|dpkg --set-selections

Kontrolle:

# dpkg --get-selections |awk '$2 == "hold" { print $1 }'
openswan

Quelle: http://superuser.com/questions/740545/l2tp-ipsec-stopped-working-after-openssl-upgrade

Die Installation ist untypischerweise bei Debian NICHT schnell gemacht. Als erstes sollte man seinen Mailserver entsprechend konfigurieren:
Bei mir ist das sendmail. Zuerst die Einstellung in der Datei /etc/mail/virtuser-table, die bei mir in Verwendung ist:

…
# mailman aliases
mailman@example.org             local-user
mailman-owner@example.org       local-user
…
mailman-admin@example.org        mailman-admin
mailman-bounces@example.org      mailman-bounces
mailman-confirm@example.org      mailman-confirm
mailman-join@example.org         mailman-join
mailman-leave@example.org        mailman-leave
mailman-owner@example.org        mailman-owner
mailman-request@example.org      mailman-request
mailman-subscribe@example.org    mailman-subscribe
mailman-unsubscribe@example.org  mailman-unsubscribe
…
mailing-list-admin@example.org        mailing-list-admin
mailing-list-bounces@example.org      mailing-list-bounces
mailing-list-confirm@example.org      mailing-list-confirm
mailing-list-join@example.org         mailing-list-join
mailing-list-leave@example.org        mailing-list-leave
mailing-list-owner@example.org        mailing-list-owner
mailing-list-request@example.org      mailing-list-request
mailing-list-subscribe@example.org    mailing-list-subscribe
mailing-list-unsubscribe@example.org  mailing-list-unsubscribe
…

Die Liste mailman ist für administrative Zwecke notwendig. Ohne diese Liste startet der mailman nicht, wie man später sehen wird. Für mailing-list ist der entsprechende Listenname einzusetzen, den man später als öffentliche Liste verwenden will!
Jetzt kann man in der Datei /etc/alias die entsprechenden Übergaben an die Mailinglist-Applikation hinterlegen:

…
mailman:         "|/var/mailman/mail/mailman post mailman"
mailman-admin:   "|/var/mailman/mail/mailman admin mailman"
mailman-bounces: "|/var/mailman/mail/mailman bounces mailman"
mailman-confirm: "|/var/mailman/mail/mailman confirm mailman"
mailman-join:    "|/var/mailman/mail/mailman join mailman"
mailman-leave:   "|/var/mailman/mail/mailman leave mailman"
mailman-owner:   "|/var/mailman/mail/mailman owner mailman"
mailman-request: "|/var/mailman/mail/mailman request mailman"
mailman-subscribe: "|/var/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe:"|/var/mailman/mail/mailman unsubscribe mailman"
…
mailing-list:         "|/var/mailman/mail/mailman post mailing-list"
mailing-list-admin:   "|/var/mailman/mail/mailman admin mailing-list"
mailing-list-bounces: "|/var/mailman/mail/mailman bounces mailing-list"
mailing-list-confirm: "|/var/mailman/mail/mailman confirm mailing-list"
mailing-list-join:    "|/var/mailman/mail/mailman join mailing-list"
mailing-list-leave:   "|/var/mailman/mail/mailman leave mailing-list"
mailing-list-owner:   "|/var/mailman/mail/mailman owner mailing-list"
mailing-list-request: "|/var/mailman/mail/mailman request mailing-list"
mailing-list-subscribe: "|/var/mailman/mail/mailman subscribe mailing-list"
mailing-list-unsubscribe:"|/var/mailman/mail/mailman unsubscribe mailing-list"
…

So, jetzt aber zur Installation von mailman:

apt-get install mailman

Leider ist die Konfiguration damit nicht vollständig, selbst die während der Installation abgefragten Konfigurationseinstellungen werden nicht übernommen (ich habe als Sprachen en und de und dann als Standardsprachen de gewählt). Danach wird angemeckert, dass die Mailingliste mailman noch nicht angelegt sind, das merkt man dann auch beim weiteren Ablauf der Paketinstallation, die mit der Meldung:

Site list for mailman missing (looking for list named 'mailman'). ... (warning).
Please create it; until then, mailman will refuse to start. ... (warning).

Als nächstes die Konfigurationsdatei /etc/mailman/mm_cfg.py anpassen:

…
#-------------------------------------------------------------
# Default domain for email addresses of newly created MLs
DEFAULT_EMAIL_HOST = 'list.example.org'
#-------------------------------------------------------------
# Default host for web interface of newly created MLs
DEFAULT_URL_HOST   = 'lists.example.org'
#-------------------------------------------------------------
…

Als nächstes die angemeckerte Mailingliste mailman anlegen:

 newlist mailman

Den Hinweis, dass die entsprechenden Einträge in der Datei /etc/alias angelegt werden müssen, kann man negieren, weil wir das gleich am Beginn gemacht haben.
Der letzte Schritt ist jetzt das dpkg-reconfigure mailman um jetzt tatsächlich alles umzusetzen, was zuerst nicht gegangen ist, nämlich auch die Deutsche Sprache zu installieren (wenn man will auch andere) und diese dann als Standardsprache einzustellen. Am Ende wird mailman automatisch gestartet und in der Mailbox sollte die neue Mailingliste mailman angekündigt sein.
Im Verzeichnis /etc/mailman liegt die Datei apache.conf, die man als Vorlage für die Konfiguration des Webservers nehmen kann. Wenn der Webserver dann entsprechend konfiguriert ist (und die Konfiguration geladen wurde), steht einem der Zugriff via http nichts mehr im Wege.

Aus welch Gründen auch immer, kamen beim Ausführen von System-Perl-Skripten auf Einem Debian-Server plötzlich Warnungen wie folgt:

…
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LC_MONETARY = "de_AT.utf-8",
LC_NUMERIC = "de_AT.utf-8",
LC_MESSAGES = "de_AT.utf-8",
LC_COLLATE = "de_AT.utf-8",
LC_CTYPE = "de_AT.utf-8",
LC_TIME = "de_AT.utf-8",
LANG = "de_DE.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
…

Diese Warnungen bekommt man wieder weg, wenn man als Root ein beherztes dpkg-reconfigure locales absetzt und die angemotzten Sprachen wieder aktiviert.