クラウド移行の過渡期や、既存の物理サーバーをすぐに廃止できない現場では、このような相談がよく出てきます。AzureのVPN Gatewayを使えば、オンプレミスネットワークとAzure VNet(仮想ネットワーク)をIPsec(IKEv2)の暗号化トンネルで安全に接続できます。
この記事では、Azure VPN GatewayとLinuxのIPsecソフトウェア「strongSwan」を組み合わせたサイト間VPN(Site-to-Site VPN)の構築手順を、azコマンドの実行ログとともに解説します。GatewaySubnetの設計と役割から始まり、Local Network Gatewayの設定、strongSwanの設定ファイル記述、VPN接続後のNSG(ネットワークセキュリティグループ)設定、疎通確認まで手順を網羅します。
動作確認環境:Azure CLI 2.61 / RHEL 9.4・Ubuntu 24.04 LTS / strongSwan 5.9
この記事のポイント
・az network vnet-gateway createでVPN Gatewayを作成(完了まで20~45分かかる)
・GatewaySubnetは/27以上が必須・サブネット名は「GatewaySubnet」固定・VMの配置は禁止
・オンプレLinuxにstrongSwanを導入しipsec.conf・ipsec.secretsで接続を定義する
・VPN接続後はNSGでオンプレのCIDRからアプリサブネットへのアクセスを明示的に許可する
・接続後はaz network vpn-connection showとpingで疎通を確認する
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
サイト間VPNとはオンプレとAzureをIPsecで繋ぐ仕組み
Azureの「VPN Gateway」は、オンプレミスのネットワークとAzure仮想ネットワーク(VNet)をIPsecトンネルで繋ぐためのマネージドゲートウェイサービスです。接続の種類として「サイト間VPN(S2S)」「ポイント対サイトVPN(P2S)」「ExpressRoute」がありますが、この記事では拠点(オンプレ)とAzureを繋ぐS2S VPNを扱います。Azure側のS2S VPN構築に必要なリソースは4種類です。
・GatewaySubnet:VPN Gateway専用のサブネット(名前を「GatewaySubnet」固定・変更不可・VMの配置禁止)
・VPN Gateway:IPsec終端とルーティングを担うAzureマネージドゲートウェイ
・Local Network Gateway:オンプレミス側のパブリックIPとネットワーク範囲を定義するリソース
・Connection:VPN GatewayとLocal Network Gatewayを紐づける接続オブジェクト
接続の流れはIKEv2による2フェーズのネゴシエーションです。まずIKE Phase1でSA(Security Association)を確立し、次にIKE Phase2でIPsecトンネルを確立します。確立後はオンプレの内部IPからAzure VNet内のプライベートIPへ、暗号化された通信が通ります。
AWSのSite-to-Site VPNと比べると、リソース名称と概念の対応関係は以下のとおりです。
| Azure | AWS VPC相当 | 補足 |
|---|---|---|
| VPN Gateway | Virtual Private Gateway(VGW) | AzureはGatewaySubnetが必須・VMの配置禁止 |
| Local Network Gateway | Customer Gateway(CGW) | オンプレ側のIPとCIDRを登録するリソース |
| Connection(IPsec) | Site-to-Site VPN Connection | PSKまたは証明書認証 |
| GatewaySubnet(名前固定) | (VGWはVPCアタッチのみ・専用サブネット不要) | Azure固有の概念。名称が違うとGateway作成エラーになる |
今回の構成と前提条件
今回の手順では次の構成を前提とします。・Azure VNet CIDR:10.1.0.0/16
・GatewaySubnet:10.1.255.0/27
・アプリケーション用サブネット:10.1.1.0/24
・オンプレミスネットワーク:192.168.0.0/24
・オンプレLinuxのパブリックIP:固定グローバルIPが必要(NAT環境は追加設定が必要)
前提条件を確認してください。
・Azure CLIがインストール・ログイン済み(
az account showで確認)・オンプレLinuxに固定グローバルIPがある(またはNATアドレスが固定)
・オンプレLinuxのファイアウォールでUDP 500・4500が通過できる
・strongSwanをインストールできるsudo権限がある
VNetのサブネット設計について
VPN接続の設定に入る前に、サブネット分割の考え方を整理しておきます。今回の構成ではVNetを「アプリケーション用サブネット」と「GatewaySubnet」の2つに分割しています。サブネットを役割ごとに分割することで得られる主な利点は次のとおりです。
・セキュリティの境界を層ごとに引ける:アプリケーションサブネットにNSG(ネットワークセキュリティグループ)を適用し、オンプレのCIDR(192.168.0.0/24)からのアクセスのみ許可することで、インターネットから直接アクセスできない層をネットワーク設計レベルで実現できます
・NSG設定の見通しがよくなる:NSGをサブネット単位で適用するとVMが増えても「このサブネット全体にこのルールが適用されている」という構造が崩れません
・GatewaySubnetの専用確保:VPN GatewayはGatewaySubnetという名前固定の専用サブネットにしか作成できません。将来のVPN接続やExpressRoute追加に備えて/27以上のブロックを事前に予約するのが実務の慣例です
今回使うサブネット構成をまとめると次のとおりです。
| サブネット名 | CIDR | 役割 |
|---|---|---|
| subnet-app(アプリケーション層) | 10.1.1.0/24 | VMやサービスを配置する実業務用サブネット |
| GatewaySubnet(ゲートウェイ専用) | 10.1.255.0/27 | VPN Gateway専用・VMの配置禁止 |
Azure側の設定手順
1. リソースグループとVNetを作成する
まずリソースグループとVNetを用意します。既存のVNetを使う場合はこのステップを省略してください。# リソースグループを作成 az group create \ --name rg-s2s-vpn \ --location japaneast # VNetを作成(まず汎用サブネットのみ定義し、GatewaySubnetは後の手順で追加) az network vnet create \ --resource-group rg-s2s-vpn \ --name vnet-hub \ --address-prefix 10.1.0.0/16 \ --subnet-name subnet-app \ --subnet-prefix 10.1.1.0/24
2. GatewaySubnetを追加する
GatewaySubnetはVPN GatewayやExpressRoute Gatewayを配置するための専用サブネットです。作成にあたって次の3点を必ず守ってください。・名前は必ず「GatewaySubnet」:大文字小文字を含め完全一致が必要。「gatewaysubnet」「Gateway-Subnet」ではVPN Gateway作成時にエラーになります
・/27(32アドレス)以上のサイズを確保する:/28(16アドレス)でも動作しますが、将来的なActiveActive構成やExpressRoute共存を考えると最初から/27以上を確保しておくことをお勧めします
・通常のVMを置かない:AzureがGatewaySubnet内のIPアドレスをゲートウェイ用に内部管理するため、ここにVMを配置すると競合や予期しない通信障害が発生します
# GatewaySubnetを追加する(名前変更不可・/27以上必須) az network vnet subnet create \ --resource-group rg-s2s-vpn \ --vnet-name vnet-hub \ --name GatewaySubnet \ --address-prefix 10.1.255.0/27
3. パブリックIPとVPN Gatewayを作成する
VPN Gateway用のパブリックIPを確保してから、ゲートウェイ本体を作成します。VPN Gatewayの作成は20~45分かかります。--no-waitで非同期実行し、作業を続けながら待機できます。# VPN Gateway用パブリックIPを作成(StaticのStandard SKU) az network public-ip create \ --resource-group rg-s2s-vpn \ --name pip-vpngw \ --allocation-method Static \ --sku Standard \ --location japaneast # VPN Gatewayを作成(--no-waitで非同期実行) az network vnet-gateway create \ --resource-group rg-s2s-vpn \ --name vpngw-hub \ --vnet vnet-hub \ --public-ip-address pip-vpngw \ --gateway-type Vpn \ --vpn-type RouteBased \ --sku VpnGw1 \ --no-wait # 作成状況を確認(Succeeded になるまで数分おきに確認する) az network vnet-gateway show \ --resource-group rg-s2s-vpn \ --name vpngw-hub \ --query "provisioningState" -o tsv
# VPN GatewayのパブリックIPを取得 az network public-ip show \ --resource-group rg-s2s-vpn \ --name pip-vpngw \ --query ipAddress -o tsv # 出力例(このIPをstrongSwanのrightに設定する) 40.74.xxx.xxx
4. Local Network Gatewayを作成する
Local Network Gatewayは「オンプレミス側の情報」をAzureに登録するリソースです。オンプレのパブリックIPとルーティング先のネットワーク範囲を指定します。# Local Network Gatewayを作成 # --gateway-ip-address : オンプレLinuxの固定グローバルIP # --local-address-prefixes : オンプレの内部ネットワーク(複数指定可) az network local-gateway create \ --resource-group rg-s2s-vpn \ --name lgw-onprem \ --gateway-ip-address 203.0.113.xxx \ --local-address-prefixes 192.168.0.0/24 \ --location japaneast
5. VPN Connectionを作成する
VPN GatewayとLocal Network Gatewayを紐づけるConnectionを作成します。事前共有鍵(PSK)はopensslで生成した32バイト以上のランダム文字列を使用してください。# 事前共有鍵(PSK)を生成 openssl rand -base64 32 # 出力例(この値をAzureとstrongSwanの両方に設定する) # 7Xt5vBqN2mP8wRkL4sYjDcHaUeGfZnIo9T3pEyMuAvWX1b6= # VPN Connectionを作成(IKEv2・PSK認証) az network vpn-connection create \ --resource-group rg-s2s-vpn \ --name conn-s2s-onprem \ --vnet-gateway1 vpngw-hub \ --local-gateway2 lgw-onprem \ --connection-type IPsec \ --shared-key "7Xt5vBqN2mP8wRkL4sYjDcHaUeGfZnIo9T3pEyMuAvWX1b6="
6. アプリケーションサブネット用NSGを設定する
VPN Connectionを作成しただけでは、オンプレのLinuxサーバーからAzure VNet内のVMへの通信がNSGにブロックされる場合があります。subnet-appにNSGを作成・適用し、オンプレのCIDRからのアクセスを明示的に許可します。NSGルールは優先度の数値が小さいほど先に評価されます。AllowルールをDenyルールより小さい優先度番号で設定することで、VPN経由のオンプレアクセスは許可・インターネットからの直接アクセスはブロックというセキュリティ設計が実現できます。VPN Gatewayの作成に20~45分かかるのが最大の待ち時間なので、--no-waitで走らせている間にLocal Network Gateway・strongSwan設定・NSG設定を並行して進めると効率的に作業できます。
# アプリケーションサブネット用NSGを作成する az network nsg create \ --resource-group rg-s2s-vpn \ --name nsg-app # オンプレネットワーク(192.168.0.0/24)からSSH・アプリポートを許可する(優先度100) az network nsg rule create \ --resource-group rg-s2s-vpn \ --nsg-name nsg-app \ --name allow-from-onprem \ --priority 100 \ --protocol Tcp \ --source-address-prefixes "192.168.0.0/24" \ --destination-port-ranges 22 80 443 8080 \ --access Allow \ --direction Inbound # インターネットからの直接インバウンドを拒否する(優先度4000) az network nsg rule create \ --resource-group rg-s2s-vpn \ --nsg-name nsg-app \ --name deny-internet-inbound \ --priority 4000 \ --protocol "*" \ --source-address-prefixes Internet \ --destination-port-ranges "*" \ --access Deny \ --direction Inbound # subnet-appにNSGを紐付ける az network vnet subnet update \ --resource-group rg-s2s-vpn \ --vnet-name vnet-hub \ --name subnet-app \ --network-security-group nsg-app # NSGルール一覧を優先度順に確認する(sort_byで評価順が一目でわかる) az network nsg rule list \ --resource-group rg-s2s-vpn \ --nsg-name nsg-app \ --query "sort_by([].{Name:name, Priority:priority, Access:access, SrcPrefix:sourceAddressPrefix}, &Priority)" \ --output table # 出力例(「DenyAllInBound」はAzureが自動追加するデフォルトルール) # Name Priority Access SrcPrefix # --------------------- -------- ------ ---------------- # allow-from-onprem 100 Allow 192.168.0.0/24 # deny-internet-inbound 4000 Deny Internet # DenyAllInBound 65500 Deny *
Azure対応セミナーの詳細を見る >>
オンプレミスLinuxサーバー側の設定(strongSwan)
1. strongSwanをインストールする
strongSwanはRHEL 9/Rocky LinuxとUbuntu 24.04 LTSの両方で利用できます。# RHEL 9 / Rocky Linux 9の場合 sudo dnf install -y strongswan # Ubuntu 24.04 LTSの場合 sudo apt update && sudo apt install -y strongswan strongswan-pki libcharon-extra-plugins # バージョン確認 ipsec version # strongSwan 5.9.x University of Applied Sciences Rapperswil...
2. /etc/ipsec.confを設定する
strongSwanの接続定義ファイルを編集します。leftがオンプレ側(自分)、rightがAzure側(相手)です。暗号スイートはAzureのデフォルト互換であるAES-256・SHA-256・DH Group14(modp2048)を指定します。# /etc/ipsec.conf config setup charondebug="ike 2, knl 2, cfg 2" conn azure-vpn # 認証・起動設定 authby=secret auto=start type=tunnel keyexchange=ikev2 # オンプレ側(left)の設定 left=%defaultroute leftid=203.0.113.xxx # オンプレのパブリックIP leftsubnet=192.168.0.0/24 # オンプレの内部ネットワーク # Azure側(right)の設定 right=40.74.xxx.xxx # VPN GatewayのパブリックIP rightsubnet=10.1.0.0/16 # Azure VNetのCIDR # 暗号スイート(Azureデフォルト互換・DH Group14=modp2048) ike=aes256-sha256-modp2048! esp=aes256-sha256-modp2048! # ライフタイム(Azureデフォルト値に合わせる) ikelifetime=28800s lifetime=27000s margintime=540s # Dead Peer Detection(DPD) dpddelay=30 dpdtimeout=120 dpdaction=restart
3. /etc/ipsec.secretsを設定する
PSKをipsec.secretsに登録します。フォーマットは「オンプレIP Azure側IP : PSK "鍵文字列"」です。# /etc/ipsec.secrets 203.0.113.xxx 40.74.xxx.xxx : PSK "7Xt5vBqN2mP8wRkL4sYjDcHaUeGfZnIo9T3pEyMuAvWX1b6="
sudo chmod 600 /etc/ipsec.secrets sudo chown root:root /etc/ipsec.secrets
4. strongSwanを起動し接続を確立する
設定ファイルを保存したらstrongSwanを起動します。# strongSwanを有効化・起動 sudo systemctl enable strongswan sudo systemctl start strongswan # 接続を手動で開始する sudo ipsec up azure-vpn
initiating IKE_SA azure-vpn[1] to 40.74.xxx.xxx IKE_SA azure-vpn[1] established between 192.168.0.10[203.0.113.xxx]...40.74.xxx.xxx[40.74.xxx.xxx] CHILD_SA azure-vpn{1} established with SPIs c3a8f1b2_i 7e5d4c6a_o connection 'azure-vpn' established successfully
接続確認と疎通テスト
VPNトンネルが確立されたら、Azure側・オンプレ側の両方から状態を確認します。Azure CLIで接続状態を確認する
az network vpn-connection show \ --resource-group rg-s2s-vpn \ --name conn-s2s-onprem \ --query "{status:connectionStatus,egress:egressBytesTransferred,ingress:ingressBytesTransferred}" \ -o table # 出力例(Connectedが成功の証) Status Egress Ingress --------- ------ ------- Connected 45231 12087
# Azure VM(10.1.1.4)への疎通確認 ping -c 4 10.1.1.4 # 出力例(オンプレ192.168.0.10からAzure VM 10.1.1.4へ到達確認) PING 10.1.1.4 (10.1.1.4) 56(84) bytes of data. 64 bytes from 10.1.1.4: icmp_seq=1 ttl=63 time=18.4 ms 64 bytes from 10.1.1.4: icmp_seq=2 ttl=63 time=17.8 ms 64 bytes from 10.1.1.4: icmp_seq=3 ttl=63 time=18.1 ms 64 bytes from 10.1.1.4: icmp_seq=4 ttl=63 time=18.3 ms --- 10.1.1.4 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3005ms rtt min/avg/max/mdev = 17.8/18.15/18.4/0.219 ms
sudo ipsec statusall # 出力例(ESTABLISHEDが成功・転送バイト数が増えていれば通信中) Security Associations (1 up, 0 connecting): azure-vpn[1]: ESTABLISHED 12 minutes ago, 192.168.0.10[203.0.113.xxx]...40.74.xxx.xxx[40.74.xxx.xxx] azure-vpn[1]: IKEv2 SPIs: 8a2c1b4e9f3d7a01_i* 5c7e2a4b6d8f0e3c_r, rekeying in 7 hours azure-vpn{1}: INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: c3a8f1b2_i 7e5d4c6a_o azure-vpn{1}: AES_CBC_256/HMAC_SHA2_256_128, 45231 bytes_i, 12087 bytes_o azure-vpn{1}: 192.168.0.0/24 === 10.1.0.0/16
接続できない時のトラブルシュート
【確認1】IKEネゴシエーションが失敗している場合
journalctl -u strongswan -fでリアルタイムログを確認します。よくあるエラーと対処は次のとおりです。・「no proposal chosen」:ike=またはesp=の暗号スイートがAzure側と一致していない。Azure側でカスタムIPsecポリシーを設定している場合は、そのパラメータとstrongSwanの設定を突き合わせてください
・「authentication failed」:ipsec.secretsのPSKがAzure接続のShared Keyと一致していない。PSKにスペースや改行が混入していないか確認してください
・「received INVALID_ID_INFORMATION」:leftidに指定したIPがNAT越しの実際のIPと異なる。NAT環境では
leftid=%anyを試してください【確認2】UDPポートがブロックされている場合
IKEv2はUDP 500でSA確立を行い、NAT越しの場合はUDP 4500(NAT-T)を使用します。オンプレのファイアウォールで開放されているか確認します。# LinuxのfirewalldでIPsec関連サービスを確認 sudo firewall-cmd --list-services | grep ipsec # 開放されていない場合は追加 sudo firewall-cmd --permanent --add-service=ipsec sudo firewall-cmd --reload # UDPポートの待受を確認(ssコマンド) sudo ss -nulp | grep -E "500|4500"
【確認3】接続がすぐに切れる場合
DPD(Dead Peer Detection)の設定不一致が原因の場合があります。Azureのデフォルトは30秒間隔・45秒でタイムアウトです。また、IPsecに必須の要件として時刻同期があります。オンプレとAzure間で時刻がずれているとIKEネゴシエーションが失敗することがあります。LinuxのNTP・時刻同期設定でchronydの動作を確認してください。
接続が確立してもすぐ切れる場合は、Azure側のNSGでオンプレのパブリックIPからのUDP 500・4500が許可されているかも確認が必要です。VPN GatewayのGatewaySubnet向けNSGはデフォルトでは不要ですが、カスタムNSGを適用している環境では意図せずブロックされることがあります。
【確認4】VPN接続後にアプリへの通信がブロックされる場合
VPNトンネル自体は確立(ESTABLISHEDの状態)しているのに、Azure VM上のアプリケーションに到達できないケースはNSGの設定漏れが最もよくある原因です。次のコマンドでsubnet-appのNSG紐付けとルール内容を確認してください。# subnet-appのNSG紐付け状況を確認する az network vnet subnet show \ --resource-group rg-s2s-vpn \ --vnet-name vnet-hub \ --name subnet-app \ --query "networkSecurityGroup.id" \ --output tsv # 出力が空(null)の場合はNSGが未紐付け → az network vnet subnet updateで紐付けを実施する # NSGルール一覧を優先度順に確認する az network nsg rule list \ --resource-group rg-s2s-vpn \ --nsg-name nsg-app \ --query "sort_by([].{Name:name, Priority:priority, Access:access, SrcPrefix:sourceAddressPrefix}, &Priority)" \ --output table
本記事のまとめ
AzureのVPN Gatewayによるサイト間VPN構築の要点をまとめます。| やりたいこと | コマンド・ポイント |
|---|---|
| GatewaySubnetを作成する | az network vnet subnet create --name GatewaySubnet --address-prefix 10.1.255.0/27 |
| VPN Gatewayを作成する | az network vnet-gateway create --gateway-type Vpn --vpn-type RouteBased --sku VpnGw1 |
| オンプレ情報をAzureに登録する | az network local-gateway create --gateway-ip-address <IP> --local-address-prefixes <CIDR> |
| VPN Connectionを作成する | az network vpn-connection create --connection-type IPsec --shared-key <PSK> |
| NSGを作成してサブネットに適用する | az network nsg create → az network nsg rule create → az network vnet subnet update --network-security-group NSG名 |
| NSGルール一覧を優先度順に確認する | az network nsg rule list --query "sort_by([],&Priority)" --output table |
| strongSwanで接続を確立する | ipsec up azure-vpn(ipsec.conf・ipsec.secrets設定後) |
| Azure側の接続状態を確認する | az network vpn-connection show --query connectionStatus |
| オンプレ側の接続状態を確認する | ipsec statusall(ESTABLISHEDが成功) |
Azure対応セミナーの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます