Linux Kernel RTL8169 NIC Remote Denial of Service

The Linux Kernel is exposed to a remote denial of service issue in the NTL6269 driver. This issue occurs when a large packet is sent to a computer with NTL6269 NIC installed. Specifically, the driver permits frame sizes of up to 16383 bytes, but allocates only “skb” to “rx” rings of 1536 bytes.

Linux Kernel versions prior to 2.6.30 are affected.


Securing Apache against HTTP DoS and/or Brute Force attacks

There are some native Apache directives that can be configured to help mitigate the effects of a Denial of Service (DoS) attack. The directives included Timeout, KeepAlive, and KeepAliveTimeout.


One way of attacking web servers is to try and exhaust the target systems resources by opening multiple connections and then never closing them. The more connections the server has open at once, the more resources are tied up holding details of those connections, which can lead to increased load and eventually to the server running out of resources.

The TimeOut directive tells the server how long to wait to receive a GET request, the amount of time between receipt of TCP packets on a POST or PUT request, or the amount of time between ACKs on transmissions of TCP packets in responses. Basically, this is the total time it takes to receive and respond to an http request.

In order to prevent a DoS attack from shutting down our web server, we need to change the default setting of 300 (which is 5 minutes) to something more reasonable such as 60 (which is 1 minute). You may even adjust this setting to be lower than 60. Think about this for a minute.

How many individual graphics files do you think there are in the average web page? Last check on the home page showed approximately 58 graphics files (gif and jpg) being referenced. Now imagine if your web browser had to create a brand-new connection for every one of those files. The overhead associated with initializing the HTTP connection would increase the time to fully load a web page significantly. This is where the concept of KeepAlives and “pipelining” web requests came from. The idea is simple: to allow multiple requests from the same client to utilize the same established HTTP connection. This efficient use of this capability dramatically decreases the amount of time it takes to fully download and display a web page. It is for this reason that the KeepAlive directive should be turned on.

Much in the same way that the Timeout directive limited the amount of time that the established HTTP connection would be valid, the KeepAliveTimeout directive will expire a socket after the designated amount of time. The difference between the Timeout and the KeepAliveTimeout directives is that the timeout setting designates the amount of time that the entire connection will be open and the KeepAliveTimeout directive states how long the server will wait for a subsequent request from the client. This means that the KeepAliveTimeout setting should always be less then the timeout setting. The default setting for KeepAliveTimeout is 15 seconds, which is reasonable; however, you could lower this just a bit if desired.

While these directives help with the performance of Apache and will lessen the impact of a DoS attack, there is another third-party module that is extremely effective.

mod_evasive is an evasive maneuvers module for Apache whose purpose is to react to HTTP DoS and/or Brute Force attacks. It was developed by Jonathan Zdziarski.

An additional capability of the module is that it is also able to execute system commands when DoS attacks are identified. This provides an interface to send attacking IP addresses to other security applications such as local host-based firewalls to block the offending IP address.

Installing mod_evasive on Centos 5.3:

( you can find lots of documents that explains how to install mod_evasive on other distributions )
# rpm -Uvh
# yum install mod_evasive

Configuring  mod_evasive :

/etc/httpd/conf.d/mod_evasive.conf is main configuration file for mod_evasive :

LoadModule evasive20_module modules/

<IfModule mod_evasive20.c>
 DOSHashTableSize    3097
 DOSPageCount        5
 DOSSiteCount        100
 DOSPageInterval     1
 DOSSiteInterval     1
 DOSBlockingPeriod   10
 #DOSSystemCommand    "su - someuser -c '/sbin/... %s ...'"
 DOSLogDir           "/var/lock/mod_evasive"


We will now discuss each of the mod_evasive directives. Most of this information is taken directly from the README file of mod_evasive, so proper credit should be given to the developer of this module.


This directive specifies the number of top-level nodes for each apache child process’s hash table. Increasing this number will provide faster performance by decreasing the number of iterations required to get to the record, but consume more memory for table space. You should increase this if you have a busy web server.


This is the threshold for the number of requests for the same page (or URI) per page interval. Once the threshold for that interval has been exceeded, the IP address of the client will be added to the blocking list.


This is the threshold for the total number of requests for any object by the same client on the same listener per site interval. Once the threshold for that interval has been exceeded, the IP address of the client will be added to the blocking list.


