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

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

共通化すると楽なはず

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.confIPsec 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接続が行えるようにする。

OSOS VersionstrongSwan Version
macOSSequoia 15.7.36.0.4
Ubuntu Server24.04 LTS5.9.13
  1. strongSwanをインストールする:
    • macOS: brew install strongswan
    • Ubuntu: sudo apt install strongswan
  2. 設定ファイル等を配置する
    • macOS: /opt/homebrew/etc/以下
    • Ubuntu: /etc/以下
  3. Ubuntu: 500番ポートの使用状況を確認する (使われているはず): sudo lsof -i :500
    COMMAND  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
  4. Ubuntu: 今回の場合は必要な時だけstrongSwanを手動起動する方針とするので、strongswan-starterのサービスを停止&自動起動無効化しておく: sudo systemctl disable --now strongswan-starter
  5. 500番ポートの使用状況を再確認する (使われていないはず): sudo lsof -i :500
  6. IPsec VPN接続サービスを(再)起動する: sudo ipsec restart
  7. IPsec VPN接続を開始する: sudo ipsec up example-ipsecvpn_subnet1
  8. IPsec VPN接続を終了する: sudo ipsec down

接続試行時に便利なコマンド

strongSwanの接続を色々と試行錯誤する場合には、設定ファイルを書き換えて、VPN接続を試して、ログの内容を確認する……、これを繰り返すことになる。その際に便利なipsecコマンドを以下に示す。

コマンド操作接続中のVPNセッションへの影響
ipsec rereadsecretsipsec.secretsを再読み込み (即時反映)切断なし
ipsec reloadipsec.confを再読み込み (既存セッションは維持, 新規セッションから設定反映)切断なし
ipsec restartstrongSwanサービスを再起動全て切断
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=add

ipsec.secretsのサンプル

: RSA {{秘密鍵ファイル名}}
{{XAuthのユーザー名}} {{VPN接続先ゲートウェイのIPアドレス}} : XAUTH "{{パスワード}}"
# 例: hogehoge AAA.BBB.CCC.DDD : XAUTH "123456"