Network Filtering (IP Anti-Hijacking)
Since version 3.0, VirtFusion has built in native bridge network filtering.
Network filters protect the addresses and network roles of a VM, such as preventing MAC and IP spoofing. The VM firewall controls which IP traffic it allows or denies. Native v2 provides separate settings for these two protections:
| Setting | Purpose |
|---|---|
Filter Type | Chooses the network protection engine for the hypervisor. |
Native v2 Components | Chooses the protections applied by Native v2, with per-interface overrides. |
Firewall Engine | Chooses how existing VM firewall rules are enforced when Native v2 is selected. |
Block on filter failure | Chooses whether a failed filter application stops the affected VM action. |
The following filter types are available:
NoneNo filters will be applied to any virtual servers on the hypervisor.LibvirtA standard set of filters to prevent MAC spoofing, IP stealing and various other filters to clean traffic.Native StandardThis filter applies the same rule sets asLibvirt.Native Performance (IPv4)A minimal rule set to prevent IPv4 MAC spoofing and IP stealing. IPv6 is not filtered.Native Performance (IPv4 + IPv6)A minimal rule set to prevent IPv4 and IPv6 MAC spoofing, IP stealing and various ICMPv6 codes ( including router advertisement).Native v2A new filtering engine, added in 7.1 and marked experimental. The filter is a set of components you choose rather than a fixed rule set. See Native v2 below.
Existing hypervisors (added pre v2.4) will continue to use Libvirt filters until native filters are enabled on a per
hypervisor basis. Any hypervisors added post v2.4 will have Native Performance (IPv4 + IPv6) filters enabled by default.
If you would like to switch your existing hypervisors to native filtering (or vice versa), you may change
The Network Filtering type under the hypervisor settings.

