Configuring Private VLAN (PVLAN) on VMware vSphere: Network Traffic Isolation for VMs on the Same Subnet

VMware tutorial - IT technology blog
VMware tutorial - IT technology blog

The Problem: Same Subnet, But VMs Shouldn’t See Each Other

Imagine you’re running a small hosting infrastructure — 10 customers, each with their own VM, all sitting in the 192.168.1.0/24 range. In theory, a single VLAN should be enough. But there’s a hidden problem: Customer A could use ARP spoofing to intercept Customer B’s traffic, or launch a direct attack on a neighboring VM in the same subnet.

The usual fix is to put each customer in their own VLAN — but with 10 or 100 customers, you’d need 10–100 VLANs, 10–100 different subnets, and a pile of routing rules to go with them. IP addresses get fragmented, and management becomes a nightmare.

Private VLAN (PVLAN) solves exactly this problem: it isolates traffic between VMs within the same subnet, without requiring additional VLANs or any IP reconfiguration on any machine.

How Private VLAN Works

PVLAN uses a “Primary + Secondary VLAN” model. The Primary VLAN is the parent VLAN, which is subdivided into Secondary VLANs with three types of ports:

  • Promiscuous port: Can communicate with everything — typically used for routers, firewalls, and load balancers.
  • Isolated port: Can only communicate with Promiscuous ports, invisible to other VMs even on the same subnet.
  • Community port: Can communicate with other ports in the same community and with Promiscuous ports — but cannot see Isolated ports or other Community groups.

A practical example: Primary VLAN 200, containing:

  • Secondary VLAN 201 — Isolated (each customer’s web server, invisible to each other)
  • Secondary VLAN 202 — Community (Dev Team A can ping each other, but not Team B)
  • Secondary VLAN 203 — Community (Dev Team B, completely isolated from Team A)
  • Promiscuous port using Primary VLAN 200 (gateway/firewall)

Prerequisites

PVLAN on VMware vSphere has a few requirements you need to meet:

  • vSphere Distributed Switch (VDS) — Standard Switch does not support PVLAN
  • vSphere Enterprise Plus license or higher (VDS is an enterprise feature)
  • Access to vCenter Server with Network Administrator privileges
  • The underlying physical switch must also support PVLAN if traffic needs to leave the host

If you only have a Standard Switch or are running standalone ESXi without vCenter, PVLAN will not be available — this is a significant difference compared to Proxmox, which I’ll cover later.

Setup: Creating PVLAN on a Distributed Virtual Switch

Step 1: Open PVLAN Configuration in vCenter

Log in to vCenter, go to Networking → select your Distributed Switch → ConfigurePrivate VLAN. You’ll see an empty configuration table. Click Add to add your first Primary VLAN.

Step 2: Define Primary VLAN and Secondary VLANs

I typically use VLAN 200 as the Primary to avoid conflicts with standard VLANs (1–199). When you add Primary VLAN 200, vCenter automatically creates a Promiscuous 200↔200 entry. Next, add the Secondary VLANs:

Primary VLAN: 200
  Secondary VLAN 201 → Type: Isolated
  Secondary VLAN 202 → Type: Community
  Secondary VLAN 203 → Type: Community

For Community VLANs, you can create multiple groups — VMs in VLAN 202 can see each other but not VMs in VLAN 203.

Step 3: Create Port Groups with PVLAN Mapping

Once the PVLAN mapping is defined, create the corresponding Port Groups. Go to VDS → Distributed Port GroupsNew Distributed Port Group:

# Port Group for Gateway/Firewall
Name: PVLAN-200-Promiscuous
VLAN Type: Private VLAN
Private VLAN Mode: Promiscuous (Primary VLAN 200)

# Port Group for isolated VMs
Name: PVLAN-201-Isolated
VLAN Type: Private VLAN
Private VLAN Mode: Isolated (Secondary VLAN 201)

# Port Group for Team A
Name: PVLAN-202-Community-A
VLAN Type: Private VLAN
Private VLAN Mode: Community (Secondary VLAN 202)

# Port Group for Team B
Name: PVLAN-203-Community-B
VLAN Type: Private VLAN
Private VLAN Mode: Community (Secondary VLAN 203)

Detailed Configuration: Assigning VMs and Verifying IPs

Assign VMs to the Correct Port Group

Edit settings for each VM → Network Adapter → select the appropriate Port Group:

  • VM-Gateway → PVLAN-200-Promiscuous
  • VM-WebServer-CustomerA → PVLAN-201-Isolated
  • VM-WebServer-CustomerB → PVLAN-201-Isolated (same Isolated VLAN but invisible to each other)
  • VM-Dev-TeamA-01 → PVLAN-202-Community-A
  • VM-Dev-TeamA-02 → PVLAN-202-Community-A
  • VM-Dev-TeamB-01 → PVLAN-203-Community-B

IP Configuration — No Changes Needed

This is the beauty of PVLAN: all VMs still share the same IP range. PVLAN handles isolation at Layer 2 without affecting Layer 3:

# VM-WebServer-CustomerA
IP: 192.168.1.10/24
Gateway: 192.168.1.1

# VM-WebServer-CustomerB
IP: 192.168.1.11/24
Gateway: 192.168.1.1

# Both can ping the gateway but CANNOT ping each other

Physical Switch Configuration (if traffic leaves the host)

If the ESXi host uplink goes through a Cisco physical switch:

! Define PVLANs
vlan 200
 private-vlan primary
vlan 201
 private-vlan isolated
vlan 202
 private-vlan community
vlan 203
 private-vlan community

! Associate secondary VLANs with primary
vlan 200
 private-vlan association 201,202,203

! Port connected to ESXi uplink
interface GigabitEthernet0/1
 switchport mode trunk
 switchport trunk allowed vlan 200-203

If all VMs are on the same ESXi host (lab/test environment), you can skip this step — traffic never needs to reach the physical switch.

Testing & Monitoring

Test Isolation with Ping

Once configured, verify behavior from each VM using the following scenarios:

# From VM-WebServer-CustomerA (Isolated, IP: 192.168.1.10)
ping 192.168.1.1    # Gateway Promiscuous → MUST succeed
ping 192.168.1.11   # CustomerB same Isolated → MUST fail
ping 192.168.1.20   # Community VM → MUST fail

# From VM-Dev-TeamA-01 (Community 202, IP: 192.168.1.20)
ping 192.168.1.1    # Gateway → MUST succeed
ping 192.168.1.21   # TeamA-02 same Community 202 → MUST succeed
ping 192.168.1.30   # TeamB Community 203 → MUST fail
ping 192.168.1.10   # CustomerA Isolated → MUST fail

Audit Configuration with PowerCLI

# View PVLAN config of VDS
$vds = Get-VDSwitch -Name "DSwitch-Production"
$vds.ExtensionData.Config.PrivatVlanConfig |
    Format-Table PrimaryVlanId, SecondaryVlanId, PrivateVlanType

# List Port Groups using PVLAN
Get-VDPortgroup | Where-Object { $_.VlanConfiguration -match "Private" } |
    Select-Object Name, VlanConfiguration

Monitor with NetFlow/IPFIX

Enable IPFIX on the VDS to track traffic patterns and detect anomalies:

# Enable IPFIX for VDS
$vds = Get-VDSwitch -Name "DSwitch-Production"
$spec = New-Object VMware.Vim.DVSConfigSpec
$spec.IpfixConfig = New-Object VMware.Vim.VMwareIpfixConfig
$spec.IpfixConfig.CollectorIpAddress = "192.168.1.200"  # NetFlow collector
$spec.IpfixConfig.CollectorPort = 2055
$spec.IpfixConfig.ActiveFlowTimeout = 60
$spec.ConfigVersion = $vds.ExtensionData.Config.ConfigVersion
$vds.ExtensionData.ReconfigureDvs($spec)

Real-World Comparison: PVLAN on VMware vs. Proxmox

When I migrated from VMware to Proxmox for a personal lab, I noticed some interesting differences in how the two platforms handle network isolation.

Proxmox uses Linux bridge and can achieve similar results by combining a VLAN-aware bridge with ebtables rules, but there’s no built-in GUI for it. Getting “true” PVLAN on Proxmox requires writing your own scripts or using Open vSwitch — significantly more complex than a few clicks in vCenter.

What I appreciate about VMware PVLAN is its consistency: configure it once at the VDS level and it instantly applies across all hosts in the cluster. With Proxmox, you’d need to configure each node individually or write an automation script to keep things in sync.

That said, the Enterprise Plus license is a real barrier — especially for a personal lab or small startup. For environments that don’t require high SLAs, Proxmox + OVS is a far more cost-effective choice.

Common Issues

  • VM can’t ping the gateway after configuration: Verify that VM-Gateway is assigned to the Promiscuous port group, not an Isolated one.
  • Community VMs can’t see each other: Make sure both VMs share the same Secondary VLAN ID — for example, both must be 202, not one 202 and one 203.
  • Physical switch not forwarding traffic: PVLAN must be configured on the physical switch if the uplink is a trunk port, not an access port.
  • Private VLAN menu missing in vCenter: Double-check — Standard Switch and Standard license do not include this feature.
  • PVLAN config missing after adding a new host to the cluster: PVLAN mapping is stored at the VDS level and should auto-apply, but verify the uplink configuration on the new host.

Share: