さくらのVPSでiPhone用の野良WiFi通信傍受対策のL2TP/IPsec(VPN)を設定したメモ(CentOS5)


野良WiFiの危険性については、こちら[FONなど野良WiFiの通信内容傍受の危険性について - nori_no のメモ]に書いた通りですが、さくらのVPSを借りたので、iPhoneFON などの野良WiFiに接続したときの盗聴対策用 L2TP/IPSec (VPN)サーバの設定をしてみました。

※見よう見まねで設定していますので、突っ込み歓迎です。

L2TP/IPsecについては先日試したところ失敗したので[とりあえずPPTPで設定していた]のですが、今回は何とか成功しました。

ただし、PPTPの時のように確認できるすべての環境で接続可能とする事はできませんでした(「WindowsXPでの接続不具合」の項参照)ので、まだ改善の余地があるのだと思います。

openswan, xl2tpd のインストール

設定方針として、CentOS5.5の標準カーネルはそのまま(2.6.18)としていますが、2.6.23以上だとカーネルにPPP over L2TPLinux 2 6 23] が実装されているため、効率よく処理できるようになっているようです。また、[NATトラバーサルの処理にも改善が加えられている]ようです。できればより新しいカーネルを使用した方がよいのでしょう。


CentOS 標準設定の yum でインストールされる openswan のバージョンでは、最新の xl2tpd に対応できないなどいくつか問題があるため、現時点で最新の openswan-2.6.28 をソースからインストールしました。また、CentOS用の xl2tpd の yum パッケージは無いようですので、こちらもソースからコンパイルしました。

※openswanのコンパイルに必要なパッケージのインストール
# yum install make gcc gmp-devel bison flex

※ソースを展開してインストール
# tar zxvf openswan-2.6.28.tar.gz
# cd openswan-2.6.28
# make programs install
※xl2tpdのコンパイルに必要なパッケージのインストール
# yum install libpcap-devel ppp

※ソースを展開してインストール
tar zxvf xl2tpd-1.2.6.tar.gz
cd xl2tpd-1.2.6
make install

※起動ファイルもコピーしておきます。
# cp packaging/fedora/xl2tpd.init /etc/init.d/xl2tpd
# chmod 755 /etc/init.d/xl2tpd

起動ファイル内のパスは以下のように修正しておく必要があります。

[init.d]# diff -U 1 xl2tpd.ORG xl2tpd
--- xl2tpd.ORG  2010-09-19 17:42:29.000000000 +0900
+++ xl2tpd      2010-09-19 17:43:18.000000000 +0900
@@ -8 +8 @@
-# processname: /usr/sbin/xl2tpd
+# processname: /usr/local/sbin/xl2tpd
@@ -35 +35 @@
-[ -x /usr/sbin/$SERVICE ] || exit 0
+[ -x /usr/local/sbin/$SERVICE ] || exit 0
@@ -45 +45 @@
-       daemon $SERVICE
+       daemon /usr/local/sbin/$SERVICE


あと、CentOSで xl2tpd を使用する場合にいくつかの記事で rp-l2tpl2tp-control を流用しているサンプルがあったため、真似して入れています(VPNサーバ側にも必要なものかどうか理解していません)。

※ソースを展開してインストール
# tar zxvf rp-l2tp-0.4.tar.gz
# cd rp-l2tp-0.4
# ./configure
# make
# cp handlers/l2tp-control /usr/local/sbin/
# mkdir /var/run/xl2tpd/
# ln -s /usr/local/sbin/l2tp-control /var/run/xl2tpd/l2tp-control

openswanの設定

(以下すべての設定でコメント行は

grep -v '^[[:blank:]]*#'

して記載を省略しています。)

/etc/ipsec.conf
version 2.0

config setup
        nat_traversal=yes
        virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
        oe=off
        protostack=netkey

