Skip to main content
Topic: How do I get nftables to work with libvirt? (Read 660 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

How do I get nftables to work with libvirt?

I started using nftables as my firewall, with the default configuration in /etc/nftables.conf as I wanted a simple, secure firewall that "just works". However, I noticed that my VMs with virt-manager and QEMU/KVM stopped being able to access the internet.

Here's my nftables config:

/etc/nftables.conf:

Code: [Select]
#!/usr/bin/nft -f
# vim:set ts=2 sw=2 et:

# IPv4/IPv6 Simple & Safe firewall ruleset.
# More examples in /usr/share/nftables/ and /usr/share/doc/nftables/examples/.

destroy table inet filter
table inet filter {
  chain input {
    type filter hook input priority filter
    policy drop

    ct state invalid drop comment "early drop of invalid connections"
    ct state {established, related} accept comment "allow tracked connections"
    iif lo accept comment "allow from loopback"
    ip protocol icmp accept comment "allow icmp"
    meta l4proto ipv6-icmp accept comment "allow icmp v6"
    tcp dport ssh accept comment "allow sshd"
    pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
    counter
  }
  chain forward {
    type filter hook forward priority filter
    policy drop
  }
}

This is just the config that was pre-installed.

I set up virt-manager with networking according to this guide. It works so long as the nftables service is not running.

I'm using runit.

Would anyone be able to advise me on how to configure nftables so that it doesn't block my virtual network? Thanks

Re: How do I get nftables to work with libvirt?

Reply #1
You'll need to add a rule like:
Code: [Select]
iifname virbr0 accept
artist

Re: How do I get nftables to work with libvirt?

Reply #2
You'll need to add a rule like:
Code: [Select]
iifname virbr0 accept
artist

I updated /etc/nftables.conf to

Code: [Select]
#!/usr/bin/nft -f
# vim:set ts=2 sw=2 et:

# IPv4/IPv6 Simple & Safe firewall ruleset.
# More examples in /usr/share/nftables/ and /usr/share/doc/nftables/examples/.

destroy table inet filter
table inet filter {
  chain input {
    type filter hook input priority filter
    policy drop

    ct state invalid drop comment "early drop of invalid connections"
    ct state {established, related} accept comment "allow tracked connections"
    iif lo accept comment "allow from loopback"
    ip protocol icmp accept comment "allow icmp"
    meta l4proto ipv6-icmp accept comment "allow icmp v6"
    tcp dport ssh accept comment "allow sshd"
    pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
    counter
    iifname virbr0 accept
  }
  chain forward {
    type filter hook forward priority filter
    policy drop
  }
}

Is that correct? Because I'm still unable to use the internet inside VMs while nftables is running.

nftables list ruleset shows the following:

Code: [Select]
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state invalid drop comment "early drop of invalid connections"
ct state { established, related } accept comment "allow tracked connections"
iif "lo" accept comment "allow from loopback"
ip protocol icmp accept comment "allow icmp"
meta l4proto ipv6-icmp accept comment "allow icmp v6"
tcp dport 22 accept comment "allow sshd"
meta pkttype host limit rate 5/second burst 5 packets counter packets 355 bytes 44184 reject with icmpx admin-prohibited
counter packets 1076 bytes 263274
iifname "virbr0" accept
}

chain forward {
type filter hook forward priority filter; policy drop;
}
}
table ip libvirt_network {
chain forward {
type filter hook forward priority filter; policy accept;
counter packets 99 bytes 23309 jump guest_cross
counter packets 99 bytes 23309 jump guest_input
counter packets 99 bytes 23309 jump guest_output
}

chain guest_output {
ip saddr [ip address] iif "virbr0" counter packets 99 bytes 23309 accept
iif "virbr0" counter packets 0 bytes 0 reject
}

chain guest_input {
oif "virbr0" ip daddr [ip address] ct state established,related counter packets 0 bytes 0 accept
oif "virbr0" counter packets 0 bytes 0 reject
}

chain guest_cross {
iif "virbr0" oif "virbr0" counter packets 0 bytes 0 accept
}

chain guest_nat {
type nat hook postrouting priority srcnat; policy accept;
ip saddr [ip address] ip daddr [netmask] counter packets 0 bytes 0 return
ip saddr [ip address] ip daddr [netmask] counter packets 0 bytes 0 return
meta l4proto tcp ip saddr [ip address] ip daddr != [ip address] counter packets 0 bytes 0 masquerade to :1024-65535
meta l4proto udp ip saddr [ip address] ip daddr != [id address] counter packets 0 bytes 0 masquerade to :1024-65535
ip saddr [ip address] ip daddr != [ip address] counter packets 0 bytes 0 masquerade
}
}
table ip6 libvirt_network {
chain forward {
type filter hook forward priority filter; policy accept;
counter packets 0 bytes 0 jump guest_cross
counter packets 0 bytes 0 jump guest_input
counter packets 0 bytes 0 jump guest_output
}

chain guest_output {
}

chain guest_input {
}

chain guest_cross {
}

chain guest_nat {
type nat hook postrouting priority srcnat; policy accept;
}
}

the libvirt_network tables are not there if libvirtd is not running so I assume libvirtd must be adding its own tables to nftables.

Sorry if this is a stupid question, I don't really know anything about networking; I just enabled a firewall for some security and I just want to be able to use VMs. I have tried to look through the Arch Wiki nftables article but couldn't find anything that seemed to me like it would solve my problem.

Re: How do I get nftables to work with libvirt?

Reply #3
In case anyone stumbles across this thread while searching for stuff, I couldn't actually get this to work with nftables, but I switched to UFW as my firewall.

Code: [Select]
sudo ufw allow in on virbr0

allows internet to work completely fine in QEMU virtual machines.