Help us understand the problem. What is going on with this article?

Azure Application Security Group(ASG)がPublic Previewになったので使ってみた

はじめに

2017年9月末に開催されたIgnite 2017で発表がありました、Application Security Group(ASG)がPublic Previewで出ましたので早速使ってみました。

ASGって?

誤解を恐れずに一言で表すなら「仮想マシンのIPアドレスをNSGでいちいち設定しなくても適当な名前(ラベル名)で解決できるよ」ってことです。

英語ドキュメントでの説明は https://docs.microsoft.com/en-us/azure/virtual-network/security-overview#application-security-groups です。

NSGのおさらい

仮想マシンの用途別にサブネットを分ける場合

たとえば複数台のWebサーバとDBサーバが、種類毎に別のサブネットに配置されている場合↓↓

image.png

NSG-1にはWebサーバに関する受信ルールとして以下の設定をすると思います。

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowHTTP 300 Internet * VirtualNetwork 80 TCP Allow
AllowSSH 500 (自社のWAN側IP) * VirtualNetwork 22 TCP Allow

NSG-2も同様にDBサーバに関する受信ルールとして以下の設定をするかと。

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowDB 300 (サブネット1のCIDR) * VirtualNetwork 1433 TCP Allow
AllowSSH 500 (自社のWAN側IP) * VirtualNetwork 22 TCP Allow

「Webサーバ」「DBサーバ」と用途ごとに仮想ネットワークのサブネットを分ける設計であれば従来どおりの書き方で、サブネットに紐付けたNSGは受信ルールの宛先IPとして「VirtualNetwork」を指定すればサブネット内の全ての仮想マシンが対象となります。

ひとつのサブネット内に用途が異なる仮想マシンが混在している場合

仮想マシンの用途毎に専用のNSGを準備して、個々の仮想マシンのNICに対してNSGを紐付ける方法がひとつ考えられますね。

image.png

Web用、DB用それぞれのNSGを準備する必要があって、今後別の用途の仮想マシンが増えてくる事も考慮すると先々のメンテも大変そうです。

二番目の方法として、NSGをサブネットに対して紐付けて、一つのNSGの受信ルールに全ての用途別のルールを書く方法です。

image.png

仮想マシンの内部IPアドレスは必ず固定にする必要があります。
NSGは受信ルールとして以下の感じに設定します。

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowDB1 300 192.168.0.10 * 192.168.0.20 1433 TCP Allow
AllowDB2 301 192.168.0.11 * 192.168.0.20 1433 TCP Allow
AllowDB3 302 192.168.0.10 * 192.168.0.21 1433 TCP Allow
AllowDB4 303 192.168.0.11 * 192.168.0.21 1433 TCP Allow
AllowWeb1 400 Internet * 192.168.0.10 80 TCP Allow
AllowWeb2 401 Internet * 192.168.0.11 80 TCP Allow
AllowSSH 500 (自社のWAN側IP) * VirtualNetwork 22 TCP Allow

NSGの設定の中に、仮想マシンのプライベートIPアドレスを全ての組み合わせで記載する必要があり、非効率です。

従来は上記の何れかの方法で細かいアクセス制御を実現する必要がありました。
今後はAzure Application Security Group(ASG)を使うと、NSG内で発信元IP、宛先IPの場所に任意のASGを指定してグルーピングできるようになります。

ASGの簡単な説明

まず、新しいリソースとしてASGリソースをWeb用とDB用の2つ作成します。
NSGでは発信元IP、宛先IPに直接IPアドレスを書かずに、このASGを指定します。

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowDB 300 Web用ASG * DB用ASG 1433 TCP Allow
AllowWeb 400 Internet * Web用ASG 80 TCP Allow
AllowSSH 500 (自社のWAN側IP) * VirtualNetwork 22 TCP Allow

image.png

NSGはサブネットと、個々の仮想マシン(NIC)両方に指定する必要があります。
更に仮想マシン(NIC)側には自分が所属するASGを指定します。

このような設定を行うと、一つのNSGリソースだけで種別の異なるサーバを細かく制御することができ、更にNSGのルール内にプライベートIPアドレスを記載しなくても良いので、本来すべきネットワーク設計に集中する事ができるのではないかと。

実際試用してみる

本記事執筆時点ではまだPublic Previewで米国中西部のリージョンのみ可能です。
具体的な利用開始手順は英語ですが、以下のサイトを参照下さい。

https://docs.microsoft.com/en-us/azure/virtual-network/create-network-security-group-preview

Azure PowershellはVersion 4.4.0以降が必要で、Public PreviewのASGを使うには先に利用申請が必要です。

PowerShellから以下のコマンドを実行して、暫く待ちます。

Register-AzureRmProviderFeature -FeatureName AllowApplicationSecurityGroups -ProviderNamespace Microsoft.Network
Register-AzureRmResourceProvider -ProviderNamespace Microsoft.Network

私の場合は10分くらいで利用申請の許可が降りました。
以下のコマンドで状況を確認します。

Get-AzureRmProviderFeature -FeatureName AllowApplicationSecurityGroups -ProviderNamespace Microsoft.Network

RegistrationStateに「Registered」が返ってくればOKです。

