Skip to main content
Version: Next

Network Filtering (IP Anti-Hijacking)

Since version 3.0, VirtFusion has built in native bridge network filtering.

The following filters are available:

  • None No filters will be applied to any virtual servers on the hypervisor.
  • Libvirt A standard set of filters to prevent MAC spoofing, IP stealing and various other filters to clean traffic.
  • Native Standard This filter applies the same rule sets as Libvirt.
  • 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 v2 A 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.

network

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​

  • A supported hypervisor operating system with the nft command installed. Debian 12 and 13, Ubuntu 22.04 and 24.04 and RHEL 10 all ship it.
  • Bridged (simpleBridge) networks. Interfaces on MacVTap, Open vSwitch and NAT networks are not filtered by v2, exactly as they are not filtered by the native v1 filters.

Enabling it​

  1. Open the hypervisor, select Native v2 under Network Filtering and save. Nothing changes on the hypervisor yet: the page shows that the filter settings have changed and have not been applied.
  2. Review the components (below) and the management ranges, and save again if you change anything.
  3. Click Regenerate filters and 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.

info

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.

GroupComponents
Identity, frames from the serverMAC binding (always on), IPv4 source, IPv6 source, ARP sender, ARP opcodes
Layer 2, frames from the serverNo VLAN tags, IP and ARP only
Roles the server must not playNo router advertisements, No ICMP redirects, No DHCP server, No DHCPv6 server, No multicast querier
Neighbour discovery, frames from the serverWell-formed ND, ND from own addresses, ND link-layer option, Advertise own addresses only, ARP replies for own addresses only
Towards the serverNo 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
HypervisorProtect management ranges
Rate limits, both directionsARP rate limit, ND rate limit, Broadcast and multicast rate limit, SYN rate cap
Opt-ins that break specific setupsGateway only, Multicast lockdown, Blocked outbound ports, Blocked inbound ports
Bridge port settingsBridge 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.

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

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​

  • The server firewall (the rules a client sets on their server) is unchanged by v2: it is still applied through libvirt as before.
  • Custom filters (below) apply to the native v1 filters only.

Creating a Custom Filter​

info

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.

FilterLocation
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]]"]
}
  • service should be ebtables
  • table should be nat or filter. If omitted, nat will be used.
  • type can be either rule, rule-repeat-ipv4 or rule-repeat-ipv6
  • cmd should 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.