Cato クラウドに Linux サーバから IPsec 接続してみた

本記事は 夏休みクラウド自由研究 8/9付の記事です

はじめに

Cato クラウドのネットワークに AWS や Azure などのパブリッククラウドを接続する場合、vSocket という仮想マシンイメージ形式で提供されるアプライアンスを利用するのが一般的ですが、IPsec やインターコネクト (AWS Direct Connect など) で接続することもできます。

vSocket は機能面や管理の手間という点で断然メリットが多いものの、アプライアンスの中身のソフトウェアがブラックボックスであるという点は、エンジニアとして少しだけ不安な要素でもあります。やはり通信は標準化されたプロトコルで行い、実際に見える形にして安心したいという思いがあります。

そこで、アプライアンスやルータ機器などを用いず、Linux サーバから IPsec で Cato クラウドに接続してみたいと思います。今回のブログは「夏休みクラウド自由研究」の一環ですので、自身の探求心に従い自由気ままにやっていきましょう。

今回試した構成

今回はシンプルに次のようなネットワーク構成で試しました。

Linux サーバはオフィスやパブリッククラウド上のネットワークの中にある想定で、次の前提・想定を置いています。

  1. Linux サーバからインターネットに任意にアクセスできる
  2. Linux サーバは NAT (IPマスカレード) を行うルータの内側に存在し、グローバルIPアドレスを持たない
  3. ゲートウェイのグローバルIPアドレスは固定ではない

要するにこの Linux サーバは一般的なネットワーク環境にある1端末という位置づけです。このサーバと Cato PoP との間で IPsec 接続を試しました。

実際は AWS 環境上で環境を構築しており、Linux サーバをプライベートサブネットに配置し、NAT Gateway 経由でインターネットにアクセスするような構成としています。

Cato 側の設定

まずは CMA 上で IPsec 接続用の検証用 Site を作成します。

IPsec 接続に関する設計ポイントや具体的な設定方法は、弊社の別記事Cato クラウドのドキュメント に詳しく記載されています。

【Catoクラウド】YAMAHAルータでIPsec接続
YAMAHAルータをCatoへIPsec接続する際の、Config例や注意点をご紹介します。

今回は次の設定で Site を作成しました。

  • Site Name : Linux IPsec Test
  • Site Type : Branch
  • Connection Type : IPsec IKEv2
  • Country : Japan
  • Timezone : Tokyo
  • City : Tokyo
  • License Type, License : 適切なもの
  • Native Range : 192.168.200.0/24 (Linux サーバの LAN のレンジ)

作成した Site の IPsec の設定は次のようにしました。

  • Connection Mode : Responder Only
  • Authentication Identifier : FQDN
  • Primary
    • Destination Type : FQDN
    • Cato FQDN : 自動で割り当てられる
    • PoP Location : 空欄
    • Public Site Identifier : 自動で割り当てられる
    • Private IPs : Cato, Site ともに空欄 (今回はBGPを利用しないため)
    • Last-mile Bandwidth : License と同じ帯域幅
    • Primary PSK : 事前共有鍵 (64文字以下の任意の英数字)
  • Secondary : 設定しない
  • Init Message Parameters : 変更しない (Responder Mode では設定できない)
  • Auth Message Parameters : 変更しない (全てデフォルトのまま)
  • Routing : 設定しない

上記設定のポイントは3か所あります。

今回のネットワーク構成では NAT のせいで Cato PoP から Linux サーバに対して IPsec 接続を開始できないため、Connection Mode を “Responder Only” とすることで Cato PoP から IPsec 接続を行わないようにしています。

Destination Type についてですが、”IPv4″ にすると IP Allocation 機能で確保した特定 PoP に紐づくIPアドレスを指定する必要があり、その PoP で大きな障害が起きてサービスダウンが発生すると IPsec 接続が行えなくなってしまいます。そうなっても困らないようにするために、通常は Secondary も指定して2本目の IPsec 接続を行って冗長化する必要があります。しかし、Destination Type を “FQDN” を選択して PoP Location を空欄にしておけば、PoP でサービスダウンが発生しても別の正常な PoP に接続するよう名前解決が自動で切り替わり、数分間の通信断を許容できるのであれば IPsec 接続を冗長化しなくても済むという特徴があるので、今回採用してみました。

