StrongSwan IPsec IKEv2によるサイト間VPN:Linuxでのプロダクション環境構築ガイド

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

ベンダーへの「上乗せ費用」を回避して拠点間接続をセキュアにする

複数のオフィス拠点を接続しようとすると、インフラチームは高価な専用ハードウェアの導入を検討しがちです。CiscoやFortinetの機器は非常に堅牢ですが、高スループット機能のライセンス料だけで、1ノードあたり年間2,000ドルを超えることも珍しくありません。

昨年、私は基幹インフラをStrongSwanベースのサイト間VPNに移行しました。標準的な Ubuntuノード上で動作するこのセットアップは、現在、メインのデータセンターと3つの地方拠点の間で、継続的な850 Mbpsのデータベース・レプリケーションとVoIPトラフィックを処理しています。移行以来、計画外のダウンタイムは一度も発生していません。

StrongSwanは、LinuxにおけるIPsecの業界標準です。IKEv2(Internet Key Exchange version 2)プロトコルを利用することで、従来のIKEv1セットアップでは実現できなかったレベルの回復力を提供します。一時的なISPの切断からもミリ秒単位で復旧し、複雑な回避策なしでNATトラバーサルを処理できます。Linuxサーバーを管理しており、パブリックインターネットを介してサブネット間をブリッジする必要がある場合、このアプローチはベンダーロックインなしでプロフェッショナルグレードのトンネルを提供します。

前提条件とネットワーク構成

このガイドに従うには、2つのLinuxインスタンス(Ubuntu 22.04またはDebian 12が理想的)が必要です。500 Mbps以上のトラフィックを処理する本番環境のトンネルでは、少なくとも2 vCPUと4GBのRAMを推奨します。この例では以下の構成を使用します:

  • サイトA (本社):
    • パブリックIP: 1.2.3.4
    • プライベートサブネット: 192.168.10.0/24
  • サイトB (支店):
    • パブリックIP: 5.6.7.8
    • プライベートサブネット: 192.168.20.0/24

まず、IPフォワーディングが有効であることを確認してください。これが無効だと、サーバーは暗号化されたパケットを受信しても、内部ネットワークに転送する方法がわかりません。sysctl net.ipv4.ip_forwardで現在のステータスを確認し、出力が0の場合は、恒久的に有効化してください。

# IPv4フォワーディングを即座に有効化
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

ステップ1:StrongSwanスイートのインストール

ソフトウェアのインストールは2分もかかりません。コアとなるStrongSwanパッケージと、charon-systemdバックエンドをインストールします。これにより、古いチュートリアルで使用されていたレガシーなipsec.confファイルよりも、はるかに読みやすくモジュール化された現代的な設定ツールであるswanctlを使用できるようになります。

sudo apt update
sudo apt install strongswan libcharon-extra-plugins libcharon-extauth-plugins strongswan-swanctl

サービスはインストール時に自動的に開始されます。ただし、設定が完全に検証されるまでは、ハンドシェイクの失敗ログで溢れるのを防ぐため、通常はトンネルを停止した状態にしておきます。

ステップ2:トンネル設定の構築

まずはサイトAから始めます。サイトBの設定は論理的な対称(ミラー)設定になります。swanctlディレクトリに新しいファイルを作成し、IKEv2セッションとトラフィックセレクターを定義します。

# サイトAで設定ファイルを作成
sudo nano /etc/swanctl/conf.d/hq-to-branch.conf

以下のブロックをファイルに貼り付けます。ここでは簡素化のため事前共有鍵(PSK)を使用しますが、多数のエンドポイントを持つ大規模なデプロイメントではRSA証明書の方が適しています。

connections {
    hq-to-branch {
        remote_addrs = 5.6.7.8
        local_addrs = 1.2.3.4
        
        local {
            auth = psk
            id = 1.2.3.4
        }
        remote {
            auth = psk
            id = 5.6.7.8
        }
        
        children {
            net-to-net {
                local_ts = 192.168.10.0/24
                remote_ts = 192.168.20.0/24
                esp_proposals = aes256-sha256-modp2048
                start_action = trap
            }
        }
        version = 2
        proposals = aes256-sha256-modp2048
    }
}

