Setting up Port Mirroring to Capture Mirrored Traffic on a Hyper-V Virtual Machine

Applies To: Windows Server 2012, Windows Server 2012 R2, Windows Server 2016, Nano Server.

Hi folks Gopal here again from the Microsoft Networking Escalation team. 

The article below provides steps on how a Hyper-V virtual machine running on Windows Server 2012/2012 R2 can be used to capture mirrored traffic that is hitting the Hyper-V host. 

Note: These steps and functionality exists in Windows Server 2016 including Nano Server.

Port mirroring also called as SPAN is a method used to monitor network traffic. With port mirroring enabled or a switch port spanned, the switch sends a copy of all the packets hitting one specific port or a VLAN to another port — where the packet can then be picked up and analyzed. The usual practice here, is another physical machine is connected to the SPAN/Mirrored port and a packet monitoring utility is run to sniff the traffic there.

However, users who would like to use a virtual solution, rather than using a physical machine itself to perform sniffing from the mirrored network port.

This can be achieved using Hyper-V in 2012/2012 R2.

Let us take the following scenario as an example:

  • Server1 and Server2 are two physical machines connected to a switch.
  • HyperVServer is a the host which is also connected to the same switch.
  • VM1 is a virtual machine running on the HyperVServer.

All the above machines are part of the same network subnet. Port mirroring has been configured on the switch — to mirror any traffic on port Server2 is connected to –> to the port that HyperVServer is connected to.

Now any communication happening between Server1 and Server2 can be captured from a packet sniffing software (say netmon) running on the HyperVServer.

The goal here now though is, how can we achieve the same, but capture the mirrored traffic onto a VM running on the HyperVServer instead of on the host itself?

This is achievable both in Windows Server 2012/2012 R2 through very simple configurations that can be made to the Hyper-V and the virtual switch settings– note the virtual switch here is connected to a physical network.

By default the mirroring mode will only allow a VM to capture from the Virtual switch that the VM is attached to.

In order to enable the VM to also capture traffic hitting the mirrored port the host is connected to, we need to do the following broad steps:

  1. Set the Mirroring mode of the capturing VM to “Destination”.
  2. Set the Mirror mode on the External port of the virtual switch the VM is attached to reflect the “Source”.
  3. Configure the destination VM NIC to trunk mode and specify the VLANs it is going to receive traffic from.

Steps are discussed in detail below:

SETTING THE MIRRORING MODE OF THE VM TO DESTINATION:

On the virtual machine where we want the mirrored traffic to be captured on, do the following:

  1. Go to the Virtual machine settings from the hyper-V console.
  2. Expand the respective network adapter and click on “Advanced Features”.
  3. Select the Mirroring more under the “Port Mirroring” section and set it to “Destination”.

    clip_image002

Remember, when we configure port mirroring it is like configuring a pair. We always configure a “SOURCE” and then we configure a “DESTINATION” so that the SOURCE knows who to forward the information over to.

In this case, we are really setting one of the interfaces (virtual ports) of the Virtual switch to “DESTINATION” by doing this.

SET THE MIRROR MODE ON THE EXTERNAL PORT OF THE VIRTUAL SWITCH TO “SOURCE”:

  1. Next, we need to let the Virtual Switch know that any traffic that hits the external port, has to be forwarded on to the port that we configured “DESTINATION” earlier.
    Imagine this as the following:
    All traffic hitting the hyper-v Host is also hitting the external port of the virtual switch. However for the NIC on the VM to get these packets, we need to now “mirror” this Switch port (on the Virtual switch) to let him know that he has to forward the packets onto the “DESTINATION” we had configured earlier.
  2. We can use the following PowerShell command to accomplish the same and set the External port to “SOURCE” Mirror mode: 

    $a = Get-VMSystemSwitchExtensionPortFeature -FeatureId 776e0ba7-94a1-41c8-8f28-951f524251b5
    $a.SettingData.MonitorMode = 2
    add-VMSwitchExtensionPortFeature -ExternalPort -SwitchName <name of the switch> -VMSwitchExtensionFeature $a
     

    Where <name of the switch> has to be replaced by the name of the Virtual Switch. 

    MonitorMode=2 is what sets the Mirror mode to “SOURCE” here.

