VPN Gateway のデフォルト サイトについて


Azure で S2S VPN を構成した際に、デフォルト サイト (デフォルト ゲートウェイ) を設定するパラメーターがあります。
通常ポータル等には出てこないので、Azure PowerShell を使わないと設定できないんですが、知らないとたまに困るのでメモ。

どういったタイミングで使うかというと…

  • VPN で強制トンネリングを使う場合
    (ローカル ネットワーク ゲートウェイで指定したアドレス空間以外もオンプレにルーティングする場合)
  • マルチ サイトと VPN 接続をした場合
    (アドレス空間が重複する場合に、どれを優先させるか指定したい場合)
# 既存の設定を取得
$VnetGw = Get-AzureRmVirtualNetworkGateway -Name "<仮想ネットワーク ゲートウェイ名>" -ResourceGroupName "<リソース グループ名>"
$LocalGw = Get-AzureRmLocalNetworkGateway -Name "<デフォルト サイトとして設定するローカル ネットワーク ゲートウェイ名>" -ResourceGroupName "<リソース グループ名>"

# デフォルト サイトのパラメーターを設定、保存
$VnetGw.GatewayDefaultSite = $LocalGw
Set-AzureRmVirtualNetworkGateway -VirtualNetworkGateway $VnetGw

こんな感じで、GatewayDefaultSite といパラメーターに、デフォルト サイトとして使うローカル ネットワーク ゲートウェイを指定してあげてください。


日本語化した Azure VM で .NET Framework 3.5 のインストールに失敗する


タイトルの通りですが、Azure VM をテンプレートの英語版で作成したのち、日本語化した環境で .NET Framework 3.5 等のインストールに失敗することがあります。

1 つ以上の役割、役割サービス、または機能のインストールに失敗しました。
ソース ファイルが見つかりませんでした。役割と機能の追加ウィザードの新しいセッションで役割、役割サービス、または機能のインストールを再実行し、ウィザードの [確認] ページで [大体ソース パスの指定] をクリックして、インストールに必要なソース ファイルの有効な場所を指定してください。指定する場所は、インストール先サーバーのコンピューター アカウントによってアクセスできる必要があります。

installfailed

通常、インターネットに接続できる環境であれば、必要なモジュールは適宜ダウンロードされるので、上記のエラーは発生しないと思います。ただ、外部接続を NSG や Firewall で制限している場合、ExpressRoute の構成をしていたりする場合には、ダウンロードできず上記のエラーになることがあります。

ここでエラーにも書いてある通り、代替ソース パスを指定してインストールしようとするのですが、これもエラーで失敗します。(SxS は適当に Windows Server の評価版なり MSDN から ISO をダウンロードしてきて、Source フォルダ内の SxS をコピーします。)

sxs

installfailed

明示的にインストール ファイルを指定しても失敗するのは何故かというと、英語 OS を日本語化しているからです。つまり、.NET Framework 3.5 の日本語・英語の両モジュールがないとインストールができません。

日本語の ISO と英語の ISO をそれぞれ用意して、両方の SxS フォルダーを統合し、代替ソース パスとして指定することで、以下の通り無事にインストールが完了します。

installsuccessfully

 

Azure というより、Windows OS のお作法的な話なので、知らないと意外にハマります。

元々日本語の OS を使えば問題ないですし、インターネットにつながればダウンロードしてくれるので、めったに遭遇することはありませんが、似た症状に遭遇したら試してみてください。


Login-AzureRmAccount がエラーになる件


ちょっと相談を受けたのですが、他にもはまる人がいそうな気がしたのでメモ。

Azure PowerShell のログイン処理で Login-AzureRmAccout を使いますが、以下のようなエラーが出る場合があります。

$cred = Get-Credential
Login-AzureRmAccount -Credential $cred
Login-AzureRmAccount : シーケンスに要素が含まれていません
 発生場所 行:2 文字:1
 + Login-AzureRmAccount -Credential $cred
 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 + CategoryInfo : CloseError: (:) [Add-AzureRmAccount]、AadAuthenticationFailedException
 + FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.AddAzureRMAccountCommand

