-1

I have a couple of kvm vms running with libvirt and they are using openvswitch bridges. I need a mechanism to prevent mac spoofing on a guest. I tried libvirt filters no-mac-spoofing and clean-traffic but they only work with linux bridges. I thought I could maybe use openflow rules to try to restrict the traffic that do not match an specific src mac (drop all packets that have a different mac than what was configured on the vm xml). This is what I have:

[root@t6 /]# ovs-ofctl show vswitch2            
OFPT_FEATURES_REPLY (xid=0x2): dpid:00000030641a7b82
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 1(eth5): addr:00:30:64:1a:7b:82
     config:     0
     state:      0
     current:    1GB-FD COPPER AUTO_NEG
     advertised: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
     supported:  10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
     speed: 1000 Mbps now, 1000 Mbps max
 2(vnet0): addr:fe:54:00:00:00:11
     config:     0
     state:      0
     current:    10MB-FD COPPER
     speed: 10 Mbps now, 0 Mbps max
 3(vnet1): addr:fe:54:00:00:00:22
     config:     0
     state:      0
     current:    10MB-FD COPPER
     speed: 10 Mbps now, 0 Mbps max
 4(vnet2): addr:fe:54:00:00:00:33
     config:     0
     state:      0
     current:    10MB-FD COPPER
     speed: 10 Mbps now, 0 Mbps max
 LOCAL(vswitch2): addr:00:30:64:1a:7b:82
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max

And I wanted to restrict the traffic on packets coming from vnet2. So I tried dropping the packets in which the src mac didn't match the mac configured on libvirt nic:

[root@t6 /]# ovs-ofctl add-flow vswitch2 dl_src!=52:54:00:00:00:33,in_port=4,actions=drop
ovs-ofctl: unknown keyword dl_src!

[root@t6 /]# ovs-ofctl add-flow vswitch2 dl_src!52:54:00:00:00:33,in_port=4,actions=drop
-bash: !52: event not found

But as you can see, the ! symbol is not recognized. I looked at the documentation for openflow but couldn't find anything that could help me with that... Can anyone that has some openflow and openvswitch knowledge help me with that? Is what I'm trying to do even possible with openflow? Honestly I'm really confused at the moment, as the openflow documentation is a bit overwhelming for first time users.... I thank you in advance for any help you could give!

igalvez
  • 29
  • 3

1 Answers1

0

The simplest solution is to reverse your logic:

ovs-vsctl add-flow vswitch2 in_port=4,dl_src=52:54:00:00:00:33,action=NORMAL
ovs-vsctl add-flow vswitch2 in_port=4,action=drop

I've tested this out and it seems to work. I have two virtual machines attached to a bridge ovsbr0 with addresses 192.168.124.10 and 192.168.124.11. The first machine has this interface:

3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:06:88:31 brd ff:ff:ff:ff:ff:ff
    altname enp2s0
    inet 192.168.124.10/24 scope global eth1
       valid_lft forever preferred_lft forever

And I can successfully ping the second system at 192.168.124.11:

[root@fedora ~]# ping -c2 192.168.124.11
PING 192.168.124.11 (192.168.124.11) 56(84) bytes of data.
64 bytes from 192.168.124.11: icmp_seq=1 ttl=64 time=0.351 ms
64 bytes from 192.168.124.11: icmp_seq=2 ttl=64 time=0.314 ms

--- 192.168.124.11 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1017ms
rtt min/avg/max/mdev = 0.314/0.332/0.351/0.018 ms

If I add those two openflow rules:

host# ovs-ofctl add-flow ovsbr0 in_port=4,dl_src=52:54:00:06:88:31,actions=NORMAL
host# ovs-ofctl add-flow ovsbr0 in_port=4,actions=drop

I can still ping the second system:

[root@fedora ~]# ping -c2 192.168.124.11
PING 192.168.124.11 (192.168.124.11) 56(84) bytes of data.
64 bytes from 192.168.124.11: icmp_seq=1 ttl=64 time=0.398 ms
64 bytes from 192.168.124.11: icmp_seq=2 ttl=64 time=0.188 ms

--- 192.168.124.11 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1050ms
rtt min/avg/max/mdev = 0.188/0.293/0.398/0.105 ms

But if I change the MAC address:

[root@fedora ~]# ip link set eth1 down
[root@fedora ~]# ip link set eth1 address 52:54:00:06:12:34
[root@fedora ~]# ip link set eth1 up

I find that ping no longer works:

[root@fedora ~]# ping -c2 192.168.124.11
PING 192.168.124.11 (192.168.124.11) 56(84) bytes of data.
From 192.168.124.10 icmp_seq=1 Destination Host Unreachable
From 192.168.124.10 icmp_seq=2 Destination Host Unreachable

--- 192.168.124.11 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1052ms
pipe 2
larsks
  • 41,276
  • 13
  • 117
  • 170