暗号化プロポーザルに注意してください: aes256-sha256-modp2048という文字列は暗号化のハンドシェイク設定です。両方のサイトでこれが完全に一致している必要があります。start_action = trap設定は本番環境では不可欠です。これは、内部サーバーがリモートサブネットに通信を試みた瞬間に、Linuxカーネルが自動的にVPNを起動するように指示するものです。

共有シークレットの保護

PSKは専用のシークレットファイルに保存します。簡単なパスワードは避け、本番環境では最低でも64文字のランダムな文字列を使用してください。

sudo nano /etc/swanctl/conf.d/secrets.conf
secrets {
    ike-hq-branch {
        id-1 = 1.2.3.4
        id-2 = 5.6.7.8
        secret = "V3ry_Str0ng_R4ndom_K3y_Th4t_Is_Unique"
    }
}

次に、これをサイトBでも繰り返します。localremoteのIPアドレスおよびサブネットを入れ替えるだけです。シークレット(secret)は両方のサーバーで同一である必要があります。

ステップ3:ファイアウォールルールとMSS「サイレントキラー」

多くの管理者がここで躓きます。パブリックインターフェースでUDPポート500と4500を開放する必要があります。さらに、内部ファイアウォールに対し、リモートサブネットから送られてくるトラフィックを信頼するように設定する必要があります。

# IKEおよびNAT-Tポートを開放
sudo ufw allow 500/udp
sudo ufw allow 4500/udp

# リモート拠点のサブネットからローカルサービスへの通信を許可
sudo ufw allow from 192.168.20.0/24 to any

隠れた罠が一つあります。それはMTUの断片化(フラグメンテーション)です。IPsecは各パケットにヘッダーを追加するため、標準の1500バイトのMTU制限を超えてしまうことがあります。これにより、SSHセッションがハングしたり、ウェブページの読み込みに失敗したりすることがよくあります。これを解決するために、iptablesを使用して最大セグメントサイズ(MSS)を固定(クランプ)します。

sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu

ステップ4:監視と検証

ファイルを保存したら、設定をリロードします。swanctlは、標準的なサービス再起動よりもはるかに優れたフィードバックを提供してくれます。

sudo swanctl --load-all

トンネルがアクティブかどうかを確認するには、--list-sasコマンドを実行します。セキュリティアソシエーション(SA)、暗号化アルゴリズム、そして最も重要な、転送データのバイトカウンターが表示されます。

sudo swanctl --list-sas

正常なトンネルの出力は以下のようになります:

hq-to-branch: #1, ESTABLISHED, IKEv2
  local  '1.2.3.4' @ 1.2.3.4[500]
  remote '5.6.7.8' @ 5.6.7.8[500]
  AES_CBC-256/HMAC_SHA2_256_128/MODP_2048
  net-to-net: #1, INSTALLED, TUNNEL, ESP:AES_CBC-256/HMAC_SHA2_256_128
    local  192.168.10.0/24
    remote 192.168.20.0/24

もし “ESTABLISHED” と表示されない場合は、journalctl -f -u strongswanを使用してリアルタイムでログを確認してください。これにより、キーの不一致かポートのブロックかなど、ネゴシエーションが失敗している箇所を正確に特定できます。私の経験では、失敗の90%は単純なファイアウォールの設定漏れや、リモートIPアドレスの入力ミスによるものです。

安定性に関する最終的な考察

半年間の激しい使用を経て、IKEv2sの自己修復機能は際立った特徴となっています。午前3時にISPがメンテナンスを行った際も、StrongSwanのDead Peer Detection(DPD)が停止を検知し、経路が回復した瞬間にトンネルを再確立しました。暗号化レイヤーの完全な可視化、隠れたライセンス料なし、そしてVMインスタンスのサイズを変更するだけで帯域幅をスケールできる柔軟性は、無駄のないIT運用にとって大きな勝利です。

Share: