はじめに
AzureのNetwork Security Group(NSG)の登録作業をAzureポータルで行うと手間が掛かり、ミスも起きる可能性があるため
一括で入出力が出来るようにします。
動作確認環境
PowerShell 7.1.3
Azure PowerShell 5.7.0
作成
設定ファイル
入出力ファイルのレイアウト、区切り文字等を変更出来るよう設定ファイルを用意しました。
{
"Azure": {
"SubscriptionID": "xxxxxx",
"TenantID": "xxxxxx"
},
"Convert": {
"EntryType": [
{
"Caption": "登録",
"DeleteRule": false
},
{
"Caption": "削除",
"DeleteRule": true
}
]
},
"Import": {
"InitialDirectory": "C:\\",
"csv": {
"Delimiter": "\t"
}
},
"Export": {
"Directory": "",
"csv": {
"Delimiter": "\t"
}
},
"Layout": [
{
"Title": "EntryType",
"Resource": "EntryType",
"in": 0,
"out": -1,
"NSGResource": false
},
{
"Title": "NSGName",
"Resource": "Name",
"in": 1,
"out": 0,
"NSGResource": true
},
{
"Title": "ResourceGroup",
"Resource": "ResourceGroupName",
"in": 2,
"out": 1,
"NSGResource": true
},
{
"Title": "Direction",
"Resource": "Direction",
"in": 3,
"out": 2,
"NSGResource": false
},
{
"Title": "Priority",
"Resource": "Priority",
"in": 4,
"out": 3,
"NSGResource": false
},
{
"Title": "RuleName",
"Resource": "Name",
"in": 5,
"out": 4,
"NSGResource": false
},
{
"Title": "SourceAddressPrefix",
"Resource": "SourceAddressPrefix",
"in": 6,
"out": 5,
"NSGResource": false
},
{
"Title": "SourcePortRange",
"Resource": "SourcePortRange",
"in": 7,
"out": 6,
"NSGResource": false
},
{
"Title": "DestinationAddressPrefix",
"Resource": "DestinationAddressPrefix",
"in": 8,
"out": 7,
"NSGResource": false
},
{
"Title": "DestinationPortRange",
"Resource": "DestinationPortRange",
"in": 9,
"out": 8,
"NSGResource": false
},
{
"Title": "Protocol",
"Resource": "Protocol",
"in": 10,
"out": 9,
"NSGResource": false
},
{
"Title": "Access",
"Resource": "Access",
"in": 11,
"out": 10,
"NSGResource": false
}
]
}
必ずエクスポートを実行
誤った内容を登録してしまうことも考慮し、インポート前に必ずエクスポートするようにしました。
これで間違って登録してしまっても修正が簡単に行えます。
エクスポート処理は設定ファイルで指定したヘッダ、区切り文字、列順で行います。
サブスクリプション内のNSGすべてを対象とし、NSG毎にファイル出力します。
以下のコードではLogの出力処理は別途作成しています。
function exportNSG {
param (
$Settingjson,
$Log,
$returnCode
)
$Log.Info("NSGのエクスポートを開始します。")
$TimeStamp = Get-Date -Format "yyyyMMddHHmmss"
if (!(Test-Path -Path $Settingjson.Export.Directory)) {
$Log.Error("出力ディレクトリ「$($Settingjson.Export.Directory)」が存在しません。")
return $returnCode.Error
}
$Log.info("出力可能な全てのNSGを取得します。")
$NSGALL = Get-AzNetworkSecurityGroup
if (!$NSGALL) {
$Log.Error("NSGの取得に失敗しました。")
return $returnCode.Error
}
$Log.Info("NSGの取得に成功しました。")
foreach ($NSG in $NSGALL) {
$Log.Info("NSG「$($NSG.Name)」の定義出力を開始します。")
$OutNSG = $null
$OutLayoutjson = $Settingjson.Layout | where { $_.out -ge 0 } | sort out
$OutNSG = $($OutLayoutjson.Title -join $Settingjson.Export.csv.Delimiter)
foreach ($Rule in ($NSG.SecurityRules | sort Direction, Priority)) {
$OutLine = @()
foreach ($eachLayout in $OutLayoutjson) {
$Column = $Rule
if ($eachLayout.NSGResource) {
$Column = $NSG
}
$OutLine += $Column.$($eachLayout.Resource) -join ","
}
$OutNSG += "`n" + $($OutLine -join $Settingjson.Export.csv.Delimiter)
}
$OutFilePath = Join-Path $Settingjson.Export.Directory -ChildPath "$($NSG.Name)_${TimeStamp}_${PID}.csv"
$OutNSG | Out-File -FilePath $OutFilePath -Encoding utf8
$Log.Info("NSG「$($NSG.Name)」の定義出力が終了しました。")
}
$Log.Info("NSGのエクスポートが終了しました。")
return $returnCode.Success
}
インポート処理の動作
セキュリティルールの登録、更新、および削除は行うけど、NSGそのものを削除するような事は避けました。
誤ってバンバン削除してしまいそうなので…
実行
インポートするファイルの内容
EntryType NSGName ResourceGroup Direction Priority RuleName SourceAddressPrefix SourcePortRange DestinationAddressPrefix DestinationPortRange Protocol Access
登録 sample-nsg sample-rg Inbound 100 AllowRDP 10.0.0.5 * * 3389 TCP Allow
# 登録 sample-nsg sample-rg Inbound 300 AllowRDP3 10.0.0.5 * * 3389 TCP Allow
登録 sample2-nsg sample-rg Inbound 100 AllowRDP 10.0.0.5 * * 3389 TCP Allow
登録 sample-nsg sample-rg Inbound 200 AllowCIFS 10.0.0.5,10.0.1.5,10.0.1.6 * * 445 TCP Allow
登録 sample-nsg sample-rg outbound 200 AllowVnet * * VirtualNetwork 80,443 * Allow
登録 sample-nsg sample-rg Inbound 500 DenyRDP 10.0.0.5,10.1.0.5 3389 * 3389 * Deny
登録 sample-nsg sample-rg outbound 100 DenyInternet 10.0.0.5,10.1.0.5,10.1.0.6 * Internet 80,443 TCP Deny
登録 sample-nsg sample-rg Inbound 600 AllowDNS 10.0.0.5 * * 53 UDP Allow
登録 sample-nsg sample-rg Inbound 700 AllowPing 10.0.0.5 * 10.1.0.0/24 * ICMP Allow
登録 sample-nsg sample-rg Inbound 800 AllowInternet internet 443,80 internet 443,80 TCP Allow
PowerShellを開いて実行します。
.\AzureNSGRegister.ps1 -ConfigFileName testSetting.json
ファイルを開くダイアログが表示されますのでインポートファイルを選択します。
複数ファイルも選択可能です。
ブラウザで認証画面が開きますので設定ファイルで指定したサブスクリプションが使用できるアカウントを選択してAzureへログインします。
処理が完了したのでログを確認します。
[2021/04/06 23:24:03] INFO 設定ファイル「testsetting.json」
[2021/04/06 23:24:10] INFO NSGのエクスポートを開始します。
[2021/04/06 23:24:10] INFO 出力可能な全てのNSGを取得します。
[2021/04/06 23:24:11] INFO NSGの取得に成功しました。
[2021/04/06 23:24:11] INFO NSG「main-nsg」の定義出力を開始します。
[2021/04/06 23:24:11] INFO NSG「main-nsg」の定義出力が終了しました。
[2021/04/06 23:24:11] INFO NSG「sub-nsg」の定義出力を開始します。
[2021/04/06 23:24:11] INFO NSG「sub-nsg」の定義出力が終了しました。
[2021/04/06 23:24:11] INFO NSG「test2-nsg」の定義出力を開始します。
[2021/04/06 23:24:11] INFO NSG「test2-nsg」の定義出力が終了しました。
[2021/04/06 23:24:11] INFO NSG「test3-nsg」の定義出力を開始します。
[2021/04/06 23:24:11] INFO NSG「test3-nsg」の定義出力が終了しました。
[2021/04/06 23:24:11] INFO NSGのエクスポートが終了しました。
[2021/04/06 23:24:11] INFO ファイル「sample.csv」の読込を開始します。
[2021/04/06 23:24:11] INFO NSG「sample-nsg」のインポート処理を開始します。
[2021/04/06 23:24:13] INFO NSG「sample-nsg」を作成します。
[2021/04/06 23:24:17] INFO NSG「sample-nsg」の作成に成功しました。
[2021/04/06 23:24:18] INFO 受信セキュリティ規則「AllowRDP」の追加を開始します。
[2021/04/06 23:24:19] INFO 受信セキュリティ規則「AllowRDP」の追加に成功しました。
[2021/04/06 23:24:19] INFO 受信セキュリティ規則「AllowCIFS」の追加を開始します。
[2021/04/06 23:24:20] INFO 受信セキュリティ規則「AllowCIFS」の追加に成功しました。
[2021/04/06 23:24:20] INFO 送信セキュリティ規則「AllowVnet」の追加を開始します。
[2021/04/06 23:24:21] INFO 送信セキュリティ規則「AllowVnet」の追加に成功しました。
[2021/04/06 23:24:22] INFO 受信セキュリティ規則「DenyRDP」の追加を開始します。
[2021/04/06 23:24:22] INFO 受信セキュリティ規則「DenyRDP」の追加に成功しました。
[2021/04/06 23:24:23] INFO 送信セキュリティ規則「DenyInternet」の追加を開始します。
[2021/04/06 23:24:23] INFO 送信セキュリティ規則「DenyInternet」の追加に成功しました。
[2021/04/06 23:24:24] INFO 受信セキュリティ規則「AllowDNS」の追加を開始します。
[2021/04/06 23:24:25] INFO 受信セキュリティ規則「AllowDNS」の追加に成功しました。
[2021/04/06 23:24:25] INFO 受信セキュリティ規則「AllowPing」の追加を開始します。
[2021/04/06 23:24:26] INFO 受信セキュリティ規則「AllowPing」の追加に成功しました。
[2021/04/06 23:24:26] INFO 受信セキュリティ規則「AllowInternet」の追加を開始します。
[2021/04/06 23:24:27] INFO 受信セキュリティ規則「AllowInternet」の追加に成功しました。
[2021/04/06 23:24:27] INFO NSG「sample-nsg」のセキュリティ規則を更新します。
[2021/04/06 23:24:31] INFO NSG「sample-nsg」のセキュリティ規則更新に成功しました。
[2021/04/06 23:24:31] INFO NSG「sample-nsg」のインポート処理を終了します。
[2021/04/06 23:24:31] INFO NSG「sample2-nsg」のインポート処理を開始します。
[2021/04/06 23:24:32] INFO NSG「sample2-nsg」を作成します。
[2021/04/06 23:24:37] INFO NSG「sample2-nsg」の作成に成功しました。
[2021/04/06 23:24:37] INFO 受信セキュリティ規則「AllowRDP」の追加を開始します。
[2021/04/06 23:24:38] INFO 受信セキュリティ規則「AllowRDP」の追加に成功しました。
[2021/04/06 23:24:38] INFO NSG「sample2-nsg」のセキュリティ規則を更新します。
[2021/04/06 23:24:42] INFO NSG「sample2-nsg」のセキュリティ規則更新に成功しました。
[2021/04/06 23:24:42] INFO NSG「sample2-nsg」のインポート処理を終了します。
[2021/04/06 23:24:42] INFO ファイル「sample.csv」の読込が終了しました。
[2021/04/06 23:24:42] INFO 全ての処理が終了しました。
[2021/04/06 23:24:42] INFO Exit code: 0
Azureポータルで確認します。
無事NSGが作られていました。
終わりに
煩わしい手動での登録作業ともこれでおさらばです。
ただ、Application Security Groupに対応していない中途半端さです…
今回作成したスクリプトはGithubにて公開しています。