How to Get Rid of Denial-of-Service Attacks

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.

Filtering Possibilities

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.

Destination Address Filtering

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
announces /32 routes with this black hole community set,
in addition to the regular address block announcements. All traffic
for these /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
the following:

This route map will set the next hop address for all routes with
the community 65000:13 attached to it to
13.13.13.13. (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
13.13.13.13 address. Then, on all routers in the network,
the 13.13.13.13 address must be routed to the null
interface and the packets will end up being discarded:

!
ip route 13.13.13.13 255.255.255.255 Null0
!

In the real world you would use an address out of your own address
block rather than the 13.13.13.13 address.

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.)

Source Address Filtering with Unicast RPF

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.

Using a Filter Box

So now we arrive at the solution I'm advocating: having a separate
filter box in the network:

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.

Advantages

no NOC actions necessary

no performance penalty on the production network

no special hardware or protocols necessary

customer has complete control

customer can't mess with the production network

customer can't mess with other customer's view of the attacking source
addresses (well, only for boxes from other customers also under attack)

Disadvantages

doesn't work with full scale source address spoofing

extra hardware necessary

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.

Stateful Firewalling

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.