見慣れないエラーなので、何が起きているかがわかりにくいですが、結論としては Microsoft アカウント (hotmail.com とか outlook.com とか) で
Credential オプションを使っちゃだめなようです。

Credential オプションなしでログインするか、Credential を使う場合はAzure AD 上の組織アカウントを指定すれば、このエラーは起きません。

ドキュメントを読んでも、「職場または学校のアカウントにサインインします。」と記載があるので、組織アカウントしか対応していないみたいですね。

以上。


Azure Active-Active VPN Gateway


Ignite 初日ですが、大量にアップデートが出ましたね。

事前に Azure PowerShell にオプション増えて察知できていた Active-Active Gateway も構成できるようになったので、まとめておきます。

何が変わったのか

今回新たに Virtual Network Gateway (VPN Gateway) の Active-Active 構成ができるようになりました。

これまでは 2 台のインスタンスが Active-Standby で、死んだら切り替わる動作のため、メンテナンスなり障害なりでダウンタイムが数分ほど発生しました。さらに言うと、Azure の VPN Gateway が持つ Public IP も 1 つだったため、オンプレとはセッションを一本しか張っておらず、仮にオンプレにルーターを二台おいても切り替えが発生した際の数分程度のダウンタイムは避けられませんでした。

active-standby

multiple-onprem-vpns

これが、新たに 2 台のインスタンスそれぞれに Public IP を振れるようになって、オンプレと 2 セッション (ないし 2×2 セッション) 張れるようになったので、冗長性を高めることが可能になったというわけ。(BGP で経路の再計算をさせて切り替えるため、対応ルーターが必要と思われます)

active-active

dual-redundancy

要件

Azure 側の VPN Gateway は High Performance SKU 必須で、オンプレも BGP が喋れるルーターが必要になるので、そこそこお高い構成になります。あと、既に BGP が有効の Gateway であれば Public IpConfigurations に Public IP を足せば構成できそうですが、BGP が無効な場合は Gateway の再作成が必要になりますのでご注意を。

サンプル

取り急ぎ、事前にある程度組んでおいた PowerShell が通ることを確認したので、Active-Active Gateway を作成するサンプルを載せておきます。(オンプレとの接続までは未検証)

$ResourceGroupName = "<リソース グループ名>"
$Location = "<リージョン名>"
$VNetName = "<仮想ネットワーク名>"
$VNetPrefix = "10.0.0.0/16"
$GwPrefix = "10.0.0.0/28"
$Subnet1Prefix = "10.0.1.0/24"
New-AzureRmResourceGroup -Name $ResourceGroupName -Location $Location
$subnet1 = New-AzureRmVirtualNetworkSubnetConfig -Name "GatewaySubnet" -AddressPrefix $GwPrefix
$subnet2 = New-AzureRmVirtualNetworkSubnetConfig -Name "Subnet1" -AddressPrefix $Subnet1Prefix
New-AzureRmVirtualNetwork -Name $VNetName -ResourceGroupName $ResourceGroupName -Location $Location -AddressPrefix $VNetPrefix -Subnet $subnet1, $subnet2
$gwpip1 = New-AzureRmPublicIpAddress -Name gwpip1 -ResourceGroupName $ResourceGroupName -Location $Location -AllocationMethod Dynamic
$gwpip2 = New-AzureRmPublicIpAddress -Name gwpip2 -ResourceGroupName $ResourceGroupName -Location $Location -AllocationMethod Dynamic
$vnet = Get-AzureRmVirtualNetwork -Name $VNetName -ResourceGroupName $ResourceGroupName
$subnet = Get-AzureRmVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet
$gwipconfig1 = New-AzureRmVirtualNetworkGatewayIpConfig -Name gwipconfig1 -SubnetId $subnet.Id -PublicIpAddressId $gwpip1.Id
$gwipconfig2 = New-AzureRmVirtualNetworkGatewayIpConfig -Name gwipconfig2 -SubnetId $subnet.Id -PublicIpAddressId $gwpip2.Id
New-AzureRmVirtualNetworkGateway -Name VNetGW1 -ResourceGroupName $ResourceGroupName -Location $Location -IpConfigurations $gwipconfig1,$gwipconfig2 -GatewayType Vpn -VpnType RouteBased -GatewaySku HighPerformance -ActiveActive $True -EnableBgp $True

 

