How to Get Rid of Denial-of-Service Attacksby Iljitsch van Beijnum, author of BGP
On August 10th I had the opportunity to talk about (Distributed) Denial of Service (DDoS) at the Megabit 2002 event. I wanted to show a new way to use standard routers and protocols to combat denial of service. Unfortunately there wasn't enough time to really prepare the test setup. I was unable to show conclusively that it works. I was able to explain how it is supposed to work. I'm going to repeat that part here and then talk about the Cisco router configurations that make it all happen.
Network-based (D)DoS attacks boil down to a lot of unwanted traffic coming in, which uses up either the available bandwidth, CPU time, memory, or some combination of these. The idea is to filter out this unwanted traffic. This has to happen as close to the source as possible, since the available bandwidth typically goes down as the traffic gets closer to the destination. Filtering out traffic that has already succeeded in completely filling up the link to an ISP isn't extremely useful. This means in practical terms that the ISP has to configure a filter when a customer is under attack.
How do we filter? We filter either on the source address, on the service, or on the destination address. Filtering on the source address is the preferred way to get rid of unwanted traffic: it catches only traffic from the attacker. Unfortunately this approach can't be used very often. Attackers usually falsify or spoof the source address in attacking traffic, with the result that the attack seems to come from many different hosts throughout the net. Even when the source addresses are real, in a distributed attack there may be so many of them that it's impractical to configure a filter for all of them.
If you're lucky you may encounter an attacker who uses a single, inessential service for all attacking packets. For example, some early DDoS tools used a single UDP port for all attacking traffic. Smurf directed broadcast attacks by their nature only create ICMP echo reply packets. In these cases the attacking traffic can easily be filtered out by filtering a UDP or TCP port or by ICMP type. If the attack uses unpredictable ports or ports that can't be filtered because they are used for important services, it's not possible to filter on service type.
As a last resort, it's possible to filter out all traffic to the host or hosts under attack in order to protect the rest of the network. This is usually possible because most attacks are directed at a small number of hosts. If the attack is directed at the entire network, filtering on destination address isn't possible.
Installing the right type of filter will get rid of most attacks. Unfortunately this has to be done at a transit ISP, at least one hop closer to the core of the Internet, so the attacking traffic doesn't overload the customer connection. This is very inconvenient because it requires an ISP engineer to install the filter, which often takes a long time. I propose incorporating mechanisms so customers can do this themselves in the ISP network.
Let's start with filtering on destination address, which is the
easiest to create. An ISP can give a customer the necessary tools to
do this by creating a BGP community that routes traffic for the
advertised address range to the null interface. The customer then
/32 routes with this black hole community set,
in addition to the regular address block announcements. All traffic
/32s is then sent to the null interface. A
/32 is BGP-speak for a single IP address, and communities
are labels which indicate that special treatment of some kind is
desired. In this case, the special treatment is to throw away all
traffic that has this IP address as its destination. An admittedly
Cisoc-centric route map to accomplish this might look something like
! ip community-list 13 permit 65000:13 ! route-map customer-in permit 10 match community 13 set ip next-hop 184.108.40.206 !
This route map will set the next hop address for all routes with
65000:13 attached to it to
220.127.116.11. (A community takes the shape of a 32 bit
value written as two values separated by a colon, where the first
value is often the Autonomous System number of the network that will
act on the community.) This route map must be applied to the customer
BGP session. This makes the router check for the community in all
routing updates received from the customer and change the destination
of the packets that match the route to the special
18.104.22.168 address. Then, on all routers in the network,
22.214.171.124 address must be routed to the null
interface and the packets will end up being discarded:
! ip route 126.96.36.199 255.255.255.255 Null0 !
In the real world you would use an address out of your own address
block rather than the
Related Articles by Iljitsch van Beijnum:
Running Zebra on a Unix Machine: An Alternative to a Real Router? -- Iljitsch van Beijnum, author of O'Reilly's BGP, looks at whether Zebra, the host-based routing software, can be used as an alternative to a real router.
A Look at Multihoming and BGP -- This article walks you through the steps for multihoming to two different ISPs using BGP, by the author of O'Reilly's upcoming BGP.
When this setup is in effect, all traffic directed to a black-holed address is immediately thrown away as soon as it enters the network. Unlike regular anti-DoS filters that are applied to customer interfaces, traffic is first transported through the ISP network to the router connecting the customer, only to be thrown out there. The main advantage is the customer can initiate filtering at any time without any need for cooperation from the ISP. (Obviously, customers shouldn't be allowed to announce addresses that aren't theirs with this black hole community, or they could black hole addresses belonging to others. Regular filters on customer BGP sessions should take care of this.)
Since routing looks at the destination addresses, filtering on those is pretty simple. But, if we employ Cisco's unicast reverse path forwarding (uRPF) check, filtering on source addresses isn't that hard either. uRPF takes the source address of incoming packets and checks in the CEF table, a copy of the routing table used for high-speed packet forwarding, whether the interface the packet arrived on is the next hop interface for the source address. Packets that arrive on an interface the router wouldn't use to reach the source address are considered falsified and are dropped. This works very well for interfaces that connect to well-defined networks. It can also work for peers (over private connections or over an Internet exchange) but uRPF isn't very useful on links to ISPs that sell you transit service; they are supposed to deliver packets from all possible sources connected to the net. And uRPF can't be used with two ISPs: packets with a certain source address can come in over either ISP, while the router only considers one of them the valid source of these packets.
By enabling the uRPF feature and using the same community as in the previous example, we can now filter on source address:
! interface Serial0 ip verify unicast reverse-path !
The community makes sure the address is routed to the null interface, and packets with the indicated source address are only allowed if they are received from the null interface. (Actually the uRPF feature has a special check for "null adjacencies", which are immediately dropped.) Since attacking traffic tends to come in over other interfaces, this should work very well as long as uRPF is enabled. There is also a "loose" uRPF that doesn't check where the packet came from; instead, it checks whether the source address is in the routing table. My router doesn't support this and I can't find the right command, so I'll leave implementing it as an exercise for the reader. This type of uRPF can be enabled for all interfaces because it doesn't break asymmetric routing (the problem with two ISPs), which makes it very useful here.
Unfortunately this kind of filtering on the source address can't be used in practice, since customers would be allowed to blac khole source addresses arbitrarily in an ISP network. This is way too dangerous to allow.
So now we arrive at the solution I'm advocating: having a separate filter box in the network:
inet | +---+------+ +----------+ | ISP +--------+ Filter | | router 1 | | box | +--------+-+ +-+--------+ \ / \ / +-+------+-+ | ISP | | router 2 | +----+-----+ | | +----+-----+ | Customer | | router | +----------+
Whenever a customer's address is under attack, the customer announces this address with a community similar to the one in the first example. Rather than changing the next hop address to an unreachable address, the next hop address is set to that of the filter box. All traffic to hosts under attack is routed through the filter box.
Any traffic surviving the filtering process is sent on its way to the customer. Essentially, the filter box cleanses traffic.
Since different routers in the ISP network need different views of the next hop address for the addresses under attack, (ISP router 1 needs to send traffic to the filter box, ISP router 2 to the customer) there should probably be route maps configured on iBGP sessions. This isn't particularly elegant, but I see no reason why it couldn't be done. If this is a problem, the traffic can be sent from the filter box to the customer over a tunnel.
On the filter box it shouldn't be a problem to use the BGP black holing + uRPF trick described above to filter on source addresses. Customers would have an extra BGP session to the filter box so they can tell it which source addresses to filter out. Since only traffic under attack is being rerouted over the filter box, this essentially creates a filter on the source/destination combinations. It is entirely possible to create the filters on the filter box in a different way. The filter box could be a host-based router on which filters can be set and removed using a web interface.
If it proves impossible to get rid of spoofed source addresses, there is a last resort -- stateful firewalling. The filter box would then monitor all (TCP) sessions and only allow traffic that belongs to a valid session or an IP address partaking in a valid session. Since it is nearly impossible to complete the TCP three-way handshake with a falsified source address, this will get rid of all excess traffic except TCP SYNs, and these can be rate limited to a level the host under attack can handle.
This solution won't be easy to implement; it will be hard to get the outgoing traffic that matches the incoming traffic that must be filtered flowing through the same box, which is necessary to do the stateful filtering. This problem could be solved by having different stateful firewalls work together. A customer firewall could monitor the outgoing traffic and instruct the ISP "filter box" firewall to allow traffic as soon as there is a valid three-way handshake.
(If you're interested in testing this approach, email me at .)
Iljitsch van Beijnum has been working with BGP in ISP and end-user networks since 1996.
Return to ONLamp.com.
Copyright © 2009 O'Reilly Media, Inc.