Lyosha.dev

Нет интернета в виртуальных машинах QEMU/KVM

27 декабря 2025 г.

На всякий случай

Сначала убедиться, что сеть существует и активна:

$ sudo virsh net-list --all
 Name      State    Autostart   Persistent
--------------------------------------------
 default   active   yes         yes

Включить сеть можно следующим образом:

$ sudo virsh net-start default

iptables-nft и UFW

libvirt >=10.4.0, UFW, виртуальная NAT-сеть

Начиная с libvirt v10.4.0 (2024-06-03), если в системе присутствует nftables, правила по умолчанию добавляются через него заместо iptables.

В современных системах обычно установлен iptables-nft, который реализует API традиционного iptables, но под капотом использует nftables. UFW не умеет использовать nftables напрямую, поэтому использует iptables-nft для управления правилами если бэкендом является nftables.

Чтобы трафик дошёл в интернет, все цепочки должны одобрить его. libvirt создаёт свою таблицу с правилами, разрешающими доступ в интернет для виртуальных интерфейсов, однако таблица, созданная iptables-nft по запросу UFW, не имеет исключения для этих интерфейсов. Если UFW настроен на drop/reject, трафик будет отклонён.

По этому поводу есть issue на GitLab’е с объяснением от разработчика libvirt.

Как исправить

Есть три основных варианта решения, от лёгкого к сложному:

1. Смена фаервола в конфиге libvirt - спасибо комментатору с Reddit

Можно настроить libvirt на добавление правил через iptables, что приведёт к попаданию правил в общую таблицу iptables-nft, и разрешит трафик.

$ sudo nano /etc/libvirt/network.conf

В конец файла добавить:

firewall_backend = "iptables"

Затем перезапустить сервис с новым конфигом:

$ sudo systemctl restart libvirtd

2. Ручное добавление правил в UFW

Включить IP-форвардинг (из man ufw):

$ nano /etc/ufw/sysctl.conf

Раскомментировать или добавить следующие строки:

net/ipv4/ip_forward=1
net/ipv6/conf/default/forwarding=1
net/ipv6/conf/all/forwarding=1

Перезапустить UFW:

$ ufw disable
$ ufw enable

Затем добавить правила на разрешение трафика (virbr0 - сетевой интерфейс libvirt):

$ sudo ufw allow in on virbr0 # Разрешает любой входящий трафик
$ sudo ufw route allow in on virbr0 # Разрешает форвардинг

Разрешение любого входящего трафика может быть избыточным и подходить не во всех ситуациях; в таком случае стоит точечно разрешить только нужный трафик.

3. Переезд с UFW

Один из вариантов решения - переехать на фронтенд, который поддерживает nftables нативно, без слоя совместимости с API iptables.

Варианты: firewalld либо nft для более тонкой настройки. Они оба будут более дружелюбны к libvirt из коробки.