KVMのネットワークフィルタ設定
libvirtに備わっているネットワークフィルタ機能 (nwfilter) をVMに適用してみる。
libvirtの公式ドキュメントを参考に作業を進める。
nwfilterは(バックエンドがnftablesであっても)iptablesを使ってフィルタリングを行うので、まずはnwfilter未設定時のiptables設定を確認する。
# iptables -nvL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 161 14807 LIBVIRT_INP all -- * * 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 LIBVIRT_FWX all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 LIBVIRT_FWI all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 LIBVIRT_FWO all -- * * 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 122 11453 LIBVIRT_OUT all -- * * 0.0.0.0/0 0.0.0.0/0 Chain LIBVIRT_FWI (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED 0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable Chain LIBVIRT_FWO (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0 0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable Chain LIBVIRT_FWX (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0 Chain LIBVIRT_INP (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67 Chain LIBVIRT_OUT (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:53 0 0 ACCEPT tcp -- * virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:68 0 0 ACCEPT tcp -- * virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:68
既にlibvirtによってDNSやDHCPを通すフィルタリングなどが設定されている。
まずはフィルタtest-filter
を定義する。
ここではホスト環境のIPアドレス192.168.122.1
へのsshをブロックするルールを書いてみる。
ルールの詳細は公式ドキュメントを参考にする。
$ virsh nwfilter-define <(cat <<EOF <filter name='test-filter'> <rule action='drop' direction='out'> <tcp dstipaddr='192.168.122.1' dstportstart='22'/> </rule> </filter> EOF ) $ virsh nwfilter-dumpxml test-filter <filter name='test-filter' chain='root'> <uuid>49978302-912f-45b2-8298-af957757177e</uuid> <rule action='drop' direction='out' priority='500'> <tcp dstipaddr='192.168.122.1' dstportstart='22'/> </rule> </filter>
いま定義したフィルタtest-filter
をVM kvmdom
に設定する。
$ virsh edit kvmdom
<interface type='network'>
<mac address='52:54:00:fa:68:d9'/>
<source network='default'/>
<model type='virtio'/>
+ <filterref filter='test-filter'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>
Domain kvmdom XML configuration edited.
VM kvmdom
を起動する。
$ virsh start kvmdom
iptables設定を確認してみる。
# iptables -nvL
追加された部分
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 21 2032 libvirt-host-in all -- * * 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 libvirt-in all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 libvirt-out all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 libvirt-in-post all -- * * 0.0.0.0/0 0.0.0.0/0 Chain FI-vnet2 (1 references) pkts bytes target prot opt in out source destination 0 0 DROP tcp -- * * 0.0.0.0/0 192.168.122.1 tcp dpt:22 Chain FO-vnet2 (1 references) pkts bytes target prot opt in out source destination 0 0 DROP tcp -- * * 192.168.122.1 0.0.0.0/0 tcp spt:22 Chain HI-vnet2 (1 references) pkts bytes target prot opt in out source destination 0 0 DROP tcp -- * * 0.0.0.0/0 192.168.122.1 tcp dpt:22 Chain libvirt-host-in (1 references) pkts bytes target prot opt in out source destination 2 656 HI-vnet2 all -- * * 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet2 Chain libvirt-in (1 references) pkts bytes target prot opt in out source destination 0 0 FI-vnet2 all -- * * 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet2 Chain libvirt-in-post (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in vnet2 Chain libvirt-out (1 references) pkts bytes target prot opt in out source destination 0 0 FO-vnet2 all -- * * 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-out vnet2 --physdev-is-bridged
先ほど定義したルールはChain FI-vnet2
, FO-vnet2
, HI-vnet2
に定義されている。
実際にVM kvmdom
から192.168.122.1
にsshしてみても接続できない。