Most of the press coverage of the recent spate of distributed denial of service (DoS) attacks against well-known web sites has focused on the hunt for the perpetrators, how they should be punished, and what effect all this will have on electronic commerce. Few reports have explained how the attacks occur, and fewer still have said anything about how we might prevent them.
Let's take a Linux-focused look at denial of service attacks and what we can do as responsible Internet citizens to assist in preventing them.
A denial of service attack is any act intended to cause a service to become unavailable or unusable. In an Internet environment, a service might be an application such as a web or mail server, or a network service like routing of datagrams.
A simple form of denial of service attack involves sending a stream of connection requests to a service in the hope of exhausting the server of memory or by reaching the server connection limit, if it has one. When either of these conditions occur, the server will either refuse further connection requests or perform so poorly that the service becomes unusable to others. More sophisticated denial of service attacks might involve exploiting bugs or design problems in specific types of servers to cause the server to become extremely busy or fail completely.
A distributed denial of service attack exploits several machines to make the attack. Distributed denial of service attacks are the most effective and insidious because they can generate more traffic from more sources. This makes it much harder to identify the attack's source, and more difficult to resolve.
Sometimes the distributed denial of service attack involves cracking the security of a number of hosts and installing a program to cause denial of service a remote host. Other times the DoS attack exploits poorly configured networks and weaknesses in the IP security model.
6 Ways to Prevent DoS Attacks
A good example of the latter form of attack is the "Smurf" attack which involves sending ICMP echo request datagrams (ping packets) to the broadcast address of large networks using a faked or "spoofed" IP source address of the host to be attacked. An IP host will respond to ICMP echo requests on either the nominal address or the broadcast address of any its interfaces. When you ping the broadcast address of a network, all active hosts on that network will respond so that for any one request there are many replies. It is this amplification that makes this type of denial of service attack so powerful.
Preventing this type of attack against your own hosts is difficult. If you want to prevent distributed denial of service attacks on your hosts, the best hope you have is to prevent your own hosts and networks from being used to cause denial of service attacks on others and to encourage other network and system administrators to do the same.
So let's look at ways you can configure your Linux-based router and hosts to assist in preventing distributed denial of service attacks. Imagine that we're managing a simple installation comprising one router and three network interfaces. The first is a PPP link to the Internet, and the others are Ethernet interfaces supporting an IP network each. The interface details for our example network are:
To keep these details handy as we work through the examples in this article, you can load them into a pop-up window here.
There are several things you can do to assist in preventing your network from being used in distributed denial of service attacks.
Since some types of distributed denial of service attacks require attackers to execute programs on numerous host machines, you should ensure that your host machines are secure. Remove all unnecessary or unused network daemon programs especially the BSD "r" commands such as rlogin and rexec. Replace them with ssh.
Network programs are sometimes vulnerable to buffer overflow and other types of bugs, exposing your host to exploitation. These are fixed when they are found and you should ensure you are running current and up-to-date versions of daemons to take advantage of bug fixes.
IP spoofing is the term for causing one host to pretend to be another. A well-known case used this technique to gain access to hosts supporting the BSD "r" commands by spoofing trusted hosts.
It's quite difficult to know for certain whether a datagram is genuine or spoofed. You should ensure that any datagrams coming into your network with a source address that belongs to your network are treated as suspect. Kernels 2.2 and newer provide an implementation of the spoof protection described in RFC1812 that will suit most simple network configurations. Some distributions already use this. If yours doesn't, execute the following on each Linux hosts at boot time:
for pfile in /proc/sys/net/ipv4/conf/*/rp_filter do echo "1" > $pfile done
You can protect non-Linux hosts by using firewall rules in your Linux router. To protect our example networks we would use:
For older kernels:
ipfwadm -I -a deny -W ppp0 -S 172.29.16.0/24 ipfwadm -I -a deny -W ppp0 -S 172.29.17.0/24
For 2.2 kernels:
ipchains -A input -w ppp0 -s 172.29.16.0/24 -j deny ipchains -A input -w ppp0 -s 172.29.17.0/24 -j deny
For 2.3 and newer kernels:
iptables -A FORWARD -i ppp0 -s 172.29.16.0/24 -j DROP iptables -A FORWARD -i ppp0 -s 172.29.17.0/24 -j DROP
A New Worm Targets Linux -- Noel Davis shows us the Linux based Adore Worm; buffer overflows in xntpd and ntpd; and vulnerabilities in SharePlex, Ultimate Bulletin Board, Lucent/ORiNOCO Closed Network, Red Hat's OpenSSH, Cisco Content Services Switches, and IPFilter.
Securing Your Apache Server -- Excerpt from Chapter 13 of O'Reilly's book Apache: The Definitive Guide, 2nd Edition. Enable Apache to communicate securely over Secure Sockets Layer (SSL). Covers building, configuring, and securing an SSL-enabled Apache server under Unix.
Also in Linux Network Administration:
To prevent "smurf" type attacks you should prevent ICMP messages arriving at
your broadcast and multicast addresses from outside your network. Assuming the
network device that supports our Internet connection is
ppp0 and that
our broadcast addresses are
For older kernels:
ipfwadm -I -a deny -P icmp -W ppp0 -D 172.29.16.255 ipfwadm -I -a deny -P icmp -W ppp0 -D 172.29.17.255 ipfwadm -I -a deny -P icmp -W ppp0 -D 22.214.171.124/4
For 2.2 kernels:
ipchains -A input -p icmp -w ppp0 -d \ 172.29.16.255 -j deny ipchains -A input -p icmp -w ppp0 -d \ 172.29.17.255 -j deny ipchains -A input -p icmp -w ppp0 -d \ 126.96.36.199/4 -j deny
For 2.3 and newer kernels:
iptables -A FORWARD -m multiport -p icmp -i ppp0 -d \ 172.29.16.255 -j DROP iptables -A FORWARD -m multiport -p icmp -i ppp0 -d \ 172.29.17.255 -j DROP iptables -A FORWARD -m multiport -p icmp -i ppp0 -d \ 188.8.131.52/4 -j DROP
In 2.2 kernels and newer, you can also use the following command on each of your hosts to prevent them from replying to ICMP echo requests on broadcast and multicast addresses:
echo "1" >/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
If you're using a kernel that supports netfilter, you can also use the limiter to limit the volume of ICMP echo requests to all other addresses to a reasonable rate. To limit incoming ICMP messages in our example network to one per second, but allow bursts of two per second, you could use:
iptables -A FORWARD -m limit -p ICMP -i ppp0 \ --limit 1 --limit-burst-number 2
You might optionally want log any matching datagrams to ensure that you're able to see any potential attacks.
If you have limited requirements for Internet access, you might consider an even more tightly controlled firewall. For example, you could filter ICMP to broadcast addresses, even from local hosts to help ensure that even if a local host is breached your network cannot be used as an "amplifier." You might also consider deploying firewalls on each local host rather than relying only on filtering in routers and a more network firewall configuration (such as a NAT or masquerade-style configuration, or use of a perimeter network).
You can minimize the damage associated with distributed denial of service
attacks by being aware of them soon after they begin. It is important to keep
an eye on what is happening on your network and using the logging facilities
of the Linux firewall support can help. Use the
-l argument on
ipchains rules, and the
-j LOG target for
iptables commands to cause datagrams matching the rule to be logged to
the console. Beware: The host activity caused by this logging can precipitate
a denial of service attack all by itself. Fortunately the
limit matcher (
-m limit) works with logging as well.
The kernel provides a means of logging datagrams suspected to be spoofed IP addresses using:
echo "1" >/proc/sys/net/ipv4/conf/all/log_martians
Staying alert and aware also involves keeping up to date with bugs and exploits that have been discovered and reported by others. The Computer Emergency Response Team (CERT) provides a web site and mailing list designed to keep network and system administrators advised of newly reported security problems. You can find CERT at http://www.cert.org/.
This is the most important step. Widespread adoption of good security practices can afford reliable and effective protection against distributed denial of service attacks. Make sure you know who the network or security administrator is of your network peers and upstream providers. Talk with them, let them know what you are doing, and encourage them to do the same. When something does happen, you'll be able to quickly gain their support and assistance and work together to solve the problem.
Have a security tip or dilemma? Join the discussion in the O'Reilly Network Linux forum.
Return to the Linux DevCenter
Copyright © 2009 O'Reilly Media, Inc.