++blog: dhcp/router advertisement blocking
This commit is contained in:
		
					parent
					
						
							
								4280510712
							
						
					
				
			
			
				commit
				
					
						23b5be2448
					
				
			
		
					 1 changed files with 106 additions and 0 deletions
				
			
		| 
						 | 
					@ -0,0 +1,106 @@
 | 
				
			||||||
 | 
					title: Blocking DHCP servers and router advertisements with nftables
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					pub_date: 2020-08-27
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					author: ungleich
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					twitter_handle: ungleich
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					_hidden: no
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					_discoverable: yes
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					abstract:
 | 
				
			||||||
 | 
					Blocking typical data center workloads with nftables
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					body:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Motivation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Here at [ungleich](https://ungleich.ch) we are providing a variety of
 | 
				
			||||||
 | 
					hosting services in the [Data Center
 | 
				
			||||||
 | 
					Light](https://datacenterlight.ch). One of the workloads we offer is
 | 
				
			||||||
 | 
					VM hosting and we need to take some security measures to prevent one
 | 
				
			||||||
 | 
					customer abusing another customer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## The problem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The virtual machines in our next generation uncloud hosting will be
 | 
				
			||||||
 | 
					using standard DHCP and IPv6 address assignments and not the
 | 
				
			||||||
 | 
					[OpenNebula](https://github.com/OpenNebula/addon-context-linux)
 | 
				
			||||||
 | 
					contextualisation scripts that read the networking information from an
 | 
				
			||||||
 | 
					attached ISO.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					While this makes it easier to create VM images and VMs behave even
 | 
				
			||||||
 | 
					more like regular computers, this exposes the VMs to attacks where one
 | 
				
			||||||
 | 
					customer runs a DHCP server or IPv6 router advertisement daemon and
 | 
				
			||||||
 | 
					tricks the other VMs into sending traffic to it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## The architecture
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VMs are connected to a single shared network in which they get
 | 
				
			||||||
 | 
					their IP addresses (in uncloud usually only IPv6) and then they can
 | 
				
			||||||
 | 
					retrieve more information from a metadata server. So the main
 | 
				
			||||||
 | 
					protection that is required is preventing to trick other customers
 | 
				
			||||||
 | 
					into using a wrong IP address or route.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Fixing it
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					So the easiest thing to do is to disallow IPv6 router advertisements
 | 
				
			||||||
 | 
					and IPv4 DHCP server answers. However as all the interfaces are put
 | 
				
			||||||
 | 
					into one bridge, we will need to filter on bridge and not ip level:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					table bridge filter {
 | 
				
			||||||
 | 
					    chain prerouting {
 | 
				
			||||||
 | 
					        type filter hook prerouting priority 0;
 | 
				
			||||||
 | 
					        policy accept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next we create a chain to drop the packets we dislike:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					    chain drop_ra_dhcp {
 | 
				
			||||||
 | 
					        # Default blocks: router advertisements, dhcpv6, dhcpv4
 | 
				
			||||||
 | 
					        icmpv6 type nd-router-advert drop
 | 
				
			||||||
 | 
					        ip6 version 6 udp sport 547 drop
 | 
				
			||||||
 | 
					        ip  version 4 udp sport 67 drop
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now the only thing left is to correctly classify the traffic:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Let's assume the bridge is named **br100**
 | 
				
			||||||
 | 
					* Let's assume the upstream interface that should allow RA/DHCP is
 | 
				
			||||||
 | 
					  named **vxlan100**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then we can connect the chains together:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					table bridge filter {
 | 
				
			||||||
 | 
					    chain prerouting {
 | 
				
			||||||
 | 
					        type filter hook prerouting priority 0;
 | 
				
			||||||
 | 
					        policy accept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        iifname != vxlan100 meta ibrname br100 jump drop_ra_dhcp
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    chain drop_ra_dhcp {
 | 
				
			||||||
 | 
					        # Blocks: router advertisements, dhcpv6, dhcpv4
 | 
				
			||||||
 | 
					        icmpv6 type nd-router-advert drop
 | 
				
			||||||
 | 
					        ip6 version 6 udp sport 547 drop
 | 
				
			||||||
 | 
					        ip  version 4 udp sport 67 drop
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This way we have a very simple filter to prevent router advertisements
 | 
				
			||||||
 | 
					or dhcp answers to come from customer VMs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If something does not make sense,
 | 
				
			||||||
 | 
					you can ask on our [open chat](/u/projects/open-chat/) or
 | 
				
			||||||
 | 
					[consult the nftables reference](https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Meta).
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue