libvirt-nft-ruler is script written in Python for automatically applying/removing your own firewall rules with nft when a virtual network in libvirt starts or stops.
Libvirt uses iptables for the firewall configuration of the virtual networks. It has no good compatibility to nftables (the successor of iptables) which I use myself.
I wanted to insert the input rules from libvirt into my own input chain in a specific order which was not possible.
So I wrote this script.
If you are runnig Arch Linux on your computer, just use the PKGBUILD script otherwise do the Manual Install.
After the installation restart libvirtd with systemctl.
- nftables python library (in Arch Linux shipped with the
nftablespackage) - python-jsonschema (used for validating templates)
Clone the repo and copy libvirt-nft-ruler to /etc/libvirt/hooks/network.d. Additionally, copy the templates folder into /etc/libvirt-nft-ruler.
Create a new virtual network in libvirt and name it <network name>-nft-ruler-<template name> for example network-nft-ruler-nat.
<network name>is just the normal name of the network.-nft-ruler-tells the script to apply rules for this network.<template name>the name of the template to use, equivalent to the beginning of the files intemplates.
When you start this network in Libvirt the script will apply the rules in the specified template. If you stop this network the script will remove the applied rules. You can use the predefined templates but be careful see Predefined Templates or you can create your own templates see Creating your own Templates.
Templates are json files in the templates folder which contain the rulesets.
In every file there are placeholders which are replaced when the script runs.
$virtualInterfacespecifies the interface for the virtual network.$networkNameis the name of the virtual network.
Additionally every rule has the property "comment": "libvirtd $networkName" which has the purpose to identify the rules on deletion.
I have already made templates with rules for a nat and a private network. The rules are based on the default ruleset libvirt uses.
Attention: The templates assume that a insert-input chain is already defined. The reason behind it is that I want to easily insert my input rules in a specific order in my standard input base chain.
- create
insert-inputchain usingnft - call the chain in the
base input chainusing the verdict statementjumpinnft
You can easily create your own template by do the following steps:
flushyour current rulesetapplythe rules you want the script to apply automaticallysavethe active ruleset as json withnft -j list ruleset > <template name>-template.jsonand edit it:- remove unwanted rules
- remove
metainfo - remove the
handleproperties - replace the network interface name with
$virtualInterface - add the property
"comment": "libvirtd $networkName"to every rule
moveit to the templates folder