What are Hyper-V Extended Port ACLs?

There is a common misconception that Hyper-V does not offer any level of network security. The best solution would be to use a Hyper-V virtual switch extension however the virtual switch already has built-in basic firewalling functionality. This was introduced in Windows Server 2012 (WS2012) Hyper-V with Port ACLs and improved in Windows Server 2012 R2 (WS2012 R2) Hyper-V with Extended Port ACLs.

What Are Extended Port ACLs?

Before Windows Server 2012 Hyper-V, any virtual machine could talk to any other virtual machine if they were about to route to each other. Perhaps they were on the same private virtual network (switch), on the same VLAN, or on VLANs that were not isolated. There was nothing in Hyper-V to prevent those virtual machines from communicating across all network protocols. Before we had network virtualization this meant we had to create VLANs and configure firewall rules in the physical network core. That could get very messy and time consuming requiring interaction with the network admins thus adding bureaucracy.
Alternatively, we could configure the Windows Firewall however that could  subject us to being interfered with by the guest OS admins. These guests are often developers or testers. They simply cannot be trusted by the fabric/virtualization administrators to consistently put the company’s best interests ahead of their own.
Things changed in WS2012 when Hyper-V Network Virtualization (HNV) was added and later improved on in WS2012 R2. If we need even greater granularity we can use a partner solution in the form of a virtual switch extension. Though this is often the best product there can be a cost to it.
What if there was a built in firewall that could be managed? We got that with WS2012 Hyper-V in the form of Port ACLs (Access Control Lists). Port ACLs allowed us to manage access between two IP addresses (machine or network) but there was no port level control.
WS2012 R2 gave us protocol (TCP/UDP/numbering) and port level control, and stateful inspection, when Port ACLs were upgraded to Extended Port ACLs.
Port ACLs are assigned to virtual NICs. This means that the rule moves with the virtual machine, which is very important in the mobile world of virtualization. Rules can be applied to all/selected inbound or outbound traffic to a virtual machine so traffic coming from or going to a physical device is also affected.

Hyper-V Extended Port ACLs are applied by the virtual switch to virtual NICsAn extended Port ACL filtering traffic to a virtual machine

A Simple Rule

A simple requirement would be to isolate a virtual machine from all inbound traffic. We can do that using PowerShell. PowerShell is the only way to do the really clever stuff in the Microsoft world. (If you haven’t been getting the hint; you need to start learning PowerShell if you haven’t already!)

If you want to prevent all inbound traffic to a virtual machine with the filtering being done by the virtual switch under the sole control of Hyper-V administrators and no control by guest OS admins, run a cmdlet like this:

​ Add-VMNetworkAdapterExtendedAcl –VMName “VM01” –Action “Deny” –Direction “Inbound” –Weight 1

The Add-VMNetworkAdapterExtendedACL cmdlet creates Port ACL or firewall rules. The big advantage of using PowerShell is that you can automate easily (see Service Management Automation or SMA) or you can speed up deployment via a script.
The rule is created as “inbound”. This means that the rule is applied to traffic coming into the named virtual machine. The action is “Deny” which blocks traffic. A weight is assigned to the rule; 1 being the lowest weight. This will be a default rule for the virtual machine. In other words, the “block all inbound traffic” is the default rule but we might create other rules with higher weights that allow selected traffic into the virtual machine.
This rule does not block any outbound traffic from the virtual machine. We can do that by using the “Outbound” option in another rule.

Combining Rules

You can add a number of rules with different weights to a virtual machine. In this example we will block all inbound traffic except for TCP traffic that comes in to port 80. This was not possible with WS2012 Port ACLs but WS2012 R2 allows us to define a specific port.

​ Add-VMNetworkAdapterExtendedAcl –VMName “VM01” –Action “Deny” –Direction “Inbound” –Weight 1
​ Add-VMNetworkAdapterExtendedAcl –VMName “VM01” –Action “Allow” –Direction “Inbound” –LocalPort 80 –Protocol “TCP” –Weight 10

The first rule blocks all traffic by default. A higher weight rule (good practice is to increment by 10 to allow other rules to be inserted in-between) is created to allow inbound traffic on the local port (on the virtual machine) of 80 via the TCP protocol. In other words, this machine is only available to the network as a web server.

Stateful Inspection

Rules that blindly block traffic can be useful but network administrators prefer stateful inspection. This allows for a response to an allowed request.
Imagine you have a scheduling server that orchestrates jobs on several other computers using SSL communications to agents on those machines and retrieves results within a certain time. You want to block all traffic to and from this server, but you need to allow it to connect to other servers on TCP 443 and allow a response within a certain timeout window. This is an example of Stateful inspection.

​ Add-VMNetworkAdapterExtendedAcl –VMName “VM01” –Action “Deny” –Direction “Inbound” –Weight 1
​ Add-VMNetworkAdapterExtendedAcl –VMName “VM01” –Action “Deny” –Direction “Outbound” –Weight 1
​ Add-VMNetworkAdapterExtendedAcl –VMName “VM01” –Action “Allow” –Direction “Outbound” 443 “TCP” –Weight 10 –Stateful –Timeout 120


The first rule blocks all inbound traffic to the virtual machine. The second rule blocks all outbound traffic from the virtual machine. A third rule allows the virtual machine to talk to other computers via SSL (TCP 443) by overruling the second rule for this specific kind of traffic. Note that the –Stateful flag is added. This will allow a response within the timeout of 120 seconds.