1. 要旨
OCIのサイト間VPN接続は、顧客管理のルーター (CPE) とOCIの間でIPsecトンネルを提供するサービスです。これまで様々なルーターを利用したサイト間VPN接続の手順書記事が公開されており、物理ルーターだけでなく、ソフトウェアルーターをOCIのコンピュート・インスタンスにインストールして構築する手順などが公開されています [1, 2, 3]。
本記事では、VMware vSphere上で稼働する仮想マシンにソフトウェアルーターであるlibreswanをインストールして、サイト間VPNを構築する手順を記録しました(投稿内容は個人の見解であり、所属組織とは関係ありません)。
2. ネットワーク構成の解説
検証環境として、OCI VCN (Virtual Cloud Network) を東京リージョンと大阪リージョンに用意しました。東京リージョンにはOCVS (Oracle Cloud VMware Solution) 環境があり、vSphere環境があります。
サイト間VPNの構築に利用するコンポーネントやIPアドレスは以下です。
- 東京リージョン側のOCVS上にlibreswan VMを構築し、疑似オンプレミス環境とします
- VCNのCIDR:192.168.1.0/16
- libreswan VMが接続するVLANのCIDR:192.168.1.0/24
- VLANに紐づくルート表(VLAN内のVMが参照します)
- libreswan VMのプライベートIPアドレス:192.168.1.53
- NAT後のパブリックIPアドレス:132.226.x.x (一部マスクします)
- Internet Gateway
- libreswan VMが接続するVLANのCIDR:192.168.1.0/24
- VCNのCIDR:192.168.1.0/16
- 大阪リージョン側には、東京リージョン側とCIDRが被らないようにVCNを用意しました
- VCNのCIDR:10.2.0.0/16
- DRG (Dynamic Routing Gateway, 動的ルーティングゲートウェイ)
- DRGのIPsecアタッチメントに紐づくルート表(オンプレミスからOCIへの通信で参照されます)
- DRGのVCNアタッチメントに紐づくルート表(OCIからオンプレミスへの通信で参照されます)
libreswan VMのネットワーク的な配置は、オンプレミス環境を想定してNSXを利用しないVLAN backing構成 [4] にしました。ESXiホストがVCN内のVLANに接続しており、仮想マシンをVLAN IDに該当する分散ポートグループに参加させることでVLAN接続します。
3. 手順
VLAN Backing構成の作成
より詳細な手順は他の記事に説明を譲ります [4]。
OCI VCNにVLANを作成します。VLAN IDは1130です。

ESXiホストをVLAN接続します。OCVSにおいて、ホストはユーザー管理のコンピュート・インスタンスです。インスタンスのVNICを、作成したVLANに接続します。検証環境のホストシェイプでは物理NICが2本あるタイプなので、1台につき2本ずつ接続を構成してきます。

分散ポートグループを作成します。VLAN IDをOCIで作成したVLANに合わせることがポイントです。

スイッチの中で重複しないIPアドレスを確認し、libreswan VMのIPアドレスを192.168.1.53に決定しました。

仮想マシンでnmcliコマンドを実行し、ens33にIPアドレスを設定しました。
デフォルト・ゲートウェイのアドレスはVLANの1つ目のアドレスです。
自身に対するpingが成功したことを確認して次の手順に入ります。

libreswan VMにパブリックIPの割り当てとCPEリソースの設定
NAT用のパブリックIPアドレスを外部アクセス機能で追加しました。
事前に予約していたパブリックIPアドレスを選択しました(予約済みパブリックIPアドレスは、オラクルが持っているIPアドレスがランダムに割り当てられます。ユーザー側で特定のIPアドレスを指定することはできません)。

libreswan VMのプライベートIPアドレス(192.168.1.53)をNAT後のパブリックIPアドレスとして、132.226.x.xが割り当たりました。

大阪リージョンにサイト間VPNの接続先として、IPsecVCN (10.2.0.0/16) を作成しました。
その中に10.2.0.0/24のパブリックサブネットを作成し、東京のVCNと通信ができるようにセキュリティリストを設定します。

引き続き、大阪でサイト間VPNのトンネル部分に該当するコンポーネントである、IPsec接続を作成していきます。IPsec接続を作成するためには顧客構内機器 (CPE) というリソースが必要です。
これはオンプレミスルーターのエンティティで(ここではlibreswan VM)、IPsec接続に紐づけて利用します。
- IPアドレス:libreswanのパブリックIPアドレス
- CPEベンダー情報:Libreswanとし、プラットフォーム/バージョンは最新のものを選択
まだアイテムが表示されていませんが、この後、OCIコンソールで接続を作成して紐づけるとCPEの詳細画面でIPsec接続が表示されるようになります。

IPsec接続アタッチメントとVCNアタッチメントの構成
IPsec接続の作成時にはDRGが必要なので先に作成します。

IPsec接続を作成する前にVCNとDRGとの間を接続しておきます。VCNアタッチメント(DRGとVCNとつなぐ部分)を作成しました。

この時点でネットワークビジュアライザを確認すると、IPsec-VCN(六角形)とDRG(円)が接続され、DRGの先にCPEが認識されている状態になりました。あとはこのCPEとDRGの間の接続を構成していきます。

IPsec接続の作成ウィザードにて作成済みのCPEとDRGを紐づけます。
静的ルーティングを行うので、libreswanのVLANを含むVCNのCIDRを追記しました。

一つ目のトンネルは静的ルーティングとIKEv2を選択し、静的ルーティングではトンネル内インターフェースのアドレスはオプションですが、一応、利用していないIPアドレス帯から採択します。

二つ目のトンネルも同じ要領で作成します。

IPsec接続を一つ作成すると、その中に二つのトンネルヘッド(ルーター)が含まれます。

この段階でネットワークビジュアライザーを確認すると、先ほどDRGとCPEの間に無かったIPsecConnectionアタッチメントが構成されています(薄い線で表現されており、2本繋がっています)。

各IPsec接続のトンネルにはIKEv2形式の事前共有キー(Preshared Key)が自動で設定されます。後ほど、Libreswanのパラメーターとして設定が必要なため、確認をしてメモをしておきます。
伏字になっている共有シークレットの項目の「表示」をクリックします。

東京リージョンでLibreswanの構築
Libreswanが配置されたVLANのネットワーク・セキュリティ・グループに以下のイングレス・ルールを追記します(VLANではセキュリティ・リストが利用できない)。
- IPsecVCNのCIDRからの通信を「すべてのプロトコル」
- OCIのIPsecルーターからの通信を「すべてのプロトコル」(TCP, UDPでそれぞれ500番と4,500番ポートを解放するとより綺麗です)
VMでlibreswanツールをdnfインストールするために一時的にインターネットゲートウェイへのルートを作成しました。

