Engineering

Azure ポイント対サイトVPN(S2P)の設計

ちょっと分かりづらいAzure ポイント対サイト VPN の接続方法を検証しました。Azureでは複数のVPN接続方法がありますが今回は最もコストが安いVPN Basicでの接続についてご紹介します。帯域が100Mbps、冗長性不要、BGP利用不要ということでしたらBasicが最もコスト的にお安くVPNを構築できます。

AzureのVPN Gatewayとは?

Azure VPN Gatewayは、Microsoft Azureが提供する仮想ネットワーク間やオンプレミス環境とAzureの間でセキュアな接続を確立するための重要なサービスです。具体的には、パブリックインターネット上で暗号化された接続を利用して、Azure仮想ネットワーク (VNet) と他のリソースを結びつけます。これにより、拠点間VPNやポイント対サイトVPN、さらにはエクスプレスルートと併用することによって、ハイブリッドクラウド構成を簡単に実現できます。

Azure VPN Gatewayには複数の種類があり、帯域幅や冗長性、BGPのサポートといった機能に応じて選ぶことができます。例えば、帯域幅が100Mbpsで冗長性が不要、BGPを利用しない場合には、最もコストパフォーマンスが高いのはBasic SKUです。このプランは月額およそ3,700円と手頃な価格で、検証環境や、停止が許容される環境には特におすすめです。

VPN Gateway の価格 | Microsoft Azure

今回構築したい環境

この構成では、10.10.0.0/16の仮想ネットワークを使用してVPN環境を構築し、Azure内の他の仮想ネットワークや、Azure FilesなどのPaaSサービスにアクセスできる環境を目指します。この構成により、オンプレミス環境や他のネットワークから、Azureのリソースにセキュアに接続できるようになります。今回は、VPNが接続できるところまで試していきたいと思います。

VPN経由でアクセスする仮想ネットワークService-vnet(10.11.0.0/16)は作成済み前提とします。
手順としては下記の手順になります。
・VPN環境用の仮想ネットワーク(default-vnet)の作成
・VPN Gateway (Basic)をプロビジョニング
・Service-vNetとdefault-vnetのピアリング
・VPN Serverのクライアント証明書作成手順
・VPNGatewayの設定(ルーティング設定、証明書登録)
・WindowsクライントをインストールしVPN接続
今回はここまで実施していきたいと思います。

VPN環境用の仮想ネットワーク(default-vnet)とVPN Gateway (Basic)をプロビジョニング

一番安いVPN Gateway BasicはPowerShellでしか作成できません。将来的にはできるようですが、VpnGw1以上の高いGatewayのみがAzurePortalで作成となっております。今回は下記サイトの手順でVPN Gateway Basicを作りたいと思います。仮想ネットワークの作成からプロビジョニングまでを実行します。
仮想ネットワーク ゲートウェイを作成する: PowerShell – Azure VPN Gateway | Microsoft Learn

PCからAzureにPowershellを実行する場合は下記を先に実施しておいてください。
How to install Azure PowerShell | Microsoft Learn

上のマニュアルをコピペでもできますが、結構面倒くさいので、自動実行できるスクリプトを作成しました。コピーしてご利用下さい。必要な情報を入れると仮想ネットワークの作成からVPN Gatewayの作成まで実行できます。

# Azureへの認証
Write-Host "Azureにサインインしています..."
Connect-AzAccount

# 対話式でリソース名とプレフィックスを確認
function Get-Input {
    param (
        [string]$promptMessage,
        [string]$defaultValue
    )
    $input = Read-Host -Prompt "$promptMessage [$defaultValue]"
    if ([string]::IsNullOrEmpty($input)) {
        return $defaultValue
    } else {
        return $input
    }
}

