いろいろあってVPNを張りたくなったので, Arch LinuxでL2TP/IPsecなVPNサーバを構築したときのメモです.

環境

図にするとこんな感じ.
記事中では, この図のIPアドレス及びネットワークインターフェース名を使っていきます.
diagram

ちなみに, サーバにはクーポンが残っていたConoHa(リニューアル前)のメモリ1GBプラン(2core-CPU, 1GB-RAM, 100GB-HDD)を使いました.

利用したソフトウェアとバージョンは以下のとおり.

ソフトウェア バージョン メモ
Arch Linux - 最高のLinuxディストリビューション
Openswan 2.6.47 LinuxのためのIPsec(Internet Protocol Security)実装
xl2tpd 1.3.7 LinuxのためのL2TP(Layer 2 Tunneling Protocol)実装
ppp 2.4.7 LinuxやSolarisのためのPPP(Point-to-Point Protocol)実装
iptables 1.6.0 ファイアウォール

準備

必要なソフトウェアをインストール. Openswanは公式のリポジトリにないのでAURから入れました.

$ yaourt -S iptables xl2tpd openswan

また, いくつかのカーネルパラメータを変更するために, /etc/sysctl.d/99-sysctl.conf(名前は適当)を作成.

# /etc/sysctl.d/99-sysctl.conf

net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1

以下のコマンドを実行して反映させます.

$ sudo sysctl --system

サーバ側の設定

Openswan

/etc/ipsec.confの41行目, # Add connections hereの下にinclude /etc/ipsec.d/*.confを追記.

# /etc/ipsec.conf - Openswan IPsec configuration file

# This file:  /usr/share/doc/openswan/ipsec.conf-sample
#
# Manual:     ipsec.conf.5


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

# basic configuration
config setup
	# Do not set debug options to debug configuration issues!
	# plutodebug / klipsdebug = "all", "none" or a combation from below:
	# "raw crypt parsing emitting control klips pfkey natt x509 dpd private"
	# eg:
	# plutodebug="control parsing"
	# Again: only enable plutodebug or klipsdebug when asked by a developer
	#
	# enable to get logs per-peer
	# plutoopts="--perpeerlog"
	#
	# Enable core dumps (might require system changes, like ulimit -C)
	# This is required for abrtd to work properly
	# Note: incorrect SElinux policies might prevent pluto writing the core
	dumpdir=/var/run/pluto/
	#
	# NAT-TRAVERSAL support, see README.NAT-Traversal
	nat_traversal=yes
	# exclude networks used on server side by adding %v4:!a.b.c.0/24
	# It seems that T-Mobile in the US and Rogers/Fido in Canada are
	# using 25/8 as "private" address space on their 3G network.
	# This range has not been announced via BGP (at least upto 2010-12-21)
	virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v6:fd00::/8,%v6:fe80::/10
	# OE is now off by default. Uncomment and change to on, to enable.
	oe=off
	# which IPsec stack to use. auto will try netkey, then klips then mast
	protostack=auto
	# Use this to log to a file, or disable logging on embedded systems (like openwrt)
	#plutostderrlog=/dev/null