で、エラーなくできるとこんな感じです。

IpConfigurations           : {gwipconfig1, gwipconfig2}
GatewayType                : Vpn
VpnType                    : RouteBased
EnableBgp                  : True
ActiveActive               : True
GatewayDefaultSite         : 
ProvisioningState          : Succeeded
Sku                        : Microsoft.Azure.Commands.Network.Models.PSVirtualNetworkGatewaySku
VpnClientConfiguration     : 
BgpSettings                : Microsoft.Azure.Commands.Network.Models.PSBgpSettings
IpConfigurationsText       : [
                               {
                                 "PrivateIpAllocationMethod": "Dynamic",
                                 "Subnet": {
                                   "Id": "/subscriptions/49dde45f-5712-44b2-b0ab-296bde83af6b/resourceGroups/shuda0927/providers/Microsoft.Network/virtualNetworks/shuda0927/subnets/GatewaySubnet"
                                 },
                                 "PublicIpAddress": {
                                   "Id": "/subscriptions/49dde45f-5712-44b2-b0ab-296bde83af6b/resourceGroups/shuda0927/providers/Microsoft.Network/publicIPAddresses/gwpip1"
                                 },
                                 "Name": "gwipconfig1",
                                 "Etag": "W/\"0378e30c-82ac-4d27-9be3-c11ec55d16a9\"",
                                 "Id": "/subscriptions/49dde45f-5712-44b2-b0ab-296bde83af6b/resourceGroups/shuda0927/providers/Microsoft.Network/virtualNetworkGateways/VNetGW1/ipConfigurations/gwipconfig1"
                               },
                               {
                                 "PrivateIpAllocationMethod": "Dynamic",
                                 "Subnet": {
                                   "Id": "/subscriptions/49dde45f-5712-44b2-b0ab-296bde83af6b/resourceGroups/shuda0927/providers/Microsoft.Network/virtualNetworks/shuda0927/subnets/GatewaySubnet"
                                 },
                                 "PublicIpAddress": {
                                   "Id": "/subscriptions/49dde45f-5712-44b2-b0ab-296bde83af6b/resourceGroups/shuda0927/providers/Microsoft.Network/publicIPAddresses/gwpip2"
                                 },
                                 "Name": "gwipconfig2",
                                 "Etag": "W/\"0378e30c-82ac-4d27-9be3-c11ec55d16a9\"",
                                 "Id": "/subscriptions/49dde45f-5712-44b2-b0ab-296bde83af6b/resourceGroups/shuda0927/providers/Microsoft.Network/virtualNetworkGateways/VNetGW1/ipConfigurations/gwipconfig2"
                               }
                             ]
GatewayDefaultSiteText     : null
SkuText                    : {
                               "Capacity": 2,
                               "Name": "HighPerformance",
                               "Tier": "HighPerformance"
                             }
VpnClientConfigurationText : null
BgpSettingsText            : {
                               "Asn": 65515,
                               "BgpPeeringAddress": "10.0.0.4,10.0.0.5",
                               "PeerWeight": 0
                             }
ResourceGroupName          : shuda0927
Location                   : japaneast
ResourceGuid               : dd386981-ca4d-49a5-8ddf-9f81e892cf5e
Tag                        : 
TagsTable                  : 
Name                       : VNetGW1
Etag                       : W/"0378e30c-82ac-4d27-9be3-c11ec55d16a9"
Id                         : /subscriptions/49dde45f-5712-44b2-b0ab-296bde83af6b/resourceGroups/shuda0927/providers/Microsoft.Network/virtualNetworkGateways/VNetGW1

我が家の機材で疎通確認取れたら、またアップデートするかもしれません。()


Azure のネットワーク周りを整理してみる


ここ半年で Azure のネットワーク機能が進化しすぎて、正直ついていけません。
備忘とリンク集を兼ねて各種機能・接続形態を整理しておきます。(注釈がない限り ARM が対象です)

※ 2016/09/18 時点の情報に基づいて書いていますが、Azure の進化が速すぎるので記載が正しくない可能性が多分にあります。

Azure Network 関連機能

ざっと書き出すと、以下が Azure Network 関連機能ですかね。

