Intro

In a previous post I showed you how to mirror your physical network to a VM hosted on Proxmox with Open vSwitch (OVS). I recently changed up my network and swapped out my Juniper switch for a Mikrotik one. Unfortunately the Mikrotik switch does not support enough port-mirror sessions for my needs 😭 Therefore, I needed to change the way I mirrored traffic to my Extrahop sensors to allow them to analyse network packet data.

In this post, I will show you how to mirror all traffic from a Virtual Switch (VM Bridge in Proxmox speak) to a VM in Proxmox.

Software Versions

The following software was used in this post.

  • Proxmox - 7.1-11
  • Open vSwitch - 2.15.0

Lab Diagram

The following diagram shows the port-mirroring configuration outlined in this post. The goal is to mirror all the traffic from the virtual switch: vmbr0 to the capture port: int2 on eda01 for analysis.

blog/proxmox-vm-bridge-port-mirror/proxmox.png

The following points summarize the important items from the above diagram.

  • vmbr0 is the virtual switch that all VMs connect to.
  • vmbr0 is the source for our port-mirror traffic.
  • tap201i1 is the virtual interface assigned to the capture port on eda01
  • tap201i1 is the destination for our port-mirror traffic.

Hook Script

Hook scripts allow you to run a script during various execution phases of a VM. For example post-start or pre-stop.

Hook scripts are saved in the /var/lib/vz/snippets/ directory. The following hookscript named port-mirror.sh starts and stops a port-mirror when the eda01 VM boots-up, reboots or shutsdown.

/var/lib/vz/snippets/port-mirror.sh
#! /usr/bin/env bash

VM_ID=$1;
EXECUTION_PHASE=$2
VM_BRIDGE="vmbr0";
LOGGING=/root/scripts/port-mirror.log;

function create_mirror {

  /usr/bin/date >> $LOGGING;

  /usr/bin/echo "Creating mirror on $VM_BRIDGE for $VM_ID"... >> $LOGGING;

  /usr/bin/ovs-vsctl \
  -- --id=@tap"$VM_ID"i1 get Port tap"$VM_ID"i1 \
  -- --id=@"$VM_ID"m create Mirror name="$VM_ID"-mirror \
    select-all=true \
    output-port=@tap"$VM_ID"i1 \
    -- set Bridge "$VM_BRIDGE" mirrors=@"$VM_ID"m >> $LOGGING;

  /usr/bin/echo "####################" >> $LOGGING;

}

function clear_mirror {

  /usr/bin/date >> $LOGGING;

  /usr/bin/echo "Clearing mirror on $VM_BRIDGE for $VM_ID..." >> $LOGGING;

  /usr/bin/ovs-vsctl \
    -- --id=@"$VM_ID"m get Mirror "$VM_ID"-mirror \
    -- remove Bridge "$VM_BRIDGE" mirrors @"$VM_ID"m >> $LOGGING;

  /usr/bin/echo "####################" >> $LOGGING;

}

function show_mirrors {

  /usr/bin/date >> $LOGGING;

  /usr/bin/echo "Show existing mirrors..." >> $LOGGING;

  /usr/bin/ovs-vsctl list Mirror >> $LOGGING;

  /usr/bin/echo "####################" >> $LOGGING;

}

if [[ "$EXECUTION_PHASE" == "post-start" ]]; then

  clear_mirror;

  create_mirror;

  show_mirrors;

elif [[ "$EXECUTION_PHASE" == "pre-stop" ]]; then

  clear_mirror;

  show_mirrors;

fi

Don't forget to make the hook script executable.

cmd
chmod +x /var/lib/vz/snippets/port-mirror.sh

Also apply the hook script to the eda01 VM.

cmd
qm set 201 --hookscript local:snippets/port-mirror.sh

Once this is done, you will start seeing traffic mirrored to the capture port of the eda01 VM for analysis.

Outro

In this post, I showed you how to mirror all the traffic from a virtual switch in Proxmox to a VM for analysis using Open vSwitch and hook scripts. May you live long and prosper my friends 🖖