On-PとOCI間のIPSec VPN接続のシミュレーション (Libreswanを利用)

OCI General

初めに

今回は、Libreswanを使用して、On-P (または他のクラウド) と Oracle Cloud Infrastruture (OCI) 間の IPSec VPN 接続を検証するシミュレーションを紹介します。OCI大阪リージョンをOn-P側 ()、東京リージョンをVPNヘッドエンド側 ()とした例で説明します。 Libreswan は、"Customer Premises Equipment" (CPE) をシミュレートするために、左側でインストールおよび構成されます。

Architect Diagram
項目内容コメント
OCI リージョン (左)大阪Libreswan CPE
(On-Pまたは他のクラウドをシミュレート)
OCI リージョン (右)東京VPN ヘッドエンド
Computeインスタンスの数合計3個左側:2個 (接続元 + Libreswan)
右側:1個 (接続先)
ComputeインスタンスのOSOracle Linux 8
Libreswan バージョン4.5
  • このテストでは、左側が Librswan CPE(接続元)を意味し、右側がVPNヘッドエンド(接続先)を意味します。
  • Libreswanインスタンス (CPE) にはパブリックIPが必要なため、パブリック・サブネットに作成する必要があります。他の2つのインスタンスについては、パブリック・サブネットまたはプライベート・サブネットのいずれかに作成できます (この例では、全部パブリック・サブネットに作成します)。 左側のクライアントとLibreswanを異なるサブネットに置いても問題ありません。その場合、サブネット間のトラフィックが許可されていることを確保する必要があります。
  • OCIアカウントごとに2つの「Always Free Compute VMs」があるため、1つのVMを接続先クライアントとして使用できます (右側)。 その他のネットワーク関連リソース(VCN/サブネット、インターネットGW、DRG、IPSec VPNなど)は無料でご利用いただけます。

1. 事前準備

次のようにネットワーク関連のリソースを作成します。

1-1. 左側(接続元)

タイプ項目内容コメント
VCNCIDR192.168.0.0/16
SubnetCIDR192.168.0.0/24パブリック
Internet GW
Security ListIngressXX.XX.XX.XX/32, TCP 22SSH 経由でインスタンスに接続する IP アドレスを指定
192.168.0.0/24, 全てのプロトコルSSH/PINGを含め、内部トラフィック(左側のクライアント<==>Libreswan)を許可
10.0.0.0/24, 全てのプロトコルSSH/PINGを含め、右側からのインバウンド・トラフィックを許可
VPN パブリック IP 1,
TCP 500,4500
IPSecトンネル1のエンドポイント (取得方法は、STEP 2-2をご参照)
VPN パブリック IP 1,
UDP 500,4500
同上
VPN パブリック IP 2,
TCP 500,4500
IPSecトンネル2のエンドポイント (取得方法は、STEP 2-2をご参照)
VPN パブリック IP 2,
UDP 500,4500
同上
Egress0.0.0.0/0, 全てのプロトコル
Route Tableルールターゲット: Internet GW
宛先: 0.0.0.0/0
外部からインスタンスを接続するするため
ターゲット: Libreswan's Private IP
宛先: 10.0.0.0/24
右側のサブネットのCIDRブロックを指定

1-2. 右側(接続先)

タイプ項目内容コメント
VCNCIDR10.0.0.0/16
SubnetCIDR10.0.0.0/24パブリック
DRGAttachmentVCN (Right)
Internet GW
Security ListIngressXX.XX.XX.XX/32, TCP 22SSH 経由でインスタンスに接続する IP アドレスを指定
192.168.0.0/24, 全てのプロトコルSSH/PINGを含め、左側からのインバウンド・トラフィックを許可
Libreswan パブリック IP,
TCP 500,4500
Libreswanからのインバウンド・トラフィックを許可
Libreswan パブリック IP,
UDP 500,4500
同上
Egress0.0.0.0/0, 全てのプロトコル
Route Tableルールターゲット: Internet GW
宛先: 0.0.0.0/0
外部からインスタンスを接続するするため
ターゲット: DRG
宛先: 192.168.0.0/24
左側のサブネットのCIDRブロックを指定

2. CPE(顧客構内機器)とIPSec接続の作成 (右)

2-1. CPEの作成

ネットワーキング → 顧客接続性 → 顧客構内機器 → 「顧客構内機器の作成」ボタンを押す

名前: CPE名を入力
Public IP Address: LibreswanインスタンスのパブリックIPを入力
ベンダー: Libreswanを選択
Platform Version: リストから選択
Create CPE

2-2. IPSec接続の作成

ネットワーキング → 顧客接続性 → サイト間VPN →「IPSec接続の作成」ボタンを押す

以下のように必要な情報を入力し、「IPSec接続の作成」ボタンを押します。
名前: IPSec接続名を入力
CPE: リストから作成した CPE を選択
DRG: リストから既存のDRGを選択。
オンプレミス・ネットワークへのルート: 左側のサブネットの CIDR ブロックを入力
トンネル1と2のルーティング・タイプ: 静的ルーティングを指定

Create IPSec connection
IPSec接続が作成されたら、次のようにVPNのパブリックIPと秘密鍵を取得します。(これらの情報はSTEP-4で使用されます。)

VPN パブリック IP
Check IPSec tunnels
最初は、各トンネルは停止状態(オフライン)になっています。これは、後で追加設定がまだあるためです。

秘密鍵
Show shared secret
2つのトンネルの秘密鍵をコピーします。
View shared secret

3. Libreswanのインストール (左)

インストール用コマンド: sudo yum -y install libreswan
バージョンを確認するコマンド: sudo ipsec --version

[opc@linux8-libreswan ~]$ sudo yum -y install libreswan
...
[opc@linux8-libreswan ~]$ sudo ipsec --version
Linux Libreswan 4.5 (XFRM) on 5.4.17-2136.309.5.el8uek.x86_64
[opc@linux8-libreswan ~]$

インストール後、以下のファイルとディレクトリが作成されます。
/etc/ipsec.conf
/etc/ipsec.secrets
/etc/ipsec.d/

4. Libreswanの設定 (左)

4-1. ファイル sysctl.conf を編集

/etc/sysctl.confを開き、次のように内容を追加します。

[opc@linux8-libreswan ~]$ sudo vi /etc/sysctl.conf
...
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.ens3.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.ens3.accept_redirects = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.ens3.rp_filter = 0


追加後、sudo sysctl -pを使用して更新を適用します。

※、ens3以外のインターフェイスを使用している場合は、そのインターフェイスに変更します (ip addrまたはifconfigで確認してください)。

4-2. 構成ファイルの作成

以下のように構成ファイルを作成します。

ファイル名: /etc/ipsec.d/oci-ipsec.conf
例:

[opc@linux8-libreswan ~]$ sudo vi /etc/ipsec.d/oci-ipsec.conf
conn oracle-tunnel-1
     left=192.168.0.59 # Private IP of Libreswan CPE
     leftid=XX.XX.145.20 # Public IP of Libreswan CPE
     right=XX.XX.57.17 # VPN Public IP 1
     authby=secret
     leftsubnet=192.168.0.0/24
     rightsubnet=10.0.0.0/24
     auto=start
     mark=5/0xffffffff # Needs to be unique across all tunnels
     vti-interface=vti01
     vti-routing=no
     ikev2=no # To use IKEv2, change to ikev2=insist
     ike=aes_cbc256-sha2_384;modp1536
     phase2alg=aes_gcm256;modp1536
     encapsulation=yes
     ikelifetime=28800s
     salifetime=3600s
conn oracle-tunnel-2
     left=192.168.0.59 # Private IP of Libreswan CPE
     leftid=XX.XX.145.20 # Public IP of Libreswan CPE
     right=XX.XX.68.238 # VPN Public IP 2
     authby=secret
     leftsubnet=192.168.0.0/24
     rightsubnet=10.0.0.0/24
     auto=start
     mark=6/0xffffffff # Needs to be unique across all tunnels
     vti-interface=vti02
     vti-routing=no
     ikev2=no # To use IKEv2, change to ikev2=insist
     ike=aes_cbc256-sha2_384;modp1536
     phase2alg=aes_gcm256;modp1536
     encapsulation=yes
     ikelifetime=28800s
     salifetime=3600s

4-3. シークレット・ファイルの作成

次のようにシークレット ファイルを作成します。IPSec接続ごとに2つの行が含まれます(トンネルごとに1行)。

ファイル名: /etc/ipsec.d/oci-ipsec.secrets
ファイルの中身:
CPE_Public_IP VPN_Public_IP_1: PSK "Secret_Key_1"
CPE_Public_IP VPN_Public_IP_2: PSK "Secret_Key_2"

例:

[opc@linux8-libreswan ~]$ sudo vi /etc/ipsec.d/oci-ipsec.secrets
XX.XX.145.20 XX.XX.57.17:  PSK "vOO9ICtswi................<omitted>.......................DGPT49"
XX.XX.145.20 XX.XX.68.238: PSK "bM3QiQFPee................<omitted>......................OYY7XGY"

4-4. Libreswanサービスの起動

コマンド: sudo systemctl restart ipsec

[opc@linux8-libreswan ~]$ sudo systemctl restart ipsec

サービスが開始されたら、次のコマンドで結果を確認します。
コマンド: sudo ipsec verify

[opc@linux8-libreswan ~]$ sudo ipsec verify
Verifying installed system and configuration files

Version check and ipsec on-path                         [OK]
Libreswan 4.5 (XFRM) on 5.4.17-2136.309.5.el8uek.x86_64
Checking for IPsec support in kernel                    [OK]
 NETKEY: Testing XFRM related proc values
         ICMP default/send_redirects                    [OK]
         ICMP default/accept_redirects                  [OK]
         XFRM larval drop                               [OK]
Pluto ipsec.conf syntax                                 [OK]
Checking rp_filter                                      [OK]
Checking that pluto is running                          [OK]
 Pluto listening for IKE on udp 500                     [OK]
 Pluto listening for IKE/NAT-T on udp 4500              [OK]
 Pluto ipsec.secret syntax                              [OK]
Checking 'ip' command                                   [OK]
Checking 'iptables' command                             [OK]
Checking 'prelink' command does not interfere with FIPS [OK]
Checking for obsolete ipsec.conf options                [OK]

コマンド: sudo ipsec status
以下のように出力結果を絞りこむと、確認しやすいです。
例:
sudo ipsec status | grep active
sudo ipsec status | grep established
2つのVPNトンネルが立てられることを確認します。

[opc@linux8-libreswan ~]$ sudo ipsec status | grep active
000 Total IPsec connections: loaded 2, active 2
[opc@linux8-libreswan ~]$ sudo ipsec status | grep established
000 #1: "oracle-tunnel-1":4500 STATE_MAIN_I4 (IKE SA established); REPLACE in 27394s; newest ISAKMP; lastdpd=2s(seq in:0 out:0); idle;
000 #4: "oracle-tunnel-1":4500 STATE_QUICK_I2 (IPsec SA established); REPLACE in 1975s; newest IPSEC; eroute owner; isakmp#1; idle;
000 #2: "oracle-tunnel-2":4500 STATE_MAIN_I4 (IKE SA established); REPLACE in 27153s; newest ISAKMP; lastdpd=2s(seq in:0 out:0); idle;
000 #3: "oracle-tunnel-2":4500 STATE_QUICK_I2 (IPsec SA established); REPLACE in 1984s; newest IPSEC; eroute owner; isakmp#2; idle;

コマンド: ip addr or ifconfig
2つの仮想インターフェイスが追加されていることを確認します。

[opc@linux8-libreswan ~]$ ip addr
...<omitted>...
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
4: vti01@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 8980 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ipip 192.168.0.59 peer XXX.XXX.57.17
    inet6 fe80::5efe:c0a8:97/64 scope link
       valid_lft forever preferred_lft forever
5: vti02@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 8980 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ipip 192.168.0.59 peer XXX.XXX.68.238
    inet6 fe80::5efe:c0a8:97/64 scope link
       valid_lft forever preferred_lft forever

コマンドip linkで結果を確認することもできます。ip addrの結果と大体同じで、省略させてください。

IPSec ステータス
全ての出力が上記のように問題がない場合は、接続先のOCIコンソールからIPSecステータスを確認します。ステータスが「稼働中」(Up)になったらOKです。