ポータルに項目としてあるやつを書き出したつもりですが、これで網羅できてますかね…。(まだありそう)

Azure 内で VNet 同士を繋ぐ方法

最近 VNet Peering が増えたので、ざっくり三通り?

Azure とオンプレを繋ぐ方法

オンプレとの接続も三通り。

ただ、BGP の有無とか、Active-Active とか、オプションを組み合わせると膨大に…。

原則として Azure の VNet Gateway は IPsec のパラメーターをいじれないので、オンプレ側を調整して繋ぎましょう。(繋がらない・繋がってもすぐ切れる場合は、オンプレ側の VPN 機器で設定ミスってるか、ファームが古いか、そもそも対応してない可能性大で、Azure はほぼ問題ないです。ずっと繋がってたのが突如切れた場合を除いて。)

ExpressRoute の種類

ExpressRoute にも L2 / L3 の二種類のモデルあります。

  • L2 モデル
    国内だとおそらく Equinix のみが提供中で、L2 の名の通り回線設備のみを提供してくれます。
    ルーターのコンフィグ (経路制御とか) は全部自前でやる必要があるので、BGP が喋れない人には無理。
    l2
  • L3 モデル
    Equinix 以外の各社はルーターの面倒も見てくれる L3 モデルのはずです。(IIJ, Softbank, NTT Com, etc…)
    l3

それから、ExpressRoute は Azure のエッジ ルーターとオンプレ側のルーターを繋ぐ部分なので、上図の通り Azure エッジ ルーターと各 VNet にある Gateway をリンクする必要があります。リンクできる VNet は 10 個までです。(Premium アドオンが有効な場合はそれ以上)

同じジオ (日本だと東・西日本) 内の VNet にはバックボーン経由でリンクが可能で、その他にも費用が二倍かかりますが東・西日本でそれぞれ ExpressRoute 引いたりも多分できるはず。

multiregion

S2S VPN の種類

VPN は Gateway が二種類あります。

  • 静的 / ポリシー ベース / IKEv1
  • 動的 / ルート ベース / IKEv2

静的だと 1 拠点としか接続できないので、基本的には動的で。動的の場合には Basic / Standard SKU で 10 拠点、High Performance で 30 拠点まで行けます。ただし、オンプレミス側の VPN 機器が動的に対応していない場合は静的を使うしかないです。(対応状況はこちらおよび各ベンダーのページを確認しましょう。なお、国内でよく使われているヤマハの RTX は動的未対応です。)

それから、気づけば VPN でも BGP が喋れるようになりました。下図のように組めば、切断が発生しても BGP で経路が再計算されて、迂回経路を通るようにできます。(多分) 詳しくは図の拝借元でもあるこちらのドキュメントを参照。

multiple-active-tunnels

full-mesh-transit

さらに、Azure PowerShell 2.1.0 からは Active-Active というパラメーターが追加されています。まだコマンドのオプションがこっそり用意された段階で、プレビューにすらなっていないので使えないようですが、コマンドのエラーを見ると High Performance SKU 限定の機能のようです。通常は Active-Standby で単一の Public IP を持っている VPN Gateway (2 台) を、Public IP を一つずつ持たせて、Active-Active にできるようですね。(なんか発表されたら後日書き足します。)

VNet Peering の構成

まだ Public Preview 中ですが、Azure の “同一リージョン内” の VNet を VPN なしに接続できるのが VNet Peering です。Azure の基盤は NVGRE を使っているので、SDN 側でよしなに繋いでくれるんでしょう。

いろいろ組み合わせがありますが、現状以下の模様。ARM 同士を繋ぐ場合は、双方向で Peering が必要です。

  • 同一サブスクリプション内の ARM 同士: OK
  • 同一サブスクリプション内の ARM と ASM: OK
  • 異なるサブスクリプションの ARM 同士: 同一 AAD 配下なら OK (?)
  • 異なるサブスクリプションの ARM と ASM: NG
  • ASM 同士: NG

この辺は「焦げlog」さんが詳しいです。

 

また気まぐれで書き足します。


PowerShell Direct で VM 展開を自動化してみる


Windows 10 / Windows Server 2016 から、PowerShell Direct という機能が増えています。