Authentication Identifier は “IPv4″ (プライベートIPアドレスを指定する) としても問題はないのですが、Cato 側にピアのIPアドレスを意識させたくなかったため、”FQDN” としました。

Linux サーバの設定

OS・ネットワークの確認

今回は Linux サーバのOSとして、Red Hat Enterprise Linux 9 と互換性の高い AlmaLinux OS 9 を採用しました。

$ cat /etc/redhat-release
AlmaLinux release 9.4 (Seafoam Ocelot)

$ uname -a
Linux alma 5.14.0-427.26.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Jul 17 15:51:13 EDT 2024 x86_64 x86_64 x86_64 GNU/Linux

ネットワークインターフェースやルートテーブルなど、関連する設定は次のようになっていました。

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 06:0c:19:8a:6a:b5 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 192.168.200.132/28 brd 192.168.200.143 scope global dynamic noprefixroute eth0
       valid_lft 2102sec preferred_lft 2102sec
    inet6 fe80::40c:19ff:fe8a:6ab5/64 scope link
       valid_lft forever preferred_lft forever

$ ip route
default via 192.168.200.129 dev eth0 proto dhcp src 192.168.200.132 metric 100
192.168.200.128/28 dev eth0 proto kernel scope link src 192.168.200.132 metric 100

$ ip rule
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

ネットワーク的にはインターフェースを1つだけ持つシンプルなマシンです。

Libreswan のインストール・設定

Linux サーバで IPsec 接続を行う場合、OSS ですと Libreswan, strongSwan, Openswan といったソフトウェアを使うことになりますが、今回は RHEL で採用されている Libreswan を使っていきます。

インストールは libreswan パッケージを dnf でインストールするだけです。

$ sudo dnf install libreswan

$ ipsec --version
Libreswan 4.12

次に Libreswan の設定ですが、ipsec.conf(5)ipsec.secrets(5) のマニュアルを参考に次の内容で作成し、/etc/ipsec.d/ ディレクトリに配置しました。

$ sudo vim /etc/ipsec.d/cato.conf
$ sudo cat /etc/ipsec.d/cato.conf
conn cato
        left=192.168.200.132
        leftid=@XXXXXXXXXX.YYYY.catonetworks.com
        leftnexthop=192.168.200.129
        right=ZZZZZZZZZZ.ipsec.catonetworks.net
        rightid=@ZZZZZZZZZZ.ipsec.catonetworks.net
        leftsubnet=0.0.0.0/0
        rightsubnet=0.0.0.0/0
        ipsec-interface=yes
        encapsulation=yes
        authby=secret
        ikev2=insist
        auto=start


$ sudo vim /etc/ipsec.d/cato.secrets
$ sudo cat /etc/ipsec.d/cato.secrets
@XXXXXXXXXX.YYYY.catonetworks.com @ZZZZZZZZZZ.ipsec.catonetworks.net : PSK "事前共有鍵"

$ sudo chmod 600 /etc/ipsec.d/cato.secrets

left は Linux サーバ側、right は Cato PoP 側を表す設定項目です。また、”XXXXXXXXXX.YYYY.catonetworks.com” と “ZZZZZZZZZZ.ipsec.catonetworks.net” は、Cato 側の IPsec の設定で自動で割り当てられた Public Site Identifier および Cato FQDN の値です。

left や leftnexthop には Linux サーバのプライベートIPアドレスやゲートウェイのIPアドレスを指定しています。

今回は IPsec 接続の認証IDとして FQDN を利用しますので、FQDN の先頭に “@” を付けた文字列を leftid や rightid に指定する必要がありました。