# Add connections here
include /etc/ipsec.d/*.conf

/etc/ipsec.d/examples/l2tp-psk.conf/etc/ipsec.d/にコピー.
33行目のYourGatewayIPの部分をサーバのIPアドレスに変更. また, 47行目以降の設定は今回必要ないので消しておきます.

$ sudo cp /etc/ipsec.d/examples/l2tp-psk.conf /etc/ipsec.d/
# /etc/ipsec.d/l2tp-psk.conf

conn L2TP-PSK-NAT
	rightsubnet=vhost:%priv
	also=L2TP-PSK-noNAT

conn L2TP-PSK-noNAT
	#
	# Configuration for one user with any type of IPsec/L2TP client
	# including the updated Windows 2000/XP (MS KB Q818043), but
	# excluding the non-updated Windows 2000/XP.
	#
	#
	# Use a Preshared Key. Disable Perfect Forward Secrecy.
	#
	# PreSharedSecret needs to be specified in /etc/ipsec.secrets as
	# YourIPAddress	 %any: "sharedsecret"
	authby=secret
	pfs=no
	auto=add
	keyingtries=3
	# we cannot rekey for %any, let client rekey
	rekey=no
	# Apple iOS doesn't send delete notify so we need dead peer detection
	# to detect vanishing clients
	dpddelay=10
	dpdtimeout=90
	dpdaction=clear
	# Set ikelifetime and keylife to same defaults windows has
	ikelifetime=8h
	keylife=1h
	# l2tp-over-ipsec is transport mode
	type=transport
	#
	left=157.x.x.x
	#
	# For updated Windows 2000/XP clients,
	# to support old clients as well, use leftprotoport=17/%any
	leftprotoport=17/1701
	#
	# The remote user.
	#
	right=%any
	# Using the magic port of "%any" means "any one single port". This is
	# a work around required for Apple OSX clients that use a randomly
	# high port.
	rightprotoport=17/%any

今回はサクッと立てたかったため, 認証方式にはPSK(Pre Shared Keys, 事前共有鍵)を選択.
/etc/ipsec.secretsをこんな感じに記述しました.

: PSK "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

xl2tpd

/etc/xl2tpd/xl2tpd.confをこんな感じに記述.
listen-addrにサーバのIPアドレス, hostnameに適当な名前, ip rangeにクライアントに割り当てるIPアドレスの範囲, local ipにサーバのVPN側のIPアドレスを設定します.

[global]
listen-addr=157.x.x.x
auth file = /etc/ppp/chap-secrets
debug avp = no
debug network = no
debug packet = no
debug state = no
debug tunnel = no

[lns default]
hostname = hogefuga
ip range = 10.2.0.100-10.2.0.149
local ip = 10.2.0.1
assign ip = yes
length bit = yes
ppp debug = no
pppoptfile = /etc/ppp/options.l2tpd
require authentication = yes
require chap = yes
require pap = no

ppp

/etc/ppp/options.l2tpdをこんな感じに記述.
ms-dnsmtu, mruは環境に合わせて適宜変更します.

Openswanのドキュメント等ではcrtsctslockも設定されていますが, これを入れるとエラーが出て起動しなかったため消してあります.

ipcp-accept-local
ipcp-accept-remote

ms-dns 8.8.8.8
ms-dns 8.8.4.4

auth
debug
idle 1800
mtu 1500
mru 1500
nodefaultroute
persist
proxyarp
name l2tpd

refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2

接続するユーザとパスワードを/etc/ppp/chap-secretsに記述しておきます.

# Secrets for authentication using CHAP
# client	server	secret			IP addresses
nyan l2tpd bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb *

iptables

500/UDP, 1701/UDP, 4500/UDPを開放.
また, NICとL2TP間をパケットが出入りできるように, いくつかのルールも設定します.

# iptables -A INPUT -i ens3 -p udp -m policy --dir in --pol ipsec -m udp --dport 1701 -j ACCEPT
# iptables -A INPUT -i ens3 -p udp --dport 4500 -j ACCEPT
# iptables -A INPUT -i ens3 -p udp --dport 500 -j ACCEPT

# iptables -A FORWARD -i ens3 -d 10.2.0.0/24 -j ACCEPT
# iptables -A FORWARD -s 10.2.0.0/24 -o ens3 -j ACCEPT
# iptables -t nat -A POSTROUTING -s 10.2.0.0/24 -o ens3 -j MASQUERADE

サービスを有効にする

とりあえずスタートして, エラーが出なければ有効にしておきます.

$ sudo systemctl start openswan xl2tpd
$ sudo systemctl enable openswan xl2tpd

クライアント側の設定

Openswan

/etc/ipsec.confの20行目をplutoopts="--interface=wlp2s0"のようにして通信を行うインターフェースを指定し, また41行目の# Add connections here以下に接続の設定を記述してしまいます.

# /etc/ipsec.conf - Openswan IPsec configuration file

# This file:  /usr/share/doc/openswan/ipsec.conf-sample
#
# Manual:     ipsec.conf.5


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

# basic configuration
config setup
	# Do not set debug options to debug configuration issues!
	# plutodebug / klipsdebug = "all", "none" or a combation from below:
	# "raw crypt parsing emitting control klips pfkey natt x509 dpd private"
	# eg:
	# plutodebug="control parsing"
	# Again: only enable plutodebug or klipsdebug when asked by a developer
	#
	# enable to get logs per-peer
	plutoopts="--interface=wlp2s0"
	#
	# Enable core dumps (might require system changes, like ulimit -C)
	# This is required for abrtd to work properly
	# Note: incorrect SElinux policies might prevent pluto writing the core
	dumpdir=/var/run/pluto/
	#
	# NAT-TRAVERSAL support, see README.NAT-Traversal
	nat_traversal=yes
	# exclude networks used on server side by adding %v4:!a.b.c.0/24
	# It seems that T-Mobile in the US and Rogers/Fido in Canada are
	# using 25/8 as "private" address space on their 3G network.
	# This range has not been announced via BGP (at least upto 2010-12-21)
	virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v6:fd00::/8,%v6:fe80::/10
	# OE is now off by default. Uncomment and change to on, to enable.
	oe=off
	# which IPsec stack to use. auto will try netkey, then klips then mast
	protostack=netkey
	# Use this to log to a file, or disable logging on embedded systems (like openwrt)
	#plutostderrlog=/dev/null

# Add connections here
conn L2TP-PSK
	authby=secret
	pfs=no
	auto=add
	keyingtries=3
	dpddelay=30
	dpdtimeout=120
	dpdaction=clear
	rekey=yes
	ikelifetime=8h
	keylife=1h
	type=transport
	left=%defaultroute
	leftprotoport=17/1701
	right=157.x.x.x
	rightprotoport=17/1701

/etc/ipsec.secretsにサーバのIPアドレスとPSKを記述します.

%any 157.x.x.x : PSK "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

xl2tpd

/etc/xl2tpd/xl2tpd.confをこんな感じに記述.

[lac vpn-connection]
lns = 157.x.x.x
ppp debug = no
pppoptfile = /etc/ppp/options.l2tpd.client
length bit = yes

ppp

/etc/ppp/options.l2tpd.clientをこんな感じに記述.
mtumruは環境に合わせて適宜変更します. また, namepasswordにはサーバの/etc/ppp/chap-secretsに設定したものを記述します.

ipcp-accept-local
ipcp-accept-remote

refuse-eap
require-mschap-v2
noauth
noccp
debug
idle 1800
mtu 1500
mru 1500
defaultroute
usepeerdns
noipdefault
connect-delay 5000

name nyan
password bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

接続する

予めxl2tpdコントロール用のファイルを作成しておきます.

$ sudo mkdir -p /var/run/xl2tpd
$ sudo touch /var/run/xl2tpd/l2tp-control

Openswan, xl2tpdを起動し, サーバに接続.

$ sudo systemctl start openswan xl2tpd
$ ipsec auto --up L2TP-PSK
$ sudo sh -c 'echo "c vpn-connection" > /var/run/xl2tpd/l2tp-control'

ip a等でppp0のようなインターフェースが現れていればおそらく成功です.

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever

---

18: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 3
    link/ppp 
    inet 10.2.0.100 peer 10.2.0.1/32 scope global ppp0
       valid_lft forever preferred_lft forever

全てのトラフィックをVPN経由にするために, ルーティングの設定をしてやります.

$ sudo ip route add 157.x.x.x via 192.168.0.1 dev wlp2s0
$ sudo ip route add default via 10.2.0.100

試しにtracerouteしてみると, 確かにVPSを経由しているっぽいことが確認できました.

$ traceroute google.com
traceroute to google.com (172.217.25.78), 30 hops max, 60 byte packets
 1  10.2.0.1 (10.2.0.1)  25.864 ms  25.858 ms  25.887 ms
 2  v157-x-x-x.xxx.static.cnode.jp (157.x.x.x)  26.937 ms  26.912 ms  26.727 ms
 3  157.7.42.33 (157.7.42.33)  31.746 ms  32.370 ms  31.793 ms
 4  unused-133-130-013-017.interq.or.jp (133.130.13.17)  31.812 ms  31.729 ms  31.742 ms
 5  unused-133-130-012-033.interq.or.jp (133.130.12.33)  31.415 ms  31.326 ms  30.830 ms
 6  as15169.ix.jpix.ad.jp (210.171.224.96)  32.713 ms  22.008 ms  24.173 ms
 7  216.239.54.5 (216.239.54.5)  31.506 ms  31.349 ms  31.465 ms
 8  108.170.233.77 (108.170.233.77)  30.116 ms 108.170.233.79 (108.170.233.79)  31.230 ms 108.170.233.77 (108.170.233.77)  30.432 ms
 9  nrt13s50-in-f14.1e100.net (172.217.25.78)  30.481 ms  30.522 ms  33.844 ms

切断する

こんな感じにするようです. 接続の逆をする感じですね.

$ ipsec auto --down L2TP-PSK
$ sudo sh -c 'echo "d vpn-connection" > /var/run/xl2tpd/l2tp-control'
$ sudo systemctl stop openswan xl2tpd

$ sudo ip route del 157.x.x.x via 192.168.0.1 dev wlp2s0

その他

Openswanやxl2tpdが出力するログは, 以下のようなコマンドで確認できます.

$ journalctl -f -u openswan.service -u xl2tpd.service

また, 設定ファイルのdebug xxx等の項目をyesにすると出力される情報が増えるので, 上手く接続できないときは試してみると良いかもしれません.

参考文献