Sorry for the late reply — old thread, I completely missed the notification.
For the record:
@Dunuin's suggestion in #2 was the right one, and it does work. My failed test back in 2023 was almost certainly the conntrack issue
@SteveITS and
@fba just described — I enabled the drop rule while the pings were already running, so the established state kept passing traffic. `conntrack -F` on the node (or just stopping/restarting the flow) makes the difference.
What I ended up deploying: a single datacenter-level security group applied to every VM that has to be isolated. No SDN, no extra VLANs, no reconfiguration on the VM side.
Datacenter aliases + IPSet + group (dumped from `/etc/pve/firewall/cluster.fw` for readability, but everything was created through the GUI):
Code:
[ALIASES]
CustA-LAN 192.168.200.0/22 # Customer A LAN
CustA-WebServer 192.168.201.210 # Web Server
CustA-GW 192.168.200.253 # Customer A Gateway
CustA-MailServer 192.168.202.1 # Mail server
[IPSET custa_whitelist] # Customer A whitelist for VM isolation
dc/custa-gw # Gateway
dc/custa-mailserver # Mail server
dc/custa-webserver # Web server
...
[IPSET not-rfc1918] # Internet networks
!10.0.0.0/8 # IPv4 Class A
!169.254.0.0/16 # IPv4 Local link
!172.16.0.0/12 # IPv4 Class B
!192.168.0.0/16 # IPv4 Class C
[IPSET rfc1918] # RFC1918 private networks
10.0.0.0/8 # IPv4 Class A
169.254.0.0/16 # IPv4 Local link
172.16.0.0/12 # IPv4 Class B
192.168.0.0/16 # IPv4 Class C
...
[group vm-custa] # Customer A VMs (gateway + internet only)
IN ACCEPT -source +dc/mgmt-lan -dest dc/custa-lan -log nolog # [Customer A] Allow Management LAN > LAN
IN ACCEPT -source dc/custa-gw -dest dc/custa-lan -log nolog # [Customer A] Allow Gateway > LAN
IN ACCEPT -source +dc/custa_whitelist -dest dc/custa-lan -log nolog # [Customer A] Allow Whitelist > LAN
IN DROP -source dc/custa-lan -dest dc/custa-lan -log info # [Customer A] Deny intra-LAN
IN ACCEPT -source +dc/rfc1918 -dest dc/custa-lan -log nolog # [Customer A] Allow Other LANs (VPN) > LAN
IN ACCEPT -source +dc/not-rfc1918 -dest dc/custa-lan -log nolog # [Customer A] Allow Internet > LAN
OUT ACCEPT -source dc/custa-lan -dest +dc/mgmt-lan -log nolog # [Customer A] Allow LAN > Management LAN
OUT ACCEPT -source dc/custa-lan -dest dc/custa-gw -log nolog # [Customer A] Allow LAN > Gateway
OUT ACCEPT -source dc/custa-lan -dest +dc/custa_whitelist -log nolog # [Customer A] Allow LAN > Whitelist
OUT DROP -source dc/custa-lan -dest dc/custa-lan -log info # [Customer A] Deny intra-LAN
OUT ACCEPT -source dc/custa-lan -dest +dc/rfc1918 -log nolog # [Customer A] Allow LAN > Other LANs (VPN)
OUT ACCEPT -source dc/custa-lan -dest +dc/not-rfc1918 -log nolog # [Customer A] Allow LAN > Internet
And then, on each VM that has to be isolated, `/etc/pve/firewall/<vmid>.fw`:
Code:
[OPTIONS]
policy_in: ACCEPT
policy_out: ACCEPT
enable: 1
[RULES]
GROUP vm-custa # VM isolation
A few notes on why it's built this way:
- Rules are evaluated top-down, first match wins. The two intra-LAN DROP rules sit *after* the gateway/whitelist ACCEPTs, so the exceptions (gateway, mail, web, management LAN) survive while everything else inside `192.168.200.0/22` is dropped in both directions.
- Both IN and OUT are covered on purpose. Dropping only IN is enough on paper, but doing both means an isolated VM can't initiate anything towards a neighbour either, and the `log info` on those two rules makes lateral-movement attempts visible in the VM firewall log.
- `rfc1918` / `not-rfc1918` are the standard IPSets; splitting the last two ACCEPTs that way keeps VPN/other-subnet traffic and plain internet traffic as separate, individually revocable rules.
- Default policies stay ACCEPT on the VM: all the filtering logic lives in the group, so adding a VM to the isolation set is a one-line change and the whitelist is maintained in exactly one place.
- Firewall must be enabled at datacenter level, on the VM, and on the vNIC (the "Firewall" checkbox on the network device) — all three, otherwise nothing is filtered.
Caveat worth repeating for anyone landing here: this is L3 filtering on the bridge, not real L2 isolation. It's not a substitute for separate VLANs if the threat model includes ARP/L2 games, but for "50 tiny VMs that only need the gateway and internet" it's been solid and enormously cheaper to operate than one VLAN per VM.
Bye,
Edoardo