NOTE:

From some discussions internally and feedback received about the
“Get-VMSystemSwitchExtensionPortFeature commandlet”, the following command i.e. using
“Set-VMNetworkAdapter –PortMirroring” context seems to be a better and more straight forward means of setting the external port of the virtual switch to MonitorMode source.

For example:
Set-VMNetworkAdapter -ManagementOS -VMNetworkAdapterName “trunk1” -PortMirroring Source

That said, from experience we have seen both the above methods of setting the Mirroring mode of the External port of the Virtual switch to source, work.
Usually the above steps are sufficient to see the traffic destined to the Hyper-V host on the VM.

However in scenarios where we are sniffing other traffic from the VLAN/Network onto the Hyper-V host, or the Hyper-V host is receiving traffic mirrored from different VLANs — then we would also need to configure the destination VM NIC to trunk mode and specify the VLANs that it is expected to receive traffic from – this is to ensure that the destination VM NIC does not drop packets forwarded to it from other VLANs or networks that it is not expecting to receive traffic from.

CONFIGURING TO MONITOR TRAFFIC FROM MULTIPLE VLANs

So far we discussed a scenario where Server1 and Server2 are in the same network and HyperVServer is a Hyper-V host connected to the mirrored switch port—where mirroring was configured to receive any traffic from the port that Server2 was connected to.

Practically, we could also have scenarios where the port that HyperVServer is connected to, is configured to receive traffic from multiple other VLANs.

When the destination VM NIC has to receive mirrored traffic from multiple VLANs the VM NIC has to be set for trunk mode explicitly and configured with a list of allowed VLAN IDs.

For example:
Set-VMNetworkAdapterVlan -VMName Contoso_App2 -Trunk -AllowedVlanIdList 1-100 -NativeVlanId 10

In the above command, we are setting the VM NIC of the destination VM named “Contoso_App2” to Trunk mode. We are also explicitly telling the VMNIC to receive any traffic from the allowed VLAN IDs here which are from VLAN ID 1 to VLAN ID 100.
When receiving sniffed traffic from the same VLAN as well, it is good to setup the destination VM NIC to trunk mode with the allowed VLAN id which might be of the same local network.
With the above steps configured now, we should be able to see mirrored traffic received on a Hyper-V host

Note: The above steps should work natively on Windows Server 2012 R2 Hyper-V Hosts. However, on Windows Server 2012 servers you would need the following hotfix if applicable:
http://support.microsoft.com/kb/2885541/en-us

ADDITIONAL INFORMATION

  • While sniffing traffic from the VM—ensure that the tracing utility is configured to run in promiscuous mode!!
  • You can use the following commands to verify the configuration.

On the host:
If the Get-VMSystemSwitchExtensionPortFeature was used to set MonitorMode to 2, the following commands can be used to display and see the current configuration. For example:

PS C:\> $feature = Get-VMSwitchExtensionPortFeature -FeatureId 776e0ba7-94a1-41c8-8f28-951f524251b5 -ExternalPort -SwitchName test123

PS C:\> $feature.SettingData

__GENUS : 2

__CLASS : Msvm_EthernetSwitchPortSecuritySettingData

__SUPERCLASS : Msvm_EthernetSwitchPortFeatureSettingData

__DYNASTY : CIM_ManagedElement

__RELPATH : Msvm_EthernetSwitchPortSecuritySettingData.InstanceID=”Microsoft:55E3FD03-CB20-4266-9E31-91D4DA

4FD4AD\\83BFFC88-DEE2-4C46-8F1A-85769DFE1F5B\\776E0BA7-94A1-41C8-8F28-951F524251B5\\DD0CF4A7-0C

8D-4690-9590-69C8CFEAF308″

__PROPERTY_COUNT : 16

__DERIVATION : {Msvm_EthernetSwitchPortFeatureSettingData, Msvm_FeatureSettingData, CIM_SettingData,

CIM_ManagedElement}

__SERVER : CONTOSO

__NAMESPACE : root\virtualization\v2

__PATH : \\CONTOSO\root\virtualization\v2:Msvm_EthernetSwitchPortSecuritySettingData.InstanceID=”Microsof

t:55E3FD03-CB20-4266-9E31-91D4DA4FD4AD\\83BFFC88-DEE2-4C46-8F1A-85769DFE1F5B\\776E0BA7-94A1-41C

8-8F28-951F524251B5\\DD0CF4A7-0C8D-4690-9590-69C8CFEAF308″

AllowIeeePriorityTag : False

AllowMacSpoofing : False

AllowTeaming : False

Caption : Ethernet Switch Port Security Settings

Description : Represents the security feature setting data.

DynamicIPAddressLimit : 0

ElementName : Ethernet Switch Port Security Settings

EnableDhcpGuard : False

EnableRouterGuard : False

InstanceID : Microsoft:55E3FD03-CB20-4266-9E31-91D4DA4FD4AD\83BFFC88-DEE2-4C46-8F1A-85769DFE1F5B\776E0BA7-94

A1-41C8-8F28-951F524251B5\DD0CF4A7-0C8D-4690-9590-69C8CFEAF308

MonitorMode : 2

MonitorSession : 0

StormLimit : 0

TeamName :

TeamNumber : 0

VirtualSubnetId : 0

PSComputerName : CONTOSO

If the Set-VMNetworkAdapter command was used then you can use “Get-VMNetworkAdapter” command to check the PortMirroringMode parameter:
PS C:\WINDOWS\system32> Get-VMNetworkAdapter -ManagementOS | fl *

IsManagementOs : True

DeviceId : {89D529BD-AC97-4928-AD1F-8883A3B0CB51}

Name : Test123

MandatoryFeatureId :

IsLegacy : False

IsExternalAdapter : False

Id : Microsoft:55E3FD03-CB20-4266-9E31-91D4DA4FD4AD\7E4CEC7D-F186-445A-BF5F-F6B09206E450

AdapterId : 1D3698A3-D4B2-4B56-8FBB-8D54E7880ECC

DynamicMacAddressEnabled : False

MacAddress : 3C970E866F9F

MacAddressSpoofing : Off

SwitchId : 55e3fd03-cb20-4266-9e31-91d4da4fd4ad

Connected : True

PoolName :

SwitchName : Test123

AclList : {}

ExtendedAclList : {}

IsolationSetting : Microsoft.HyperV.PowerShell.VMNetworkAdapterIsolationSetting

CurrentIsolationMode : Vlan

RoutingDomainList : {}

DhcpGuard : Off

RouterGuard : Off

PortMirroringMode : Source

IeeePriorityTag : Off

VirtualSubnetId : 0

DynamicIPAddressLimit : 0

StormLimit : 0

AllowTeaming : Off

VMQWeight : 100

IPsecOffloadMaxSA : 512

VmqUsage : 0

IPsecOffloadSAUsage : 0

VFDataPathActive : False

VMQueue :

MandatoryFeatureName :

VlanSetting : Microsoft.HyperV.PowerShell.VMNetworkAdapterVlanSetting

BandwidthSetting :

BandwidthPercentage : 0

TestReplicaPoolName :

TestReplicaSwitchName :

StatusDescription : {OK}

Status : {Ok}

IPAddresses :

ComputerName : CONTOSO

IsDeleted : False

VMId : 00000000-0000-0000-0000-000000000000

VMName :

VMSnapshotId : 00000000-0000-0000-0000-000000000000

VMSnapshotName :

Key :

Additionally to get the VM Network Adapter configuration and the Operation mode/Allowed VLAN information the “Get-VMNetworkAdapterVlan” command can be used:

PS C:\WINDOWS\system32>Get-VMNetworkAdapterVlan -VMName Contoso_app2 | fl *

ParentAdapter : Microsoft.HyperV.PowerShell.VMNetworkAdapter

OperationMode : Trunk

AccessVlanId : 0

NativeVlanId : 1

AllowedVlanIdList : {1, 2, 3, 4…}

AllowedVlanIdListString : 1-100

PrivateVlanMode : 0

PrimaryVlanId : 0

SecondaryVlanId : 0

SecondaryVlanIdList :

SecondaryVlanIdListString :

Above configurations are very simple, however if there are issues then to debug a VMSwitch etl would come in very handy in these scenarios.

 ~Gopalakrishnan Krishnan