IPsec にはポリシーベースとルートベースの2種類がありますが、ルートベースのほうが扱いやすいため、そうするため leftsubnet, rightsubnet, ipsec-interface を上記のように指定しています。また、Linux サーバは NAT (IPマスカレード) を行うルータの内側に存在するので、NAT トラバーサルを有効にするため “encapsulation=yes” としています。

今回の検証において、ちゃんと動作する Libreswan の設定を作るのが一番大変でした…。

IPsec 接続

Libreswan の設定を配置したら、IPsec 接続をして確認していきます。

その前に、Cato PoP の接続先の FQDN を名前解決してみると次のような結果となりました。

$ dig +noall +answer A ZZZZZZZZZZ.ipsec.catonetworks.net
ZZZZZZZZZZ.ipsec.catonetworks.net. 30 IN A      150.195.218.109

150.195.218.109 というIPアドレスは東京にあるいずれかの PoP のものですね。Socket や Cato Client による PoP 接続とは異なり、いくつかの接続先の候補が提示されて近いものを選択するという仕組みではないようです。Site の設定で場所を東京としていましたので、その設定をもとに近い PoP が自動で選択されたものと思います。

DNS レコードの TTL は30秒となっており、IPsec の接続先が切り替わったときに素早く反映されるようになっていますね。

それでは IPsec 接続を開始してみます。systemctl で ipsec サービスを起動すれば接続が行われます。

$ sudo systemctl start ipsec

無事にうまく接続されれば、ipsec1 というインターフェースが作成されているはずです。

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 06:0c:19:8a:6a:b5 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 192.168.200.132/28 brd 192.168.200.143 scope global dynamic noprefixroute eth0
       valid_lft 2987sec preferred_lft 2987sec
    inet6 fe80::40c:19ff:fe8a:6ab5/64 scope link
       valid_lft forever preferred_lft forever
3: ip_vti0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
5: ipsec1@eth0: <NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none
    inet6 fe80::4e73:f3e6:521e:1678/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

journalctl で接続時のログも見てみましたが、Child SA も確立して問題なく接続できているようです。

Jul 29 17:19:34 alma pluto[1480]: "cato": added IKEv2 connection
Jul 29 17:19:34 alma pluto[1480]: listening for IKE messages
Jul 29 17:19:34 alma pluto[1480]: Kernel supports NIC esp-hw-offload
Jul 29 17:19:34 alma pluto[1480]: adding UDP interface eth0 192.168.200.132:500
Jul 29 17:19:34 alma pluto[1480]: adding UDP interface eth0 192.168.200.132:4500
Jul 29 17:19:34 alma pluto[1480]: adding UDP interface lo 127.0.0.1:500
Jul 29 17:19:34 alma pluto[1480]: adding UDP interface lo 127.0.0.1:4500
Jul 29 17:19:34 alma pluto[1480]: adding UDP interface lo [::1]:500
Jul 29 17:19:34 alma pluto[1480]: adding UDP interface lo [::1]:4500
Jul 29 17:19:34 alma pluto[1480]: loading secrets from "/etc/ipsec.secrets"
Jul 29 17:19:34 alma pluto[1480]: loading secrets from "/etc/ipsec.d/cato.secrets"
Jul 29 17:19:34 alma pluto[1480]: "cato" #1: initiating IKEv2 connection
Jul 29 17:19:34 alma pluto[1480]: "cato" #1: sent IKE_SA_INIT request to 150.195.218.109:500
Jul 29 17:19:34 alma pluto[1480]: "cato" #1: received anti-DDOS COOKIE response, resending IKE_SA_INIT request with COOKIE payload
Jul 29 17:19:34 alma pluto[1480]: "cato" #1: sent IKE_SA_INIT request to 150.195.218.109:500
Jul 29 17:19:34 alma pluto[1480]: "cato" #1: sent IKE_AUTH request {cipher=AES_GCM_16_256 integ=n/a prf=HMAC_SHA2_256 group=DH19}
Jul 29 17:19:34 alma pluto[1480]: "cato" #1: initiator established IKE SA; authenticated peer using authby=secret and ID_FQDN '@ZZZZZZZZZZ.ipsec.catonetworks.net'
Jul 29 17:19:34 alma pluto[1480]: "cato" #2: route-client output: leftsubnet == rightsubnet = 0.0.0.0/0 cannot add route
Jul 29 17:19:34 alma pluto[1480]: "cato" #2: initiator established Child SA using #1; IPsec tunnel [0.0.0.0-255.255.255.255:0-65535 0] -> [0.0.0.0-255.255.255.255:0-65535 0] {ESPinUDP=>0x42a73e98 <0x32b41687 xfrm=AES_GCM_16_256-NONE NATD=150.195.218.109:4500 DPD=passive}
Jul 29 17:19:34 alma pluto[1480]: netlink_expire got message with length 116 < 232 bytes; ignore message
Jul 29 17:19:34 alma pluto[1480]: netlink_expire got message with length 116 < 232 bytes; ignore message
Jul 29 17:19:34 alma pluto[1480]: netlink_expire got message with length 116 < 232 bytes; ignore message
Jul 29 17:19:34 alma pluto[1480]: netlink_expire got message with length 60 < 232 bytes; ignore message

ネットワーク関連の設定も見てみると、ポリシーベースルーティングにより IPsec の通信は50番のルーティングテーブルを参照し、Cato PoP 宛の通信は Linux サーバがあるネットーワークのゲートウェイ経由で行われるようになっていました。

$ ip route
default via 192.168.200.129 dev eth0 proto dhcp src 192.168.200.132 metric 100
192.168.200.128/28 dev eth0 proto kernel scope link src 192.168.200.132 metric 100

$ ip rule
0:      from all lookup local
100:    from all fwmark 0x1 lookup 50
32766:  from all lookup main
32767:  from all lookup default

$ ip route show table 50
150.195.218.109 via 192.168.200.129 dev eth0

もしも ipsec1 というインターフェースが作られていなかった場合、設定の不備や不整合により IPsec 接続に失敗しています。この場合、設定を変更して再接続を試してみるわけですが、CMA 上の設定変更が反映されるまで5分程度時間がかかったり、接続失敗を何度も繰り返していると一定期間は接続拒否されたりするため、試行錯誤が大変でした…。

ルーティング変更

IPsec 接続に成功したら、次はルーティングを変更して Cato 側にトラフィックが流れていくようにします。

デフォルトルートを IPsec のインターフェースに向けつつ、Linux サーバがある LAN やリンクローカルのネットワーク宛のトラフィックは Cato 側に流れないようにしました。

$ sudo ip route add 192.168.200.0/24 via 192.168.200.129 dev eth0    # LAN
$ sudo ip route add 169.254.0.0/16 via 192.168.200.129 dev eth0      # リンクローカル
$ sudo ip route add default dev ipsec1

$ ip route
default dev ipsec1 scope link
default via 192.168.200.129 dev eth0 proto dhcp src 192.168.200.132 metric 100
169.254.0.0/16 via 192.168.200.129 dev eth0
192.168.200.0/24 via 192.168.200.129 dev eth0
192.168.200.128/28 dev eth0 proto kernel scope link src 192.168.200.132 metric 100

これでOKと言いたいところですが、これではまだ Cato 経由でのインターネットとの通信が期待通り動作しませんでした。また、この状態では Cato PoP 側からの IPsec 接続の生存確認も失敗するため、すぐに接続が切れて再接続が必要となってしまいます。

rp_filter 変更

前項のルーティング変更後、インターネット上のサーバ (Google Public DNS) に対して ping を打っても成功せず、tcpdump でパケットキャプチャを眺めてみると次の結果となりました。

17:22:25.383815 ipsec1 Out IP 192.168.200.132 > 8.8.8.8: ICMP echo request, id 1, seq 1, length 64
17:22:25.383858 eth0  Out IP 192.168.200.132.4500 > 150.195.218.109.4500: UDP-encap: ESP(spi=0x42a73e98,seq=0x2), length 120
17:22:25.388051 eth0  In  IP 150.195.218.109.4500 > 192.168.200.132.4500: UDP-encap: ESP(spi=0x32b41687,seq=0x2), length 120
17:22:26.442569 ipsec1 Out IP 192.168.200.132 > 8.8.8.8: ICMP echo request, id 1, seq 2, length 64
17:22:26.442606 eth0  Out IP 192.168.200.132.4500 > 150.195.218.109.4500: UDP-encap: ESP(spi=0x42a73e98,seq=0x3), length 120
17:22:26.445991 eth0  In  IP 150.195.218.109.4500 > 192.168.200.132.4500: UDP-encap: ESP(spi=0x32b41687,seq=0x3), length 120

ICMP パケットは ipsec1 インターフェースに向けて送信 (1,4行目) され、eth0 インターフェースで IPsec のパケット (UDP でカプセル化された ESP パケット) が Cato PoP に向けて送信 (2,5行目) されています。また、おそらく ping の戻りの ICMP パケットをカプセル化した IPsec のパケットを Cato PoP から受信 (3,6行目) しているようですが、ICMP echo reply は受信できていません。

eth0 インターフェースで IPsec パケットを受信しているのに、ipsec1 インターフェースからカプセル化を解除したパケットが出てきていないということは、受信した IPsec パケットが Linux カーネルで破棄され、Libreswan のプロセスに渡っていないということです。思い当たる心当たりとしては rp_filter ですね。

rp_filter - INTEGER
	0 - No source validation.
	1 - Strict mode as defined in RFC3704 Strict Reverse Path
	    Each incoming packet is tested against the FIB and if the interface
	    is not the best reverse path the packet check will fail.
	    By default failed packets are discarded.
	2 - Loose mode as defined in RFC3704 Loose Reverse Path
	    Each incoming packet's source address is also tested against the FIB
	    and if the source address is not reachable via any interface
	    the packet check will fail.

	Current recommended practice in RFC3704 is to enable strict mode
	to prevent IP spoofing from DDos attacks. If using asymmetric routing
	or other complicated routing, then loose mode is recommended.

	The max value from conf/{all,interface}/rp_filter is used
	when doing source validation on the {interface}.

	Default value is 0. Note that some distributions enable it
	in startup scripts.

https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt より引用

端的に説明すると、rp_filter というカーネルパラメータが1の場合、FIB (どのIPアドレス宛のパケットをどのインターフェースから送信するかを示すテーブル) によって選択されるインターフェースと、パケットを受信したインターフェースが異なると、パケットを破棄するというものです。

実際、eth0 インターフェースの rp_filter の値は1でした。

$ sudo sysctl -a | grep "\.rp_filter"
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.ip_vti0.rp_filter = 1
net.ipv4.conf.ipsec1.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1

FIB を参照すると Cato PoP (150.195.218.109) から来るパケットはデフォルト経路により ipsec1 インターフェースで受信されるべきですが、eth0 インターフェースで受信しているため破棄されているのですね。

このような場合、Cato PoP のIPアドレス宛の通信を eth0 インターフェースから送信する経路をデフォルトのルーティングテーブルに追加 (“sudo ip route add 150.195.218.109/32 via 192.168.200.129 dev eth0”) すれば解決できますが、Cato PoP のIPアドレスを明確に意識しなければならなくなるため、この方法は避けたいです。

そこで、rp_filter を緩めることにしました。

$ sudo sysctl net.ipv4.conf.eth0.rp_filter=2

これで ping も正常に通るようになりました。