# 初期入力
$resourceGroupName = Get-Input -promptMessage "リソースグループ名を入力してください" -defaultValue "default-rg"
$region = Get-Input -promptMessage "リージョンを入力してください (例: JapanEast)" -defaultValue "JapanEast"
$virtualNetworkName = Get-Input -promptMessage "仮想ネットワーク名を入力してください" -defaultValue "default-vnet"
$subnetName = Get-Input -promptMessage "サブネット名を入力してください" -defaultValue "default-subnet"
$gatewaySubnetName = Get-Input -promptMessage "ゲートウェイサブネット名を入力してください" -defaultValue "GatewaySubnet"
$publicIpName = Get-Input -promptMessage "パブリックIPアドレスの名前を入力してください" -defaultValue "default-publicip"
$vpnGwName = Get-Input -promptMessage "VPNゲートウェイ名を入力してください" -defaultValue "default-vpngw"
$addressPrefix = Get-Input -promptMessage "アドレスプレフィックス (例: 10.0.0.0/16) を入力してください" -defaultValue "10.0.0.0/16"
$subnetPrefix = Get-Input -promptMessage "サブネットプレフィックス (例: 10.0.0.0/24) を入力してください" -defaultValue "10.0.0.0/24"
$gatewaySubnetPrefix = Get-Input -promptMessage "ゲートウェイサブネットプレフィックス (例: 10.0.254.0/24) を入力してください" -defaultValue "10.0.254.0/24"

# 入力内容を確認
do {
    Write-Host "以下の設定を確認してください:"
    Write-Host "1. リソースグループ名: $resourceGroupName"
    Write-Host "2. リージョン: $region"
    Write-Host "3. 仮想ネットワーク名: $virtualNetworkName"
    Write-Host "4. サブネット名: $subnetName"
    Write-Host "5. ゲートウェイサブネット名: $gatewaySubnetName"
    Write-Host "6. パブリックIPアドレス名: $publicIpName"
    Write-Host "7. VPNゲートウェイ名: $vpnGwName"
    Write-Host "8. アドレスプレフィックス: $addressPrefix"
    Write-Host "9. サブネットプレフィックス: $subnetPrefix"
    Write-Host "10. ゲートウェイサブネットプレフィックス: $gatewaySubnetPrefix"

    $modify = Read-Host "変更したい項目番号があれば入力してください (終了するには Enter を押してください)"
    
    switch ($modify) {
        "1" { $resourceGroupName = Get-Input -promptMessage "リソースグループ名を入力してください" -defaultValue $resourceGroupName }
        "2" { $region = Get-Input -promptMessage "リージョンを入力してください (例: JapanEast)" -defaultValue $region }
        "3" { $virtualNetworkName = Get-Input -promptMessage "仮想ネットワーク名を入力してください" -defaultValue $virtualNetworkName }
        "4" { $subnetName = Get-Input -promptMessage "サブネット名を入力してください" -defaultValue $subnetName }
        "5" { $gatewaySubnetName = Get-Input -promptMessage "ゲートウェイサブネット名を入力してください" -defaultValue $gatewaySubnetName }
        "6" { $publicIpName = Get-Input -promptMessage "パブリックIPアドレスの名前を入力してください" -defaultValue $publicIpName }
        "7" { $vpnGwName = Get-Input -promptMessage "VPNゲートウェイ名を入力してください" -defaultValue $vpnGwName }
        "8" { $addressPrefix = Get-Input -promptMessage "アドレスプレフィックス (例: 10.0.0.0/16) を入力してください" -defaultValue $addressPrefix }
        "9" { $subnetPrefix = Get-Input -promptMessage "サブネットプレフィックス (例: 10.0.0.0/24) を入力してください" -defaultValue $subnetPrefix }
        "10" { $gatewaySubnetPrefix = Get-Input -promptMessage "ゲートウェイサブネットプレフィックス (例: 10.0.254.0/24) を入力してください" -defaultValue $gatewaySubnetPrefix }
    }
} while ($modify -ne "")

# ユーザーに最終確認
$confirmation = Read-Host "上記の設定で作成しますか?(Y/N)"
if ($confirmation -ne "Y") {
    Write-Host "作成を中止しました。"
    exit
}

# リソースグループの存在確認と作成
$resourceGroup = Get-AzResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
if (-not $resourceGroup) {
    Write-Host "リソースグループ '$resourceGroupName' が存在しません。作成します。"
    New-AzResourceGroup -Name $resourceGroupName -Location $region
} else {
    Write-Host "リソースグループ '$resourceGroupName' は既に存在します。"
}

# 仮想ネットワークの存在確認と作成
$virtualNetwork = Get-AzVirtualNetwork -ResourceGroupName $resourceGroupName -Name $virtualNetworkName -ErrorAction SilentlyContinue
if (-not $virtualNetwork) {
    Write-Host "仮想ネットワーク '$virtualNetworkName' が存在しません。作成します。"
    $virtualNetwork = New-AzVirtualNetwork -ResourceGroupName $resourceGroupName -Location $region -Name $virtualNetworkName -AddressPrefix $addressPrefix
    $subnetConfig = Add-AzVirtualNetworkSubnetConfig -Name $subnetName -AddressPrefix $subnetPrefix -VirtualNetwork $virtualNetwork
    $virtualNetwork | Set-AzVirtualNetwork
} else {
    Write-Host "仮想ネットワーク '$virtualNetworkName' は既に存在します。"
}

# ゲートウェイサブネットの存在確認と作成
$vnet = Get-AzVirtualNetwork -ResourceGroupName $resourceGroupName -Name $virtualNetworkName
$gatewaySubnet = Get-AzVirtualNetworkSubnetConfig -Name $gatewaySubnetName -VirtualNetwork $vnet -ErrorAction SilentlyContinue
if (-not $gatewaySubnet) {
    Write-Host "ゲートウェイサブネット '$gatewaySubnetName' が存在しません。作成します。"
    Add-AzVirtualNetworkSubnetConfig -Name $gatewaySubnetName -AddressPrefix $gatewaySubnetPrefix -VirtualNetwork $vnet
    $vnet | Set-AzVirtualNetwork
} else {
    Write-Host "ゲートウェイサブネット '$gatewaySubnetName' は既に存在します。"
}

# パブリックIPアドレスの存在確認と作成
$gwpip = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -Name $publicIpName -ErrorAction SilentlyContinue
if (-not $gwpip) {
    Write-Host "パブリックIPアドレス '$publicIpName' が存在しません。作成します。"
    $gwpip = New-AzPublicIpAddress -Name $publicIpName -ResourceGroupName $resourceGroupName -Location $region -AllocationMethod Dynamic -Sku "Basic"
} else {
    Write-Host "パブリックIPアドレス '$publicIpName' は既に存在します。"
}

# VPNゲートウェイの存在確認と作成
$vpnGateway = Get-AzVirtualNetworkGateway -ResourceGroupName $resourceGroupName -Name $vpnGwName -ErrorAction SilentlyContinue
if (-not $vpnGateway) {
    Write-Host "VPNゲートウェイ '$vpnGwName' が存在しません。作成します。"

    # ゲートウェイサブネットが作成された後、$subnet.Idがnullでないことを確認するループ
    $subnet = $null
    while (-not $subnet -or -not $subnet.Id) {
        Write-Host "ゲートウェイサブネットの構成を取得中..."
        $vnet = Get-AzVirtualNetwork -ResourceGroupName $resourceGroupName -Name $virtualNetworkName
        $subnet = Get-AzVirtualNetworkSubnetConfig -Name $gatewaySubnetName -VirtualNetwork $vnet
        if ($subnet.Id) {
            Write-Host "ゲートウェイサブネットが正常に取得されました。"
        } else {
            Write-Host "ゲートウェイサブネットがまだ準備中です。5秒後に再試行します..."
            Start-Sleep -Seconds 5
        }
    }

    $gwipconfig = New-AzVirtualNetworkGatewayIpConfig -Name "$vpnGwName-ipconfig" -SubnetId $subnet.Id -PublicIpAddressId $gwpip.Id

    # VPNゲートウェイ作成
    Write-Host "VPNゲートウェイ作成中(数十分かかります)"
    New-AzVirtualNetworkGateway -Name $vpnGwName -ResourceGroupName $resourceGroupName -Location $region -IpConfigurations $gwipconfig -GatewayType "Vpn" -VpnType "RouteBased" -GatewaySku "Basic" -VpnGatewayGeneration "Generation1"
} else {
    Write-Host "VPNゲートウェイ '$vpnGwName' は既に存在します。"
}

# VPNゲートウェイ表示
Get-AzVirtualNetworkGateway -Name $vpnGwName -ResourceGroup $resourceGroupName

# パブリックIPアドレス表示
Get-AzPublicIpAddress -Name $publicIpName -ResourceGroupName $resourceGroupName

Powershellを保存して実行するとAzureへのサインインを促されますので、管理者アカウントでのサインインを行います。メニューが表示されますのでそのまま実行すると、仮想ネットワークからVPNGatewayまで作成が全自動で作成されます。実行すると下記のメニューが表示されます。下記のように入力すると構成図と同じものが作成されます。

