ARP Spoofing Prevention in Hyper-V 2008 R2 SP1

Note: This article only applies to Windows Server 2008 R2 SP1. Please refer to this site if you want to learn how to implement ARP Spoofing in Windows Server 2012 using Port ACLs https://blogs.technet.com/b/wincat/archive/2012/11/18/arp-spoofing-prevention-in-windows-server-2012-hyper-v.aspx

My name’s Thomas Roettinger and I am a private cloud and virtualization Premier Field Engineer over Microsoft Germany. I’m proud to be submitting my first blog post in our brand new PFE Virtualization Blog. Today I am blogging about a new network feature that is made available in Hyper-V R2 SP1.

This feature is called ARP Spoofing Prevention and is not exposed through Hyper-V or SCVMM 2008 R2 SP1 management consoles.

Many private cloud hosters are looking for a functionality to make sure that customers can’t compromise a virtual machine by changing the IP Address.

This also a nice option when you plan to virtualize your workload inside Perimeter Network.

This is the technical explanation of the ARP Spoofing Prevention functionality:

ARP spoofing is a man-in-the-middle attack technique that is used to attack an Ethernet local area network (LAN). The attacker associates a MAC (media access control) address with the IP address of another node by sending fake ARP messages to an Ethernet LAN. Therefore, the attacker can capture data frames that are sent to another node (here Virtual Machine attached to the same virtual switch).

So, what can Hyper-V R2 SP1 do to harden your workload against this attack?

  • Checks the mapping of a MAC address and respected IP address in a virtual switch
  • WMI API to associate a MAC address with an IP address in a virtual switch
  • Protect against an ARP for IPv4 response or an NDP for IPv6 response

Technical Requirements:

Here’s a PowerShell sample script to enable the virtual machine named "TestVM” to only communicate with the IP Address 192.168.0.1

 $VmName = "TestVM"
 $Msvm_ComputerSystem = (Get-WmiObject -Namespace root\virtualization `
   -Class Msvm_ComputerSystem -Filter "ElementName='$VmName'")
  
 #Retrieve all Msvm_SyntheticEthernetPort's associated with this VM 
 #  there will be one per Synthetic NIC
 $Msvm_SyntheticEthernetPortCollection = `
  $Msvm_ComputerSystem.GetRelated("Msvm_SyntheticEthernetPort")
 #This will get the last object in a collection or if the collection 
 #  has one object just that object
 $Msvm_SyntheticEthernetPort = $Msvm_SyntheticEthernetPortCollection | % {$_}
  
 #There will only ever be one Msvm_VmLANEndpoint per 
 #  Msvm_SyntheticEthernetPort
 $Msvm_VmLANEndpointCollection = `
  $Msvm_SyntheticEthernetPort.GetRelated("Msvm_VmLANEndpoint")
 $Msvm_VmLANEndpoint = $Msvm_VmLANEndpointCollection | % {$_}
  
 #There will only ever be one Msvm_SwitchPort per Msvm_VmLANEndpoint
 $Msvm_SwitchPortCollection = ` 
  $Msvm_VmLANEndpoint.GetRelated("Msvm_SwitchPort")
 #This will get the last object in a collection or if the collection
 #   has one object just that object
 $Msvm_SwitchPort = $Msvm_SwitchPortCollection | % {$_}
  
 $Msvm_SwitchPort.PreventIPSpoofing=$true
 $Msvm_SwitchPort.AllowedIPv4Addresses= (, "192.168.0.1")
 $Msvm_SwitchPort.Put()

And the following PowerShell sample script allows communication with all IP Address again:

 $VmName = "TestVM"
 $Msvm_ComputerSystem = (Get-WmiObject -Namespace root\virtualization `
   -Class Msvm_ComputerSystem -Filter "ElementName='$VmName'")
  
 #Retrieve all Msvm_SyntheticEthernetPort's associated with this VM 
 # there will be one per Synthetic NIC
 $Msvm_SyntheticEthernetPortCollection = `
  $Msvm_ComputerSystem.GetRelated("Msvm_SyntheticEthernetPort")
 #This will get the last object in a collection or if the collection 
 #  has one object just that object
 $Msvm_SyntheticEthernetPort = $Msvm_SyntheticEthernetPortCollection | % {$_}
  
 #There will only ever be one Msvm_VmLANEndpoint per Msvm_SyntheticEthernetPort
 $Msvm_VmLANEndpointCollection = `
  $Msvm_SyntheticEthernetPort.GetRelated("Msvm_VmLANEndpoint")
 $Msvm_VmLANEndpoint = $Msvm_VmLANEndpointCollection | % {$_}
  
 #There will only ever be one Msvm_SwitchPort per Msvm_VmLANEndpoint
 $Msvm_SwitchPortCollection = $Msvm_VmLANEndpoint.GetRelated("Msvm_SwitchPort")
 #This will get the last object in a collection or if the collection 
 #  has one object just that object
 $Msvm_SwitchPort = $Msvm_SwitchPortCollection | % {$_}
  
 $Msvm_SwitchPort.PreventIPSpoofing=$false
 $Msvm_SwitchPort.AllowedIPv4Addresses=$null
 $Msvm_SwitchPort.Put()
  

This sample script is also cluster aware but you must refresh Virtual Machine’s configuration within the Failover Cluster Management Console.

Please keep in mind that this feature is different from MAC Spoofing that has been available since Windows Server 2008 R2 Hyper-V.

I hope you find this blog post helpful.

 

Disclaimer: Any software (or sample code) provided in this blog is not supported under any Microsoft standard support program or service. The sample code is provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the software and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the software be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the software or documentation, even if Microsoft has been advised of the possibility of such damages. Please test the sample code before implementing in your production environment.