The interval for the page count threshold; defaults to 1 second intervals.


The interval for the site count threshold; defaults to 1 second intervals.


The blocking period is the amount of time (in seconds) that a client will be blocked for if they are added to the blocking list. During this time, all subsequent requests from the client will result in a 403 (Forbidden) and the timer being reset (e.g., another 10 seconds). Because the timer is reset for every subsequent request, it is not necessary to have a long blocking period; in the event of a DoS attack, this timer will keep getting reset.


If this value is set, an email will be sent to the address specified whenever an IP address becomes blacklisted. A locking mechanism using /var/lock/mod_evasive prevents continuous emails from being sent.
Note: Requires /bin/mail (provided by mailx)


If this value is set, the system command specified will be executed whenever an IP address becomes blacklisted. This is designed to enable system calls to ip filter or other tools. Use %s to denote the IP address of the blacklisted IP.


Choose an alternative temp directory. By default, “/tmp” will be used for the locking mechanism, which opens some security issues if your system is open to shell users. refer to =>


IP addresses of trusted clients can be whitelisted to ensure they are never denied. The purpose of whitelisting is to protect software, scripts, local searchbots, or other automated tools from being denied for requesting large amounts of data from the server. Whitelisting should not be used to add customer lists or anything of the sort, as this will open the server to abuse. This module is very difficult to trigger without performing some type of malicious attack, and for that reason, it is more appropriate to allow the module to decide on its own whether or not an individual customer should be blocked.
To whitelist an address (or range), add an entry to the Apache configuration in the following fashion:

DOSWhitelist    127.0.0.*
Wildcards can be used on up to the last three octets if necessary. Multiple DOSWhitelist commands may be used in the configuration.


mod_evasive comes with a PERL script called Without editing the file, if you execute it, it will send a total of 100 requests for incrementing URLs (based on 0-100) to the localhost address on port 80.

# small script to test mod_evasive's effectiveness
use IO::Socket;
use strict;