FeatureName                    ProviderName      RegistrationState
-----------                    ------------      -----------------
AllowApplicationSecurityGroups Microsoft.Network Registered     

後は先に示したURLから(英語ですが)チュートリアルを実施すれば一通りの流れがわかると思います。
Azureポータル側の対応が未だなので、NSGの内容とかみると、ASGに対応していないため宛先部分が空白になっていたりするのですが、ちゃんと動きましたw

image.png

参考として私が試用で使ったスクリプトを以下に示します。
Linux(Centos 7.3)とWindows Server 2016の2台の仮想マシンを作成します。
tcp/80(HTTP)は両方の仮想マシンが受信できますが(ASGを設定していない)、Linuxにはtcp/22(ssh)を、Windowsにはtcp/3389(RDP)の受信ルールがそれぞれ有効になる感じの作りです。

ps1#asgsample.ps1
$rgname = 'ASG-test-rg'
$loc = 'westcentralus'
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."

New-AzureRmResourceGroup -Name $rgname -Location $loc

$linuxasg= New-AzureRmApplicationSecurityGroup -ResourceGroupName $rgname -Location $loc -name LinuxASG
$windowsasg= New-AzureRmApplicationSecurityGroup -ResourceGroupName $rgname -Location $loc -name WindowsASG

$linuxrule = New-AzureRmNetworkSecurityRuleConfig -Name "alllowssh" -Access Allow -Protocol Tcp -Direction Inbound -Priority 200 -SourceAddressPrefix "Internet" -SourcePortRange "*" -DestinationApplicationSecurityGroup $linuxasg -DestinationPortRange 22
$windowsrule = New-AzureRmNetworkSecurityRuleConfig -Name "alllowrdp" -Access Allow -Protocol Tcp -Direction Inbound -Priority 300 -SourceAddressPrefix "Internet" -SourcePortRange "*" -DestinationApplicationSecurityGroup $windowsasg -DestinationPortRange 3389
$commonrule = New-AzureRmNetworkSecurityRuleConfig -Name "alllowhttp" -Access Allow -Protocol Tcp -Direction Inbound -Priority 400 -SourceAddressPrefix "Internet" -SourcePortRange "*" -DestinationPortRange 80 -DestinationAddressPrefix *

$nsg = New-AzureRmNetworkSecurityGroup -ResourceGroupName $rgname -Location $loc -name defaultNSG -SecurityRules $windowsrule,$linuxrule,$commonrule

$subnet = New-AzureRmVirtualNetworkSubnetConfig -AddressPrefix 192.168.0.0/24 -Name default -NetworkSecurityGroup $nsg
$vnet = New-AzureRmVirtualNetwork -Name testVNET -AddressPrefix 192.168.0.0/16 -Subnet $subnet -ResourceGroupName $rgname -Location $loc

###linux
$pip1 = New-AzureRmPublicIpAddress -Name pip1 -ResourceGroupName $rgname -Location $loc -Sku Basic -AllocationMethod Dynamic -IpAddressVersion IPv4
$nic1 = New-AzureRmNetworkInterface -Name nic1 -ResourceGroupName $rgname -Location $loc -Subnet $vnet.Subnets[0] -PublicIpAddress $pip1 -NetworkSecurityGroup $nsg -ApplicationSecurityGroup $linuxasg
$vmconfig1 = New-AzureRmVMConfig -VMName LINVM01 -VMSize Standard_DS1_V2 | Set-AzureRmVMOperatingSystem -Linux -ComputerName LINVM01 -Credential $cred | Set-AzureRmVMSourceImage -PublisherName OpenLogic -Skus 7.3 -Offer CentOS -Version "latest" | Add-AzureRmVMNetworkInterface -Id $nic1.Id
New-AzureRmVM -ResourceGroupName $rgname -Location $loc -VM $vmconfig1

###Win
$pip2 = New-AzureRmPublicIpAddress -Name pip2 -ResourceGroupName $rgname -Location $loc -Sku Basic -AllocationMethod Dynamic -IpAddressVersion IPv4
$nic2 = New-AzureRmNetworkInterface -Name nic2 -ResourceGroupName $rgname -Location $loc -Subnet $vnet.Subnets[0] -PublicIpAddress $pip2 -NetworkSecurityGroup $nsg -ApplicationSecurityGroup $windowsasg
$vmconfig2 = New-AzureRmVMConfig -VMName WINVM01 -VMSize Standard_DS2_V2 | Set-AzureRmVMOperatingSystem -Windows -ComputerName WINVM01 -Credential $cred | Set-AzureRmVMSourceImage -PublisherName MicrosoftWindowsServer -Skus 2016-Datacenter -Offer WindowsServer -Version latest | Add-AzureRmVMNetworkInterface -Id $nic2.Id
New-AzureRmVM -ResourceGroupName $rgname -Location $loc -VM $vmconfig2

おわりに

今後、GAまでにきっとAzureポータル側の対応や、MS公式の親切な日本語ドキュメントなど充実してくると思いますが、先ずは今回の試用記事が少しでも参考になれば幸いです。

yotan
Azureコンサルタント/イクメン/カワイイモノズキ/デジタルモノズキ/バイクノリ/Microsoft MVP for Azure
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした