Linux サーバ同士の間で通常の IPsec を接続してみる。IPsec 実装として strongswan と libreswan のどちらを使うかは好みによるが、この項では strongswan を利用する。libreswan、古い openswan を使ったやり方は別記事にて。
I. 前提
環境は以下の通り。
vpn1、vpn2、host1、host2、router1 OSは全てUbuntu 18.04である。
vpn1←→vpn2の間で、strongswanでトンネルモード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 の設定:
通過パケットを転送できるように、カーネルパラメータを変更する。
user@router1:~$ sudo vi /etc/sysctl.conf
net.ipv4.ip_forward=1 #28行目のコメントを外す
上記カーネルパラメータを有効化する。
user@router1:~$ sudo sysctl -p /etc/sysctl.conf
2. vpn1の設定:
strongswan をインストールする。このネットワーク構成ではインターネットからの apt install 不可なので、インターネット接続可能なネットワークに一時的に接続しておく。
user@vpn1:~$ sudo apt install strongswan
インストールが終わったら、ネットワーク構成を検証用の構成に戻す。以下のように netplan 設定ファイルを編集する。
user@vpn1:~$ vi /etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
ens160:
addresses: [198.51.100.100/24]
gateway4: 198.51.100.1
ens192:
addresses: [10.0.1.1/24]
編集したら適用する。
user@vpn1:~$ sudo netplan apply
カーネルパラメータを設定する。
user@vpn1:~$ sudo vi /etc/sysctl.conf
net.ipv4.ip_forward=1 #28行目のコメントを外す
上記カーネルパラメータを有効化する。
user@vpn1:~$ sudo sysctl -p /etc/sysctl.conf
IPsecの事前共有鍵を設定する。
user@vpn1:~$ sudo vi /etc/ipsec.secrets
# 以下の行を追記
: PSK "mypresharedkey"
IPsecの接続設定を記述する。ファイルの最後あたりに追記する形にする。
user@vpn1:~$ sudo vi /etc/ipsec.conf
conn linux-to-linux
authby=secret # 共有鍵認証とする
auto=add # こちら側からはVPN接続を自動開始しない
closeaction=clear
dpdaction=clear
left=198.51.100.100 # 自ホストのIPアドレス
leftsubnet=10.0.1.0/24 # 自分側のプライベートネットワーク
right=203.0.113.100 # 対向側ホストのIPアドレス
rightsubnet=10.0.2.0/24 # 対向側のプライベートネットワーク
デーモンを再起動する。
user@vpn1:~$ sudo systemctl restart strongswan
3. vpn2 の設定:
vpn1 と同様に、strongswan をインストールする。検証構成ではインターネットからの apt install 不可なのも vpn1 と同様である。一時的にインターネット接続可能なネットワークに接続しておく。
user@vpn2:~$ sudo apt install strongswan
インストールが終わったら、ネットワーク構成を検証用の構成に戻す。
user@vpn2:~$ vi /etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
ens160:
addresses: [203.0.113.100/24]
gateway4: 203.0.113.1
ens192:
addresses: [10.0.2.1/24]
編集したら適用する。
user@vpn2:~$ sudo netplan apply
カーネルパラメータを設定する。
user@vpn2:~$ sudo vi /etc/sysctl.conf
net.ipv4.ip_forward=1 #28行目のコメントを外す
上記カーネルパラメータを有効化する。
user@vpn2:~$ sudo sysctl -p /etc/sysctl.conf
IPsec 事前共有鍵を設定する。
user@vpn2:~$ sudo vi /etc/ipsec.secrets
# 以下の行を追記
: PSK "mypresharedkey"
IPsecの設定を記述する。right/leftをvpn1側とは入れ換える。
user@vpn2:~$ sudo vi /etc/ipsec.conf
conn linux-to-linux
authby=secret
auto=start # こちら側からVPN接続を自動開始する
closeaction=restart
dpdaction=restart
left=203.0.113.100
leftsubnet=10.0.2.0/24
right=198.51.100.100
rightsubnet=10.0.1.0/24
デーモンを再起動する。
user@vpn2:~$ sudo systemctl restart strongswan
これで完成。
III. 確認
ipsec statusコマンドで、接続状況を確認できる。
user@vpn1:~$ sudo ipsec status
Security Associations (1 up, 0 connecting):
linux-to-linux[1]: ESTABLISHED 7 minutes ago, 198.51.100.100[198.51.100.100]...203.0.113.100[203.0.113.100]
linux-to-linux{1}: INSTALLED, TUNNEL, reqid 1, ESP SPIs: c90fad30_i c17db9d8_o
linux-to-linux{1}: 10.0.1.0/24 === 10.0.2.0/24
router1でtcpdumpを仕掛けておき、host1からhost2あてにpingを打ってみる。
user@host1:~$ ping 10.0.2.100
user@router1:~$ sudo tcpdump -n -i ens192 not tcp port 22
15:15:46.146244 IP 198.51.100.100 > 203.0.113.100: ESP(spi=0xc17db9d8,seq=0x1d), length 136
15:15:46.146569 IP 203.0.113.100 > 198.51.100.100: ESP(spi=0xc90fad30,seq=0xd), length 136
15:15:47.169558 IP 198.51.100.100 > 203.0.113.100: ESP(spi=0xc17db9d8,seq=0x1e), length 136
15:15:47.170081 IP 203.0.113.100 > 198.51.100.100: ESP(spi=0xc90fad30,seq=0xe), length 136
ESPにカプセル化されてパケットが通過していることが確認できた。
※パケットがトンネルに入るか入らないかは、IP ルーティングではなく xfrm ポリシーによって決まっている。
ip xfrm policy コマンドで確認できる。
user@vpn1:~$ sudo ip xfrm policy
src 10.0.1.0/24 dst 10.0.2.0/24
dir out priority 375423
tmpl src 198.51.100.100 dst 203.0.113.100
proto esp spi 0xc17db9d8 reqid 1 mode tunnel
src 10.0.2.0/24 dst 10.0.1.0/24
dir fwd priority 375423
tmpl src 203.0.113.100 dst 198.51.100.100
proto esp reqid 1 mode tunnel
src 10.0.2.0/24 dst 10.0.1.0/24
dir in priority 375423
tmpl src 203.0.113.100 dst 198.51.100.100
proto esp reqid 1 mode tunnel
(snip)