Edited: 2022-06-30, added capability to block multiple subnets.
First things first!
|
|
Preface
Until I learn how to tame VXLAN for a virtualization cluster, I need a dirty way of seperating infrastructure network and the VM network.
The solution presented in this post is to apply libvirt’s network filters (nwfilter
) to drop packages from and to the “uplink”, namely home LAN (10.0.0.0/18
), for any guest connected to the NAT (192.168.123.0/24
). This approach is analogous to setting firewall rules on a router, it just is virtual. Remember to adjust your subnets!
Disclaimer: I make use of sudo
while running virsh
this may not be necessary if you have added yourself to proper groups, I did not bother.If so, kindly delete them before executing.
Pitfalls
Firstly, make sure you don’t make a typo unlike me (looking at you “<filterref type=‘drop-subnet’>”).
Secondly, make use of virsh dumpxml
(or virt-manager
’s XML tab under NIC) to validate your filter was indeed applied to VM definition.
Lastly, ensure you have a single filter applied per NIC (at least I could not apply two of them). Define an umbrella filter which includes all rules and other filters.
Shortcomings
I suppose, given enough eagerness, one could find a way of proxying the connection between the two subnets, namely “home LAN” and “guest NAT”.
One such case would be using the public IP address of a DMZ host, however, one would assume the DMZ host to be already hardened. Yet, be warned to think of such cases before implementing your internet-connected virus test lab.
Virtual NAT Firewall (nwfilter)
Let us define a parametrized filter, named drop-subnet
, to be tested shortly after.
nwfilter-drop-subnet.xml
:
|
|
Define the filter:
|
|
For more details see chapter nwfilter concepts, better read it all tough.
Preparations
1. Define a seperate NAT network to be filtered
I chose to disable DHCP and DNS as I would be using static IPs and enforcing against spoofing using. See disabling DNS in Libvirt, disabling DHCP in Libvirt and especially virtual network docs for more.
net-nat-filtered.xml
:
|
|
You can omit <mac>
and <nat>
as well as commented dhcp example. Remember to change enp1s0
into what your physical interface or bridge is. Could be eth1
, enp3s0
, br0
, etc.
Now let us import the XML:
|
|
Lastly, activate and enable it:
|
|
P.S. Do not to use KVM’s default (192.168.122.0/24
) or any other existing network’s IP block.
2. Create a VM
It is assumed that you prepared a VM connected to the network nat-filtered
with name guest-01
and IP 192.168.123.11
.
If in need of assistance, can follow Server World’s tutorials (select OS of your choice at Other OS Configs
). I spun one up with GUI application virt-manager
.
Now, one could make use of either of the below:
virsh edit
virsh dumpxml
followed byvirsh define
I will go for the latter out of personal preference (seems easier to script if need ever arises).
|
|
Below use of ...
is to denote numerous lines irrelevant to the task at hand.
vm-guest-01.xml
:
|
|
Your interface type might be a bridge or ethernet (e.g. <interface type='bridge'>
) as described in nwfilter concepts, it is irrelevant.
Now make the addendum into existing <interface>
:
|
|
See my answer to “libvirt nwfilter, multiple parameters” for more insight.
At this point, shut down the VM if already running:
|
|
Then, (re)define VM using the xml:
|
|
Start it to start testing:
|
|
Testing
Connect to guest-01
one way or another. Below is accessing serial console from the hypervisor:
|
|
Test NAT-local connectivity, should work:
|
|
Test internet connectivity, should work unless DNS is 1.1.1.1:
|
|
Test connectivity to blacklisted subnet (home LAN: 10.0.0.0/18
), should not work:
|
|
Test DNS at 1.1.1.1/32
:
|
|
That’s it.
If you wish to test spoofing as well, change the IP address of guest-01
and try pinging the NAT-local gateway.
“This does not float my boat!”
If this approach isn’t suitable, you might try setting up an OPNSense/ VyOS/ IPFire guest with multiple NICs to act as a properly virtualized router/ firewall OS. This would put a bit more overhead, but might be more apt for more complicated requirements. Of course an isolated network must be used in such a case. To refresh your color-coded zone knowlegde: IPFire’s color table (red, green, orange, blue).
Cheers !