これを活用すると、Hyper-V ホストから VM の中に対してファイルをコピーしたり、コマンド実行ができるので、大量の VM を自動で展開できるようになります。例えば、Azure PowerShell のバージョン毎に VM を作るには以下のような感じ。

事前に応答ファイルを差し込んだ sysprep 済みの VHD と、各バージョンの Azure PowerShell を用意しておく必要がありますが、その辺は説明が長くなるので今回は書きません。(わからない人は、応答ファイルとか unattend とか sysprep といったキーワードで検索すればいくらでも情報でるので調べてください。)

# Azure PowerShell のインストーラーを配置したフォルダー
$PowerShellInstallder = Get-ChildItem 'C:\Users\Administrator\Desktop\Azure PowerShell'

# Azure PowerShell のインストーラー分だけ VM を作成
$PowerShellInstallder | foreach{
    # ファイル名 (azure-powershell.1.0.0.msi) からバージョンを抽出
    $Ver = $_.Name -replace 'azure-powershell.', '' -replace '.msi', ''

    # 仮想マシン名の Prefix を定義
    $VMName = 'Win 10 Ent x64 with Azure PowerShell $Ver'

    # sysprep 済みのマスター イメージをコピー
    Copy-Item -Path 'D:\Win 10 Ent x64 with Azure PowerShell Master.vhdx' -Destination 'D:\Win 10 Ent x64 with Azure PowerShell $Ver.vhdx'

    # コピーした VHD をもとに VM を作成
    New-VM -Name $VMName -VHDPath 'D:\Win 10 Ent x64 with Azure PowerShell $Ver.vhdx'

    # VM のコア数、メモリ、NIC などを任意でカスタマイズ
    Set-VMProcessor -VMName $VMName -Count 16
    Set-VMMemory -VMName $VMName -DynamicMemoryEnabled $true
    Set-VMNetworkAdapter -VMName $VMName
    Get-VMNetworkAdapter -VMName $VMName | Connect-VMNetworkAdapter -SwitchName external

    # VM を起動
    Start-VM -Name $VMName
}

上記は空の VM を作っただけなので、続いてインストーラーを VM 内にコピーして実行します。
あわせて、せっかくなので Windows PowerShell の Execution Policy とか、Explorer のレジストリも一緒に設定しています。

$PowerShellInstallder | foreach{
    # 各種変数を設定
    $FullPath = $_.FullName
    $FileName = $_.Name
    $Ver = $_.Name -replace 'azure-powershell.', '' -replace '.msi', ''
    $VMName = 'Win 10 Ent x64 with Azure PowerShell $Ver'
    $InstallerPath = 'C:\Users\Public\Documents\$FileName'

    # 新規セッションを確立
    $Session = New-PSSession -VMName $VMName -Credential $Cred

    # VM 内で実行する処理の定義
    $DeployScript = '
    reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v LaunchTo /t REG_DWORD /d 1 /f
    reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer /v ShowRecent /t REG_DWORD /d 0 /f
    reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer /v ShowFrequent /t REG_DWORD /d 0 /f
    reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v HideFileExt /t REG_DWORD /d 0 /f
    reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v Hidden /t REG_DWORD /d 1 /f
    reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell /v EnableScripts /t REG_DWORD /d 1 /f
    reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell /v ExecutionPolicy /t REG_SZ /d RemoteSigned /f
    Start-Process -FilePath $InstallerPath -ArgumentList '/quiet' # Azure PowerShell のサイレント インストール
    '

    # 上記で定義した内容を、一旦ローカルに保存
    Out-File -InputObject $DeployScript -FilePath $env:TEMP\deploy.ps1

    # VM 内に Azure PowrShell のインストーラーをコピー
    Copy-Item -ToSession $Session -Path $FullPath -Destination 'C:\Users\Public\Documents'

    # VM 内でインストール処理を実行
    Invoke-Command -VMName $VMName -Credential $Cred $env:TEMP\deploy.ps1
}

以上で各バージョンがインストールされた VM が大量に生成され、インストールも完了していることが確認できます。
VHD のコピーには結構時間がかかるので、NVMe SSD とかを使うと快適ですね。

vmms

vm