Azureにサインインしています...
リソースグループ名を入力してください [default-rg]: 
リージョンを入力してください (例: JapanEast) [JapanEast]: 
仮想ネットワーク名を入力してください [default-vnet]: 
サブネット名を入力してください [default-subnet]: 
ゲートウェイサブネット名を入力してください [GatewaySubnet]: 
パブリックIPアドレスの名前を入力してください [default-publicip]: 
VPNゲートウェイ名を入力してください [default-vpngw]: 
アドレスプレフィックス (例: 10.0.0.0/16) を入力してください [10.0.0.0/16]: 
サブネットプレフィックス (例: 10.0.0.0/24) を入力してください [10.0.0.0/24]: 
ゲートウェイサブネットプレフィックス (例: 10.0.254.0/24) を入力してください [10.0.254.0/24]: 

以下の設定を確認してください:
1. リソースグループ名: default-rg
2. リージョン: JapanEast
3. 仮想ネットワーク名: default-vnet
4. サブネット名: default-subnet
5. ゲートウェイサブネット名: GatewaySubnet
6. パブリックIPアドレス名: default-publicip
7. VPNゲートウェイ名: default-vpngw
8. アドレスプレフィックス: 10.0.0.0/16
9. サブネットプレフィックス: 10.0.0.0/24
10. ゲートウェイサブネットプレフィックス: 10.0.254.0/24
変更したい項目番号があれば入力してください (終了するには Enter を押してください): 

項目について補足すると、
・アドレスプレフィックス: 10.0.0.0/16
VPN Gatewayを配置する仮想ネットワークのアドレス帯になります。他のネットワークと被らないものに変更をしてください。
・サブネットプレフィックス: 10.0.0.0/24
上記仮想ネットワークのデフォルトになるサブネットです。VPNの構成には使用しませんが作成します。このサブネットに仮想マシンなどを置くとVPN接続後すぐに、アクセス可能となります。
・ゲートウェイサブネットプレフィックス: 10.0.254.0/24
VPN Gatewayが実際に配置されるサブネットになります。

作成には30分ほど時間がかかります。VPNゲートウェイ、パブリックIPアドレスの詳細表示実行されると完成です。AzurePortalからも確認できます。

AzurePortalのVPN Gateway

Service-vNetとdefault-vnetのピアリング

現在の状態だと、VPNに接続してもdefault-vnet(10.0.0.0/16)にしか接続できません。通常は他の仮想ネットワークにサービス用の仮想マシンやPaaSがありますのでこちらに接続できるようにdefault-vnetとピアリングを行いますい。今回は仮想ネットワークservice-vnet(10.11.0.0/16)へ接続できるようにします。他のネットワークに繋がないよという場合は飛ばしても大丈夫です。

Default-vnetのピアリングから「追加」をして設定を行います。

まずはリモート仮想ネットワークであるservice-vnet(10.11.0.0/16)の設定です。
Default-vnetへのアクセス許可と、リモートゲートウェイへの転送を許可します。

ローカルネットワーク側(default-vnet:10.0.0.0/16)は、service-vnetからのアクセスを許可。Serivice-vnetのトラフィック転送を許可します。

以上でピアリングが完了し、2つのネットワーク間の通信が可能となりました。

VPN Serverのクライアント証明書作成手順

Azure VPN Gatewayに接続する際には、クライアント証明書を使用します。今回は、自己署名のルート証明書を作成し、それを元にクライアント証明書を発行します。証明書の発行にはPowerShellを使用します。

1. 自己署名ルート証明書を生成

まず、自己署名のルート証明書を生成します。PowerShellを起動し、次のコマンドを実行します。
* RootCertSATORI は環境に合わせて任意の名称に変更してください。

$cert = New-SelfSignedCertificate -Type Custom -KeySpec Signature `<br>-Subject CN=RootCertSATORI -KeyExportPolicy Exportable `<br>-HashAlgorithm sha256 -KeyLength 2048 `<br>-CertStoreLocation Cert:\CurrentUser\My -KeyUsageProperty Sign -KeyUsage CertSign<br>

2. クライアント証明書を発行

次に、ルート証明書を使用してクライアント証明書を発行します。この操作はPowerShell上でルート証明書を作成した後、引き続き同じ画面で以下のコマンドを実行してください。クライアントごとに証明書を発行することをおすすめします。
*SATORIClient も環境に応じて変更可能です。複数作るときは連番にするなど名前が被らないように作成してください

New-SelfSignedCertificate -Type Custom -DnsName P2SChildCert -KeySpec Signature `
-Subject CN=SATORIClient -KeyExportPolicy Exportable `
-HashAlgorithm sha256 -KeyLength 2048 `
-CertStoreLocation Cert:\CurrentUser\My `
-Signer $cert -TextExtension @(2.5.29.37={text}1.3.6.1.5.5.7.3.2)

クライアント証明書を作る前に、PowerShellを閉じてしまった場合には、再度自己署名ルート証明書を指定してクライアント証明書を発行する手順が必要です。詳しくはMicrosoftの公式ドキュメントをご参照ください。公式ドキュメント: Azure VPN Gateway – クライアント証明書の作成

VPNGatewayの設定(ルーティング設定、証明書登録)

続いて、Azure VPN Gatewayでのポイント対サイト構成の設定を行います。これには、VPNクライアントが接続するための自己署名ルート証明書の設定、アドレスプールの設定、およびルーティングテーブルの設定が含まれます。

アドレスプールの設定
まず、VPNクライアントが使用するアドレス範囲(アドレスプール)を設定します。これはVPNクライアントが接続時に割り当てられるIPアドレスの範囲です。default-vnetとは異なるネットワーク帯を指定する必要があり、今回は「10.0.0.0/24」を設定します。
重要な点として、VPNクライアントが接続しているネットワークセグメントと競合しない範囲を選択してください。

追加のルーティング設定
次に、Azure Virtual Network(VNet)同士のピアリングを行った後、必要なルーティングを追加します。このルート設定がないと、デフォルトの仮想ネットワーク「default-vnet(10.10.0.0/16)」以外のネットワークにはアクセスできません。ここでは、サービス用の仮想ネットワーク「service-vnet(10.11.0.0/16)」を追加します。複数のルートを指定する場合は、カンマ区切りで入力してください。新たに接続するネットワークが増えるたびに、ルートの追加を行い、VPNクライアント用の構成ファイルを再ダウンロードする必要があります。

ルート証明書(自己署名ルート証明書)の登録
前の手順で作成した自己証明ルート証明書を登録します。まず作成した端末で、「certmgr.msc」を実行し、証明書をエクスポートします。

エクスポートした証明書をメモ帳で開き,—–BEGIN CERTIFICATE—–と—–END CERTIFICATE—–を除いてコピーをします。

VPN Gatewayの「ポイント対サイトの構成」にルート証明書をコピーします。

すべて入力後、「保存」します。VPNが再起動するため適用に少し時間がかかります。「VPNクライアントのダウンロード」が表示されたら、VPNクライアントをダウンロードして下さい。設定変更した場合は常に再ダウンロードが必要です。

WindowsクライントでのVPN接続設定

最後に、VPNクライアント側の設定手順について説明します。ここでは、ダウンロードしたVPNクライアントソフトを使用して、接続端末での設定を進めていきます。

VPNクライアント側の設定手順

  1. クライアント証明書のインストール
    まず、作成したクライアント証明書を接続端末にインストールします。
  2. VPNクライアントソフトのインストール
    次に、ダウンロードしたVPNクライアントソフトを接続端末にインストールします。

クライアント証明書のインストール

1.クライアント証明書を作成した端末で certmgr.msc を起動します。
2.作成したクライアント証明書をエクスポートします。エクスポート時には、秘密鍵も含めて、.pfx形式でエクスポートします。
3.エクスポートした証明書をVPNクライアント側の端末にコピーし、インポートします。

VPNクライアントソフトのインストール

ダウンロードしたVPNクライアントソフトを接続する端末に配置します。ファイルを解凍すると下記の構成になっています。WindowsAmd64の「VpnClientSetupAmd64.msi」を実行してインストールします。

Windows設定アプリのVPNにvpngatewayの接続設定が作成されますのでそちらから「接続」を行います。

接続をすると専用アプリケーションが起動し、接続することができます。
途中でルート情報の変更を確認するメッセージが出た場合は承認をしてください。

専用のVPNアプリが不要の場合は「WindowsPowershell」フォルダにあるスクリプトで構成することも可能です。この場合は上記の専用アプリはインストールされません。

VPN接続でエラーが出た場合は下記を参照ください。
Azure ポイント対サイト接続の問題のトラブルシューティング – Azure VPN Gateway | Microsoft Learn

以上でVPN接続が完了します。

                       

弊社では、Microsoft Azure関連の最新情報を日本語で分かりやすく、月1回(緊急時は都度)ご案内するメールマガジンを配信しています。
Azure管理者様必見です!ご興味お持ちいただけましたらぜひ下記よりご登録くださいね。

    
    

関連記事

コメント

この記事へのコメントはありません。

TOP