パッケージを配布するyumサーバーの名前解決を行うためにVLANの一個目のIPアドレスをnameserverとして/etc/resolv.confに追記します。
[opc@localhost ~]$ cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.1.1
libreswanをdnfインストールし、ルート表上でインターネットゲートウェイへの経路は削除します。
[opc@localhost ~]$ sudo dnf -y install libreswan
Oracle Linux 8 BaseOS Latest (x86_64) 0.0 B/s | 0 B 00:00
Errors during downloading metadata for repository 'ol8_baseos_latest':
- Curl error (6): Couldn't resolve host name for https://yum.oracle.com/repo/OracleLinux/OL8/baseos/latest/x86_64/repodata/repomd.xml [Could not resolve host: yum.oracle.com]
Error: Failed to download metadata for repo 'ol8_baseos_latest': Cannot download repomd.xml: Cannot download repodata/repomd.xml: All mirrors were tried
[opc@localhost ~]$ sudo vim /etc/resolv.conf
[opc@localhost ~]$ sudo dnf -y install libreswan
Oracle Linux 8 BaseOS Latest (x86_64) 153 kB/s | 4.3 kB 00:00
Oracle Linux 8 BaseOS Latest (x86_64) 141 MB/s | 101 MB 00:00
Oracle Linux 8 Application Stream (x86_64) 187 kB/s | 4.5 kB 00:00
Oracle Linux 8 Application Stream (x86_64) 129 MB/s | 71 MB 00:00
Latest Unbreakable Enterprise Kernel Release 7 for Oracle Linux 8 (x86_64) 196 kB/s | 3.5 kB 00:00
Latest Unbreakable Enterprise Kernel Release 7 for Oracle Linux 8 (x86_64) 110 MB/s | 65 MB 00:00
Last metadata expiration check: 0:00:09 ago on Wed 25 Jun 2025 01:07:23 AM EDT.
Dependencies resolved.
========================================================================================================================
Package Architecture Version Repository Size
========================================================================================================================
Installing:
libreswan x86_64 4.12-2.0.1.el8_10.4 ol8_appstream 1.4 M
Installing dependencies:
ldns x86_64 1.7.0-22.el8 ol8_appstream 164 k
nss-tools x86_64 3.90.0-6.el8_9 ol8_appstream 583 k
Transaction Summary
========================================================================================================================
Install 3 Packages
Total download size: 2.1 M
Installed size: 7.8 M
Downloading Packages:
(1/3): ldns-1.7.0-22.el8.x86_64.rpm 4.1 MB/s | 164 kB 00:00
(2/3): nss-tools-3.90.0-6.el8_9.x86_64.rpm 13 MB/s | 583 kB 00:00
(3/3): libreswan-4.12-2.0.1.el8_10.4.x86_64.rpm 27 MB/s | 1.4 MB 00:00
------------------------------------------------------------------------------------------------------------------------
Total 39 MB/s | 2.1 MB 00:00
Oracle Linux 8 Application Stream (x86_64) 3.0 MB/s | 3.1 kB 00:00
Importing GPG key 0xAD986DA3:
Userid : "Oracle OSS group (Open Source Software group) <build@oss.oracle.com>"
Fingerprint: 76FD 3DB1 3AB6 7410 B89D B10E 8256 2EA9 AD98 6DA3
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : nss-tools-3.90.0-6.el8_9.x86_64 1/3
Installing : ldns-1.7.0-22.el8.x86_64 2/3
Installing : libreswan-4.12-2.0.1.el8_10.4.x86_64 3/3
Running scriptlet: libreswan-4.12-2.0.1.el8_10.4.x86_64 3/3
Verifying : ldns-1.7.0-22.el8.x86_64 1/3
Verifying : libreswan-4.12-2.0.1.el8_10.4.x86_64 2/3
Verifying : nss-tools-3.90.0-6.el8_9.x86_64 3/3
Installed:
ldns-1.7.0-22.el8.x86_64 libreswan-4.12-2.0.1.el8_10.4.x86_64 nss-tools-3.90.0-6.el8_9.x86_64
Complete!
次の内容を/etc/sysctl.confファイルに追記し、sysctl -pで設定を更新しました。
ip aでIPアドレスを割り当てたインターフェース名を確認し、記載する内容を調整してください。ここでのインターフェース名はens33です。
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.ens33.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.ens33.accept_redirects = 0
設定に必要なパラメーターをまとめておきます。
| 変数名 | 説明 | 例 |
|---|---|---|
${cpeLocalIP} |
LibreswanデバイスのIPアドレス | 192.168.1.53 |
${cpePublicIpAddress} |
LibreswanのパブリックIPアドレス(外部インターフェース)。トポロジにより ${cpeLocalIP} と異なる場合あり |
132.226.x.x |
${oracleHeadend1} |
最初のトンネル用のOracleパブリックIPエンドポイント(Oracle Consoleで確認) | 168.138.y.y |
${oracleHeadend2} |
2番目のトンネル用のOracleパブリックIPエンドポイント | 168.138.z.z |
${vti1} |
最初のVTIインターフェース名(自分で決める) | vti01 |
${vti2} |
2番目のVTIインターフェース名(自分で決める) | vti02 |
${sharedSecret1} |
最初のトンネルの事前共有キー(Oracleで自動設定。変更可能) | LVW (中略) 4LL |
${sharedSecret2} |
2番目のトンネルの事前共有キー | GSK (中略) vGl |
${vcnCidrNetwork} |
VCNのIPアドレス範囲 | 10.2.0.0/16 |
/etc/ipsec.d/oci-ipsec.confのプレースホールダーに上記の内容を書き込んでいきます。
leftidのコメントアウトを外すことと、ikev2パラメーターのデフォルトがnoになっているのでinsistに変更することがポイントです。
conn oracle-tunnel-1
left=192.168.1.53
leftid=132.226.x.x # See preceding note about 1-1 NAT device
right=168.138.y.y
authby=secret
leftsubnet=0.0.0.0/0
rightsubnet=0.0.0.0/0
auto=start
mark=5/0xffffffff # Needs to be unique across all tunnels
vti-interface=vti01
vti-routing=no
ikev2=insist # 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.1.53
leftid=132.226.x.x # See preceding note about 1-1 NAT device
right=168.138.z.z
authby=secret
leftsubnet=0.0.0.0/0
rightsubnet=0.0.0.0/0
auto=start
mark=6/0xffffffff # Needs to be unique across all tunnels
vti-interface=vti02
vti-routing=no
ikev2=insist # To use IKEv2, change to ikev2=insist
ike=aes_cbc256-sha2_384;modp1536
phase2alg=aes_gcm256;modp1536
encapsulation=yes
ikelifetime=28800s
salifetime=3600s
/etc/ipsec.d/oci-ipsec.secretsファイルに事前共有キーの内容を記入
132.226.x.x 168.138.y.y: PSK "LVW (中略) 4LL"
132.226.x.x 168.138.z.z: PSK "GSK (中略) vGl"
OSのfirewallの停止をしました。
[opc@localhost ~]$ systemctl stop firewalld
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to stop 'firewalld.service'.
Authenticating as: opc
Password:
==== AUTHENTICATION COMPLETE ====
[opc@localhost ~]$ 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 2025-06-25 02:09:44 EDT; 5s ago
Docs: man:firewalld(1)
Process: 1035 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS)
Main PID: 1035 (code=exited, status=0/SUCCESS)
Jun 24 22:03:45 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon...
Jun 24 22:03:46 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon.
Jun 24 22:03:46 localhost.localdomain firewalld[1035]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure >
Jun 25 02:09:43 localhost.localdomain systemd[1]: Stopping firewalld - dynamic firewall daemon...
Jun 25 02:09:44 localhost.localdomain systemd[1]: firewalld.service: Succeeded.
Jun 25 02:09:44 localhost.localdomain systemd[1]: Stopped firewalld - dynamic firewall daemon.
lines 1-13/13 (END)
VLANのルート表にオラクルVPNルーターへのルートを書き込みました。

次のコマンドで、構成ファイルを再度読み取り、Libreswanサービスを再起動します。
[opc@localhost ~]$ service ipsec restart
Redirecting to /bin/systemctl restart ipsec.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to restart 'ipsec.service'.
Authenticating as: opc
Password:
==== AUTHENTICATION COMPLETE ====
この時点でvti01, vti02インターフェースが表示されます。
これらはIPsecトンネルの送信先、経路制御を行う仮想インターフェースです。
[root@localhost opc]# service ipsec restart
Redirecting to /bin/systemctl restart ipsec.service
[root@localhost opc]# ip a
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:50:56:aa:b3:fc brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.1.53/24 brd 192.168.1.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::250:56ff:feaa:b3fc/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:14:53:c2 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: 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: vti02@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip 192.168.1.53 peer 168.138.z.z
inet6 fe80::5efe:c0a8:135/64 scope link
valid_lft forever preferred_lft forever
6: vti01@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip 192.168.1.53 peer 168.138.y.y
inet6 fe80::5efe:c0a8:135/64 scope link
valid_lft forever preferred_lft forever
少し待つと、トンネルのIPsecステータスが「稼働中」の状態になりました。

疎通確認
libreswan VMと同じ分散ポートグループ上のtest-vmを用意し(赤色)、大阪リージョンのコンピュート・インスタンスと疎通できるかを確認します。IPアドレスはそれぞれ192.168.1.2、10.2.0.253です。