「稼働中」(Up)の状態が表示されるまで、それほど時間はかかりません。 (私のテストでは数秒しかかかりませんでした。しばらく状態が変更されない場合は、コンソール画面をリフレッシュしてください。)
Check IPSec status

4-5. IPルーティングの設定

このステップを実施しなかった場合、このような問題が発生します。

[opc@linux8-libreswan ~]$ sudo ip route add 10.0.0.0/24 nexthop dev vti01 nexthop dev vti02
[opc@linux8-libreswan ~]$ ip route show
default via 192.168.0.1 dev ens3
default via 192.168.0.1 dev ens3 proto dhcp src 192.168.0.59 metric 100
10.0.0.0/24
        nexthop dev vti01 weight 1
        nexthop dev vti02 weight 1
...<omitted>...

ip routeコマンドで作成される静的ルートは、再起動後は維持されません。ルートを維持する方法については、使用しているLinuxディストリビューションのドキュメントを参照してください。

4-6. VNICの編集

コンピュート → インスタンス → インスタンスの詳細 → アタッチされたVNIC

3ドットのメニューを右クリックし、「VNCIの編集」を選択して、「ソース/宛先チェックのスキップ」をチェックします。
Edit VNIC
このステップを実行しなかった場合は、Libreswanと右側のクライアントの間で接続できますが、Libreswanを介して左側から右側のクライアントに接続することはできません。

5. 接続テスト(Ping & SSH)

5-1. 左から右へ

PING

[opc@linux8-onp ~]$ ping 10.0.0.3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=1 ttl=252 time=8.67 ms
64 bytes from 10.0.0.3: icmp_seq=2 ttl=252 time=19.2 ms
^C
--- 10.0.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 8.673/13.923/19.174/5.251 ms
[opc@linux8-onp ~]$

ファイアウォール・サービス
まず、Libreswan のファイアウォール・サービスを停止します。 そうしないと、Libreswanを経由し左側と右側の間、双方向にSSH接続しようとすると、「No route to host」のような問題を遭遇する可能性があります。

注意

  • ファイアウォール・サービスの停止は、Libreswanだけで行えば問題ありません。左側と右側のクライアントでの停止は不要です(誤解される人が多い)。
  • Oracle Linux 上のファイアウォール・サービスは、VM再起動後にデフォルトで自動的に開始されます。
[opc@linux8-libreswan ~]$ sudo systemctl stop firewalld
[opc@linux8-libreswan ~]$ sudo systemctl status firewalld
œ firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Wed 2022-08-24 03:05:32 GMT; 8s ago
     Docs: man:firewalld(1)
  Process: 1462 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS)
 Main PID: 1462 (code=exited, status=0/SUCCESS)
...<omitted>...

SSH 接続
接続元のクライアントに SSH 秘密鍵を保存しておきます。(例:/home/opc/.ssh/id_rsa)

[opc@linux8-onp ~]$ ssh 10.0.0.3
The authenticity of host '10.0.0.3 (10.0.0.3)' can't be established.
ECDSA key fingerprint is SHA256:<key_fingerprint_is_omitted>.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.3' (ECDSA) to the list of known hosts.
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Tue Aug 23 20:39:20 2022 from XXX.XXX.XXX.XXX
[opc@linux8-vpn ~]$

5-2. 右から左へ

PING

[opc@linux8-vpn ~]$ ping 192.168.0.230
PING 192.168.0.230 (192.168.0.230) 56(84) bytes of data.
64 bytes from 192.168.0.230: icmp_seq=1 ttl=61 time=8.72 ms
64 bytes from 192.168.0.230: icmp_seq=2 ttl=61 time=8.68 ms
^C
--- 192.168.0.230 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 8.681/8.702/8.723/0.021 ms
[opc@linux8-vpn ~]$

SSH 接続
上記「STEP 5-1」と同じように、Libreswan のファイアウォール・サービスが停止していることと、秘密鍵が右側のクライアントに格納されていることを確認しておいでください。

[opc@linux8-vpn ~]$ ssh 192.168.0.230
The authenticity of host '192.168.0.230 (192.168.0.230)' can't be established.
ECDSA key fingerprint is SHA256:<key_fingerprint_is_omitted>.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.230' (ECDSA) to the list of known hosts.
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Wed Aug 24 03:04:35 2022 from XXX.XXX.XXX.XXX
[opc@linux8-onp ~]$

