Я пытаюсь настроить nwfilter для KVM, но пока мне не удалось определить рабочую конфигурацию.
Настройка сети: dom0 (Debian 7.1, ядро 3.2.46-1, libvirt 0.9.12) подключен через eth0, часть внешней подсети 192.168.17.0/24, и имеет дополнительную подсеть 192.168.128.160/28, направленную на его основной адрес 192.168.17.125.
Подсеть хоста настроена как мост в virsh:
<network>
<name>foo</name>
<forward dev='eth0' mode='route'>
<interface dev='eth0'/>
</forward>
<bridge name='foo-br0' stp='off' delay='0' />
<ip address='192.168.128.161' netmask='255.255.255.240'>
</ip>
</network>
DomU настроен на использование этого моста (статический IP-адрес настроен в DomU):
<interface type='network'>
<source network='foo'/>
<target dev='vnet0'/>
<model type='virtio'/>
<filterref filter='test-eth0'>
<parameter name='CTRL_IP_LEARNING' value='none'/>
<parameter name='IP' value='192.168.128.162'/>
</filterref>
<alias name='net0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
С пустым фильтром связь работает нормально. Теперь, если я добавлю пример набора правил, предложенный в документации ( http://libvirt.org/formatnwfilter.html#nwfwriteexample ), входящий ICMP работает (но не исходящий), а входящий трафик SSH блокируется вместе с исходящим DNS.
Связанные правила создают следующие цепочки iptables:
Chain INPUT (policy ACCEPT)
target prot opt source destination
libvirt-host-in all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:67
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
Chain FORWARD (policy ACCEPT)
target prot opt source destination
libvirt-in all -- 0.0.0.0/0 0.0.0.0/0
libvirt-out all -- 0.0.0.0/0 0.0.0.0/0
libvirt-in-post all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 192.168.128.160/28
ACCEPT all -- 192.168.128.160/28 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain FI-vnet0 (1 references)
target prot opt source destination
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:22 state ESTABLISHED ctdir ORIGINAL
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:80 state ESTABLISHED ctdir ORIGINAL
RETURN icmp -- 0.0.0.0/0 0.0.0.0/0 state NEW,ESTABLISHED ctdir REPLY
RETURN udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53 state NEW,ESTABLISHED ctdir REPLY
DROP all -- 0.0.0.0/0 0.0.0.0/0
Chain FO-vnet0 (1 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW,ESTABLISHED ctdir REPLY
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 state NEW,ESTABLISHED ctdir REPLY
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED ctdir ORIGINAL
ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp spt:53 state ESTABLISHED ctdir ORIGINAL
DROP all -- 0.0.0.0/0 0.0.0.0/0
Chain HI-vnet0 (1 references)
target prot opt source destination
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:22 state ESTABLISHED ctdir ORIGINAL
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:80 state ESTABLISHED ctdir ORIGINAL
RETURN icmp -- 0.0.0.0/0 0.0.0.0/0 state NEW,ESTABLISHED ctdir REPLY
RETURN udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53 state NEW,ESTABLISHED ctdir REPLY
DROP all -- 0.0.0.0/0 0.0.0.0/0
Chain libvirt-host-in (1 references)
target prot opt source destination
HI-vnet0 all -- 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet0
Chain libvirt-in (1 references)
target prot opt source destination
FI-vnet0 all -- 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet0
Chain libvirt-in-post (1 references)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in vnet0
Chain libvirt-out (1 references)
target prot opt source destination
FO-vnet0 all -- 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-out vnet0
Если я попробую второй набор фильтров из второго примера из документации ( http://libvirt.org/formatnwfilter.html#nwfwriteexample2nd ), итоговые правила брандмауэра имеют еще меньше смысла.
Процитирую, что он должен делать:
- открывает только TCP-порты 22 и 80 интерфейса виртуальной машины
- позволяет виртуальной машине отправлять ping-трафик с интерфейса, но не позволяет виртуальной машине проверять связь с интерфейсом
- позволяет виртуальной машине выполнять поиск DNS (UDP на порт 53)
- включить ftp-сервер (в активном режиме) для запуска внутри виртуальной машины
Что оно делает:
Я не изменял ни один из включенных наборов правил nwfilter, ни какую-либо другую часть сетевого стека. Как мне заставить nwfilter работать правильно?