やることは二つあります。
- libreswan VMが受け取ったパケットをIPsecトンネルを通じて転送するためのルーティング設定
- test-vmがOCI宛てのパケットをlibreswan VMに向けるためのルーティング設定
疑似オンプレミスからOCIへのルーティング設定
libreswan VMにルートを追記します。
大阪のIPsec VCN向け(10.2.0.0/16向け)の通信を、追加された2つのインターフェースから転送するようにします。これにより、受け取った通信をIPsecトンネルを通してルーティングすることが可能になります。
[opc@localhost ~]$ sudo ip route add 10.2.0.0/16 nexthop dev vti01 nexthop dev vti02
[opc@localhost ~]$ ip route show
default via 192.168.1.1 dev ens33 proto static metric 100
10.2.0.0/16
nexthop dev vti01 weight 1
nexthop dev vti02 weight 1
192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.53 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
[opc@localhost ~]$
test-vmのデフォルト・ゲートウェイはVLANの1つ目のIPアドレスを向いています。
ここにスタティックでルートを追加して、大阪のVCN宛ての全ての通信がlibreswan VMを向くようにします。
[takahnak@localhost ~]$ ip route
default via 192.168.1.1 dev ens33 proto static metric 100
192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.2 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
[takahnak@localhost ~]$ sudo ip route add 10.2.0.0/16 via 192.168.1.53
[takahnak@localhost ~]$ ip route
default via 192.168.1.1 dev ens33 proto static metric 100
10.2.0.0/16 via 192.168.1.53 dev ens33
192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.2 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
これにてオンプレミス → OCIのルーティング設定は完了です。
OCIから疑似オンプレミスへのルーティング設定
大阪リージョンのOCIコンソールから、サブネットのルート表に疑似オンプレミスネットワーク(192.168.0.0/16)へのルールを追記します。IPsecトンネルを通すためにネクストホップはDRGです。

DRGのルート表も確認します。
VCNアタッチメントのルート表には、デフォルトのインポートルールにより(「Match ALL」でルートをインポート)、VCNとIPsecトンネルアタッチメントから伝播された疑似オンプレミスへのルートが含まれます。

IPsecアタッチメントのルート表には、デフォルトのインポートルールにより(仮想クラウドネットワークのアタッチメントからルートをインポート)OCIのIPsec VCNへのルートが書き込まれています。

まず、test-vmからIPsec VCNのコンピュート・インスタンスに向けてpingをします。無事疎通しました。
[takahnak@localhost ~]$ ping -c 3 10.2.0.253
PING 10.2.0.253 (10.2.0.253) 56(84) bytes of data.
64 bytes from 10.2.0.253: icmp_seq=1 ttl=60 time=9.04 ms
64 bytes from 10.2.0.253: icmp_seq=2 ttl=60 time=8.87 ms
64 bytes from 10.2.0.253: icmp_seq=3 ttl=60 time=8.77 ms
--- 10.2.0.253 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 8.765/8.891/9.038/0.112 ms
反対の経路も疎通確認します。
コンピュート・インスタンスからtest-vmに向けてpingを行いました。
無事に疎通しました。
[opc@test-instance ~]$ ping -c 3 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=61 time=8.92 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=61 time=8.77 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=61 time=8.81 ms
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 8.765/8.832/8.923/0.066 ms
4. 結論
vSphere上の仮想マシンにlibreswanをインストールしてOCIのサイト間VPNを設定することができました。オンプレミスで物理ルーターを用意できない場合に同構成検討は検討に値するかもしれないです。また、vSphereに限らず他の仮想環境を利用した構成もありえるため、機会があれば検証してみたいです。
5. トラブルシューティングに役立つ機能
手打ちの箇所が多く、構成要素も多いので上手く繋がらない場合は切り分け作業が必要です。トラブルシューティングのためには、IPsec接続でログを有効化してみることをお薦めします。

私は、途中でログのメッセージによってsecretsファイルを書き間違えていたことに気づきました(上記の手順では修正済みです)。
" \"1310621564\"[1] 132.226.x.x #210: IKE SA authentication request rejected by peer: AUTHENTICATION_FAILED"
各メッセージの解説はこちらのドキュメントにまとまっています。




