Linux サーバ間 IPsec 接続 (openswan)

※本記事は内容が古くなっています。Ubuntu 14.04 と openswan を使った記事になります。可能ならば最新の OS と strongswan または libreswan を利用してください。新しい記事はこちら

Linuxサーバ同士の間で通常のIPsecを接続したことが無かったので、検証してみた。

I. 前提

環境は以下の通り。
01

vpn1、vpn2、host1、host2、router1 OSは全てUbuntu 14.04である。

vpn1←→vpn2の間で、openswanでトンネルモードIPsec接続をする。10.0.1.0/24 から 10.0.2.0/24 へのパケット、またその逆方向のパケットはトンネルへ入るようにする。つまり、例えばhost1からhost2へpingを打つとトンネルを通ることになる。10.0.1.0/24や10.0.2.0/24へのスタティックルートはrouter1に追加しないようにしておくので、VPNトンネルが出来なければhost1からhost2へのpingは到達できない。

vpn2側に自動接続開始の設定を入れることで、VPNトンネルを自動的に張ることにする。

II. 設定

以下、設定を記述する(IPアドレス設定など基本的なところは省略)

1. router1 の設定:

router1:~$ sudo vi /etc/sysctl.conf
net.ipv4.ip_forward=1  #28行目のコメントを外す
router1:~$ sudo sysctl -p /etc/sysctl.conf

2. vpn1の設定:

デフォルトルートは router1 に向けておく。向いていなかったら /etc/network/interfaces などを編集して変更する。

vpn1$ ip route
default via 1.2.3.1 dev eth1
1.2.3.0/24 dev eth1  proto kernel  scope link  src 1.2.3.4
10.0.1.0/24 dev eth0  proto kernel  scope link  src 10.0.1.1

OpenSWANをインストールする。

vpn1:~$ sudo apt-get install openswan

カーネルパラメータを設定する。

vpn1:~$ sudo vi /etc/sysctl.conf
net.ipv4.ip_forward=1  #28行目のコメントを外す
# 以下、追記する
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.eth0.accept_redirects=0
net.ipv4.conf.eth0.send_redirects=0
net.ipv4.conf.lo.accept_redirects=0
net.ipv4.conf.lo.send_redirects=0
net.ipv6.conf.eth0.accept_redirects=0
net.ipv6.conf.lo.accept_redirects=0
vpn1:~$ sudo sysctl -p /etc/sysctl.conf

IPsecの事前共有鍵を設定する。

vpn1:~$ sudo vi /etc/ipsec.secrets
# 以下の行を追記
: PSK "passwordstring"

IPsecの接続設定を記述する。

vpn1:~$ sudo vi /etc/ipsec.conf
config setup	# protostack以外はデフォルトのまま
	dumpdir=/var/run/pluto/
	nat_traversal=yes
	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=off
	protostack=netkey	# auto から変更
# 以下、追記
conn linux-to-linux
	authby=secret	# 共有鍵認証とする
	left=1.2.3.4	# 自ホストのIPアドレス
	leftsubnet=10.0.1.0/24	# 自分側のプライベートネットワーク
	right=5.6.7.8	# 対向側ホストのIPアドレス
	rightsubnet=10.0.2.0/24	# 対向側のプライベートネットワーク
	auto=add	# こちら側からはVPN接続を自動開始しない

デーモンを再起動する。

vpn1:~$ sudo service ipsec restart

3. vpn2 の設定:

デフォルトルートは router1 に向けておく。向いていなかったら /etc/network/interfaces などを編集して変更する。

vpn1$ ip route
default via 5.6.7.1 dev eth1
5.6.7.0/24 dev eth1  proto kernel  scope link  src 5.6.7.8
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.1

OpenSWANをインストールする。

vpn1:~$ sudo apt-get install openswan

カーネルパラメータを変更する。

vpn2:~$ sudo vi /etc/sysctl.conf	# vpn1と同じ記述をする。
vpn2:~$ sudo sysctl -p /etc/sysctl.conf

IPsec事前共有鍵を設定する。

vpn2:~$ sudo vi /etc/ipsec.secrets	# これもvpn1と同じ記述をする。

IPsecの設定を記述する。

vpn2:~$ sudo vi /etc/ipsec.conf
config setup	# protostack以外はデフォルトのまま
	dumpdir=/var/run/pluto/
	nat_traversal=yes
	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=off
	protostack=netkey	# auto から変更
# 以下、追記する。right/leftをvpn1側とは入れ換える。
conn linux-to-linux
	authby=secret
	left=5.6.7.8
	leftsubnet=10.0.2.0/24
	right=1.2.3.4
	rightsubnet=10.0.1.0/24
	auto=start	# こちら側からVPN接続を自動開始する

デーモンを再起動する。

vpn1:~$ sudo service ipsec restart

これで完成。

III. 確認

ipsec verify を実行すると FAILED が出るが、気にしなくてよい。

vpn1:~$ sudo ipsec verify
Two or more interfaces found, checking IP forwarding        [FAILED]

router1でtcpdumpを仕掛けておき、host1からhost2あてにpingを打ってみる。

host1:~$ ping 10.0.2.100
router1:~$ sudo tcpdump -n -i eth1 not tcp port 22
10:49:22.294046 IP 1.2.3.4 > 5.6.7.8: ESP(spi=0x8f3ac7ea,seq=0x1), length 132
10:49:22.294543 IP 5.6.7.8 > 1.2.3.4: ESP(spi=0x0293d289,seq=0x1), length 132
10:49:23.295411 IP 1.2.3.4 > 5.6.7.8: ESP(spi=0x8f3ac7ea,seq=0x2), length 132
10:49:23.295890 IP 5.6.7.8 > 1.2.3.4: ESP(spi=0x0293d289,seq=0x2), length 132

ESPにカプセル化されてパケットが通過していることが確認できた。

※パケットがトンネルに入るか入らないかは、IPルーティングではなくxfrmポリシーによって決まっている。
ip xfrm state、ip xfrm policy コマンドで確認できる。

vpn1:~$ sudo ip xfrm state
src 1.2.3.4 dst 5.6.7.8
	proto esp spi 0x8f3ac7ea reqid 16385 mode tunnel
	replay-window 32 flag af-unspec
	auth-trunc hmac(sha1) 0xdbc2f99d8243e36fc8920c790c0b6b9d85c84a48 96
	enc cbc(aes) 0x506786cc1fbf21c272ddeab0c4deb739
src 5.6.7.8 dst 1.2.3.4
	proto esp spi 0x0293d289 reqid 16385 mode tunnel
	replay-window 32 flag af-unspec
	auth-trunc hmac(sha1) 0x10110db5180fb3773d47cb538b29ae9371137ebd 96
	enc cbc(aes) 0xb29c28de3d0e40111f6f9720fddf117f
vpn1:~$ sudo ip xfrm policy
src 10.0.1.0/24 dst 10.0.2.0/24 
	dir out priority 2344 
	tmpl src 1.2.3.4 dst 5.6.7.8
		proto esp reqid 16385 mode tunnel
src 10.0.2.0/24 dst 10.0.1.0/24 
	dir fwd priority 2344 
	tmpl src 5.6.7.8 dst 1.2.3.4
		proto esp reqid 16385 mode tunnel
src 10.0.2.0/24 dst 10.0.1.0/24 
	dir in priority 2344 
	tmpl src 5.6.7.8 dst 1.2.3.4
		proto esp reqid 16385 mode tunnel
(snip)