include /etc/ipsec.d/*.conf
/etc/ipsec.secrets
: PSK "ABCD1234"

※"ABCD1234"のところは任意のパスワード(Pre Shared Key)を設定してください。

なお、ipsec-secrets は

chmod 600 ipsec-secrets

するなどして、root以外は読めない設定にしておく事をお勧めします。

xl2tpdの設定

/etc/ipsec.d/l2tp-psk.conf
conn L2TP-PSK-NAT
        rightsubnet=vhost:%priv
        forceencaps=yes
        also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
        authby=secret
        pfs=no
        auto=add
        keyingtries=3
        rekey=no
        ikelifetime=8h
        keylife=1h
        type=transport
        left=%defaultroute
        leftnexthop=%defaultroute
        leftprotoport=17/1701
        right=%any
        rightprotoport=17/%any
/etc/xl2tpd/xl2tpd.conf
[global]

[lns default]
ip range = 192.168.253.128-192.168.253.254
local ip = 192.168.253.1
require chap = yes
refuse pap = yes
require authentication = yes
name = (任意の接続名。chap-secretsのserver欄を*以外にする場合にはこれと合わせる必要がある)
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
/etc/ppp/options.xl2tpd
ipcp-accept-local
ipcp-accept-remote
ms-dns (さくらさんのDNS IP一つ目を書きました)
ms-dns (さくらさんのDNS IP二つ目を書きました)
noccp
auth
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
lock
#proxyarp (今回の構成では不要なのでコメントアウトしました)
connect-delay 5000
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
logfile /var/log/xl2tpd.log

ログファイルを作成しておく。

# touch /var/log/xl2tpd.log
/etc/ppp/chap-secrets

これは PPTP のものと共通(*じゃなくて接続名を入れれば使い分けられるんだと思います)。

"ユーザ名" * "接続パスワード" *

OS側の設定

iptables

さくらのVPSにはグローバルIPが一つ割り当てられていますが、VPNクライアントからの通信は、そのグローバルIPにNATして出て行ってもらわないといけません。よって以下の設定を入れます。

iptables -t nat -A POSTROUTING -s 192.168.253.0/24 -j MASQUERADE

※IPセグメントはxl2tpd.confで書いたセグメントと合わせる必要があります。

"iptables -t nat -L" で確認して問題がなければ、ファイルに save します。

service iptables save
/etc/sysctl.conf

ルーティングしてもらう必要があるので、/etc/sysctl.conf の以下の行を 1 に書き換えます。

# Controls IP packet forwarding
net.ipv4.ip_forward = 1

あと、/etc/sysctl.conf の最後に以下の行を付け加えています。

net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.lo.send_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0

※他にも IF がある場合は同様に追加してください。

sysctl.conf の設定を反映させます。

# sysctl -p

起動と自動起動設定

問題がなければこんなふうに起動するはずです。

# service ipsec start
ipsec_setup: Starting Openswan IPsec U2.6.28/K2.6.18-***.11.3.el5...

# service xl2tpd start
Starting xl2tpd:                                           [  OK  ]

ipsec の設定を確認しておきます(起動してからでないとNGだらけになります)。

# ipsec verify
Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path                                 [OK]
Linux Openswan U2.6.28/K2.6.18-***.11.3.el5 (netkey)
Checking for IPsec support in kernel                            [OK]
NETKEY detected, testing for disabled ICMP send_redirects       [OK]
NETKEY detected, testing for disabled ICMP accept_redirects     [OK]
Checking that pluto is running                                  [OK]
Pluto listening for IKE on udp 500                              [OK]
Pluto listening for NAT-T on udp 4500                           [OK]
Two or more interfaces found, checking IP forwarding            [OK]
Checking NAT and MASQUERADEing
Checking for 'ip' command                                       [OK]
Checking for 'iptables' command                                 [OK]
Opportunistic Encryption Support                                [DISABLED]

NG が出ている場合には修正が必要かもしれません。


次項のクライアントの接続確認を行い、問題がなさそうであれば自動起動するように設定します。

# chkconfig ipsec on
# chkconfig xl2tpd on

クライアント側の設定

L2TP/IPSecクライアントの設定メモ - nori_no のメモ

私の確認できる以下の環境で、一つだけ接続できないケースがありました。

クライアント 回線 IPセグメント 接続可否
iPhone SoftBank 3G global IP OK
iPhone (9/21追記)近所のマクドナルドのBBモバイルポイント OK
iPhone (9/22追記)東京メトロのHOTSPOT global IP OK
iPhone 自宅WiFi NAT配下(private IP) OK
iPhone 自宅から見えてる野良FON_FREE_INTERNET WiFi NAT配下(private IP) OK
Windows7 自宅有線LAN NAT配下(private IP) OK
WindowsXP EMOBILEデータ通信カード global IP OK
WindowsXP 自宅WiFi NAT配下(private IP) NG

※恐らくNATルータが NAT Traversalに対応している必要があると思いますが、うちのルータはプロバイダ(KDDI)提供のものですので、詳細な仕様を知りません。

課題

NAT配下のWindowsXPでの接続不具合

Windows XPのPCから、上記Windows7と同じNAT配下から接続試験してみましたが、上記「クライアント側の設定」記事のレジストリ設定をすべてのパターンで試しても接続できませんでした。ただしこのPCにはCiscoVPNクライアントが入っているため、それが何か悪さをしているのかもしれません(Ciscoのサービスが動いているとPPTPすらできなくなるため、停止して確認しています)。

なお、同じ端末で EMOBILE の global IP からはVPN接続できています。

考えられる設定パターンはほぼすべて試しましたので、設定の問題ではない感じです。Windows側の機能的な制約か、NATルータの機能上の問題か、サーバ側のkernelのバージョンの問題だろうと思います。

とりあえずの workaround としては、こちら[さくらのVPSでiPhone用の野良WiFi通信傍受対策のPPTPサーバ(VPN)を設定したメモ(CentOS5) - nori_no のメモ]の設定も併せて行っています(ほんとはL2TP/IPSecのみに絞りたいですが)。

l2tp-psk.conf の最適化の余地

global IPなら難なくすべての環境でつながるのですが、NAT配下でもなるべく多くの環境がつながる設定を見つけるために、ipsec.conf と l2tp-psk.conf の様々な設定パターンを試行錯誤し数時間を費やしましたが、これが最も適した設定かどうかは自信がありません。

  • nat_traversal と forceencaps の組み合わせ
設定 環境(NAT配下)
nat_traversal=no, forceencaps無し, rightprotoport=17/%any iPhone:OK, Win7:NG
nat_traversal=yes, forceencaps=no Win7:OK, iPhone:NG
nat_traversal=yes, forceencaps=yes Win7, iPhoneともOK


forceencapsの設定をせずに繋がる設定が最良だと思いますが、他にも色々な設定項目との組み合わせを試してNGでしたので、諦めました。forceencapsのmanには以下のように書かれています。

forceencaps
In some cases, for example when ESP packets are filtered or when a broken IPsec peer does not properly recognise NAT, it can be useful to force RFC-3948 encapsulation. forceencaps=yes forces the NAT detection code to lie and tell the remote peer that RFC-3948 encapsulation (ESP in UDP port 4500 packets) is required. For this option to have any effect, the setup section option nat_traversal=yes needs to be set. Acceptable values are yes or no (the default).

あと、パターンとしては以下の設定の組み合わせを色々と試しましたが、これの組み合わせによっては、NAT配下のiPhoneで一度接続を切ると二回目以降接続できなくなる不具合が発生したりします(Windowsでは接続できなくなったりはしても、二回目以降に接続できなる現象は起きませんでした)。

        rightsubnet=vhost:%priv
        #rightsubnet=vhost:%no,%priv
        # For updated Windows 2000/XP clients,
        # to support old clients as well, use leftprotoport=17/%any
        leftprotoport=17/1701
        #leftprotoport=17/%any
        # Using the magic port of "0" means "any one single port". This is
        # a work around required for Apple OSX clients that use a randomly
        # high port, but propose "0" instead of their port. If this does
        # not work, use 17/%any instead.
        #rightprotoport=17/0
        rightprotoport=17/%any


以下の設定は一番参考にさせていただいた[http://www.jacco2.dds.nl/networking/freeswan-l2tp.html#Client:Title]に書いてあったので試してみましたが、これをつけると同様にiPhoneで二回目以降の接続ができたりできなかったりするようなので、結局無効にしました。

        # If you want to support Mac OS 10.5 and Linux clients it is highly recommended to enable DPD.
        #dpddelay=40
        #dpdtimeout=130
        #dpdaction=clear
NAT-Traversalについて

上記 forceencaps の部分にも書きましたが、より多くの環境で接続できるようにするためには、NAT-Traversalの設定が肝な感じです。NAT配下のWindowsXPで接続できないのもここの設定の問題かもしれません。

このへんにヒントがあるのかなと思って読んでみたいのですが、解決できませんでした。

http://www.openswan.org/docs/local/README.NAT-Traversal

Using a Linux L2TP/IPsec VPN server with Mac OS X and iPhone
Using a Linux L2TP/IPsec VPN server with Windows 2000/XP

http://www.osronline.com/ddkx/network/209offl_4tev.htm

Receiving connection message 789 when trying to establish a VPN connection to IBM Smart Cube for Linux


どなたか詳しい方のコメントを期待します。