$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=122 time=3.63 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=122 time=3.55 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=122 time=3.41 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 3.411/3.531/3.634/0.091 ms
17:23:07.224050 ipsec1 Out IP 192.168.200.132 > 8.8.8.8: ICMP echo request, id 2, seq 1, length 64
17:23:07.224087 eth0  Out IP 192.168.200.132.4500 > 150.195.218.109.4500: UDP-encap: ESP(spi=0x42a73e98,seq=0x5), length 120
17:23:07.227627 eth0  In  IP 150.195.218.109.4500 > 192.168.200.132.4500: UDP-encap: ESP(spi=0x32b41687,seq=0x5), length 120
17:23:07.227664 ipsec1 In  IP 8.8.8.8 > 192.168.200.132: ICMP echo reply, id 2, seq 1, length 64
17:23:08.225956 ipsec1 Out IP 192.168.200.132 > 8.8.8.8: ICMP echo request, id 2, seq 2, length 64
17:23:08.225994 eth0  Out IP 192.168.200.132.4500 > 150.195.218.109.4500: UDP-encap: ESP(spi=0x42a73e98,seq=0x6), length 120
17:23:08.229374 eth0  In  IP 150.195.218.109.4500 > 192.168.200.132.4500: UDP-encap: ESP(spi=0x32b41687,seq=0x6), length 120
17:23:08.229454 ipsec1 In  IP 8.8.8.8 > 192.168.200.132: ICMP echo reply, id 2, seq 2, length 64
17:23:09.227701 ipsec1 Out IP 192.168.200.132 > 8.8.8.8: ICMP echo request, id 2, seq 3, length 64
17:23:09.227736 eth0  Out IP 192.168.200.132.4500 > 150.195.218.109.4500: UDP-encap: ESP(spi=0x42a73e98,seq=0x7), length 120
17:23:09.231011 eth0  In  IP 150.195.218.109.4500 > 192.168.200.132.4500: UDP-encap: ESP(spi=0x32b41687,seq=0x7), length 120
17:23:09.231065 ipsec1 In  IP 8.8.8.8 > 192.168.200.132: ICMP echo reply, id 2, seq 3, length 64

良い感じです。

MTU 変更

IPsec 接続による作られた ipsec1 インターフェースの MTU は 1500 となっていました。

IPsec 接続時のログを見ると “AES_GCM_16_256” アルゴリズムで接続されており、今回のインターネット回線の MTU は 1500 ですので、IPsec のインナーパケットの最大長は 1438 バイトのはずです。

※計算式 : rounddown((1500 – 20 – 8 – 8 – 8 – 16) / 4, 0) * 4 – 2

  • 回線MTU : 1500
  • IPヘッダ長 : 20 (IPv4)
  • UDPヘッダ長 : 8 (NATトラバーサル用)
  • ESPヘッダ長 : 8
  • ESP初期化ベクトル : 8 (AES-GCM)
  • ESP認証データ : 16 (AES-GCM)
  • ESPトレーラ : 2
  • ブロックサイズ : 4

実際、1438 バイトのパケット (ペイロードが 1410 バイトの ping) は送信でき、1439 バイトのパケットは送信できませんでした。

17:26:54.130174 ipsec1 Out IP 192.168.200.132 > XXX.XXX.XXX.XXX: ICMP echo request, id 13, seq 1, length 1418
17:26:54.130210 eth0  Out IP 192.168.200.132.4500 > 150.195.218.109.4500: UDP-encap: ESP(spi=0x57179fd4,seq=0x1f), length 1472
17:26:54.138973 eth0  In  IP 150.195.218.109.4500 > 192.168.200.132.4500: UDP-encap: ESP(spi=0xb3a32ad4,seq=0x22), length 1416
17:26:54.138973 eth0  In  IP 150.195.218.109.4500 > 192.168.200.132.4500: UDP-encap: ESP(spi=0xb3a32ad4,seq=0x23), length 112
17:26:54.139047 ipsec1 In  IP XXX.XXX.XXX.XXX > 192.168.200.132: ICMP echo reply, id 13, seq 1, length 1360
17:26:54.139047 ipsec1 In  IP XXX.XXX.XXX.XXX > 192.168.200.132: ip-proto-1

17:26:58.465889 ipsec1 Out IP 192.168.200.132 > XXX.XXX.XXX.XXX: ICMP echo request, id 14, seq 1, length 1419
17:26:58.465922 eth0  Out IP 192.168.200.132.4500 > 150.195.218.109.4500: UDP-encap: ESP(spi=0x57179fd4,seq=0x21), length 1476
17:26:58.466157 eth0  In  IP 192.168.200.1 > 192.168.200.132: ICMP 150.195.218.109 unreachable - need to frag (mtu 1500), length 36

そのため、ipsec1 インターフェースの MTU を 1438 に変更しておきましょう。

$ sudo ip link set dev ipsec1 mtu 1438

なお、1438 バイトのパケットは送信できているものの、戻りの 1438 バイトのパケットはIPフラグメント化されて受信しています。これは過去の検証の通り、Cato PoP 経由でのインターネットとの通信の MTU が 1383 であることと一致していました。

Cato Client を用いた通信における MTU の調査
Cato クラウドの PoP 経由で通信する場合の MTU の値を調査・検証してみました。

接続確認

CMA 上での接続確認

CMA 上では、Site 画面で今回の IPsec 接続用の Site の状態を確認できますが、無事に Connected となっており、Tokyo PoP に接続されていました。新しい Tokyo_DC2 や Tokyo_DC3 PoP に接続されるとは限らないようです。

また、Site の IPsec の設定画面で「Connection Status」ボタンを押せば IPsec 接続の状態を確認できます。

この内容に特に見どころはありませんが、IPsec 接続で利用されている暗号スイートぐらいは確認しておくと良いですね。

さらに、Events 画面を見てみると、IPsec 接続が成功したときのログや、接続確認時の ICMP (ping) のログもちゃんとイベントとして記録されていました。(接続確認より前に NTP の通信も行われていました。)

CMA で見れる内容としては問題なさそうです。

Linux サーバ側の接続確認

Linux サーバからインターネットに通信してみて、ちゃんと Cato PoP を通っているのか確認してみます。

今回は「確認くん」の Web サイトにアクセスし、インターネット側から見えるグローバルIPアドレスを確認してみました。

$ curl https://www.ugtop.com/spill.shtml
<!DOCTYPE html>
<html lang="ja">
(中略)
        <th>あなたのIPアドレス(IPv4)</th>
        <td><font size=+2 color=blue>150.195.218.108</font></td>
        <tr>
        <th>ゲートウェイの名前</th>
        <td><font size=+1 color=red>(none)</font></td><tr>
(後略)

自マシンのIPアドレスは 150.195.218.108 として見えているようであり、これは Cato の東京の PoP のものですので、問題なさそうですね。

その後 CMA で Events を見てみると、もちろん上記のアクセスも記録されていました。

まとめ

Linux サーバから Cato クラウドに問題なく IPsec 接続を行えることが確認できました。IPsec は標準化されたプロトコルですし、流れるパケットも手軽に見れるので良い感じです。

vSocket を用意したりクラウドの IPsec サービスを利用したりしなくても、軽いノリで Cato クラウドに接続できるのも良い点です。Cato クラウドを Pooled ライセンスで利用しているのであれば、今回のように気軽に Site を立てて利用するといったこともできますので、ライセンスは余剰分を確保しておきたいですね。

ただし、今回はあくまでも IPsec 接続できるかを検証したものであり、本番環境用途で利用するためには次のようなことも追加で検証・構築する必要があります。

  • 同じネットワーク上の他のマシンから今回の Linux サーバを介して Cato クラウドに接続する
  • IPsec 接続時に手動で行っている内容 (ルーティングや MTU の変更) を自動で行う
  • Linux サーバ側からも IPsec 接続の生存確認を行い、生存が確認できなければ自動で再接続する
  • 高い可用性が必要なら、IPsec 接続を冗長化 (Secondary 接続や Linux サーバを複数用意) する

この中でも4つ目は検証も構築も大変なので、本番環境用途を考えるなら間違いなく vSocket やパブリックラウドが提供する IPsec サービスなどを利用することを推奨します。vSocket や IPsec サービスなどを利用できないような環境で Cato クラウドに接続する手段の1つとして本記事を参考にしていただければと思います。

タイトルとURLをコピーしました