Comment 0 for bug 1884341

Revision history for this message
Etienne CHAMPETIER (champtar) wrote : Anti-spoofing bypass using VLAN0 stacking

Hello OpenStack Team,

Looking at the neutron code I believe OpenStack to be vulnerable to VLAN0 stacking when using iptables + ebtables (bridge only, not OVS).
I was not able to validate this issue on an OpenStack deployment (I tried to setup microstack but was unable to connect to the VMs ...)

VLAN 0 or priority tagging allow to add 802.1p class of service information to a packet.
When received by a linux machine (I haven't checked Windows or other OS behavior) the VLAN header with VID=0 is removed and the packet processed as if there was no VLAN header (It actually loop until there is no VLAN 0 headers left).

Now Linux bridge firewall (net.bridge.bridge-nf-call-*tables) handles the packets normally, ie a packet with a VLAN header will not match any ip*tables rules on the forward path, which is expected.
When enabling net.bridge.bridge-nf-filter-vlan-tagged=1, it will go look into the first VLAN header, but not deeper.

Using this simple scapy script:
```
ra = Ether()/Dot1Q(vlan=0)/Dot1Q(vlan=0)
ra /= IPv6(dst='ff02::1')
ra /= ICMPv6ND_RA(chlim=64, prf='High', routerlifetime=1800)
ra /= ICMPv6NDOptSrcLLAddr(lladdr=get_if_hwaddr('enp1s0'))
ra /= ICMPv6NDOptPrefixInfo(prefix="2001:db8:1::", prefixlen=64, validlifetime=1810, preferredlifetime=1800)
sendp(ra)
```

We send an IPv6 router advertisement stacked on top of 2 VLAN 0 headers
This bypass any ip6tables rules, and looking at the usage of ebtables in neutron it should go thru as it's not ARP (I only see ebtables used in arp_protect.py and matching ARP protocol)
When received by a neighboor Linux VMs it's accepted.

This same attack should allow DHCP, ARP or any traffic spoofing.
(We might be able to use NFQUEUE to had VLAN 0 headers to all our egress packets to bypass MAC/IP checks)

I've seen some system actually use VLAN 0 tagged packets by default (Cisco UCS) so a possible fix is to allow 1 level of VLAN 0 and enable net.bridge.bridge-nf-filter-vlan-tagged=1

In my tests Linux 'removes' both Dot1Q(vlan=0) and Dot1AD(vlan=0).
(for example this is accepted by Linux: 'Ether()/Dot1Q(vlan=0)/Dot1Q(vlan=0)/Dot1AD(vlan=0)/Dot1Q(vlan=0)')

I wasn't able to find any reference to VLAN 0 attacks searching on Google, so this might affect other OSS projects (I need to check LXC at least, maybe some K8S CNI)

All my tests were performed with a Fedora 32 host (Linux 5.6) running 2 ubuntu 20.04 VM, and using scapy 2.4.3.

Best
Etienne Champetier