拠点間 WAN 接続にインターネット VPN を利用する場合、IPsec を使うことがよくある。
IPsec を使ったインターネット VPN の構築では、VPN の両端の機器を同一にすることがほとんどだろう。
筆者の場合だと YAMAHA の RTX シリーズ ルーターを IPsec VPN の両端にすることが多い。
たまには変わったことをということで、IPsec VPN の片側端を Linux に、他方端を YAMAHA RTX シリーズ ルーターにして構築を試みることにした。
Linux のデストリビューションはいつもの如く Ubuntu にして IPsec の実装に Openswan を使う。
RTX シリーズ ルーターは RTX1100 だ。
検証環境
検証した環境は以下の通り。
検証の目標は、Linux と RTX シリーズ ルーターの間に IPsec で VPN セッションを張り、Linux から RTX シリーズ ルーターを越えた先のネットワークにある機器を通信できるようにすることだ。
Linux の通信相手には VPN セッションの片側の端点になる RTX シリーズ ルーターも含み、通信のパケットはすべて VPN セッションを通るようにしたい。
Linux のデストリビューションは ubuntu 12.04 LTS にした。
この時期にしてはちょっと古い気もするが、次の LTS がまだリリースされていないので仕方ない。
Openswan は ubuntu 12.04 LTS の標準パッケージを使うので、そのバージョンは 2.6.37 だ。
Linux 側の LAN インターフェースは eth0 の一枚だけで、そこに 172.26.0.101 を割り当て、サブネットマスクを 24 bit (255.255.255.0) にする。
RTX シリーズ ルーターには RTX1100 を使う。
RTX1200 にしたかったところだが、残念ながら自由に使える機材が手元に無かった。
ファームウェアは Rev.8.03.94 だ。
RTX1100 の LAN1 に 172.26.255.250 を割り当て、LAN2 に 172.26.254.1 を割り当てる。
サブネットマスクはどちらも 24 bit (255.255.255.0) だ。
Linux と RTX1100 の間には YAMAHA RTX810 を置いて、双方のネットワークを分離した。
間に入れた RTX810 の LAN1、LAN2 には 172.26.0.1/24 と 172.26.255.2/24 を割り当てる。
この構成で、IPsec VPN セッションは Linux の eth0 に割り当てた 172.26.0.101 と RTX1100 の LAN1 に割り当てた 172.26.255.250 の間に張ることになる。
そして、IPsec VPN セッションには、Linux の eth0 に割り当てた 172.26.0.101 と RTX1100 の LAN2 とそのポートに繋がる 172.26.254.0/24 のネットワーク セグメントの機器の間の通信を通す。
IPsec のパラメーターは以下のようにした。
| 相互認証の方式 | 共通鍵 (pre-shared-key) |
|---|---|
| 交換モード | メイン モード |
| IKE ハッシュ アルゴリズム | SHA1 |
| IKE 暗号アルゴリズム | AES128 |
| IPsec モード | トンネル モード |
| IPsec ハッシュ アルゴリズム | SHA1 |
| IPsec 暗号アルゴリズム | AES128 |
| DH グループ | Phase 1: グループ 2 (1024 bit) Phase 2: グループ 2 (1024 bit) |
| ID のタイプ | ID_IPV4_ADDR |
| PFS の使用 | 使用しない |
| ISAKMP SA の寿命 | 28800 秒 (8 時間) |
| IPsec SA の寿命 | 28800 秒 (8 時間) |
なお、共通鍵は “atIB926vecGI32yi” にした。
Linux の設定
まずは Linux (Ubuntu 12.04LTS) の LAN インターフェースを設定し、IPsec VPN の対向端点を含むネットワーク 172.26.255.0/24 宛ての経路情報を設定しておく。
さらに、IPsec の実装になる Openswan も
apt-get install openswan コマンドでインストールする。
ubuntu の場合、Openswan をインストールしただけだと、動作環境を確認する sudo ipsec verify コマンドを実行したときに、以下のように FAILED が出てしまう。
|
1 |
sudo ipsec verify |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Checking your system to see if IPsec got installed and started correctly: Version check and ipsec on-path [OK] Linux Openswan U2.6.37/K3.2.0-58-generic (netkey) Checking for IPsec support in kernel [OK] SAref kernel support [N/A] NETKEY: Testing XFRM related proc values [FAILED] Please disable /proc/sys/net/ipv4/conf/*/send_redirects or NETKEY will cause the sending of bogus ICMP redirects! [FAILED] Please disable /proc/sys/net/ipv4/conf/*/accept_redirects or NETKEY will accept bogus ICMP 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] Checking for 'ip' command [OK] Checking /bin/sh is not /bin/dash [WARNING] Checking for 'iptables' command [OK] Opportunistic Encryption Support [DISABLED] |
この sudo ipsec verify コマンドの結果から「FAILED」をなくすために、以下のコマンドを実行してシステムの設定を変更する。
|
1 |
for f in /proc/sys/net/ipv4/conf/*/{send,accept}_redirects; do if [ `cat $f` -eq 1 ]; then echo 0 | sudo tee $f; fi; done |
先の
sudo ipsec verify コマンドの実行結果では /proc/sys/net/ipv4/conf/*/
しかし、メッセージに従って /proc/sys/net/ipv4/conf/*/send_redirects を disable (0) に変更した後に改めて
sudo ipsec verify コマンドを実行すると /proc/sys/net/ipv4/conf/*/
このため、/proc/sys/net/ipv4/conf/*/
これだけではシステムを再起動すると元に戻ってしまうので、以下のようにして /etc/sysctl.d/ ディレクトリに 60-icmp-redirect.conf ファイルを作り、起動時にシステムの設定が変更されるようにする。
|
1 |
(for f in /proc/sys/net/ipv4/conf/{all,default}/{send,accept}_redirects; do echo "${f#/proc/sys/} = 0"; done) | sed -e 's#/#.#g' | sudo tee /etc/sysctl.d/60-icmp-redirect.conf |
この設定をした後に再度
sudo ipsec verify コマンドを実行して「FAILED」がなくなっていることを確認する。
念のために一度再起動をしてから
sudo ipsec verify コマンドを実行してもいいだろう。
|
1 |
sudo ipsec verify |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Checking your system to see if IPsec got installed and started correctly: Version check and ipsec on-path [OK] Linux Openswan U2.6.37/K3.2.0-58-generic (netkey) Checking for IPsec support in kernel [OK] SAref kernel support [N/A] NETKEY: Testing XFRM related proc values [OK] [OK] [OK] Checking that pluto is running [OK] Pluto listening for IKE on udp 500 [OK] Pluto listening for NAT-T on udp 4500 [OK] Checking for 'ip' command [OK] Checking /bin/sh is not /bin/dash [WARNING] Checking for 'iptables' command [OK] Opportunistic Encryption Support [DISABLED] |
次に、Openswan の設定をする。
Openswan に IPsec VPN セッションを追加するために、/etc/ipsec.conf に以下の内容を追記した。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
: conn vpn_session1 auto=add type=tunnel aggrmode=no authby=secret keyexchange=ike ike=aes128-sha1;modp1024 phase2=esp phase2alg=aes128-sha1;modp1024 pfs=no left=172.26.0.101 leftid=172.26.0.101 leftsubnet=172.26.0.101/32 right=172.26.255.250 rightid=172.26.255.250 rightsubnet=172.26.254.0/24 compress=no ikelifetime=8h salifetime=8h : |
相互認証に使う事前共有鍵の値は、/etc/ipsec.secrets ファイルに以下のように記述する。
|
1 2 3 |
: 172.26.0.101 172.26.255.250: PSK "atIB926vecGI32yi" : |
以上で Linux 側の設定ができた。
最後に
sudo service ipsec reload コマンド (または
sudo ipsec reload コマンド) を実行して、追記した設定を読み込ませておく。
/etc/ipsec.conf ファイルに追記した vpn_session1 セクションは
auto=add であるため、対向から接続してくるか、
sudo ipsec auto --up vpn_session1 コマンドで接続を開始しなければ、IPsec VPN セッションは動作しない。
RTX1100 の設定
RTX1100 は以下のように設定した (必要な部分だけを抜粋)。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
: ip route 172.26.0.0/24 gateway 172.26.255.2 ip route 172.26.0.101 gateway tunnel 1 filter 999 ip lan1 address 172.26.255.2/24 ip lan2 address 172.26.254.1/24 tunnel select 1 tunnel encapsulation ipsec ipsec tunnel 1001 ipsec sa policy 1001 1 esp aes-cbc sha-hmac ipsec ike encryption 1 aes-cbc ipsec ike group 1 modp1024 ipsec ike hash 1 sha ipsec ike local address 1 172.26.255.250 ipsec ike local id 1 172.26.255.250 ipsec ike pre-shared-key 1 text atIB926vecGI32yi ipsec ike remote address 1 172.26.0.101 ipsec ike remote id 1 172.26.0.101 ipsec auto refresh 1 off tunnel enable 1 ip filter 999 pass 172.26.254.0/24 * * * * ipsec auto refresh on : |
この RTX1100 の設定では、IPsec VPN に使う IKE の鍵交換を起動しないよう ipsec auto refresh 1 off にしてあるため、RTX1100 から IPsec VPN セッションを接続し始めることはない。
Linux 側から IPsec VPN を接続
まずは Linux 側から IPsec VPN を接続してみる。
Linux で IPsec VPN を接続するには
sudo ipsec auto --up vpn_session1 コマンドを使う。
--up オプションに続く引数は /etc/ipsec.conf ファイルに追記した conn に続く文字列だ。
このコマンドを実行すると以下のようなメッセージが出力され、IPsec VPN セッションが確立する。
|
1 |
sudo ipsec auto --up vpn_session1 |
|
1 2 3 4 5 6 7 |
104 "vpn_session1" #1: STATE_MAIN_I1: initiate 003 "vpn_session1" #1: received Vendor ID payload [Dead Peer Detection] 106 "vpn_session1" #1: STATE_MAIN_I2: sent MI2, expecting MR2 108 "vpn_session1" #1: STATE_MAIN_I3: sent MI3, expecting MR3 004 "vpn_session1" #1: STATE_MAIN_I4: ISAKMP SA established {auth=OAKLEY_PRESHARED_KEY cipher=aes_128 prf=oakley_sha group=modp1024} 117 "vpn_session1" #2: STATE_QUICK_I1: initiate 004 "vpn_session1" #2: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP=>0x50457104 <0xed5b5d29 xfrm=AES_128-HMAC_SHA1 NATOA=none NATD=none DPD=none |
念のために、 traceroute -n 172.26.254.1 などのコマンドを実行して、想定通りの結果が返ってくるかを確認する。
|
1 |
traceroute -n 172.26.254.1 |
|
1 2 |
traceroute to 172.26.254.1 (172.26.254.1), 30 hops max, 60 byte packets 1 172.26.254.1 (172.26.254.1) 4.398 ms 5.311 ms 5.759 ms |
|
1 |
traceroute -n 172.26.255.250 |
|
1 2 3 |
traceroute to 172.26.255.250 (172.26.255.250), 30 hops max, 60 byte packets 1 172.26.0.1 0.634 ms 0.929 ms 0.913 ms 2 172.26.255.250 3.389 ms 3.625 ms 3.934 ms |
RTX100 からも同様に、 traceroute 172.26.0.101 noresolv -sa 172.26.254.1 などのコマンドを実行して、想定通りの結果が返ってくるかを確認する。
|
1 |
traceroute 172.26.0.101 noresolv -sa 172.26.254.1 |
|
1 |
1 172.26.0.101 1.861 ms 1.769 ms 1.810 ms |
|
1 |
traceroute 172.26.0.101 noresolv |
|
1 2 |
1 172.26.255.2 1.142 ms 1.321 ms 1.023 ms 2 172.26.0.101 1.585 ms 1.404 ms 1.334 ms |
このとき RTX1100 で show ipsec sa コマンドを実行すると、きちんと SA が登録されていることが確認できる。
|
1 |
show ipsec sa |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
sa sgw connection dir life[s] remote-id -------------------------------------------------------------------------- 1 1 isakmp - 3594 172.26.0.101 2 1 tun[001]esp send 28794 172.26.0.101 3 1 tun[001]esp recv 28794 172.26.0.101 SA[1] 寿命: 3594秒 自分側の識別子: 172.26.255.250 相手側の識別子: 172.26.0.101 プロトコル: IKE SPI: 07 eb 08 36 b4 6e 4d b4 8e b3 f7 3c e1 a4 e0 cc 鍵 : ** ** ** ** ** (confidential) ** ** ** ** ** ---------------------------------------------------- SA[2] 寿命: 28794秒 自分側の識別子: 172.26.255.250 相手側の識別子: 172.26.0.101 送受信方向: 送信 プロトコル: ESP (モード: tunnel) アルゴリズム: AES-CBC (認証: HMAC-SHA) SPI: 0a 60 5a 40 鍵 : ** ** ** ** ** (confidential) ** ** ** ** ** ---------------------------------------------------- SA[3] 寿命: 28794秒 自分側の識別子: 172.26.255.250 相手側の識別子: 172.26.0.101 送受信方向: 受信 プロトコル: ESP (モード: tunnel) アルゴリズム: AES-CBC (認証: HMAC-SHA) SPI: 9e b1 91 be 鍵 : ** ** ** ** ** (confidential) ** ** ** ** ** ---------------------------------------------------- |
IPsec VPN セッションを切断するには
sudo ipsec auto --down vpn_session1 コマンドを実行する。
--down オプションに続く引数には、
--up オプションと同様に、/etc/ipsec.conf ファイルに追記した conn に続く文字列を指定する。
このコマンドは実行しても何のメッセージも表示せずに、IPsec VPN セッションを切断する。
sudo ipsec auto --down vpn_session1 コマンドを実行して IPsec VPN を切断してから、RTX1100 で show ipsec sa コマンドを実行すると、悲しことに受信側の ESP トンネル が削除されずに残っている。
|
1 |
show ipsec sa |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
sa sgw connection dir life[s] remote-id -------------------------------------------------------------------------- 3 1 tun[001]esp recv 28678 172.26.0.101 SA[3] 寿命: 28678秒 自分側の識別子: 172.26.255.250 相手側の識別子: 172.26.0.101 送受信方向: 受信 プロトコル: ESP (モード: tunnel) アルゴリズム: AES-CBC (認証: HMAC-SHA) SPI: 9e b1 91 be 鍵 : ** ** ** ** ** (confidential) ** ** ** ** ** ---------------------------------------------------- |
keepalive 辺りのパラメーターを調整すれば上手く処理できるだとうとは思うが、まだそこまでは検証していない。
この状態で
sudo ipsec auto --up vpn_session1 コマンドすると、問題なく再接続できるので、IPsec VPN を常時接続で運用する分にはとりあえず問題にはならないだろう。
RTX 側から IPsec VPN を接続
Linux 側から接続した IPsec VPN を切断して、こんどは RTX 側から IPsec VPN を接続してみる。
RTX1100 で IPsec VPN を接続するには、IPsec VPN で使う IKE の鍵交換が始動するように、
ipsec auto refresh 1 on を設定する。
これを設定するとすぐに IPsec VPN セッションを確立し始めようとする。
しかし、以下のようなログが記録されるばかりで、いつまで経っても IPsec VPN セッションが確立しない。
|
1 |
show log |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
[IKE] generate transform payload [IKE] generate ISAKMP header [IKE] send IKE message [IKE] receive IKE message [IKE] process ISAKMP header [IKE] main mode initiator 1 [IKE] process sa payload [IKE] process proposal payload [IKE] process transform payload [IKE] encryption algorithm : AES-CBC [IKE] hash algorithm : SHA-1 [IKE] authentication : pre-shared key [IKE] group : MODP 1024bit [IKE] process vid payload same message repeated 1 times [IKE] generate ke payload [IKE] generate nonce payload [IKE] generate ISAKMP header [IKE] send IKE message [IKE] ... omitted [IKE] receive IKE message [IKE] ... omitted [IKE] process ISAKMP header [IKE] main mode initiator 2 [IKE] process ke payload [IKE] process nonce payload [IKE] calculate Diffie-Hellman value [IKE] generate ISAKMP key material [IKE] pre-shared key [IKE] iNonce [IKE] rNonce [IKE] SKEYID [IKE] Diffie-Hellman value [IKE] CKY-I [IKE] CKY-R [IKE] SKEYID_d [IKE] SKEYID_a [IKE] SKEYID_e [IKE] set main mode IV [IKE] generate id payload [IKE] generate hash payload [IKE] generate ISAKMP header [IKE] change IV [IKE] send IKE message [IKE] receive IKE message [IKE] process ISAKMP header [IKE] decrypted payload [IKE] main mode initiator 3 [IKE] process id payload [IKE] ID payload : type 1, protocol 0, port 0 [IKE] process hash payload [IKE] change IV [IKE] add ISAKMP SA[1] (gateway[1]) [IKE] activate ISAKMP socket[1] [IKE] initiate IPsec phase to 172.26.0.101 [IKE] add IPsec context [313] 6dc5ff46e2860986 00443480 [IKE] quick mode initiator 0 [IKE] set quick/info mode IV [IKE] generate SA payload [IKE] generate proposal payload [IKE] generate transform payload [IKE] generate nonce payload [IKE] generate id payload [IKE] iID [IKE] generate id payload [IKE] rID [IKE] generate phase2 hash [IKE] SKEYID_a [IKE] message [IKE] ... omitted [IKE] hash [IKE] generate hash payload [IKE] generate ISAKMP header [IKE] change IV [IKE] send IKE message [IKE] receive IKE message [IKE] process ISAKMP header [IKE] set quick/info mode IV [IKE] decrypted payload [IKE] info mode responder 1 [IKE] process hash payload [IKE] process notification payload [IKE] receive notification from 172.26.0.101 [IKE] no SPI is specified. [IKE] invalid ID information : no message [IKE] [313] retransmit to 172.26.0.101 (count = 9) [IKE] send IKE message [IKE] ... omitted [IKE] receive IKE message [IKE] process ISAKMP header [IKE] set quick/info mode IV [IKE] decrypted payload [IKE] info mode responder 1 [IKE] process hash payload [IKE] process notification payload [IKE] receive notification from 172.26.0.101 [IKE] no SPI is specified. [IKE] invalid ID information : no message [IKE] [313] retransmission timeout [IKE] inactivate context [313] 6dc5ff46e2860986 00443480 [IKE] delete IPsec context [313] 6dc5ff46e2860986 00443480 : |
上記ログを取得する際は、
ipsec ike log 1 key-info message-info payload-info と
syslog debug on を RTX1100 に設定した。
ログの最後は、86 行目から 101 行目までの 16 行を、count の値が 0 になるまで繰り返しす。
上記ログの日付は省略した。
さらに、バイナリ データの行も省略した。
このログを見る限りは「invalid ID information」が原因を指し示していると思われる。
RTX1100 から IPsec VPN セッションを接続しようとしたときの、Linux 側のログは以下の通りだ。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
pluto[16739]: "vpn" #1: responding to Main Mode pluto[16739]: "vpn" #1: transition from state STATE_MAIN_R0 to state STATE_MAIN_R1 pluto[16739]: "vpn" #1: STATE_MAIN_R1: sent MR1, expecting MI2 pluto[16739]: "vpn" #1: transition from state STATE_MAIN_R1 to state STATE_MAIN_R2 pluto[16739]: "vpn" #1: STATE_MAIN_R2: sent MR2, expecting MI3 pluto[16739]: "vpn" #1: Main mode peer ID is ID_IPV4_ADDR: '172.26.255.250' pluto[16739]: "vpn" #1: transition from state STATE_MAIN_R2 to state STATE_MAIN_R3 pluto[16739]: "vpn" #1: STATE_MAIN_R3: sent MR3, ISAKMP SA established {auth=OAKLEY_PRESHARED_KEY cipher=aes_128 prf=oakley_sha group=modp1024} pluto[16739]: "vpn" #1: the peer proposed: 172.26.0.101/32:0/0 -> 172.26.255.250/32:0/0 pluto[16739]: "vpn" #1: cannot respond to IPsec SA request because no connection is known for 172.26.0.101<172.26.0.101>[+S=C]...172.26.255.250<172.26.255.250>[+S=C] pluto[16739]: "vpn" #1: sending encrypted notification INVALID_ID_INFORMATION to 172.26.255.250:500 : |
ログの最後は、9 行目から 11 行目までの 3 行を、RTX1100 のログの繰り返しと同期して繰り返す。
上記ログの日付は省略した。
IPsec VPN セッションが確立しないのは、invalid ID information (Linux 側は INVALID_ID_INFOMATION) が原因と推察できるが、解決方法は不明のままだ。
加えて、Linux 側からであれば接続できる理由も見当が付いていない。