Добрый день дорогой читатель, данное повествование не является истиной в последней инстанции, это некая инструкция (в основном для собственного пользования) по решению проблемы трафика проходящего через межсетевой экран iptables и блокирующий KVM/QEMU доступ к интернет на Arch Linux с пояснениями и все возможными мыслями. Так же подобные действия применимы и к другим дистрибутивам.
Для настройки iptables, чтобы не блокировал трафик виртуальных машин KVM, нужно учитывать, что KVM использует виртуальные сетевые интерфейсы (например, `virbr0` для мостового подключения через libvirt) и NAT, либо бриджинг с физической сетью.
Разберем основные моменты, которые следует учесть:
1. Определить, какие интерфейсы используются виртуальными машинами. Обычно это virbr0 (виртуальный мост), или физический интерфейс, если используется бридж.
2. Разрешить трафик на этих интерфейсах. Нужно разрешить входящий и исходящий трафик, который необходим виртуальным машинам.
3. Если используется NAT (по умолчанию libvirt создаёт NAT-сеть на virbr0), нужно разрешить форвардинг.
4. Обеспечить корректную работу правил FORWARD.
А теперь давайте более детально рассмотрим каждый пункт, но будем отталкиваться от iptables с базовыми правилами и политикой по умолчанию из первой части. Опять же напомню наши предыдущие настройки
И так, у нас в iptables следующая политика по умолчанию
iptables -P INPUT DROP # весь входящий трафик блокируем
iptables -P FORWARD DROP # весь пересылаемый трафик блокируем
iptables -P OUTPUT ACCEPT # весь исходящий трафик разрешаем
ранее внесены следующие правила
# разрешить соединения со статусом ESTABLISHED и RELATED
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# разрешить локальный трафик, кстати это правило нужно для KVM
iptables -A INPUT -i lo -j ACCEPT
# запретить пакеты в статусе поврежденные
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
исходя из политики по умолчанию и базовых правил будем строить правила доступа виртуальных машин в интернет.
И так запустив виртуальную машину выполнив следующую команду
ip a
видим что на сетевом интерфейсе enp1s0 ip-адрес(IPv4) не присвоен хотя интерфейс в состоянии UP(поднят), естественно о пинге не может быть и речи
перейдем на хост и посмотрим что имеется из сетевых интерфейсов запустив уже известную команду
ip a
Соединение через виртуальную сеть virbr0. И так видим на хосте у нас несколько сетевых интерфейсов но нас интересуют два это enp13s0 (у вас может быть другое название!!!) выход в интернет хоста (проще говоря кабель идущий от роутера который раздает интернет в локальную сеть) и virbr0 виртуальная сеть KVM (виртуальная сеть используемая по умолчанию виртуальными машинами)
выходим из положения следующим образом добавив три правила
iptables -A INPUT -i virbr0 -j ACCEPT
в iptables добавить (-A) в таблицу входящие (INPUT) из интерфейса (-i) virbr0 разрешить трафик (-j ACCEPT)
iptables -A FORWARD -i virbr0 -o enp13s0 -j ACCEPT
в iptables добавить (-A) в таблицу форвардинг (FORWARD) из интерфейса (-i) virbr0 в интерфейс (-o) enp13s0 разрешить трафик (-j ACCEPT)
iptables -A FORWARD -i enp13s0 -o virbr0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
в iptables добавить (-A) в таблицу форвардинг (FORWARD) из интерфейса (-i) enp13s0 в интерфейс (-o) virbr0 если статус соединений для уже установленного соединения (ESTABLISHED) и пакеты, связанные с уже установленным соединением (RELATED) разрешить трафик (-j ACCEPT)
P.S. Еcли же у вас на исходящие политика по умолчанию блокировать, то есть было выставлено
iptables -P OUTPUT DROP # весь исходящий трафик заблокирован
то добавляем правило
iptables -A OUTPUT -o virbr0 -j ACCEPT
в iptables добавить (-A) в таблицу исходящие (OUTPUT) в интерфейс (-o) virbr0 разрешить трафик (-j ACCEPT)
Будьте внимательны с интерфейсами
- virbr0 - по умолчанию интерфейс виртуальной сети KVM
- enp13s0 - интерфейс хоста, у вас он будет другой
далее смотрим как работают правила идут ли пакеты данных
iptables -nvL --line-numbers
если все работает то сохраняем правила в конфиг на arch linux доступ только у root по этому выполняем из под него
su
iptables-save > /etc/iptables/iptables.rules # сохранение правил для IPv4
exit
перезагрузим витруальную машину, опять же воспользуемся командой
ip a
как видим из скрина сетевой интерфейс enp1s0 получил ip-адрес, а следовательно и пинг должен заработать
Размышления. вероятно может потребоваться включение NAT но мне не потребовалось. Если есть необходимость включаем NAT для выхода из виртуальных машин в интернет
iptables -t nat -A POSTROUTING -s 192.168.122.0/24 -o eth0 -j MASQUERADE
- Здесь eth0 — ваш физический сетевой интерфейс, замените на ваш реальный интерфейс.
- 192.168.122.0/24 — это подсеть, которую по умолчанию создаёт libvirt для виртуальных машин.
Соединение через мост (bridge).Если виртуальные машины подключены напрямую к физической сети через мост (например, br0), то нужно разрешить трафик на этом мосту.
# разрешить входящий трафик из интерфейса(сетевого моста) br0
iptables -A INPUT -i br0 -j ACCEPT
# разрешить исходящий трафик в интерфейс(сетевого моста) br0 использовать если по умолчанию политика на исходящие стоит запрет
iptables -A OUTPUT -o br0 -j ACCEPT
# разрешить форвардинг трафика из интерфейса(сетевого моста) br0
iptables -A FORWARD -i br0 -j ACCEPT
# разрешить форвардинг трафика в интерфейс(сетевого моста) br0
iptables -A FORWARD -o br0 -j ACCEPT
Более подробнее о возможностях и управлении iptables можно изучить в статье "iptables часть 1 основы управления правилами"
За основу взята документация по iptables, а так же информация с форумов по
данной тематике, информация других пользователей размещенная на
просторах всемирной паутины и собственные наработки.
За сим откланиваюсь...