Windows Server 2012のRC(Release Candidate)版が6/1にリリースされました。Windows 7の時のスケジュールに当てはめてみると、9月くらいにRTM、ホリデーシーズン(11月末くらい?)に発売、というスケジュールになりそうな感じですね。ちょうどWindows 7の一か月遅れな感じです。

で、早速RC版を導入したので、ちょっと気になっていた機能を検証してみました。

先日のTech FieldersセミナーでWindows Server 2012 Hyper-Vの新機能として『Port ACL』がある、という話で盛り上がっていました(恐らく自分の周りだけ(笑))。

いわゆるところのNetwork SwitchのPort ACLと同一の機能のようで、ゲスト側に影響を与えずにパケットをフィルターできる機能のようです。当然の事ながら、ホスト側で処理されるはずなので、ゲスト側のパフォーマンスには影響を与えません(多分)。またゲストOSによってはFirewall機能がないものもありますので、そういった場合にも非常に役に立つ機能です。

また、某氏より指摘があったのが「LiveMigrationにACLが追従するのか」。ACLが仮想Switchに実装されているとすれば、LiveMigrationしてしまうと追従されないかとも思いますが……。

何はともあれ実際に動かしてみます。

まず環境ですが、Windows Server 2012 Hyper-Vの環境のみ用意できればOKです。それ以外に、事前に必要な設定はないようです(実際、動きましたし……)。

で、設定です。

Port ACLはGUIからは設定不可でして、全てPowerShellで設定します。

設定するPowerShellコマンドレットは『Add-VMNetworkAdapterAcl』になります。

ちなみに設定されているPort ACLを取得(確認)するコマンドレットは『Get-VMNetworkAdapterAcl』、削除は『Remove-VMNetworkAdapterAcl』になります。

一例となりますが、『Add-VMNetworkAdapterAcl』で設定する際に必要な情報は、

Action(アクション) Allow(許可)
Deny(拒否)
Meter(計測)
Direction(方向) inbound(VMへの入力方向)
outbound(VMからの出力方向)
Both(VMの入出力両方)
VMName(VM名) ACLを設定するVMの名前(not コンピューター名)
Address(ACL Address) Local IP Address(VMのローカルIP Address)
Local MAC Address(VMのローカルMAC Address)
Remote IP Address(通信対向のIP Address)
Remote MAC Address(通信対向のMAC Address)
VMNetworkAdapterName VMのネットワークアダプター名

と、こんな感じになります。

Addressは4つの中から一つのみ指定可能です。複数指定(例えばLocal IPとRemote IP)した場合、『アドレスは1つだけ!』と怒られます。

IP AddressもしくはMAC Address指定という事ですので、L4レベル(TCP/UDP、Port番号)の指定は不可能となります。Ciscoでいうところの標準ACLに近い感じですかね。

Remote IP Addressはネットワーク単位で指定可能です。書式は192.168.1.0/24という感じのCIDR表記ですね。Ciscoのネットマスク表記より判りやすいです。

よって、VM(VM01)と192.168.3.0/24との通信をinbound方向で拒否したい場合には

add-VMNetworkAdapterAcl -Action Deny -Direction Inbound -VMName VM01 -RemoteIPAddress 192.168.3.0/24

というような感じになりますね。

これを『Get-VMNetworkAdapterAcl』で確認すると、

PS C:\Windows\system32> Get-VMNetworkAdapterAcl

VMName: VM01
VMId: dea7b5c4-b3a0-409c-9982-144244f838e1
AdapterName: ネットワーク アダプター
AdapterId: Microsoft:DEA7B5C4-B3A0-409C-9982-144244F838E1\5A77EE13-08D5-450B-B8BF-257CA618F959

Direction    Address                                               Action
---------    -------                                               ------
Inbound      Remote 1792.168.3.0/24                                Deny

PS C:\Windows\system32>

こんな感じで、どのネットワークアダプターにどんなACLがセットされているかを確認できます。

で、設定したACLの評価方法ですが、これが若干癖があるようです。

次の二つのコマンドレットを実行した場合にはどうなるかを確認してみます。

add-VMNetworkAdapterAcl -Action Deny -Direction Inbound -VMName VM01 -RemoteIPAddress 192.168.3.0/24
add-VMNetworkAdapterAcl -Action Allow -Direction Inbound -VMName VM01 -RemoteIPAddress 192.168.3.1

CiscoのACLを触った事のある方は「上から順に評価されるから、最初に192.168.3.0/24をDenyしているので、192.168.3.1を後からPermitしても無駄」との回答になるかと思いますが、今回のPort ACLは全部読み込んでCIDRのbit数の大きいアドレス(=最初にホストアドレス指定)から順に評価するようでして、192.168.3.1からの通信が許可され、他が拒否される、という挙動になります。

↓のようなコマンドレットを実行した結果、172.16.20.1、Internetと疎通できたので、そんな結論に至りました(VMが172.16.10.10、G/Wが172.16.10.1)。

add-VMNetworkAdapterAcl -Action Allow -Direction Inbound -VMName VM01 -RemoteIPAddress 172.16.0.0/16
add-VMNetworkAdapterAcl -Action Deny -Direction Inbound -VMName VM01 -RemoteIPAddress 172.16.10.0/24
add-VMNetworkAdapterAcl -Action Allow -Direction Inbound -VMName VM01 -RemoteIPAddress 172.16.10.1

他、指定のないアドレスへの通信は、Ciscoの場合は『暗黙のDeny』という事で全て拒否されますが、今回のPort ACLの場合は『暗黙のAllow』扱いのようでして、全て許可されます。

で、ひとつポイント。

VMのAddressが192.168.1.1でG/Wが192.168.1.254の時、以下のPort ACLを設定して192.168.2.1と通信が可能か?

add-VMNetworkAdapterAcl -Action Deny -Direction Inbound -VMName VM01 -RemoteIPAddress 192.168.1.0/24

答えは『暗黙のAllow』なんだから通信可能、ではなく、『G/WのARPが食えないから、G/Wと一切通信ができなくなって、結果的に全て拒否』でした。

G/Wのホストアドレス『のみ』Denyした場合、他セグメントと一切通信ができなくなってしまうので、その辺も注意が必要ですね。

また、ホストアドレスで方向を指定可能、という事は、『TCP通信は片方切れば疎通不可だが、UDPはフィルターの方向に注意』という事ですね。ざっくり『both』指定してしまえばOKなのですが、逆に『同一ホストに対してTCPは止めたいけど、UDPの受信だけはOKにしたい』時なんかは方向にさえ注意すれば、要望通りの実装が可能ですね。

そうそう、Port ACLを削除する際には、『Remove-VMNetworkAdapterAcl』なんですが、ACLを追加した際のオプションを総ざらいで入力する必要があるので、注意してください。

よって、最初の例のACLを削除する場合には

Remove-VMNetworkAdapterAcl -Action Deny -Direction Inbound -VMName VM01 -RemoteIPAddress 192.168.3.0/24

というような感じになります。addしたコマンドを保存しておいて、コマンドレットの頭をremoveに変えればOKなんですが、めんどくさいですよね(笑)

せめて追加した時に行番号かなんかをセットして、削除するときは『Remove-VMNetworkAdapterAcl <行番号>』みたいな感じで削除させてほしかったですね。その辺はパイプラインをうまく使え、なんでしょうね(PowerShell使いこなしてないなぁ……)。

設定済みACLをざっくり全部削除したい場合には

Get-VMNetworkAdapterAcl | Remove-VMNetworkAdapterAcl

で、全消しする事が可能です。

Firewallほど高機能にはできていませんが、ざっくりなフィルターでも構わないけどとにかく処理を軽くしたい、という場合には今回のPort ACLは非常に使えそうですね。

次回はACLがどこに設定されているか、また某氏より指摘のあった『LiveMigrationに追従するか』を確認したいと思います。