みち草

Azure中心にまとめる技術情報ブログ

Azure AutomationとSendGridで発信元AnyのNSGルールを検出してメール通知してみた

はじめに

AzureのIaaS環境を構成するにあたり、NSG(ネットワークセキュリティグループ)はまず間違いなく使用します。 何かしらのシステム基盤であればもちろんのこと、比較的自由に利用できる検証環境の場合でもNSGでのアクセス制御をしているでしょう。

自由に使わせる場合、よくわからずVMをデプロイしたらNSGを適用していたのに発信元IPアドレスがAnyで許可してた、ということもあると思います。(おまけ参照)

ただ、毎度チェックするわけにもいかないので、発信元IPアドレスがAnyのNSGルールをまとめて、表形式でメール通知するAutomationジョブを作成してみました。

2019年11月24日、AzureポリシーでNSGのルールを制限する方法を紹介しました。

www.michikusayan.com

目次

準備/設定

使用するスクリプト

今回作成したスクリプトの全体の流れは次のような構成です。

  1. 4列のテーブルオブジェクトを作成(NSG名、リソースグループ名、ルール名、宛先ポート)
  2. Automation実行アカウントにログイン
  3. サブスクリプション内のすべてのNSGおよびNSGルールを順に取得し、条件に合致するルールの情報をテーブルに追加
  4. テーブルオブジェクトを、メール送信するためのHTML形式に整形
  5. SendGridの認証情報を作成し、結果をメール送信(検出ルールが0の場合はメール送信しない)

スクリプト中のルール検出条件は、「ソースアドレスプレフィックスがAny」かつ「許可ルール」かつ「受信ルール」です。 中にはApplication Gatewayなど使用にポート許可が必要な場合もあるので特定のポートに限定することも考えましたが、 まずはシンプルに"疑わしいルール"を検出することにしました。

xxxの部分は環境に合わせて変更が必要です。

$MailToには、メール送信先のアドレスを配列形式で指定します。 $MailFromは差出人のアドレスですが、好きに指定してOKです。

Automation実行アカウントへのログインは、実行アカウントを作成する前提の記述のため、 実行アカウントを使わず別途資格情報を登録する場合には、記述の変更が必要です。

また、Azコマンドを使用しているため、後述のモジュールの追加が必要です。

# Create a Table
$Table = New-Object system.Data.DataTable "TestTable"
$Col1 = New-Object system.Data.DataColumn NSGName,([string])
$Col2 = New-Object system.Data.DataColumn ResourceGroupName,([string])
$Col3 = New-Object system.Data.DataColumn RuleName,([string])
$Col4 = New-Object system.Data.DataColumn DestPort,([string])
$Table.columns.add($col1)
$Table.columns.add($col2)
$Table.columns.add($col3)
$Table.columns.add($col4)

#Login Azure Automation
$connection = Get-AutomationConnection -Name "AzureRunAsConnection"
Connect-AzAccount -ServicePrincipal -Tenant $connection.TenantID -ApplicationId $connection.ApplicationID -CertificateThumbprint $connection.CertificateThumbprint | Out-Null

# Detect NSG Rules
Get-AzNetworkSecurityGroup | ForEach-Object{
    $NSGName = $_.Name
    $RGName = $_.ResourceGroupName
    $AllSecrityRules = $_.SecurityRules

    $AllSecrityRules | ForEach-Object{
        $RuleName = $_.Name
        $SourceAddressPrefix = $_.SourceAddressPrefix
        $Access = $_.Access
        $Direction = $_.Direction
        $DestinationPort = $_.DestinationPortRange -join ","

        if(($SourceAddressPrefix -eq "*") -and
            ($Access -eq "Allow") -and
            ($Direction -eq "Inbound"))
        {
                $row = $table.NewRow()
                $Row.NSGName = $NSGName
                $Row.ResourceGroupName = $RGName
                $Row.RuleName = $RuleName
                $Row.DestPort = $DestinationPort
                $Table.Rows.Add($row)
        }else{
                #Nothing to do
        }
    }
}

if($Table.Rows.Count){
    # Create HTML Table of Detected Rules
    $Result = "<table border=`"1`"><tr><td>NSG Name</td><td>ResourceGroup Name</td><td>Rule Name</td><td>Destination Port</td></tr>"
    foreach($Row in $Table.Rows){
        $Result += "<tr><td>" + $Row[0] + "</td><td>" + $Row[1] + "</td><td>" + $Row[2] + "</td><td>" + $Row[3] + "</td></tr>"
    }
    $Result += "</table>"

    # Create An Alert Mail
    $SmtpServer = "smtp.sendgrid.net"
    $Port = 587
    $UserName = "azure_xxxxx@azure.com"
    $Password = "xxxxx"

    $MailFrom = "xxx@example.com"
    $MailTo = @("xxx@xxx.com","xxx@xxx.com")
    $Subject = "NSG Rule Alert"

    $Body = "Here is List of NSG Rules using * as a SourceIPAddressRange.<br /><br />" + $Result

    $pwd = ConvertTo-SecureString -String $Password -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PSCredential $UserName,$pwd

    Send-MailMessage -UseSsl -From $MailFrom -To $MailTo -Subject $Subject -Body $Body -SmtpServer $SmtpServer -Port $Port -Credential $cred -BodyAsHtml
}
参考

スクリプトを作成するうえで、以下の記事/ページを参考にしています。

qiita.com

https://codeday.me/jp/qa/20190321/445515.htmlcodeday.me

SendGrid Accounts

SendGridとは、SendGrid社の提供するメール配信サービスです。 サーバ不要であり、無料枠で月25000通のメールを配信できるので、Azure 環境からメールを送信する場合はこれを使うと楽です。

プランと料金はこちら。

https://azuremarketplace.microsoft.com/ja-jp/marketplace/apps/SendGrid.SendGrid?tab=PlansAndPriceazuremarketplace.microsoft.com

今回はAutomationのジョブからSendGridへメールを投げるため使います。Freeプランで作成します。

作成時には認証用パスワードやプラン指定、サポートからの連絡先指定が必要です。パスワードは後で変更できます。

作成したSendGrid AccountsのConfigurationsに表示されている、以下の2つの情報をスクリプト中の変数に指定します。

  • Usernameを$UserNameに格納
  • Passwordを$Passwordに格納

Automationアカウント

Automationアカウントとは、Azureで提供されているプロセスの自動化サービスです。 PowerShell/Pythonに対応しており、登録したジョブのスケジュール実行や、Webhookを作成してHTTP Postを受けての実行が可能です。

ジョブの実行時間に応じて課金されますが、無料枠が月500分あり、ちょっとしたことであれば十分足りてしまいます。 ジョブ実行以外にも、更新プログラムの管理や構成管理機能があります。 2019年9月現在、西日本リージョンには作成できません。

料金はこちら azure.microsoft.com

今回はこれを用いてジョブ実行するので、Automationアカウントをデプロイします。

実行アカウントの作成を行うと新しいサービスプリンシパルが作成され、サブスクリプションの共同作成者ロールが割り当てられます。 作成しない場合は別途資格情報の登録が必要になるので、ここでは実行アカウントを作成します。

モジュールの追加

現在のAzure PowerShellではAzモジュールがメインですが、記事作成時点では、AutomationはデフォルトではAzureRmモジュールのみ対応しています。

そのため、Azコマンドを使用する際はモジュールの追加が必要になります。 本記事のスクリプトを動作させるためには、[Az.Accounts]と[Az.Network]の2つのモジュールが必要です。

モジュール追加を行うには、[モジュールギャラリー]を選択します。

Az.AccountsとAz.Networkの2つのモジュールを検索し、両方インポートします。

※パッケージの依存関係があるため順番に注意してください。今回の例ではAz.Accountsが先です。

モジュール画面に移動し、先ほど追加したモジュールが使用可能になればOKです。

Runbookの作成

アカウントを作成しモジュールを追加したら、続いてRunbookを作成します。

Runbookの種類をPowerShellにします。

[編集]をクリックします。

ここにコードを貼り付け、[公開]を行います。

※公開を実行しないと、変更が反映されません。

スケジュール登録

Runbookを作成したら、最後にジョブのスケジュール登録を行います。

Runbookのスケジュール画面を開きます。

新しいスケジュールの作成を行い、好きな日時、タイミングで実行するように設定します。画像のように指定すれば、平日の朝10時だけ実行することが可能です。

これで設定は完了です。

メール通知

実際にメールが届くと、以下のようになります。

これで、条件に合致した特定のNSGルールを検出し、表形式でメール通知することができました。

おまけ:VMデプロイ時の注意

今回こんなスクリプトを作成してみようと思ったきっかけにも関連するのですが、 ポータルで仮想マシンを作成する場合、以下の設定画面があります。

ここで受信ポートを選択すると、新規作成され、ネットワークインターフェースに紐づけられたNSGに自動で受信ルールを追加してくれるのですが、発信元IPアドレスがAnyで許可されます。

知らないと22/3389を公開してしまう可能性があるので、これは使用せず自分で許可ルールを追加することをお勧めします。

おわりに

今回は、特定のNSGルールを検出しメール通知する、というジョブをAutomationでスケジュール設定しました。 意外とあっさりでき、AutomationとSendGridだけでもいろいろなことができそうだとわかりました。 単なるスクリプトなので条件を変えれば何でも検出できますし、検出したあと自分のグローバルIPに置き換える、ということも可能です。

本当はFunctionとか使えればよかったのですが、知識が足らず。。。 NSGの作成/変更を検出してうんぬん、というのができればやってみたいなと思います。

クラウドで構築が簡単になり、ネットワークなどよくわからなくてもいろいろ作れてしまいますが、 その結果として実は無防備でした、となると重大な問題になるので、使うにあたりある程度の理解は必要です。 また、間違えても検出できる仕組み、そもそも間違えない仕組みは大事ですね。

AzureサービスにIDを与える!マネージドID

はじめに

Azure上の仮想マシンで、Azureリソースに対するスクリプトやシェルを動かす場合、 コード中にサブスクリプションへのログインが必要です。

ログインするということはそのための資格情報が必要となりますが、コード中に資格情報もセットで記述するようなことは避けたいと思います。

マネージドIDを使用することで、コード中にログインアカウントやパスワードを記述せずともサブスクリプションへのログインが可能になります。

docs.microsoft.com

今回はマネージドIDの概要と使い方、注意点について紹介します。

目次

マネージドIDについて

概要

マネージドIDとは、Azureサービスに対してAzure ADのIDを与え、仮想マシンやその他対応したサービス上でそのアカウントを使用して認証を行うことができる、という機能です。このIDはAzure AD上で表示されません。

マネージドIDには、以下の2種類があります。

  1. システム割り当てマネージドID  対応したAzureサービス(VMやApp Serviceなど)毎に、専用のIDを作成する方式です。  設定を有効にすることで、そのサービス専用のマネージドIDがAzureADに作成され、サービス上でそれを利用することが可能になります。  Azureサービスを削除する際に、マネージドIDも一緒に削除されます。

  2. ユーザー割り当てマネージドID  マネージドIDを、Azureリソースとして作成し、複数のサービスで共用する方式です。  IDを作成後、各Azureサービスに割り当てることでサービス上での利用が可能になります。  Azureサービスを削除しても、マネージドIDは別リソースのため削除されません。  

    マネージドIDの有効化

    システム割り当て済みマネージドIDの有効化

    対応したサービスにて、マネージドID設定画面を開き、[システムマネージドID]タブの状態を[オン]にします。 ※今回はVMを利用しているので[ID]画面を開きます。

確認画面が表示されるため、[はい]を選択すると、そのサービス専用のマネージドIDがAzureADに作成されます。これで有効化は完了です。、

ユーザー割り当てマネージドIDの有効化

最初に割り当てるためのリソースを作成します。 全てのサービスから[マネージドID]を選択し、[追加]を行います。

名前、リソースグループ、リージョンを選んで作成します。

先ほどと同様[ID]画面を開き、[ユーザー割り当て済み]タブの[追加]を行います。

作成したIDリソースの割り当てを行います。

これで有効化は完了です。

マネージドIDへの権限付与

マネージドIDの有効化は上記でOKですが、各種Azureサービス用のIDであるため、ユーザーIDにするのと同様に、権限の割当てが必要です。

具体的にはマネージドIDに対して、サブスクリプションやリソースグループへのロール割り当て(所有者、閲覧者など)を行います。

例としてリソースグループへの閲覧者権限を追加します。 リソースグループの[アクセス制御]から[追加]、[ロールの割り当て]を選択します。

[アクセスの割り当て先]としてマネージドIDを指定することができます。 保存を押して権限割り当ては完了です。

マネージドIDの利用

実際に仮想マシン上でマネージドIDを使用し、アカウント情報なしでAzure CLI/PowerShellにログインしてみます。 ログインしたことになるため、az logout やLogout-AzAccountの実行も可能になります。

Azure CLIへのログイン

マネージドIDを用いてAzure CLIにログインするには、以下のコマンドを使用します。 実行することでログインが完了し、通常通りコマンドを使用できるようになります。

az login --identity

Azure PowerShellへのログイン

マネージドIDを用いてAzure PowerShellにログインするには、以下のコマンドを使用します。

Add-AzAccount -identity

注意点

マネージドIDを用いることで、仮想マシン上にアカウント情報を保持せずに資格情報を持たせることが可能ですが、仕組み上注意すべきと思う点があります。 それは、マネージドIDに付与する権限の強さです。

マネージドIDとは、Azureサービス/リソースそのものにAzure環境の操作権限を与えていることになります。

今回のようにVMにマネージドIDを付与した場合、OSにログインしCLI/PowerShellを実行可能なユーザーであれば誰でも、本来はAzureサブスクリプションの権限がないユーザーでも、VMの持つ権限を借りてAzure環境を操作するコマンドの実行が可能になります。

そのため、本来権限を持たないユーザーがリソースの作成や削除を実行可能な、抜け穴のような状況を作らないよう、マネージドIDに与える権限はよく検討した方が良いと思います。

おわりに

マネージドIDについて前々から存在は知っていたものの、使う機会がなく、たまたま試す機会があったので今回まとめてみました。

記載したようなVMで直接リソースの操作権限を持つようなことはあまりなく、読み取りでストレージのキーを取得したりアプリとAzureリソースの連携で使ったりの方が多いのかなぁと思いつつ。。。

権限の振り方に気を付けて使えば便利な機能だと思うので、そんなものもあるんだ、と知ってもらえればいいなと思います。

Azure Log Analyticsで仮想マシンの死活監視!

はじめに

今回は、Azure Log AnalyticsとAzure Monitorを用いて、 Azure仮想マシンが停止した際にメール通知を行う、死活監視の仕組みについて実装方法を紹介します。

これは、去年にLog Analyticsで収集するメトリックにハートビートが追加されたことにより可能となりました

対象仮想マシン以外には、Log AnalyticsだけあればOKです。 あまり細かいことまではできませんが、設定自体はすぐにできます。

早速、進めていきます。

目次

Log Analyticsと仮想マシンの接続

まずは、仮想マシンのメトリックを収集するため、Log Analyticsワークスペースと仮想マシンを接続します。OS種別に関わらず、操作は同じです。

使用するLog Analyticsを開き、「ワークスペースのデータソース」から「仮想マシン」を選択します。

「接続」をクリックします。

数分待ち、下の画面になれば接続完了です。

「仮想マシン」画面でも、このワークスペースに接続されていることが確認できます。

仮想マシン側の準備はこれでOKです。

アラートの設定

続いてAzure Monitorにて、仮想マシンがダウンした際に特定のメールアドレスへ通知するよう設定します。

Azure Monitorの「アラート」から、「新しいアラートルール」をクリックします。

具体的なルールを作成していきます。「選択」をクリックします。

「リソースの種類でフィルター」欄にて「Log Analyticsワークスペース」を選択し、 仮想マシンを接続したワークスペースを選んで完了をクリックします。

アラート発砲の条件を指定します。「追加」をクリックします。

「Heartbeat」をクリックします。

条件指定の画面が表示されます。 指定したLog Analyticsワークスペースに接続したすべての仮想マシンのハートビートの合計数がグラフとして表示されています。

指定の仮想マシンだけに絞るため、「Computer」ディメンションのプルダウンから、 対象仮想マシンにチェックを入れます。すると対象マシンのハートビートのみがグラフに集計されます。

「アラートロジック」にてアラート発砲の条件を指定します。

ハートビートは仮想マシンが止まれば0になるので、「ハートビートの合計値が0以下」という条件にします。

一番下の評価基準は、対象のメトリックを評価する頻度、評価する際のデータの集計範囲を指定します。例として、集約粒度5分、評価の頻度5分ごとの場合は、5分毎に、直近5分のハートビート(ハートビートは1分毎に記録)を集計する、という意味になります。

これを使うことで、30分毎に直近15分のメトリックを評価したり、1時間ごとに24時間分のメトリックを評価したりと、いろいろできます。今回は1分毎に直近5分とし完了します。

アクションの追加をクリックします。ここでは、電話番号へのプッシュ通知やメールアドレスへのメール通知を複数まとめてアクショングループとして指定します。 既にアクショングループを作成済みの場合は選択が可能です。

ここではアクショングループの作成をクリックします。

アクショングループの名前、アクション名、アクションタイプを指定します。するとアクションタイプに応じた設定用画面が開くため、要望に応じた通知設定を行います。

アクションタイプにはメール/SMS/プッシュ通知/音声、Azure Functino、ロジックアプリなどあるため、通知の種類としてもいくつかありますが、このアラートをトリガーとして他のサービスと連携することが可能です。

アクショングループの作成が完了したら、アラートの名前と説明を指定しアラートルールを作成します。

アラートの管理画面にて、作成したアラートが有効になれば設定完了です。

アラートのテスト

では、設定したアラートのテストをします。設定したマシンを停止してみます。

停止すると、こんな感じのメールが来ました。5分以内くらいで届きます。

Azure Monitor側でも、作成したアラートがあがっていることを確認できます。

マシンを起動し、アラート条件が満たされなくなれば、アラートは解除され「Resolved」のメール通知が届きます。

おわりに

LogAnalyticsを用いて仮想マシンの停止アラートを発砲し、単純ではありますが、仮想マシンの死活監視の仕組みを構成できました。

今回はハートビートのメトリックを用いましたが、その他のメトリックを用いてCPUやメモリの使用率などからアラートを上げることも可能です。 Azure Monitorは対象メトリックや集計方法、アクションタイプを変えることで様々な使い方ができるため、いろいろ試してみてください。

Application Gatewayをv1からv2へ移行する!Part2

はじめに

Part1では、以下の内容を記載しました。

www.michikusayan.com

  • Application Gatewayとは
  • v2への移行方法
  • 移行用スクリプトの注意/制限

途中、発表されたAzure Bastionに興味を惹かれ間があいてしまいましたが、Part2では、スクリプトに必要なパラメータを確認して、 実際にスクリプトを動かしてみます。 最後に、実際に移行する際はどのような流れになるか考えてみます。

目次

スクリプト実行準備

まずは、スクリプトを以下からダウンロードします。

www.powershellgallery.com

スクリプトの使い方は以下にあるため、それに従います。

docs.microsoft.com

スクリプトの実行の仕方として、Azモジュールをインストールしているかいないかで以下の2つの方法があるようです。

  1. Azモジュール無し⇒Install-Scriptオプションを使う。
  2. Azモジュールあり⇒スクリプトを直接実行する。

本記事は2の直接実行する方法で進めます。また、ダウンロードしたバージョンは1.0.3でした。

スクリプトを直接実行する場合には、以下3つのコマンドを実行すればOKです。サブスクリプションを2つ以上持つアカウントの場合には、Select-AzSubscriptionで切り替えるのを忘れずに。

Import-Module Az
Connect-AzAccount
AzureAppGwMigration.ps1 `
 -resourceId <v1AppGWのリソースID> `
 -subnetAddressRange <v2AppGW用サブネットレンジ>`
 -appgwName <v2AppGW名>`
 -sslCertificates <カンマ区切りのSSL証明書オブジェクト>`
 -trustedRootCertificates <カンマ区切りの信頼されたルート証明書オブジェクト>`
 -privateIpAddress <v2AppGWのプライベートIPアドレス>`
 -publicIpResourceName <v2AppGWのパブリックIPアドレスリソースID>`
 -validateMigration -enableAutoScale

次に、スクリプトの引数について準備が必要です。

  • v1AppGWのリソースID(必須)

リソースIDは、Azure内の「どのサブスクリプションの、どのリソースグループの、どのリソース」を表す識別子です。 これはリソースのプロパティから取得できます。

  • v2AppGW用サブネットレンジ(必須)

新しくv2AppGWを作成するサブネットのアドレス帯をCIDR形式で指定しましょう。 スクリプトが作ってくれるので、先にサブネットを作成しておく必要はありません。 今回は10.10.2.0/24にします。

  • v2ApPGW名(オプション)

v2AppGWの名前です。指定しない場合、"元の名前_v2"になります。kkv2AppGWにします。

  • カンマ区切りのSSL証明書オブジェクト(オプション)

HTTPSリスナーを持たない場合はこのオプションは不要です。

v1AppGWで使用している証明書のうち、v2AppGWにも使用したいすべての証明書について、スクリプト実行前に以下のコマンドを実行してオブジェクトを作成する必要があります。証明書は再登録ということですね。

$password = ConvertTo-SecureString <pfxファイルのパスワード> -AsPlainText -Force
$mySslCert1 = New-AzApplicationGatewaySslCertificate -Name <証明書名> `
   -CertificateFile <ローカルPC上の証明書ファイルのパス> `
   -Password $password 

証明書1つに付き1回なので、2つあれば$mySslCert2に変更してもう1度実行が必要です。 複数ある場合は、引数指定時に$mySslCert1,$mySslCert2とカンマ区切りにします。 テスト用のAppGWでは1つ登録しています。

  • カンマ区切りの信頼されたルート証明書オブジェクト(オプション)

これは、HTTP設定でエンドツーエンドのSSLを実装していなければ不要です。

先ほどと同じように、証明書をアップロードするための作業です。 テスト用AppGWでは使用していません。 オブジェクト作成にあたり、コマンドが以下に変わります。

New-AzApplicationGatewayTrustedRootCertificate -Name <証明書名> `
 -CertificateFile <ローカルPC上の証明書ファイルのパス>
  • v2AppGWのプライベートIPアドレス(オプション)

新しいサブネット内から、割当てるIPアドレスを指定します。 指定しない場合は自動で割当てされます。 今回は10.10.2.10にします。

  • v2AppGWのパブリックIPアドレスリソースID(オプション)

v2AppGWに既存のパブリックIPアドレスリソース(Standard)を割当てる場合は、 プロパティからリソースIDを取得して指定します。 新規で作成する場合は指定不要です。v2AppGW名-IPという名前で作成してくれます。 今回は新規で作成します。

  • その他(オプション)

あとの2つはオプションです。validateMigrationを使うと設定値のチェックをしてくれ、 enableAutoScaleを使うと文字通りオートスケールを有効にしてくれます。 どちらも使用してみます。

ということで、一部マスクしていますが、私の環境で移行するために実行するコマンドはこれです。 これを実行します。

Import-Module Az
Connect-AzAccount

$password = ConvertTo-SecureString '1qaz"WSX3edc' -AsPlainText -Force
$mySslCert1 = New-AzApplicationGatewaySslCertificate `
 -Name "selfsign" `
 -CertificateFile "C:\Users\kkusaya\Desktop\appgw\server.pfx" `
 -Password $password

.\C:\Users\kkusaya\Desktop\appgw\AzureAppGwMigration.ps1 `
 -resourceId /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/kkAppGW/providers/Microsoft.Network/applicationGateways/kkAppGW `
 -subnetAddressRange 10.10.2.0/24 `
 -appgwName kkv2AppGW `
 -sslCertificates $mySslCert1 `
 -privateIpAddress 10.10.2.10 `
 -validateMigration -enableAutoScale

v1AppGWの設定値確認

実行前にv1AppGWについて、全体的なパラメータを確認しておきます。 スクリプトによる移行の動きを見たかったので、設定自体は適当です。。。

〇概要

〇構成

〇WAF

〇バックエンドプール

〇HTTP設定

〇フロントエンドIP

〇リスナー

〇ルール

スクリプト実行

ではいよいよ、作成したコマンドを実行します。 ImportしてConnectして、証明書オブジェクトを作成して、いざ実行!

おー、いい感じに動いてそうだしいけるか?と思ったところで失敗しました。

エラー内容を見てみると、「新しく作成されるサブネット(kkvwAppGWSubnet)に適用されているNSG(kkAppGW)に、インターネットからのポート番号65200から65535の通信を許可してないから」失敗しています。

調べてみたところ、v2AppGWの仕様でした。 v1のときは65503から65534が必要でしたが、v2になり必要ポートが増えたようです。

docs.microsoft.com

このエラーからすると、v2AppGWのサブネットには、v1AppGWのサブネットに利用しているNSGをそのまま、スクリプトが割当ててくれるようです。また、エラーが生じた場合には作成したリソースのクリーンアップもしてくれているみたいで助かります。

v1AppGWで使用しているNSGに許可ルールを入れリトライします。

気を取り直して2回目、今度は成功しました! 時間としては5分ほど。AppGWのデプロイとしては非常に速いです。さすがv2。

これ以降はGetした結果みたいのがずらっと続くので、省略します。

v2AppGWの設定値確認

移行されたAppGWの設定値を確認していきます。

〇概要

タグが付与されました。

〇構成

v2のオートスケールになっています。最小インスタンスは2台のようです。

〇WAF

〇バックエンドプール

バックエンドプールへのVM接続は、自分で行う必要がありますね。

〇HTTP設定

〇フロントエンドIP

〇リスナー

〇ルール

タグが付いたこと、バックエンドにVMが追加されないこと以外は、名前もそのままに移行ができました。 サブネットやパブリックIPアドレスの名前を決めたい場合は自分で作成しておけばそれを使えるので、移行用スクリプトとして便利だと思います。

想定される移行の流れ

実際に移行作業をする場合、どのような流れになるか考えます。

AppGWは以下の図のように、異なるAppGWで共通の仮想マシンをバックエンドプールに追加する構成が取れるため、 新旧AppGWの並行稼働が可能です。

それを利用し、2台のAppGWを稼働させたままDNSなど向き先を切り替え、トラフィックがv2AppGWへ切り替わるのを待つのがよいかと思います。

流れとしては以下のようになります。

  1. v1AppGW用サブネットにNSGを使用している場合、65200から65535までを許可しておく。(スクリプトでv2用サブネットを作成する場合)
  2. スクリプトでv2AppGWを構成する。
  3. v2AppGWのバックエンドプールに、v1AppGWのバックエンドプールと同じサーバを追加する。
  4. DNS名やTraffic Managerなどの向き先を、v1AppGWからv2AppGWに切り替える。
  5. しばらくしてからv1AppGW停止/削除

v1AppGWをいきなり削除するのが不安な場合には、一旦停止で様子を見るのがいいかもしれません。 AppGWはPowerShellであれば停止が可能です。 ただし、再起動後はAppGWのIPアドレスが変わるため、Aレコードを使用している場合は変更が必要です。

コマンドは以下

Stop-AzApplicationGateway -ApplicationGateway <PSApplicationGateway>

終わりに

2回にわたり、提供されている移行スクリプトの仕様確認および実行をしました。

手動移行しかない中、設定値の引継ぎを自動で実施してくれるのはとても便利です。 現状の仕様による制限(プライベートのみ不可など)はありますが、移行を考える際は有効活用しましょう。

何よりも設定変更をしたとき、v2だと5分とかからず終わるのがすごくよいです。 v1だと平気で20分くらい待たされますからね。。。

AppGWの仕様変更やスクリプト改修により変わる部分はあるかもしれませんが、大きくは変わらないと思うので、移行を考える際に本記事が参考になれば嬉しいです。

踏み台サーバがPaaS化!Azure Bastionを試す!

はじめに

2019/11/24追記

先日、Azure Bastionのプレビューが発表されました。

2019年11月5日頃より、一般提供が開始されました!

azure.microsoft.com

タイトルのとおり、普段「踏み台サーバ」として構築しているものがPaaS化されたサービスです。

PaaSのため、踏み台サーバの構築やパッチ適用に監視に...とIaaSが故の手間が不要になります。

いい感じの雰囲気がするので、以下のサイトを基に仕様の確認や接続テストなどしてみます。

docs.microsoft.com

なお、本記事はプレビュー版での検証であるため、リリース版とは仕様が異なる可能性があります。

Azure BastionにNSGを設定する場合は必須のルールがあるため、以下の別記事にまとめています。

www.michikusayan.com

目次

Azure Bastion概要

  • VNet内にデプロイするPaaS
  • ポータルから1クリックで、VNet内のVMにRDP/SSH over SSL接続ができる(VNet毎にデプロイ必要)
  • VMのパブリックIP不要
  • RDP/SSHクライアントやエージェントなど不要
  • 接続のために、VM、プライベートIPアドレスを持つNIC、Bastionの読み取り権限が必要
  • VM側のNSGは、BastionからのRDP/SSHを許可すればOK
  • ポートスキャンやゼロデイ攻撃からVMを守れる
  • 専用サブネットが必要

現状、ポータルからSSH接続はできないので、1クリックでRDP/SSHができるのは嬉しいです。

over SSLのため443の通信(RDP/SSHの通信許可が不要)であることや、VMにパブリックIP不要、クライアントソフト不要などから、セキュリティや端末管理に厳しい環境でも利用できるのではないかと思います。 NSG管理が簡単なのも嬉しいです。

接続イメージはこんな感じ。 配置はよくある踏み台サーバと同じです。

Azure Bastion構築準備(現在はリリース済みのため不要)

作る前に、初回のみAzurePowerShellにて、プレビュー機能の有効化が必要です。

Connect-AzAccountでログイン後、以下のコマンドを実行します。

Register-AzProviderFeature -FeatureName AllowBastionHost -ProviderNamespace Microsoft.Network
Register-AzResourceProvider -ProviderNamespace Microsoft.Network

GetしてRegisteredになればOKですが、多少時間がかかります。

Get-AzProviderFeature -ProviderNamespace Microsoft.Network

また、プレビュー版のため通常のポータルではAzure Bastionが表示されません。 以下のプレビューポータルのリンクからポータルを開きます。(ポータル上部がオレンジ色になります。)

http://aka.ms/BastionHost

これで準備はOKです。

Azure Bastion構築

作るのは、先の図の構成です。 なお、プレビュー版2019年11月時点では以下のリージョンのみ作成可能です。

  • West US
  • East US
  • West Europe
  • South Central US
  • Australia East
  • Japan East

(1) [リソースの作成]でMarketplaceから"bastion"を検索します。

(2) [作成]をクリックします。

(3) Bastionに必要なパラメータを指定します。vpnGWやAzureFWなどと同じように、名前指定の専用サブネットが必要です。[サブネット構成の管理]からサブネットを作ります。

(4) "AzureBastionSubnet"という名前のサブネットを作成します。最低/27必要です。また、NSGやルートテーブルを割り当てる必要はありません。

(5) エラーが消えたので作成します。5分ほどで完成しました。

本記事ではBastionSubnetにNSGを適用しませんでしたが、GatewayManagerとAzureCloudのタグを許可すれば適用することは可能なので、IP制限は行えるかと思います。

Linuxマシンへの接続

BastionHostと同じネットワーク内にいる仮想マシンの概要画面にて、[Connect]をクリックします。

いつものRDP/SSH以外に[BASTION]タブがあるので選択し、ユーザー名とアクセス方法など指定して[Connect]をクリックします。

新しいウィンドウが開き、ブラウザ上で対象の仮想マシンにSSH接続できました。コマンドも実行できます。

Windowsマシンへの接続

接続の仕方はLinuxマシンの場合と同じです。

[Connect]をクリックすると新しいウィンドウが開き、ブラウザ上で仮想マシンにRDP接続できました。

費用について

料金ページはこちら

azure.microsoft.com

東日本リージョンの場合、1月を730時間(24*365/12)とすると、費用は10.64円/時間(7621円/月) + 送信データ量 * 13.44円/GBのため、使い方にもよりますが1万円くらいで使えるのでしょうか。

だとしたらA2v2のWindows立ち上げっぱなし(13899円/月)より安くなりますね。踏み台サーバの電源をオンオフしたらVMでも安くなりますが、Bastionなら更新プログラムなど管理不要、というメリットはあります。

おわりに

今回は、踏み台サーバのPaaS化というのが面白そうだったので、Azure Bastionを試してみました。PaaSのため非常に簡単にデプロイでき、すぐにブラウザ上で各OSへの接続を行うことができました。既存環境に追加するとしても、必要になるのはサブネットの払い出しくらいで、そんなに手間はいりません。

初めの方に書きましたが、SSL接続のためFWでRDP/SSHを開けていない環境でも使用でき、簡易的な踏み台サーバとして使うのにはよいかと思います。

ただ個人的には、BastionHostに接続⇒接続VMを選択⇒接続!というWVDのブローカーチックなものを期待していたので、マシンの概要から接続であることには若干もやもや...

あとは、踏み台となるとどうしてもログの取得や操作の監視などが挙がると思いますが、現状そのような機能はありません。 今後どうなるかに期待です。

作成は非常に簡単なので、気になる方はまずは試してみるのがいいと思います。

今後のロードマップとしては、Azure ADとの多要素認証やレコーディング機能、プライベートIP対応などがあるようです!

Application Gatewayをv1からv2へ移行する!Part1

はじめに

少し前にV2がリリースされたApplication Gateway(以下、AppGW)について、以下の記事がありました。

azure.microsoft.com

記事中で、"V1と同じ設定値のV2ゲートウェイを手で作れば移行できるけど大変だからスクリプト発行した。いくつか制限があるけど設定値コピーできるよ"という感じの記載があったので、実際試してみることにしました。

Part1では更改されている移行方法とスクリプトの注意点についてまとめ、Part2で実際にスクリプトを動かそうと思います。

Part2はこちら。

www.michikusayan.com

目次

Application Gatewayとは

主題ではないので簡単にですが、Application Gatewayの概要です。Application Gatewayとは、Azureが提供するロードバランサの1つです。標準ロードバランサとの違いは多々ありますが、例えば以下です。

  • L7対応(標準はL4)
  • 稼働時間により利用料金がかかる
  • 専用サブネットが必要
  • SSLオフロードが可能
  • WAF機能がある

ここまではV1でも持つ機能なのですが、V2になると更に以下の機能も増えます。

  • オートスケールに対応
  • ゾーン冗長に対応
  • デプロイと設定変更のスピードアップ

オートスケールも需要有りそうですが、個人的にはスピードアップがうれしいです。設定変更で15分くらい待たされることもあるので。。。

v2への移行方法

移行の仕方については、以下のサイトに紹介されています。

docs.microsoft.com

移行は以下の2ステップで行います、ということなのでなかなか大変です。

  1. 既存のAppGW(v1)と同じ設定のAppGW(v2)を作成する。
  2. v1で受けているトラフィックを、v2で受ける用にする。(DNS切り替えなど)

ただ、1の同一設定で作成する、という部分はMSからPowerShellスクリプトが提供されています。

先ほどのサイト内にもリンクがありますが、以下からダウンロードできます。

www.powershellgallery.com

まずは、これについて仕様を確認します。

移行用スクリプトの注意/制限

スクリプトとしては、以下のことを実行するようです。

  • 新しいAppGW(Standard/WAF)を指定のサブネットに作成する。
  • AppGW(v1)から、新しく作成されたAppGW(v2)への設定値コピーをシームレスに行う。

単純に、v1の設定値を抜いてv2に入れる、ということなのでしょう。Getだけであればv1側が停止することもありません。

スクリプトの仕様や注意点としては、以下のことが挙げられています。それぞれ補足していきます。

  • 新しいv2GWは、v2のパブリック/プライベートIPアドレスをシームレスに引き継ぐことはできない。既存の未割当のパブリックIPアドレスまたはプライベートIPアドレスを割り当てることはできる。

プライベートIPアドレスであれば、ダウンタイムが発生しますが、v1AppGWを削除やアドレス変更してやればv2AppGWに同じIPアドレスを割り当てることはできるでしょう。

しかし、"AppGWに割り当てるパブリックIPアドレスは動的でなければならない"という仕様上、AppGWから外した瞬間にIPが変わります。なので、パブリックIPアドレスの引き継ぎはできません。

素直にDNS切り替えなどする他なさそうです。

  • v1GWが属するサブネットとは別に、仮想ネットワークサブネットが必要。スクリプトでは、v1GWと同じサブネットにはv2GWを作成しない。既にv2GWがありIPアドレスの空も十分あればいけるかも。

これは仕様のようです。

ポータルでv2AppGWの作成を試みると、空が十分にあるにも関わらず、v1AppGWが属するサブネットが選べませんでした。(もう一方はVMがいる)

v2に移行が完了した後、古いサブネットを消す、などが必要になりそうです。

  • SSL設定を移行する場合には、v1GWが持つ全ての証明書を指定する必要がある。

どう指定するのか、はスクリプトを動かさないとわかりませんが、非常に手間がかかりそうな予感。。。

  • v1GWでFIPSモードを有効化していても、v2ではサポートしていないので移行されない。

これについては、少なくともポータルにはそんな設定はないので、コマンド専用なのか、FIPSモードが何を指しているのか、わかりませんでした。

  • v2GWではIPv6をサポートしていないので、使用していると移行できない。(スクリプトが止まる)

使うかどうかは別として、これは次の項目のように明確に"currently"と書かれていないので、そのうち変わる可能性があるのかどうかわかりません。

  • v1GWがプライベートIPアドレスしか持たなくても、現状v2GWではプライベートIPアドレスのみの構成をサポートしていないため、パブリック/プライベートの両IPアドレスが割り当てられる。

これは、現状プライベートでしか利用していない方からすると困るところです。

"currently"とあるので今後変更があると思いますが、今移行する場合には、サブネットにNSGを適用して、外部からは入れないようにするしかないですね。

パブリックIPアドレスがついているけど塞いでいるから大丈夫、という若干気になる構成にはなってしまうので、移行のタイミングも要検討ですね。

Part1はここまでとして、Part2に続きます。

www.michikusayan.com

Azure仮想マシンでNested Hypver-Vを構築してみる!Part3

はじめに

Part1、Part2と続き、これまで以下のことを実施しました。

最終的にやりたかった通りにはなっていないのですが、できた範囲で備忘として残しています。

■Part1

www.michikusayan.com

  • Hyper-Vの有効化
  • NATスイッチの作成
  • NATネットワークの作成
  • Windows Server2016評価版ダウンロード

■Part2

www.michikusayan.com

  • ゲストマシンの作成
  • ゲストマシンのネットワーク設定

今回は、ホスト以外のAzure仮想マシンから、Nested Hyper-V上の仮想マシンへ疎通が取れるようにします。

が、Azure仮想ネットワーク上の仮想マシンからNested Hyper-V上のマシンへのポートフォワーディングによる接続はできるのですが、pingなど直接の疎通が通りません。

これについてはRRASを入れて何やかんやしましたがどうしてもできず、今回はポートフォワーディングで通信させます。後に方法がわかれば、別途更新します。

目次

ポートフォワーディング設定

Nested Hyper-Vのホストマシン上でNATを構成することで、ホストマシンのパブリック/プライベートIPアドレスへのアクセスを、Nested Hyper-Vゲスト上の仮想マシンへの接続にポートフォワーディングします。Azureロードバランサの受信NATルールと同じです。

以下のコマンドをホストマシン上で実行します。

Add-NetNatStaticMapping -NatName <NAT名> -Protocol TCP -ExternalIPAddress 0.0.0.0 -InternalIPAddress 192.168.0.10 -InternalPort 80 -ExternalPort 80

Add-NetNatStaticMapping -NatName <NAT名> -Protocol TCP -ExternalIPAddress 0.0.0.0 -InternalIPAddress 192.168.0.10 -InternalPort 443 -ExternalPort 443

それぞのパラメータは以下のとおりです。

※ExternalIPAddressを0.0.0.0にするとインターネット経由でも接続可能になるため、NSGでの制御を忘れずに。

  • NatName:Part1で作成したNATネットワークの名前。不明な場合はGet-NetNatで取得。
  • ExternalIPAddress:接続元のIPアドレスレンジ。0.0.0.0で全体
  • InternalIPAddress:NAT後の宛先IPアドレス。Nested Hyper-V上の仮想マシンIPアドレスを指定。
  • InternalPort:NAT後のポート番号
  • ExternalPort:接続時に指定する、NAT前のポート番号

実行結果

動きとしては以下のとおりです。

変換前:ホストマシンのIPアドレスへExternalPortで接続

変換後:ゲストマシンのIPアドレス(InternalIPAddresss)へInternalPortで接続

テスト用に、ゲストマシンにIISでも突っ込んでおきます。これでホスト上の準備はOKです。

接続テスト

この状態で、Azure仮想ネットワーク上のマシンからNested Hyper-VホストマシンのIPアドレスへブラウザ接続すると...

繋がりました!もちろん、ホスト側にIISは入れていません。

NSGでの許可は必要ですが、インターネット経由でアクセスすることもできます。

これで、Azure仮想ネットワーク内の他の仮想マシンからでもアクセス可能なよう構成できました。

終わりに

ここまで3回に分けてNested Hyper-Vを構築してきました。

「どんな感じかちょっと試してみたいなー」という軽い気持ちでやってみましたが、まさかホスト外からの通信がこんなにうまくいかないとは思いませんでした。。。

ひとまずはポートフォワーディングで妥協します…

Azure仮想マシンでNested Hypver-Vを構築してみる!Part2

はじめに

全3回中の今回、Part2では以下のことを記載します。

最終的には外から Nested Hyper-V 上の VM と自由にやり取りできるようにはなっていないのですが、できた範囲で備忘として記載しています。外から中への疎通がどうしても構成できなかったので、最終的にはポートフォワーディングで接続させています。

Part1では以下のことを実施しました。

www.michikusayan.com

  • Hyper-Vの有効化
  • NATスイッチの作成
  • NATネットワークの作成
  • Windows Server2016評価版ダウンロード

今回はこの続きを作成していきます。

が、前回ちょっと勘違いと作業漏れがあったため、その修正が入ります。
Part1から続けて実施する場合は修正部分を飛ばしてください。。。
※Part1は訂正済み
2021/04/07: わかりづらいので該当部分を削除して更新

続きは以下

www.michikusayan.com

目次

ゲストマシンの作成

構成したAzure上のHyper-Vホスト上に、ゲスト仮想マシンを作成します。

ゲストマシンのディスクなどは、ホストマシンに追加したディスクでEドライブを構成し、そこに保存しています。

Part1で作成した内部スイッチを選択する以外は、少し名前を変えているくらいです。

↓ここで、内部スイッチに接続するようにしましょう。

ブートメディアとして、ダウンロードした評価版のisoを使います。

仮想マシンが作成されたので、起動してコンソール接続しましょう。OSセットアップ画面が立ち上がります。

この後は通常のOSインストールと同様のため、省略します。Standard Evaluation(デスクトップエクスペリエンス)をディスク0にインストールしています。

Administraotrアカウントのパスワード設定をして、ついに起動!

この状態ではIPアドレスが割り当てられていないため、前回作成したNATネットワーク内のIPアドレスを手動で割り当てます。

ゲストマシンのネットワーク設定

ゲストマシンのネットワーク設定を実施。

各値、以下のように設定すればOKです。

  • IPアドレス:NATネットワーク内(ここでは192.168.100.0/24)の任意のIPアドレス
  • サブネットマスク:NATネットワークのマスク長
  • デフォルトゲートウェイ:NATゲートウェイのIPアドレス(ここでは192.168.100.1)
  • DNSサーバ:今回はDNSサーバがないので、Azure内部のDNSサーバ指定(168.63.129.16)

インターネット接続が可能になりました。

また、Nested Hyper-V上のゲストマシンから、Azure仮想ネットワーク上の別のマシンへpingが通ります。

しかし、逆向きには通りません。

理由としては、Azure仮想ネットワーク上のマシンからは、"192.168.0.0/24"のネットワークへ通信する場合のネクストホップを認識できていないからです。

それに関してもうひと手間必要なのですが、Part3に続きます。 次でラストのはず...!

www.michikusayan.com