strongSwanの設定をmacOSとUbuntuで共有する方法 〜IPsec VPN接続で楽をしたい〜

共通化すると楽なはず
VPN接続を設定する作業が、設定内容をテキストファイルに記述することのみで完結できると、VPN接続の設定を1度行えば他のマシンへの複製は簡単だ。そして、CLIのツールでは設定内容がテキストファイルとして保存されることが多い。
そこで今回、IPsec VPN接続の設定をstrongSwan CLIを用いて行い、その設定内容をmacOSとUbuntuで共通化することができたのでメモします。
strongSwanと設定ファイルについて
strongSwanは、IPsecでのVPN接続を可能にするオープンソースなCLIツールである。
strongSwanの設定ファイルは、Linux系OSではおなじみの/etc/以下に配置され、macOSではHomebrewでインストールした場合、/opt/homebrew/etc/以下に配置される。
| OS | 設定ファイル配置先ディレクトリ |
|---|---|
| Ubuntu | /etc/ |
| macOS | /opt/homebrew/etc/ |
上記のディレクトリ以下には、次のファイル等を配置する。
| Path | 内容 | 備考 |
|---|---|---|
ipsec.conf | IPsec VPN接続設定 | ipsec.confのサンプル |
ipsec.secrets | 事前共有鍵 | ipsec.secretsのサンプル, ※ (Ubuntu) |
ipsec.d/cacerts/* | CA証明書ファイル | ※ (Ubuntu) |
ipsec.d/certs/* | クライアント証明書ファイル | ※ (Ubuntu) |
ipsec.d/private/* | 秘密鍵ファイル | ※ (Ubuntu) |
※Ubuntuでは、AppArmorによるものと思われる制限で、ホーム領域に配置したファイルのsymlinkを設定ファイルとして読み込ませようとするとエラーになる (failed: Permission deniedなどがログに現れる)。このエラーを避けるためには、当該Pathにsymlinkではなくファイルの実体を配置する必要がある。
インストールと接続手順
今回の実験環境は次の通り。これらの環境にstrongSwanをインストールし、IPsec VPN接続が行えるようにする。
| OS | OS Version | strongSwan Version |
|---|---|---|
| macOS | Sequoia 15.7.3 | 6.0.4 |
| Ubuntu Server | 24.04 LTS | 5.9.13 |
- strongSwanをインストールする:
- macOS:
brew install strongswan - Ubuntu:
sudo apt install strongswan
- macOS:
- 設定ファイル等を配置する
- macOS:
/opt/homebrew/etc/以下 - Ubuntu:
/etc/以下
- macOS:
- Ubuntu: 500番ポートの使用状況を確認する (使われているはず):
sudo lsof -i :500COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME charon 1331 root 12u IPv6 10214 0t0 UDP *:isakmp charon 1331 root 14u IPv4 10216 0t0 UDP *:isakmp
- Ubuntu: 今回の場合は必要な時だけstrongSwanを手動起動する方針とするので、strongswan-starterのサービスを停止&自動起動無効化しておく:
sudo systemctl disable --now strongswan-starter - 500番ポートの使用状況を再確認する (使われていないはず):
sudo lsof -i :500 - IPsec VPN接続サービスを(再)起動する:
sudo ipsec restart - IPsec VPN接続を開始する:
sudo ipsec up example-ipsecvpn_subnet1 - IPsec VPN接続を終了する:
sudo ipsec down
接続試行時に便利なコマンド
strongSwanの接続を色々と試行錯誤する場合には、設定ファイルを書き換えて、VPN接続を試して、ログの内容を確認する……、これを繰り返すことになる。その際に便利なipsecコマンドを以下に示す。
| コマンド | 操作 | 接続中のVPNセッションへの影響 |
|---|---|---|
ipsec rereadsecrets | ipsec.secretsを再読み込み (即時反映) | 切断なし |
ipsec reload | ipsec.confを再読み込み (既存セッションは維持, 新規セッションから設定反映) | 切断なし |
ipsec restart | strongSwanサービスを再起動 | 全て切断 |
ipsec statusall | 接続状態を確認 | 切断なし |
ipsec listcerts | メモリ上に読み込んでいる証明書を一覧表示 | 切断なし |
サブネット1つしか認識されない時の回避策
今回私が実験したVPN接続先環境では、VPNを経由させたいサブネットを指定するrightsubnetに、次のように複数のサブネット1と2を列挙しても、実際に認識されたのは最初のサブネット1のみであった。
# 文法上は正しいものの、今回の実験環境では効かない rightsubnet=192.168.100.0/24,192.168.200.0/24
この場合に、サブネット1と2へアクセスする時にVPN接続を切り替えるなんて、面倒で現実的ではない。なんとか上手くやる方法をGeminiに聞いてみると、次のようなコマンドを提案してくれた。
sudo ipsec restart ; sleep 5 ; sudo ipsec up example-ipsecvpn_subnet1 ; sudo ipsec up example-ipsecvpn_subnet2実際にこれで上手くいく。2番目のVPN接続は、1番目のVPNセッションを利用しているらしく、効率的だ。また、設定の記述についても、ipsec.confのサンプルで示しているように、also=で既存の接続設定を参照させることにより、各サブネット用設定の記述を簡素化できる。
参考資料
ipsec.confのサンプル
# 接続例
conn example-ipsecvpn_base
# Basic
keyexchange=ikev1
aggressive=yes
auto=add
fragmentation=yes
# Gateway
right={{VPN接続先ゲートウェイのIPアドレス}} # 例: AAA.BBB.CCC.DDD
rightid=%any
rightauth=pubkey
# Client
leftid="C={{国名}}, CN={{クライアント証明書のCN}}" # 例: "C=JP, CN=hogehoge"
leftsourceip=%config
leftauth=pubkey
leftcert={{クライアント証明書ファイル名}} # certsに配置したファイル名
# XAuth
leftauth2=xauth
xauth_identity={{XAuthのユーザー名}} # 例: hogehoge
# Phase 1
ike=aes128-sha1-modp2048,aes256-sha256-modp2048!
# Phase 2
esp=aes128-sha1-modp2048,aes256-sha256-modp2048!
# Life Time
ikelifetime=86400s # Phase1
lifetime=43200s # Phase2
dpddelay=30s # DPD (Dead Peer Detection)
dpdtimeout=120s
dpdaction=restart
conn example-ipsecvpn_subnet1
also=example-ipsecvpn_base
rightsubnet={{VPN接続先subnet1}} # 例: 192.168.100.0/24
auto=add
conn example-ipsecvpn_subnet2
also=example-ipsecvpn_base
rightsubnet={{VPN接続先subnet2}} # 例: 192.168.200.0/24
auto=addipsec.secretsのサンプル
: RSA {{秘密鍵ファイル名}}
{{XAuthのユーザー名}} {{VPN接続先ゲートウェイのIPアドレス}} : XAUTH "{{パスワード}}"
# 例: hogehoge AAA.BBB.CCC.DDD : XAUTH "123456"
