Linux サーバ同士の間で libreswan を使って IPsec を接続してみる。strongswan を使ったやり方は別記事にて。
I. 前提
環境は以下の通り。
vpn1、vpn2、host1、host2、router1 OSは全てUbuntu 18.04である。
vpn1←→vpn2の間で、libreswanでトンネルモード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の設定:
libreswan をインストールする。このネットワーク構成ではインターネットからの apt install 不可なので、インターネット接続可能なネットワークに一時的に接続しておく。user@vpn1:~$ sudo apt install libreswan
インストールが終わったら、ネットワーク構成を検証用の構成に戻す。以下のように 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.d/linux-to-linux.secrets
: PSK "mypresharedkey"
一般ユーザで読めないようパーミッションを変えておく。user@vpn1:~$ sudo chmod 600 /etc/ipsec.d/linux-to-linux.secrets
IPsecの接続設定を記述する。user@vpn1:~$ sudo vi /etc/ipsec.d/linux-to-linux.conf
conn linux-to-linux authby=secret # 共有鍵認証とする auto=add # こちら側からはVPN接続を自動開始しない 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 enable ipsec
user@vpn1:~$ sudo systemctl start ipsec
3. vpn2 の設定:
vpn1 と同様に、libreswan をインストールする。検証構成ではインターネットからの apt install 不可なのも vpn1 と同様である。一時的にインターネット接続可能なネットワークに接続しておく。user@vpn2:~$ sudo apt install libreswan
インストールが終わったら、ネットワーク構成を検証用の構成に戻す。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.d/linux-to-linux.secrets
: PSK "mypresharedkey"
一般ユーザで読めないようパーミッションを変えておく。user@vpn2:~$ sudo chmod 600 /etc/ipsec.d/linux-to-linux.secrets
IPsec の設定を記述する。right/left を vpn1 側とは入れ換える。user@vpn2:~$ sudo vi /etc/ipsec.d/linux-to-linux.conf
conn linux-to-linux authby=secret auto=start # こちら側から VPN 接続を自動開始する 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 enable ipsec
user@vpn2:~$ sudo systemctl start ipsec
これで完成。
III. 確認
ipsec status コマンドで、接続状況を確認できる。
user@vpn1:~$ sudo ipsec status
(snip)
000 #3: "linux-to-linux":500 STATE_MAIN_R3 (sent MR3, ISAKMP SA established); EVENT_SA_REPLACE in 3326s; newest ISAKMP; lastdpd=-1s(seq in:0 out:0); idle; import:not set
000 #4: "linux-to-linux":500 STATE_QUICK_R2 (IPsec SA established); EVENT_SA_REPLACE in 28526s; newest IPSEC; eroute owner; isakmp#3; idle; import:not set
000 #4: "linux-to-linux" esp.a61da06f@203.0.113.100 esp.53ec235d@198.51.100.100 ref=0 refhim=0 Traffic: ESPin=0B ESPout=0B! ESPmax=4194303B
router1 で tcpdump を仕掛けておき、host1 から host2 あてに ping を打ってみる。user@host1:~$ ping 10.0.2.100
user@router1:~$ sudo tcpdump -n -i ens192 not tcp port 22
15:27:34.103230 IP 198.51.100.100 > 203.0.113.100: ESP(spi=0xa61da06f,seq=0x1), length 132
15:27:34.103475 IP 203.0.113.100 > 198.51.100.100: ESP(spi=0x53ec235d,seq=0x1), length 132
15:27:35.131026 IP 198.51.100.100 > 203.0.113.100: ESP(spi=0xa61da06f,seq=0x2), length 132
15:27:35.131271 IP 203.0.113.100 > 198.51.100.100: ESP(spi=0x53ec235d,seq=0x2), length 132
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 2344 tmpl src 198.51.100.100 dst 203.0.113.100 proto esp reqid 16389 mode tunnel src 10.0.2.0/24 dst 10.0.1.0/24 dir fwd priority 2344 tmpl src 203.0.113.100 dst 198.51.100.100 proto esp reqid 16389 mode tunnel src 10.0.2.0/24 dst 10.0.1.0/24 dir in priority 2344 tmpl src 203.0.113.100 dst 198.51.100.100 proto esp reqid 16389 mode tunnel (snip)