Changing this setting will only enable the selected filter type for new servers or servers that have had an action run against them. You can force a configuration and filter update with this control server CLI command to force a full change and update.
Native v2
Native v2 is a separate filtering engine that sits beside the existing native filters. It renders one set of rules per server interface and applies them in a single transaction, so an interface is never half filtered and never unfiltered while its rules change. It is off by default: a hypervisor runs it only when you select it.
Requirements
- Update the hypervisor first, then the control server, to versions that include the settings you intend to use. Native v2 and the Native nft firewall engine are experimental 7.1 features.
- A supported hypervisor operating system with the
nftcommand installed. - Interfaces attached to a Linux bridge, including supported libvirt-managed bridged and routed networks. Native v2 network protections skip interfaces with Network Filtering disabled, NAT interfaces, MacVTap and Open vSwitch. The VM firewall has its own coverage, described under Firewall engine.
Enabling it
- Open the hypervisor, select
Native v2underNetwork Filteringand save. Nothing changes on the hypervisor yet: the page shows that the filter settings have changed and have not been applied. - Review the components (below) and the management ranges, and save again if you change anything.
- Click
Regenerate filtersand confirm. VirtFusion re-applies the network filters of every server on the hypervisor: each server gets its v2 rules first, and its native v1 rules are removed once the v2 rules are in place. The page shows the progress and the result.
Servers that already have v1 rules keep them until the regenerate, or until they are next started or have a configuration applied. A server never runs both engines for longer than the moment of the switch.
Saving a change to the filter type, the components, the management ranges or a network's router and DHCP server
MACs never applies anything by itself. The hypervisor page tells you a regenerate is owed, and the
Regenerate filters button is the only thing that runs it. A server's own Update & Apply applies that server
alone.
Components
Each component is one protection, with its own rule. The hypervisor page lists them in groups, each with what it
blocks. The recommended set is every component a typical server never needs to do without; the opt-ins
(SYN rate cap, Gateway only, Multicast lockdown and the four bridge port settings) are off until you choose
them, because each breaks a specific kind of server or depends on how the bridge is set up.
| Group | Components |
|---|---|
| Identity, frames from the server | MAC binding (always on), IPv4 source, IPv6 source, ARP sender, ARP opcodes |
| Layer 2, frames from the server | No VLAN tags, IP and ARP only |
| Roles the server must not play | No router advertisements, No ICMP redirects, No DHCP server, No DHCPv6 server, No multicast querier |
| Neighbour discovery, frames from the server | Well-formed ND, ND from own addresses, ND link-layer option, Advertise own addresses only, ARP replies for own addresses only |
| Towards the server | No reflection, Well-formed ND inbound, ARP for own addresses only, No flooded unicast, No broadcast, Multicast for known groups only, Router role from known routers, DHCP replies from known servers |
| Hypervisor | Protect management ranges |
| Rate limits, both directions | ARP rate limit, ND rate limit, Broadcast and multicast rate limit, SYN rate cap |
| Opt-ins that break specific setups | Gateway only, Multicast lockdown, Blocked outbound ports, Blocked inbound ports |
| Bridge port settings | Bridge answers ARP and ND, No unknown unicast, No broadcast delivery, No multicast flooding |
Two components depend on settings on the network (bridge) rather than the hypervisor: Router role from known routers needs the bridge's router MACs and DHCP replies from known servers needs its DHCP server MACs. Until
those are entered, the two components stay inactive for that bridge's interfaces and everything else applies.
The components that act on traffic towards the server (No flooded unicast, No broadcast, Multicast for known groups only, ARP for own addresses only) drop the traffic before it reaches the server's interface, so it is
not counted against the server's traffic allowance.
Blocked outbound ports drops traffic from the server to the listed TCP and UDP ports, which is how a
provider closes the mail ports for every server without touching each server's firewall; Blocked inbound ports drops traffic to the server on the listed ports, before it reaches the server's interface, so it is not
billed. Each takes its list from the hypervisor's network filter settings, entered as tcp 25, tcp 465, tcp 587, udp 123 with ranges such as 6000-6063 allowed, and on the server's network page each interface chooses, per
direction, the hypervisor's list, none at all (a mail server on a hypervisor that blocks the mail ports), or a
list of its own. Either component is inactive for an interface whose resolved list is empty. Both are applied on the hypervisor, out of the client's reach, and
coexist with the server firewall.
The four bridge port settings are not rules: they are settings on the server's port of the bridge, and they stop
the bridge sending the server traffic that is not for it, rather than dropping it on arrival. Bridge answers ARP and ND has the bridge answer ARP requests and neighbour solicitations for the server's addresses itself, so they
never reach the server; No unknown unicast stops delivery of unicast for MACs the bridge has not learned; No broadcast delivery stops delivery of broadcast from other ports; No multicast flooding limits multicast to the
groups the server has joined. The last two need the first, and each is applied only when its conditions hold: the
bridge is not VLAN-aware, every address of the interface is one the bridge answers for (a whitelist range, a
routed prefix or an unknown link-local address is not), the interface has DHCPv4 off for No broadcast delivery,
and the bridge has multicast snooping and its own querier on for No multicast flooding. When a condition does
not hold the setting is withheld for that interface, the reason is shown with the apply result, and everything
else applies. The settings are reapplied each time the server starts and are checked by the timer.
Every drop rule carries a counter, so nft list chain and v2-show show how many frames each rule has
dropped; when a filter change breaks something, the counts say which rule is responsible.
Per-server settings
On a hypervisor running v2, each server interface's network page gains a Native v2 Components section when
Network Filtering is on for that interface. By default an interface inherits the hypervisor's selection; switch
Inherit the hypervisor's selection off to choose its own, for a server that has to do something the
hypervisor-wide selection blocks, such as a router or a DHCP server for its own network.
The same section has the interface's IPv6 link-local address:
- Unknown (default): neighbour discovery from the server is accepted from any link-local address, as the v1 filters accept it.
- EUI-64: the address is derived from the interface's MAC. Correct for Debian and most cloud images; not for systems that generate stable privacy addresses, such as systemd-networkd and NetworkManager by default.
- Entered: the address, or addresses, typed in.
When the address is known, neighbour discovery is bound to the server's own addresses, which closes an exposure the v1 filters have. Leaving it unknown changes nothing compared to v1.
As with every other setting on that page, Update & Apply applies the change to the server now; Update saves it
for the next apply or start.
Network settings
Each network on the hypervisor has two fields for v2: Router MACs and DHCP server MACs, comma separated. List
every router on the bridge (both members of a VRRP pair, for example). List the routers under DHCP as well when a
DHCP relay on the router answers the servers. Changing either marks the hypervisor's filters as needing a
regenerate.
The rate limits on the hypervisor can be overridden per interface on the server's network page, each one separately; a field left empty keeps the hypervisor's limit for that one.
Hypervisor settings
Under the components: Management ranges, one CIDR per line, which servers cannot reach (used by Protect management ranges), and the Metadata address, reachable even when it falls inside a management range. Empty
means 169.254.169.254.
Below those, the Rate limits: frames per second per interface for ARP, neighbour discovery, broadcast and
multicast, and outbound SYN, above which the rest are dropped; a burst of twice the rate is allowed. Empty means
the defaults (50, 50, 200 and 500). The SYN limit only applies when SYN rate cap is selected.
Block on filter failure
With Native v2 selected, the hypervisor's Network Filtering section includes Block on filter failure.
Enable it to stop an affected VM's start, build or migration when its filters cannot be applied. This also
covers the Native nft VM firewall. When disabled, the action proceeds with a warning, so the VM can run
without the failed protection. The setting is off by default.
Save the setting, then click Regenerate filters to apply it to the hypervisor. Review the apply result
when a VM action fails, or when the page reports a filter failure.
Firewall engine
The Firewall Engine setting appears when Filter Type is Native v2. It chooses how the VM firewall rules
are applied across that hypervisor:
| Engine | Behaviour |
|---|---|
libvirt nwfilter | The default. VM firewall rules continue to use libvirt network filters. |
Native nft | Experimental. VM firewall rules use a separate nftables table alongside Native v2 network protections. |
The existing VM firewall rules, rulesets and interface controls are used by either engine. Selecting
Native nft does not create a default-deny policy or add firewall rules to VMs with no rules configured.
Both network protections and the VM firewall must allow a packet for it to pass. The rules themselves,
rulesets, locked rules and management by a server's owner are described under
Server Firewall.
The Native nft firewall covers supported Linux bridge interfaces, including libvirt-managed networks and NAT interfaces. Unlike the Native v2 network protections, it can enforce a VM's firewall when that interface's Network Filtering is disabled. MacVTap and Open vSwitch interfaces are excluded.
Switching the firewall engine
- Update the hypervisor and control server to versions that include the Native nft firewall engine.
- Open the hypervisor's settings and find
Network Filtering. - Select
Native v2as the filter type, then chooseNative nftunderFirewall Engine. - Save the settings. The page marks the filters as needing regeneration.
- Click
Regenerate filters, confirm, and wait for the host-wide operation to finish. CheckLast result. - Test the expected allowed and denied traffic on your VMs, including connections between VMs.
Saving the engine selection records the requested configuration. Regeneration performs the switch for the
whole hypervisor, including existing running VMs. If the engine in use differs from the selection, the page
shows In use. A failed regeneration leaves the settings pending; read the result before retrying.
The switch requires the hypervisor's nft command and kernel bridge connection tracking support
(nf_conntrack_bridge). An older hypervisor that does not support the engine is reported as an error;
update it before retrying.
The Native nft engine turns off net.bridge.bridge-nf-call-iptables and
net.bridge.bridge-nf-call-ip6tables on the hypervisor. Custom IP firewall rules that rely on bridged
traffic passing through iptables must be reviewed before switching. VirtFusion refuses the switch when
it detects external physdev rules that depend on this path. Review and replace the affected rules before
regenerating; do not remove protection merely to clear the refusal.
To return to the previous firewall engine, select libvirt nwfilter, save and regenerate again. The
hypervisor restores the libvirt firewall bindings before removing the Native nft firewall. Leaving Native v2
also requests a return to libvirt nwfilter.
Switching back
Select the previous filter type under Network Filtering, save, and click Regenerate filters. Every server gets
its v1 rules back first, then its v2 rules are removed. When the last interface has left v2 the hypervisor has
no v2 rules at all, and nft list table bridge vf on the host reports that the table does not exist.
Seeing the rules on a hypervisor
Every v2 rule on a host lives in one table, bridge vf, with a chain pair and address sets per server
interface named by the interface tag (the tap name shown on the server's network page).
nft list table bridge vf # everything on the host
nft list chain bridge vf in_TAG # frames from the server with that tag
nft list chain bridge vf out_TAG # frames towards it
vfcli-hv server:filters v2-show UUID # one server's interfaces, bindings, sets, chains and bridge port settings
The Native nft VM firewall uses its own table, bridge vffw. To inspect it and the host's engine state:
nft list table bridge vffw
vfcli-hv server:filters fw-status
On a Native nft host with no configured VM firewall rules, the vffw table may be absent. Network
protections remain in bridge vf. Use the hypervisor page's engine selection and Regenerate filters
for normal configuration changes.
Hypervisor CLI commands for v2
These are not needed in normal use.
vfcli-hv server:filters v2-show UUID|all # what the kernel holds
vfcli-hv server:filters v2-render UUID # what would be rendered from the server's stored configuration
vfcli-hv server:filters v2-apply UUID|all # apply, switching the interface from v1 if it has v1 rules
vfcli-hv server:filters v2-delete UUID # remove a server's v2 rules
vfcli-hv server:filters v2-load # load every stored filter, as the hypervisor does at boot
vfcli-hv server:filters v2-reconcile # what the vf-network-policy timer runs every 10 minutes
Notes
- Selecting Native v2 retains
libvirt nwfilteras the default firewall engine. ChooseNative nftseparately to move VM firewall enforcement to nftables. - Custom filters (below) apply to the native v1 filters only.
Creating a Custom Filter
You most likely don't need to do this. VirtFusion by default has an adequate filter for most use cases.
At the moment, only a single filter is supported. This means all your rules must be included in a single file and in the correct order.
You may override any of the native filters. You can do so by copying the original filter to a custom location.
| Filter | Location |
|---|---|
| Native Standard | /opt/virtfusion/app/hypervisor/app/Configurations/NetworkFilter/Native/standard.json |
| Native Performance (IPv4) | /opt/virtfusion/app/hypervisor/app/Configurations/NetworkFilter/Native/performance.json |
| Native Performance (IPv4 + IPv6) | /opt/virtfusion/app/hypervisor/app/Configurations/NetworkFilter/Native/performance-v6.json |
To copy the Standard filter.
cp /opt/virtfusion/app/hypervisor/app/Configurations/NetworkFilter/Native/standard.json /home/vf-data/conf/netfilters/standard.json
To copy the Native Performance (IPv4) filter.
cp /opt/virtfusion/app/hypervisor/app/Configurations/NetworkFilter/Native/performance.json /home/vf-data/conf/netfilters/performance.json
To copy the Native Performance (IPv4 + IPv6) filter.
cp /opt/virtfusion/app/hypervisor/app/Configurations/NetworkFilter/Native/performance-v6.json /home/vf-data/conf/netfilters/performance-v6.json
Now that your custom filter exists, the original filter will be ignored.
All content in the filter should be valid JSON and contain a set and unset parameter.
Each rule should be specified as follows.
{
"service": "ebtables",
"table": "nat",
"type": "rule",
"cmd": ["-X", "vf-pre-[[VF_INTERFACE]]"]
}
serviceshould beebtablestableshould benatorfilter. If omitted,natwill be used.typecan be eitherrule,rule-repeat-ipv4orrule-repeat-ipv6cmdshould be an array of the command to be executed.
The following global placeholders are available.
[[VF_INTERFACE]]is the interface name.[[VF_MAC]]is the MAC address for the interface.
Additionally the following placeholders are available in rule-repeat-ipv4 or rule-repeat-ipv6.
[[VF_IP]]an ipaddress.[[VF_CIDR]]the cidr of the ipaddress.
Control Server CLI Commands
Rewrite all server filters by hypervisor
vfcli-ctrl server:configurations HYPERVISOR_ID --options=network
Regenerate the network filters of a hypervisor's servers
The same as the Regenerate filters button on the hypervisor page; --server=ID limits it to one server.
vfcli-ctrl server:network-filters rebuild --hypervisor=HYPERVISOR_ID
Hypervisor CLI Commands
These commands are generally not required, but useful for testing.
Rewrite all server filters
vfcli-hv server:filters set
Rewrite filters for a specific server
vfcli-hv server:filters set UUID
UUID should be replaced with the UUID of the server.
Rewrite all server filters based on the last known server configuration
vfcli-hv server:filters set-build-force
Rewrite filters for a specific server based on the last known server configuration
vfcli-hv server:filters set-build-force UUID
UUID should be replaced with the UUID of the server.
Unset (remove) all filters
vfcli-hv server:filters unset
Unset (remove) filters for a specific server
vfcli-hv server:filters unset UUID
UUID should be replaced with the UUID of the server.
Other Important Notes
If you use ebtables outside of VirtFusion (custom scripts) we highly suggest to use the following execution command.
/usr/bin/flock /var/tmp/vf-ebtables /usr/sbin/ebtables
This will allow all commands to run concurrently and interference free.