注意
Libreswanと右側のクライアント間の接続テストをスキップしたけど、実はSTEP 5-1 と STEP 5-2 の前に実施しました。結果はOKだったので省略します。次の順番で疎通テストを行うことをお勧めします。

  • a. Libreswan ==> 右
  • b. Libreswan <== 右
  • c. 左 ==> 右
  • d. 左 <== 右

トラブル・シューティング

問題-1 (IPSec ステータス "停止")

現象: IPSecサービスを起動した後、IPSecトンネルのステータスが「停止」のままで、「稼働中」に変更しません。インターフェイスvti01vti02も作成されていません。
可能な原因-1: TCP/UDP ポート 500と4500ポートがセキュリティ・リストに追加されていません。 それらは両側に追加する必要があります。
可能な原因-2: IPSec構成ファイルに、IPアドレスが間違っています。 (パブリック/プライベートIPとCIDRブロックをコピペする時は、気を付けてください。)
可能な原因-3: シークレット・ファイルに、IPアドレスまたは PSK キーが間違っています。 (2つのIPSecトンネルに対して2行があり、IPと秘密鍵をコピペする時は気を付けてください。)

問題-2 (Libreswan<==>右)

現象: IPSecトンネルは「稼働中 (UP)」の状態を示していますが、Libreswanと右側クライアントの間、PINGができなくて、SSH接続もできません。
可能な原因-1: 右側のルート・テーブルにルートを追加する必要があります (宛先: 192.168.0.0/24, ターゲット・タイプ: DRG)。
可能な原因-2: Libreswanインスタンスに IP ルーティングを追加するのを忘れたか (STEP 4-5)、再起動後にip routeコマンドの結果が保持されない可能性があります。
可能な原因-3: 「UP」状態は、VPNパブリックIPとCPEパブリックIPの間に、TCP/UDP 500と4500ポート経由の接続が正常であることを意味します。 疎通テストを実施するため、両側のセキュリティ・リスト(あるいはNSG)に、TCP(22)/ICMPも許可される必要があります(IngressとEgress両方を確認)。

問題-3 (Ping 左<==>右)

現象: Libreswan と右側クライアントの間で PING とSSH 接続ができますが、左側クライアントと右側クライアントの間、PINGができなくて、SSH接続もできません。
可能な原因-1: 「ソース/宛先チェックのスキップ」をチェックする必要があります (STEP 4-6)。
可能な原因-2: 左側クライアントと Libreswan 間の内部トラフィックを許可する必要があります。
可能な原因-3: 左側のルート・テーブルにルートを追加する必要があります (宛先: 10.0.0.0/24, ターゲット・タイプ: Private IP, ターゲット: Libreswan's private IP).

問題-4 (SSH 左<==>右)

現象: 左側クライアントと右側クライアントの間に、双方向でPINGできますけど、相互にSSH経由で接続することはできません (エラーメッセージは次のように:"connect to host port 22: No route to host")。 なお、左側のクライアント<=>LibreswanLibreswan<=>右側のクライアントの接続は、両方共にOKです。
可能な原因: Libreswanインスタンスには、ファイアウォール・サービスが起動中のため、IPパケット転送が遮断されます。(解決方法は、STEP 5-1をご参照ください。)

問題-5 (SSH 成功, PING 失敗)

現象: 左右双方向でSSHの接続ができますが、お互いにPINGができません。
原因と対策: PINGは、TCPではなくICMPプロトコルを使用します。 デフォルトでは、許可されていません。 上記の事前準備(STEP-1) では、一部のセキュリティ・ルールに対し「全てのプロトコル」を使用します。「全てのプロトコル」を使用したくない場合は、SSHとPINGを通るため、個別にTCP/ICMPを追加してください。

サマリ
このシミュレーションは、2つのOCIリージョン間の接続を例にしています。この方法は、On-P (または他のクラウド・ベンダー)とOCI間の接続にも適用できます。その場合、Libreswanと接続元のクライアントは、On-Pか他クラウドにおいていただければよいです。

以上

OCI ドキュメント
Libreswan: 英語 日本語
Libreswanを使用したその他のクラウドへのアクセス: 英語 日本語

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