The following patch mainly adds a set of test case to verify that several spoofing attacks are prevented by the nwfilter subsystem. In order to have a well defined test machine, the patch also includes test scripts to network install a virtual disk from scratch, to boot the virtual test machine prior to running the actual test scripts and to shut it down afterwards. While I have tried to remove as much dependency on my local setup as possible there is still some left, so I am currently more interested in feedback about the general approach, not necessarily actual inclusion into the libvirt-TCK git. For example, I am currently trying to find a suitable location for the kickstart file, and also a suitable place for the common_functions.pl. Comments are appreciated ... thanks, Gerhard Index: libvirt-tck/scripts/network/README =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/README @@ -0,0 +1,14 @@ + +Test cases: + +000-install-image.t creates and install a 2GB fedora virtual disk via kickstart file from the network +001-boot-image.t defines and boots a VM which uses the fedora virtual disk +100-ping-still-working.t verifies the VM is pingable +210-no-mac-spoofing.t verifies mac spoofing is prevented +220-no-ip-spoofing.t verifies ip spoofing is prevented +230-no-mac-broadcast.t verifies mac broadcasting is prevented +240-no-arp-spoofing.t verifies arp spoofing is prevented +999-shutdown-image.t shuts the VM down + + + Index: libvirt-tck/scripts/network/000-install-image.t =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/000-install-image.t @@ -0,0 +1,181 @@ +# -*- perl -*- +# +# Copyright (C) 2010 IBM Corp. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/000-install-image.t - install network test image + +=head1 DESCRIPTION + +The test case creates and install a 2GB fedora virtual +disk via kickstart file from the network. + +=cut + +use strict; +use warnings; + +use Test::More tests => 1; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +# variables which may need to be adapted +my $domain_name ="f12nwtest"; +my $disk_name = "/var/lib/libvirt/images/${domain_name}.img"; +my $disk_size = "2147483648"; + +my $kickstart_file ="http://192.168.122.1/ks.cfg"; +my $cmdline = "ip=dhcp gateway=192.168.122.1 ks=${kickstart_file}"; + +# see if the domain already exits +my $already_defined = 0; +diag "searching if ${domain_name} is already defined"; +my $nnames = $conn->num_of_defined_domains(); +my @names = $conn->list_defined_domain_names($nnames); +foreach (@names){ + if (/${domain_name}/) { + print "$_ already exists, no need to redefine\n"; + $already_defined = 1; + } +} +diag $already_defined; + +# check for installation disk and build it if not exists +my $already_installed = 0; +my $pool = $conn->get_storage_pool_by_name("default"); +my $nnames = $pool->num_of_storage_volumes(); +my @volNames = $pool->list_storage_vol_names($nnames); +foreach (@volNames){ + if (/${domain_name}/) { + print "$_ already exists, no need to install\n"; + $already_installed = 1; + } +} + +my $volumexml = "<volume>". +" <name>${domain_name}.img</name>". +" <key>${disk_name}</key>". +" <source>". +" </source>". +" <capacity>${disk_size}</capacity>". +" <allocation>4096</allocation>". +" <target>". +" <path>${disk_name}</path>". +" <format type='raw'/>". +" <permissions>". +" <mode>0644</mode>". +" <owner>0</owner>". +" <group>0</group>". +" </permissions>". +" </target>". +"</volume>"; + + +# prepare image +if ($already_installed == 0) { + diag "Creating ${disk_name}"; + diag $volumexml; + my $vol = $pool->create_volume($volumexml) +# system("qemu-img create ${disk_name} ${disk_size}"); +} + +my $topxml = " <name>${domain_name}</name>". +" <memory>524288</memory>". +" <currentMemory>524288</currentMemory>". +" <vcpu>1</vcpu>"; + +my $osxml = " <os>". +" <type arch='x86_64' machine='fedora-13'>hvm</type>". +" <kernel>/var/cache/libvirt-tck/os-i686-hvm/vmlinuz</kernel>". +" <initrd>/var/cache/libvirt-tck/os-i686-hvm/initrd</initrd>". +" <cmdline>${cmdline}</cmdline>". +" <boot dev='hd'/>". +" </os>"; + +my $bottomxml = " <features>". +" <acpi/>". +" <apic/>". +" </features>". +" <clock offset='utc'/>". +" <on_poweroff>destroy</on_poweroff>". +" <on_reboot>restart</on_reboot>". +" <on_crash>restart</on_crash>". +" <devices>". +" <emulator>/usr/bin/qemu-kvm</emulator>". +" <disk type='file' device='disk'>". +" <driver name='qemu' type='raw'/>". +" <source file='${disk_name}'/>". +" <target dev='hda' bus='ide'/>". +" </disk>". +" <controller type='ide' index='0'>". +" </controller>". +" <interface type='network'>". +" <source network='default'/>". +" <target dev='vnet0'/>". +" <model type='virtio'/>". +" </interface>". +" <serial type='pty'>". +" <target port='0'/>". +" </serial>". +" <console type='pty'>". +" <target port='0'/>". +" </console>". +" <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='de'/>". +" <video>". +" <model type='cirrus' vram='9216' heads='1'/>". +" </video>". +" </devices>"; + +my $xml = "<domain type='kvm'>" . +$topxml. +$osxml. +$bottomxml. +"</domain>"; + +diag $xml; +diag "Defining an inactive domain config"; +my $dom; + +# no need to start if already installed +if (($already_installed == 0) && ($already_defined == 0)) { + ok_domain(sub { $dom = $conn->define_domain($xml) }, "defined persistent domain config"); + $xml = $dom->get_xml_description; + diag $xml; + diag "Starting inactive domain config"; + $dom->create; + + # wait for completion of installation + diag "wait for installation to finish .. "; + while($dom->is_active()) { + sleep(10); + diag ".. to view progress connect to virtual machine ${domain_name} .. "; + } + sleep(10); + diag " .. done"; + # cleanup + $dom->undefine; +} else { + ok_domain { $dom = $conn->get_domain_by_name($domain_name) } "the existing domain object"; +} + + + + + Index: libvirt-tck/scripts/network/001-boot-image.t =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/001-boot-image.t @@ -0,0 +1,133 @@ +# -*- perl -*- +# +# Copyright (C) 2010 IBM Corp. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/001-boot-image.t - boot installed test image + +=head1 DESCRIPTION + +The test case defines and boots a VM which uses the +fedora virtual disk create ny 000-install-image + +=cut + +use strict; +use warnings; + +use Test::More tests => 2; + +use Sys::Virt::TCK; +use XML::LibXML; + +require 'scripts/network/common_functions.pl'; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my $already_defined = 0; +my $domain_name ="f12nwtest"; + +# see if the domain already exits +diag "searching if ${domain_name} is already defined"; +my $nnames = $conn->num_of_defined_domains(); +my @names = $conn->list_defined_domain_names($nnames); +foreach (@names){ + if (/${domain_name}/) { + print "$_ already exists, no need to redefine\n"; + $already_defined = 1; + } +} +diag $already_defined; + +my $dom; +my $xml; + +if ($already_defined == 1) { + ok_domain { $dom = $conn->get_domain_by_name($domain_name) } "the existing domain object"; +} else { + my $topxml = " <name>${domain_name}</name>". + " <memory>524288</memory>". + " <currentMemory>524288</currentMemory>". + " <vcpu>1</vcpu>"; + + my $osxml = " <os>". + " <type arch='x86_64' machine='fedora-13'>hvm</type>". + " <boot dev='hd'/>". + " </os>"; + + my $bottomxml = " <features>". + " <acpi/>". + " <apic/>". + " </features>". + " <clock offset='utc'/>". + " <on_poweroff>destroy</on_poweroff>". + " <on_reboot>restart</on_reboot>". + " <on_crash>restart</on_crash>". + " <devices>". + " <emulator>/usr/bin/qemu-kvm</emulator>". + " <disk type='file' device='disk'>". + " <driver name='qemu' type='raw'/>". + " <source file='/var/lib/libvirt/images/${domain_name}.img'/>". + " <target dev='hda' bus='ide'/>". + " </disk>". + " <controller type='ide' index='0'>". + " </controller>". + " <interface type='network'>". + " <source network='default'/>". + " <filterref filter='no-spoofing'/>". + " <target dev='vnet0'/>". + " <model type='virtio'/>". + " </interface>". + " <serial type='pty'>". + " <target port='0'/>". + " </serial>". + " <console type='pty'>". + " <target port='0'/>". + " </console>". + " <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='de'/>". + " <video>". + " <model type='cirrus' vram='9216' heads='1'/>". + " </video>". + " </devices>"; + + $xml = "<domain type='kvm'>" . + $topxml. + $osxml. + $bottomxml. + "</domain>"; + + diag $xml; + diag "Defining an inactive domain config"; + ok_domain(sub { $dom = $conn->define_domain($xml) }, "defined persistent domain config"); +} + +# already existing or newly defined, start it up +$dom->create; +my $uuid = $dom->get_uuid_string(); +diag $uuid; +$xml = $dom->get_xml_description(); +diag $xml; +ok($dom->get_id() > 0, "running domain has an ID > 0"); + +my $mac = get_macaddress($xml); +diag $mac; +# wait for guest to boot and request dhcp +sleep(20); +my $ip = get_ip_from_leases($mac); +diag "ip is $ip"; + Index: libvirt-tck/scripts/network/100-ping-still-working.t =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/100-ping-still-working.t @@ -0,0 +1,71 @@ +# -*- perl -*- +# +# Copyright (C) 2010 IBM Corp. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/100-ping-still-working.t - verify machines can be pinged from host + +=head1 DESCRIPTION + +The test case validates that it is possible to ping a guest machine from +the host. + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; +use Test::Exception; +use Net::SSH::Perl; +use XML::LibXML; + +require 'scripts/network/common_functions.pl'; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { + $tck->cleanup if $tck; +} + +# create first domain and start it +diag "Trying domain lookup by name"; +my $dom1; +my $domain_name ="f12nwtest"; + +ok_domain { $dom1 = $conn->get_domain_by_name($domain_name) } "the running domain object"; +my $xml = $dom1->get_xml_description; +diag $xml; +ok($dom1->get_id() > 0, "running domain has an ID > 0"); +my $mac1 = get_macaddress($xml); +diag $mac1; +my $guestip1 = get_ip_from_leases($mac1); +diag "ip is $guestip1"; + +# check ebtables entry +my $ebtable1 = `/sbin/ebtables -L;/sbin/ebtables -t nat -L`; +diag $ebtable1; +# fixme to include mac adress +ok($ebtable1 =~ "vnet0", "check ebtables entry"); + +# ping guest1 +my $ping1 = `ping -c 10 $guestip1`; +diag $ping1; +ok($ping1 =~ "10 received", "ping $guestip1 test"); + +exit 0; Index: libvirt-tck/scripts/network/210-no-mac-spoofing.t =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/210-no-mac-spoofing.t @@ -0,0 +1,113 @@ +# -*- perl -*- +# +# Copyright (C) 2010 IBM Corp. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/210-no-mac-spoofing.t - verify MAC spoofing is prevented + +=head1 DESCRIPTION + +The test case validates that MAC spoofing is prevented + +=cut + +use strict; +use warnings; + +use Test::More tests => 5; + +use Sys::Virt::TCK; +use Test::Exception; +use Net::SSH::Perl; +use XML::LibXML; + +require 'scripts/network/common_functions.pl'; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { + $tck->cleanup if $tck; +} + +# create first domain and start it +diag "Trying domain lookup by name"; +my $domain_name ="f12nwtest"; +my $dom1; +ok_domain { $dom1 = $conn->get_domain_by_name($domain_name) } "the running domain object"; +ok($dom1->get_id() > 0, "running domain has an ID > 0"); +my $xml = $dom1->get_xml_description; +diag $xml; + +# check ebtables entry +my $ebtable1 = `/sbin/ebtables -L;/sbin/ebtables -t nat -L`; +diag $ebtable1; +# fixme to include mac adress +ok($ebtable1 =~ "vnet0", "check ebtables entry"); + +# wait for guest to boot +diag "waiting for guests to boot"; +#system("sleep 20"); +diag "done"; + +# ping guest1 first nic +my $mac1 = get_macaddress($xml); +diag "$mac1"; +my $guestip1 = get_ip_from_leases($mac1); +diag "ip is $guestip1"; +my $gateway = "192.168.122.1"; +my $macfalse = "52:54:00:f9:21:22"; +my $ping1 = `ping -c 10 $guestip1`; +diag $ping1; +ok($ping1 =~ "10 received", "ping $guestip1 test"); + +# log into guest +my $ssh = Net::SSH::Perl->new($guestip1); +$ssh->login("root", "foobar"); + +# now bring eth0 down, change MAC and bring it up again +diag "fiddling with mac"; +my $cmdfile = "echo '" . + "/sbin/ifconfig eth0\n". + "/sbin/ifconfig eth0 down\n". + "/sbin/ifconfig eth0 hw ether ${macfalse}\n". + "/sbin/ifconfig eth0 up\n". + "/sbin/ifconfig eth0\n". + "ping -c 10 ${gateway}\n". + "/sbin/ifconfig eth0 down\n". + "/sbin/ifconfig eth0 hw ether ${mac1}\n". + "/sbin/ifconfig eth0 up\n". + "/sbin/ifconfig eth0\n". + "' > /test.sh"; +diag $cmdfile; +my ($stdout, $stderr, $exit) = $ssh->cmd($cmdfile); +diag $stdout; +diag $stderr; +diag $exit; +($stdout, $stderr, $exit) = $ssh->cmd("chmod +x /test.sh"); +diag $stdout; +diag $stderr; +diag $exit; +($stdout, $stderr, $exit) = $ssh->cmd("/test.sh > /test.log"); +diag $stdout; +diag $stderr; +diag $exit; +($stdout, $stderr, $exit) = $ssh->cmd("cat /test.log"); +diag $stdout; +diag $stderr; +diag $exit; +ok($stdout =~ "100% packet loss", "packet loss expected"); + +exit 0; Index: libvirt-tck/scripts/network/230-no-mac-broadcast.t =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/230-no-mac-broadcast.t @@ -0,0 +1,102 @@ +# -*- perl -*- +# +# Copyright (C) 2010 IBM Corp. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/230-no-mac-broadcast.t - verify MAC broadcasts are prevented + +=head1 DESCRIPTION + +The test case validates that MAC broadcasts are prevented + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; +use Test::Exception; +use Net::SSH::Perl; +use XML::LibXML; + +require 'scripts/network/common_functions.pl'; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { + $tck->cleanup if $tck; +} + +# create first domain and start it +diag "Trying domain lookup by name"; +my $dom1; +ok_domain { $dom1 = $conn->get_domain_by_name("f12nwtest") } "the running domain object"; + +ok($dom1->get_id() > 0, "running domain has an ID > 0"); +my $xml = $dom1->get_xml_description; +diag $xml; +my $mac1 = get_macaddress($xml); +diag "$mac1"; +my $guestip1 = get_ip_from_leases($mac1); +diag "ip is $guestip1"; + +# check ebtables entry +my $ebtable1 = `/sbin/ebtables -L;/sbin/ebtables -t nat -L`; +diag $ebtable1; +# fixme to include mac adress +ok($ebtable1 =~ "vnet0", "check ebtables entry"); + +# prepare tcpdump +diag "prepare tcpdump"; +system("/usr/sbin/tcpdump -v -i virbr0 -n host 255.255.255.255 2> /tmp/tcpdump.log &"); + +# log into guest +my $ssh = Net::SSH::Perl->new($guestip1); +$ssh->login("root", "foobar"); + +# now generate a mac broadcast paket +diag "generate mac broadcast"; +my $cmdfile = "echo '" . + "/bin/ping -c 1 192.168.122.255 -b\n". + "' > /test.sh"; +diag $cmdfile; +my ($stdout, $stderr, $exit) = $ssh->cmd($cmdfile); +diag $stdout; +diag $stderr; +diag $exit; +($stdout, $stderr, $exit) = $ssh->cmd("chmod +x /test.sh"); +diag $stdout; +diag $stderr; +diag $exit; +($stdout, $stderr, $exit) = $ssh->cmd("/test.sh > /test.log"); +diag $stdout; +diag $stderr; +diag $exit; +($stdout, $stderr, $exit) = $ssh->cmd("cat /test.log"); +diag $stdout; +diag $stderr; +diag $exit; + +# now stop tcpdump and verify result +diag "stopping tcpdump"; +system("kill -15 `/sbin/pidof tcpdump`"); +my $tcpdumplog = `cat /tmp/tcpdump.log`; +diag($tcpdumplog); +ok($tcpdumplog =~ "0 packets captured", "tcpdump expected to capture no packets"); + +exit 0; Index: libvirt-tck/scripts/network/240-no-arp-spoofing.t =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/240-no-arp-spoofing.t @@ -0,0 +1,111 @@ +# -*- perl -*- +# +# Copyright (C) 2010 IBM Corp. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/240-no-arp-spoofing.t - verify ARP spoofing is prevented + +=head1 DESCRIPTION + +The test case validates that ARP spoofing is prevented + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; +use Test::Exception; +use Net::SSH::Perl; +use XML::LibXML; + +require 'scripts/network/common_functions.pl'; + +my $spoofid = "192.168.122.183"; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { + $tck->cleanup if $tck; +} + +# looking up domain +diag "Trying domain lookup by name"; +my $dom1; +my $domain_name ="f12nwtest"; +ok_domain { $dom1 = $conn->get_domain_by_name($domain_name) } "the running domain object"; +ok($dom1->get_id() > 0, "running domain has an ID > 0"); +my $xml = $dom1->get_xml_description; +diag $xml; +my $mac1 = get_macaddress($xml); +diag "$mac1"; +my $guestip1 = get_ip_from_leases($mac1); +diag "ip is $guestip1"; + +# check ebtables entry +my $ebtable1 = `/sbin/ebtables -L;/sbin/ebtables -t nat -L`; +diag $ebtable1; +# check if mac address is listed +ok($ebtable1 =~ "$guestip1", "check ebtables entry"); + +# prepare tcpdump +diag "prepare tcpdump"; +system("/usr/sbin/tcpdump -v -i virbr0 not ip > /tmp/tcpdump.log &"); + +# log into guest +my $ssh = Net::SSH::Perl->new($guestip1); +$ssh->login("root", "foobar"); + +# now generate a arp spoofing packets +diag "generate arpspoof"; +my $cmdfile = "echo '" . + "/usr/bin/yum -y install dsniff\n". + "/usr/sbin/arpspoof ${spoofid} &\n". + "/bin/sleep 10\n". + "kill -15 `/sbin/pidof arpspoof`\n". + "' > /test.sh"; +diag "content of cmdfile:"; +diag $cmdfile; +diag "creating cmdfile"; +my ($stdout, $stderr, $exit) = $ssh->cmd($cmdfile); +diag $stdout; +diag $stderr; +diag $exit; +($stdout, $stderr, $exit) = $ssh->cmd("chmod +x /test.sh"); +diag $stdout; +diag $stderr; +diag $exit; +diag "excuting cmdfile"; +($stdout, $stderr, $exit) = $ssh->cmd("/test.sh > /test.log"); +diag $stdout; +diag $stderr; +diag $exit; +($stdout, $stderr, $exit) = $ssh->cmd("echo test.log\ncat /test.log"); +diag $stdout; +diag $stderr; +diag $exit; + +# now stop tcpdump and verify result +diag "stopping tcpdump"; +system("kill -15 `/sbin/pidof tcpdump`"); +diag "tcpdump.log:"; +my $tcpdumplog = `cat /tmp/tcpdump.log`; +diag($tcpdumplog); +ok($tcpdumplog !~ "${spoofid} is-at", "tcpdump expected to capture no arp reply packets"); + +exit 0; Index: libvirt-tck/scripts/network/220-no-ip-spoofing.t =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/220-no-ip-spoofing.t @@ -0,0 +1,101 @@ +# -*- perl -*- +# +# Copyright (C) 2010 IBM Corp. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/220-no-ip-spoofing.t - verify IP spoofing is prevented + +=head1 DESCRIPTION + +The test case validates that IP spoofing is prevented + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; +use Test::Exception; +use Net::SSH::Perl; +use XML::LibXML; + +require 'scripts/network/common_functions.pl'; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { + $tck->cleanup if $tck; +} + +# looking up domain +diag "Trying domain lookup by name"; +my $dom1; +my $domain_name ="f12nwtest"; + +ok_domain { $dom1 = $conn->get_domain_by_name($domain_name) } "the running domain object"; +ok($dom1->get_id() > 0, "running domain has an ID > 0"); +my $xml = $dom1->get_xml_description; +diag $xml; +my $mac1 = get_macaddress($xml); +diag "$mac1"; +my $guestip1 = get_ip_from_leases($mac1); +diag "ip is $guestip1"; + +# check ebtables entry +my $ebtable1 = `/sbin/ebtables -L;/sbin/ebtables -t nat -L`; +diag $ebtable1; +# check if IP address is listed +ok($ebtable1 =~ "$guestip1", "check ebtables entry"); + +# log into guest +my $ssh = Net::SSH::Perl->new($guestip1); +$ssh->login("root", "foobar"); + +# now bring eth0 down, change IP and bring it up again +diag "preparing ip spoof"; +my $cmdfile = "echo '" . + "/bin/sleep 1\n". + "/sbin/ifconfig eth0\n". + "/sbin/ifconfig eth0 down\n". + "/sbin/ifconfig eth0 192.168.122.183 netmask 255.255.255.0 up\n". + "/sbin/ifconfig eth0\n". + "/bin/sleep 1\n". + "/bin/ping -c 1 192.168.122.1\n". + "/sbin/ifconfig eth0 down\n". + "/sbin/ifconfig eth0 ${guestip1} netmask 255.255.255.0 up\n". + "/sbin/ifconfig eth0 \n". + "/bin/sleep 1\n". + "' > /test.sh"; +diag $cmdfile; +my ($stdout, $stderr, $exit) = $ssh->cmd($cmdfile); +diag $stdout; +diag $stderr; +diag $exit; +($stdout, $stderr, $exit) = $ssh->cmd("chmod +x /test.sh"); +diag $stdout; +diag $stderr; +diag $exit; +diag "running ip spoof"; +($stdout, $stderr, $exit) = $ssh->cmd("/test.sh"); +diag $stdout; +diag $stderr; +diag $exit; +diag "checking result"; +ok($stdout =~ "100% packet loss", "packet loss expected"); + +exit 0; Index: libvirt-tck/scripts/network/999-shutdown-image.t =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/999-shutdown-image.t @@ -0,0 +1,59 @@ +# -*- perl -*- +# +# Copyright (C) 2010 IBM Corp. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/240-no-arp-spoofing.t - verify ARP spoofing is prevented + +=head1 DESCRIPTION + +The test case validates that ARP spoofing is prevented + +=cut + +use strict; +use warnings; + +use Test::More tests => 2; + +use Sys::Virt::TCK; +use Test::Exception; +use Net::SSH::Perl; + + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { + $tck->cleanup if $tck; +} + +# find domain +my $domain_name = "f12nwtest"; +diag "Trying domain lookup by name"; +my $dom; +ok_domain { $dom = $conn->get_domain_by_name($domain_name) } "the running domain object"; +ok($dom->get_id() > 0, "running domain has an ID > 0"); + +# cleanup guest +diag "cleaning up"; +$dom->shutdown(); + while($dom->is_active()) { + sleep(1); + diag ".. waiting for virtual machine ${domain_name} to shutdown.. "; + } +#$dom->undefine(); + +exit 0; Index: libvirt-tck/scripts/network/common_functions.pl =================================================================== --- /dev/null +++ libvirt-tck/scripts/network/common_functions.pl @@ -0,0 +1,35 @@ +use utf8; +#no utf8; + +sub get_macaddress { + my $xmldesc = shift; + + my $mac; + my $parser = XML::LibXML->new(); + + my $doc = $parser->parse_string($xmldesc); + + my $rootel = $doc -> getDocumentElement(); + + my @devices = $rootel->getChildrenByTagName("devices"); + foreach my $device(@devices) { + my @interfaces = $device->getChildrenByTagName("interface"); + foreach my $interface(@interfaces) { + my @targets = $interface->getChildrenByTagName("mac"); + foreach my $target(@targets) { + $mac = $target->getAttribute("address"); + } + } + } + utf8::decode($mac); + return $mac; +} + +sub get_ip_from_leases{ + my $mac = shift; + my $tmp = `grep $mac /var/lib/dnsmasq/dnsmasq.leases`; + my @fields = split(/ /, $tmp); + my $ip = $fields[2]; + return $ip; +} +1; -- Best regards, Gerhard Stenzel, ----------------------------------------------------------------------------------------------------------------------------------- IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martin Jetter Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list