for(0..100) {
 my($SOCKET) = new IO::Socket::INET( Proto   => "tcp",
 PeerAddr=> "");

 if (! defined $SOCKET) { die $!; }
 print $SOCKET "GET /?$_ HTTP/1.0\n\n";
 $response = <$SOCKET>;
 print $response;

If you run the script, you should see output similar to the following:

# ./

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 200 OK

HTTP/1.1 403 Forbidden

HTTP/1.1 403 Forbidden

HTTP/1.1 403 Forbidden

HTTP/1.1 403 Forbidden

HTTP/1.1 403 Forbidden


See HTTP headers on the command line !

You can view HTTP headers on the command line simply by firing up a terminal session and using wget:

#wget -S -O /dev/null

The majuscule “S” gets you the headers and the “-O /dev/null” dumps the file you’re about to retrieve in the bit bucket (rather than into your home directory or where ever). The output you get looks something like this:

[nasser@Zapata /tmp]$ wget -S -O /dev/null                     
Resolving,,, ...
Connecting to||:80... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Server: nginx
  Date: Thu, 11 Jun 2009 09:14:44 GMT
  Content-Type: text/html; charset=UTF-8
  Connection: close
  Vary: Cookie
  X-hacker: If you're reading this, you should visit and apply to join the fun, mention this header.
Length: unspecified [text/html]
Saving to: `/dev/null'

    [                                                                                                                  ] 64,529      45.2K/s   in 1.4s   

13:44:41 (45.2 KB/s) - `/dev/null' saved [64529]

Hide PHP version (X-Powered-By) Header

In your php.ini (based on your Linux distribution this can be found in various places, like /etc/php.ini, /etc/php5/apache2/php.ini, etc.) locate the line containing “expose_php On” and set it to Off:

expose_php = Off

After making this change PHP will no longer add it’s signature to the web server header. Doing this, will not make your server more secure… it will just prevent remote hosts to easily see that you have PHP installed on the system and what version you are running.

Linux as a Solaris JumpStart Server

Copying the install media to the server
Pick a location to put the cd images, /home/jumpstart in my case. Then create it and an install and config subdirectory. The config dir is only necessary if you intend to want to do non-interactive jumpstarts.

mkdir -p /home/jumpstart/install
mkdir /home/jumpstart/config

In order to run the setup_install_server script you’ll need to create a “/bin/bar” symlink to “/bin/tar” as the scripts calls a tar-a-like to do the copying.

ln -s /bin/tar /bin/bar

For Solaris 10 you also need to create a /bin symlink for sed, adb to gdb, and a copy of the Solaris “mach” script.

ln -s /bin/sed /usr/bin/sed
ln -s /usr/bin/gdb /usr/bin/adb

echo "#!/bin/bash" > /bin/mach
echo "uname -p" >> /bin/mach
chmod +x /bin/mach

Mount Solaris CD 1 / the Solaris DVD, and use the setup_install_server script. Then run the setup_install_server script.

mount /mnt/cdrom

cd /mnt/cdrom/Solaris_10/Tools
./setup_install_server /home/jumpstart/install
cd /
umount /mnt/cdrom 

Set up the NFS server

If you’ve not already done so, install rarpd, bootparamd and tftpd. I’m assuming you’re using the kernel nfsd here.

Set up the NFS export. Put the follwing in /etc/exports, but use appropriate values for your site. The config export is optional, depending on wether you want to use non-interactive jumpstart or not.



For newer versions of the linux nfsd, nfsv4 may well be enabled by default. It’s probably easier to disable it – add ” –no-nfs-version 4″ to the nfsdparameters, however your Linux distribution chooses to do that.

Set up the server for the client

This is where it gets a little fiddly, for each install client you need an entry in /etc/hosts, /etc/ethers and /etc/bootparams and a symlink to the appropriate kernel in /tftpboot


This one is easy, you need the hostname and its IP address. Put it in /etc/hosts in the following format: jumpstartclient

Also, ensure that your server’s hostname is *not* listed against If it is, remove it from that line and give it its own line, so your hosts file looks like this (where jumpstartserver is your server). localhost.localdomain localhost jumpstartserver jumpstartclient


This is so that rarpd can respond to the client’s request for an IP address. It does this by resolving it’s MAC address to a hostname, and uses /etc/hosts to turn that in to an IP. In /etc/ethers:

8:0:20:7a:a3:f2 jumpstartclient


This is the config so the client knows where to access the install image and configurations. In /etc/bootparams, where jumpstartserver is my jumpstart server:

jumpstartclient root=jumpstartserver:/home/jumpstart/install/Solaris_10/Tools/Boot \
install=jumpstartserver:/home/jumpstart/install \
boottype=jumpstartserver:in \

sysid_config=jumpstartserver:/home/jumpstart/install/Solaris_10/Tools/Boot/etc \
install_config=jumpstartserver:/home/jumpstart/config \


This is the really fiddly bit. Either you calculate the client’s IP address in hex format, or you use tcpdump to determine what it’s requesting.

This is becase the client will request an inetboot file from the tftp server. It will be named in the format HEXIPADDR.ARCH or just HEXIPADDR (some machines do not request the .ARCH part of the filename). In my case, it is C0A80104.SUN4U. So if, like me you don’t fancy calculating this name, start the bootparamd and the rarpd (you may need to start the rarpd with -e as some versions will not respond to rarp queries if there is not a corresponding image in /tftpboot to serve.

 perl -e 'printf "%02x"x4 ."\n",192,168,1,4;'|tr a-z A-Z 

will give you the hex address (where the IP is

Similarly, you can do it in shell like this:

printf %02x 192 168 1 4|tr [:lower:] [:upper:] 

Once your services are started, get tcpdump on the go (this is best done on a quiet or switched network, and boot net – install your client. tcpdump should produce a line like this:

08:59:24.640821 jumpstartclient.40337 > 23 RRQ “C0A80104.SUN4U”

Alternativley, running bootparamd with -d and -s flags should write the filename being requested to the syslog

Once you have this filename, you can copy the appropriate inetboot image from your /home/jumpstart/install hierachy. The example below is appropriate for a sun4m architecture machine, modify it for other systems

cp /home/jumpstart/install/Solaris_10/Tools/Boot/usr/platform/sun4m/lib/fs/nfs/inetboot /tftpboot/inetboot.sun4u

cd /tftpboot
ln -s inetboot.sun4u C0A80104.SUN4U
ln -s inetboot.sun4u C0A80104  

Jumpstart the client

Stop-A the client and get it to the openboot prompt. From there type either:

boot net - install 

Thanks to :

Installing a Solaris JumpStart server