Linux as an Ethernet Bridge

It passes packets like a bridge and filters like a firewall. Put extra security and versatility in front of any server or device, without reconfiguring it.

Have you ever been asked to secure a router over which you did not have administrative control? What about when you are on a network you don't own but want to secure the segment are you using? A request similar to this one is what brought me to the wonderful world of Bridge, the Linux Ethernet bridging project.

According to the Bridge Web site:

Ethernet bridging is a way to connect networks together to form a larger network. The standard for bridging is ANSI/IEEE 802.1d. A bridge is a way to connect two separate network segments together in a protocol-independent way. Packets are forwarded based on Ethernet address, rather than IP address (like a router). Since forwarding is done at Layer 2, all protocols can go transparently through a bridge.

The code currently is maintained by Stephen Hemminger for both the Linux 2.4 and 2.6 kernels. Most modern distributions using the 2.6 series kernel have the bridging code built in. For the purposes of this article, we are using Fedora Core 3, which is built on the 2.6 kernel. If you're stuck with the 2.4 kernel, don't despair. Kernel patches are available on the Bridge site (see the on-line Resources), so you can play too.

The firewall component of the bridging firewall is achieved by using another related project called ebtables. The ebtables program is a filtering layer for a bridging firewall. The filtering connects into the Link Layer Ethernet frame field. In addition to filtering, you also may manipulate the Ethernet MAC addresses. The ebtables code also allows iptables rules to function in bridging mode, giving you both IP- and MAC-level filters for your firewall.

What Is a Bridge?

A bridge is a device that links two or more network segments that use the same network technologies. The topologies may differ, though, so you can go from fiber to copper, but the technologies must remain the same. In its most simple form, think of a Linux hub. Add as many ports to the box as you want, and they all become part of the single hub device. What comes in one port goes out all of the other ports in the hub fabric, unless you state otherwise in the rules. Once your hub is up, you can use iptables and ebtables to filter traffic as you would any other Linux forwarding system.

Getting Started

We start out simply by attempting to achieve connectivity between a simple two-NIC machine. When we are finished, this Linux box should act as a standard hub, passing traffic from one port to another as needed. When we plug one NIC in to our regular network jack and a laptop into the second NIC, we will be able to use the network from the laptop as if we were connected directly.


Figure 1. In this simple network, the Linux system acts like an Ethernet hub, passing all traffic.

We want this bridge to be transparent to any device plugged in to it. Interestingly enough, beyond the ability to connect remotely to the bridge to maintain it and check logs, there is no requirement to give the bridge an IP address. Of course, in today's connected world it makes sense to assign an IP address and we do so here.

I started with an old box that has been waiting for a project such as this. It's an AMD K6-450 with 256MB of RAM. It has a single 15GB IDE hard drive and a single 3Com 10/100MB Ethernet card. I also had a spare 3Com 10/100MB Ethernet card that works well with Linux, so it is added as the second interface. I am going to run only the bridge software, some simple firewall rules and perhaps Snort for intrusion detection. The traffic volumes are low and I don't expect massive amounts of Snort data, so 256MB of RAM should suffice. If you're going to be passing gigabit traffic and want to sniff live, ramp up the specs of the machine considerably.

Now install Fedora Core 3, selecting the extras you feel are needed. If you work in high-security environments, I recommend keeping your software options to the bare minimum. You always can grab extras later with YUM if you forget something. For now, simply get a working Linux install going and make sure that it finds your network cards. You need the kernel source and usual compile utilities to make the ebtables code, so add those in. Remember to stay secure and remove any software you don't need once you place the device into production. Once the install completes, reboot and log in as root.

Now you are ready to create a virtual network device. You can call it whatever you want; I went with br0—the first bridge device:

#> brctl addbr br0

Run ifconfig. Do you see your network interfaces (Listing 1)?

Listing 1. Before configuring the network, check that both Ethernet interfaces are up.

#> ifconfig
 
eth0      Link encap:Ethernet  HWaddr 00:CC:D0:99:EB:26
          inet6 addr: fe80::2b0:d0ff:fe99:eb26/64 Scope:Link
          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
          RX packets:86208855 errors:0 dropped:0 overruns:63 frame:0
          TX packets:77098217 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:3871506445 (3692.1 Mb)  TX bytes:266311184 (253.9 Mb)
          Interrupt:5 Base address:0xec00
 
eth1      Link encap:Ethernet  HWaddr 00:CC:03:D8:3A:1A
          inet6 addr: fe80::201:3ff:fed8:3a1a/64 Scope:Link
          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
          RX packets:77087614 errors:0 dropped:0 overruns:0 frame:0
          TX packets:85110321 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:264995582 (252.7 Mb)  TX bytes:3672580334 (3502.4 Mb)
          Interrupt:9 Base address:0xec80

In Listing 1, you can see that we have two network cards with no IP addresses bound to them. If you have IP addresses assigned to the interface, remove them for simplicity's sake. On Fedora, edit the file /etc/sysconfig/networking-scripts/ifcfg-X, where X is the card identifier. On my system, the two interfaces are eth0 and eth1. Delete or comment out the lines that relate to the IP address. It is important to make sure the cards are on at boot time. Listing 2 shows a basic configuration that should work. Don't forget to reinitialize networking once you've completed the above, using service network reload.

Listing 2. Two Simple Config Files for Network Cards with No IP Addresses

/etc/sysconfig/networking-scripts/ifcfg-eth0:
 
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
 
 
/etc/sysconfig/networking-scripts/ifcfg-eth1:
 
DEVICE=eth1
ONBOOT=yes
BOOTPROTO=static

Next, tell the system what devices belong to this group, as shown below. Also, give the command that actually initializes the virtual device, as shown in the last line:

#> brctl addif br0 eth0
#> brctl addif br0 eth1
#> ip link set br0 up

In its most basic form, your Linux box now is acting like a hub. For the keen ones, you can plug in the Ethernet adapters and begin to play. The box itself, however, currently is passing traffic blindly and does not have an IP address assigned to it. I like to be able to connect remotely to my devices after I install them, so I am going to add an IP address and some routing information to the virtual device br0.

To add an IP address to the bridge interface, issue:

#> ip addr add 10.1.1.18/16 brd + dev br0

I had to state both the subnet mask (/16) and which bridge device it should be assigned to. This becomes important if you have more than one virtual device on the machine. I have only the one, but the syntax requires it. If you named your bridge device something else, you need to state that explicitly here.

The last thing to do before you can play with your bridge remotely is to configure the routing:

#> route add default gw 10.1.1.1 dev br0

The usual routing rules and commands apply, and for all intents and purposes you can use the device (br0) as you would any other Linux network interface.

Testing

Now that we have everything in place, let's test it out. First, let's confirm that all of our configurations have taken hold:

#> brctl show
bridge name  bridge id          STP enabled  interfaces
br0          8000.0030843e5aa2  no           eth0
                                             eth1

As you can see above, we have a single bridge device called br0 that uses interfaces eth0 and eth1. This confirms that we should be in business.

Installation

Now it's time to do the physical setup. Connect one network card to your network switch as you would normally do for any other computer. You should see link lights on both ends of the link. Connect a desktop or laptop to the other interface on your Linux box using a crossover cable. Wait for the link lights to come on, count to ten and ping another node on your network from your desktop or laptop. You should be able to use the network on the other side of the Linux hub as if it was attached directly.

Surviving a Reboot

How you set up your install to survive a reboot is your choice. A simple way is to add all of the commands we have used to /etc/rc.local, which is processed at the end of startup. Enter the commands used above to this file, and your bridge is functional after startup.

Firewalling

As with any Linux install that passes or forwards traffic, you have the ability to filter the stream of information as it passes by. A bridging firewall is no different. There are many ways to create and maintain firewall configurations. Below, I explain how to use the most basic firewall type: deny all, pass some. We want to deny everything passing this firewall unless we specifically state that something is allowed.

This firewall configuration requires you to download and install the ebtables user-space tools available from the ebtables Web site (see Resources). At the time of this writing, the latest release was v2.0.6. Grab a copy of this from one of the many mirrors. Do the usual extract and install dance without the initial configure step:

#> tar -xzf ebtables-v2.0.6.tar.gz
#> cd ebtables-v2.0.6
#> make
#> install

If all goes well, you should have the ebtables command set at your fingertips. Test this by typing ebtables at the prompt; you should see something similar to this:

#> ebtables -V
ebtables v2.0.6 (November 2003)

Let's start by making sure iptables is set to accept. Remember we're on Fedora Core 3, so we simply can tell the service to quit, which does the same thing:

#> service iptables stop
#> chkconfig --level 35 iptables off

You can do something similar by issuing the flush command. List your available chains and then flush each of them in turn:

#> iptables -L
#> iptables -F INPUT
#> iptables -F OUTPUT
#> iptables -F FORWARD
#> iptables -F RH-Firewall-1-INPUT

Now we want to stop all traffic from all areas of our network from passing through the firewall. The following rules are specific to the network we're working with for this example; you need to amend the subnets or hosts to reflect your specific requirements:

 
/sbin/ebtables -A FORWARD -p IPv4 --ip-source 10.2.0.0/16 -j DROP
/sbin/ebtables -A FORWARD -p IPv4 --ip-source 10.7.0.0/16 -j DROP
/sbin/ebtables -A FORWARD -p IPv4 --ip-source 10.4.0.0/16 -j DROP
/sbin/ebtables -A FORWARD -p IPv4 --ip-source 10.5.0.0/16 -j DROP
/sbin/ebtables -A FORWARD -p IPv4 --ip-source 10.6.0.0/16 -j DROP
/sbin/ebtables -A FORWARD -p IPv4 --ip-source 10.1.0.0/16 -j DROP
 

Those of you familiar with iptables should notice that the syntax above is similar. We tell the ebtables program that when FORWARDING using the IPv4 protocol to DROP any packets sourced from the 10.1.0.0/16 subnet. We then tell it to repeat for the rest of the subnets.

The next step is to allow the device behind the firewall itself. If you do not allow its IP address to pass through, nothing works. Also, if you assign an IP address to the firewall itself, don't forget to allow it as well:

/sbin/ebtables -I FORWARD 1 -p IPv4 --ip-source 10.1.1.5 -j ACCEPT
/sbin/ebtables -I FORWARD 1 -p IPv4 --ip-source 10.1.1.18 -j ACCEPT

Here, I add the devices on my network that are allowed to access my laptop:

 
/sbin/ebtables -I FORWARD 1 -p IPv4 --ip-source 10.1.10.30 -j ACCEPT
/sbin/ebtables -I FORWARD 1 -p IPv4 --ip-source 10.1.10.19 -j ACCEPT
/sbin/ebtables -I FORWARD 1 -p IPv4 --ip-source 10.1.10.87 -j ACCEPT
 

To test this, I simply go to a machine listed in the ACCEPT rules above and see if I can ping my laptop at 10.1.1.5. Now move to a node not listed above—no pings for you!

Real-World Implementation

Recently, I was called to a customer's site to secure a financial server. The request was simple: we need a firewall in front of this system but we cannot change its IP address. With two NICs and a Linux OS, I was able to have a working firewall up and running in a few minutes. Installation also was a breeze. I simply used a crossover cable that connected the firewall to the server and a regular cable from the other network card on the firewall to the network jack. That was it. No redesign was necessary of any part of the existing IP scheme; it truly was plug-and-play. Once a few rules were in place to drop all packets unless they were from the IP addresses and ports listed as acceptable, the project was completed.

One of the beautiful aspects of Linux is its ability to run many services on one system. Take the above example. I quickly firewalled a sensitive server, but that was not the end of the project. With all the extra time and money we saved using Linux, we were able to load Snort on the firewall. With a quick hack to the sniffer's config file—/etc/snort.conf in our case—we told Snort to listen to interface br0, and snort immediately began to do its stuff on the bridging interface.

This is where the true power of the bridging code can be felt. Ever had a segment of the network running slow but you don't know why? Next time, load a Linux box with Snort and any other sleuthing software you like and get the bridge up and running. Find your trusty crossover cable and head out to the site. Because the bridge acts like a hub, you simply can insert your Linux box at any point in the network. As long as you have the physical connections, you can drop your box in and begin to sniff live in a matter of seconds. The latest project we have been working on included transparent Squid cache servers that are truly transparent requiring zero reconfiguration to the IP scheme, clients or browsers. Simply insert the Squid box in front of the router and redirect all port 80 traffic to the box itself and you're done.

The ability of Linux to slide transparently into existing network infrastructure opens a world of new and improved services that the penguin can provide. With the ability to place dissimilar networking devices into one virtual entity, you can use a single device to firewall and monitor any aspect of your network. You're only limitation is the speed of your hardware and its number of available slots.

Continue reading Linux as an Ethernet Bridge

Installing phpMyAdmin on Linux

phpMyAdmin is a utility written in PHP which is intended to aid in the administration of a MySQL server, either locally, or over the WWW. It is maintained through the hard work and dedication of the folks at The phpMyAdmin project, and is currently available in 47 different languages...

Some of its current capabilities include the ability to create and drop databases, create , drop, and alter tables, execute SQL statements, delete, edit, and add fields, manage keys on fields, and manage privileges. In addition, it has the ability to export your data in a number of different formats. phpMyAdmin is an excellent tool and will make the life of any MySQL database administrator much more enjoyable.

This short tutorial assumes you already have Apache, MySQL, and PHP installed correctly and functioning, and will not cover those installations. Also, the machine being used for this example is running Fedora Core 1, so your mileage may vary depending on your Linux distro of choice and how the above mentioned packages were installed, however, unless you did something strange, you should find most installs similar. Lastly, it assumes you can use a text editor for basic editing tasks.

So lets get started !

Installation


First things first, we need to get the latest version of phpMyAdmin, at the time this tutorial was written the latest stable version was 2.11.5-pl1, and you can get it at:

#wget http://prdownloads।sourceforge।net/phpmyadmin/phpMyAdmin-२.11.5-english.tar.gz?download

Grab the download, then open a terminal window and do the following:

Change to the directory where you saved the downloaded file , such as:

$cd mydownloads

Cool, now we need to move the file to the root directory of your Apache webserver, which is usually /usr/local/apache/htdocs, also, root usually owns the Apache directory structure so you'll need to do the rest as root, so...

$su
$password

Now, lets move the file to where we need it:

#mv
phpMyAdmin-२.11.5-english.tar.gz /usr/local/apache/htdocs

Done, now make the Apache root directory your working directory:

#cd /usr/local/apache/htdocs

Cool, now lets unpack the file:

#tar -zxf
phpMyAdmin-२.11.5-english.tar.gz

That will take a second, then, when the machine returns the prompt, do a directory listing:

#ls

You should see a new directory which has been created called phpMyAdmin-2.11.5-pl1, assuming you do go ahead and get rid of the original file:

#rm
phpMyAdmin-२.11.5-english.tar.gz

Now, the new directory name is a bit long, and definatley not something you want to type in all the time, so lets make it easier:

#mv phpMyAdmin-2.11.5-pl1 phpmyadmin

Cool, now you've renamed the directory to something a little easier to remember, now make that your working directory:

#cd phpmyadmin

Configuration


Now, what we need to do is edit the config.inc.php file so it works with your setup. So using vi, or whatever your favorite editor happens to be, open config.inc.php, find the following lines, and edit them as appropriate for your setup:

$cfg['PmaAbsoluteUri'] = ''; (Default)
$cfg['PmaAbsoluteUri'] = 'http://www.yoursite.com/phpmyadmin/'; (Edited)

$cfg['Servers'][$i]['user'] = 'root'; (Default)
$cfg['Servers'][$i]['user'] = 'your_MySQL_root_user'; (Edited)

$cfg['Servers'][$i]['password'] = ''; (Default)

$cfg['Servers'][$i]['password'] = 'your_password'; (Edited)

Thats it, save the file and close it.

Now, lets see if it works, open a browser and point it to phpMyAdmin by using your site info such as www.yoursite.com/phpmyadmin, or, localhost/phpmyadmin if you are only working locally. If all is well you should see the welcome screen for phpMyAdmin , if you don't, then check your logs and remember, Google is your friend. If you see a page full of PHP errors, make sure you used the correct username and password when you edited the lines mentioned above.

Now, knowing what this cool program is capable of, its probably not something you want just anyone to be able to access, luckily we can take care of that very easily using Apache's authentication process, so lets do it!

Still as root make a directory to store the password file we will be creating:

#mkdir /usr/local/apache/passwd

Now, lets create the file and add an allowed user:

#/usr/local/apache/bin/htpasswd -c /usr/local/apache/passwd/authpass myphp

htpasswd will prompt you for the password you would like to assign to this user, once entered, it will create the file authpass and populate it with the information for the user called myphp. You can use whatever names you like, this is only an example.

Now the final step, change to your Apache configuration directory:

#cd /usr/local/apache/conf

And again using your favorite editor, open the file named httpd.conf and find the following section:


Options FollowSymLinks
AllowOverride None


Directly under this section add the following (assuming you used the names from the example above):


AuthType Basic
AuthName "myphp"
AuthUserFile /usr/local/apache/passwd/authpass
Require user myphp


Thats it, save the file and close it, then restart Apache by issuing the following command:

#/usr/local/apache/bin/apachectl restart

Perfect, now fire up your browser again and point it back to your phpMyAdmin site, this time you should be prompted for a username and password before being allowed access to the site. Enter the required information, and you are in business!

That brings us to the end of this tutorial, hopefully you found this information helpful, and Good Luck!
Continue reading Installing phpMyAdmin on Linux

How to install KISS Firewall

Brief Summary

KISS My Firewall is a FREE iptables script designed for a typical web server. It takes advantage of the latest firewall technologies including stateful packet inspection and connection tracking. It also contains some preventative measures for port scanning, DoS attacks, and IP spoofing, among other things.

KISS My Firewall 2 is very easy to install and does not require any initial configuration. It will work with any stock installation of Ensim WEBppliance Basic & Pro, Plesk, and Webmin. Cpanel installations require some modifications. Available at: http://www.geocities.com/steve93138/

What's New in Version 2?

The biggest change is that it does not require any initial configuration. With version 2, you won't automatically lock yourself out of your server unless you set some of the variables incorrectly. It also does extensive error checking and is distributed as a tar file. This solves a lot of the issues that were present with the older version. In addition, version 2 is highly configurable and was tested to work with the latest version of iptables - version 1.2.8.



HOW TO: Install KISS My Firewall

1) When logged in as root ( "su -" ), type:

2) cd /usr/bin

3) Download KISS firewall
wget http://www.geocities.com/steve93138/kiss-2.0.1.tar.gz

4) Extract it
tar zxvf kiss-2.0.1.tar.gz

If you want to block an offenders IP address/subnet, simply edit the BLOCK_LIST variable in the /usr/bin/kiss file. You can separate IP addresses and subnet's with a space. Once you are finished, restart the firewall.

5) Editing the config
pico -w /usr/bin/kiss

You must change config from: NOTE see our Printer friendly version to avoid text wrapping!

# Uncomment to allow DNS zone transfers
#
#$IPTABLES -A INPUT -i eth0 -p udp --sport 53 --dport 53 -m state --state NEW -j ACCEPT
#$IPTABLES -A INPUT -i eth0 -p tcp --sport 53 --dport 53 -m state --state NEW -j ACCEPT
#$IPTABLES -A OUTPUT -o eth0 -p udp --sport 53 --dport 53 -m state --state NEW -j ACCEPT
#$IPTABLES -A OUTPUT -o eth0 -p tcp --sport 53 --dport 53 -m state --state NEW -j ACCEPT

To:

# Uncomment to allow DNS zone transfers
#
$IPTABLES -A INPUT -i eth0 -p udp --sport 53 --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A INPUT -i eth0 -p tcp --sport 53 --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -o eth0 -p udp --sport 53 --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -o eth0 -p tcp --sport 53 --dport 53 -m state --state NEW -j ACCEPT

6) Cpanel Users Config - other users ignore this step
In the /usr/bin/kiss file scroll down until you see the line: TCP_IN and replace it with this.

TCP_IN="20 21 25 53 80 110 143 443 995 2082:2083 2086:2087 2095:2096 3306"

Now find the line that says TCP_OUT and replace it with this.

TCP_OUT="21 22 25 37 43 53 80 443 873 2089"

7) Save the changes and restart the firewall
Ctrl + X then Y

Restart KISS by typing:
kiss restart

That's it! You now have a nice IPtables firewall running that's easy to configure and use.

Firewall Commands
That's it! To get it running anywhere on the command line, you simply type:
kiss start

To stop the firewall, type:
kiss stop

To get status information, type:
kiss status

Restart KISS by typing:
kiss restart

Continue reading How to install KISS Firewall

Configure Web Logs in Apache

Author's Note: While most of this piece discusses configuration options for any operating system Apache supports, some of the content will be Unix/Linux (*nix) specific, which now includes Macintosh OS X and its underlying Unix kernel.

One of the many pieces of the Website puzzle is Web logs. Traffic analysis is central to most Websites, and the key to getting the most out of your traffic analysis revolves around how you configure your Web logs. Apache is one of the most -- if not the most -- powerful open source solutions for Website operations. You will find that Apache's Web logging features are flexible for the single Website or for managing numerous domains requiring Web log analysis.

For the single site, Apache is pretty much configured for logging in the default install. The initial httpd.conf file (found in /etc/httpd/conf/httpd.conf in most cases) should have a section on logs that looks similar to this (Apache 2.0.x), with descriptive comments for each item. Your default logs folder will be found in /etc/httpd/logs . This location can be changed when dealing with multiple Websites, as we'll see later. For now, let's review this section of log configuration.



ErrorLog logs/error_log

LogLevel warn

LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

CustomLog logs/access_log combined

Error Logs

The error log contains messages sent from Apache for errors encountered during the course of operation. This log is very useful for troubleshooting Apache issues on the server side.

Apache Log Tip: If you are monitoring errors or testing your server, you can use the command line to interactively watch log entries. Open a shell session and type "tail –f /path/to/error_log" . This will show you the last few entries in the file and also continue to show new entries as they occur.

There are no real customization options available, other than telling Apache where to establish the file, and what level of error logging you seek to capture. First, let's look at the error log configuration code from httpd.conf.

ErrorLog logs/error_log

You may wish to store all error-related information in one error log. If so, the above is fine, even for multiple domains. However, you can specify an error log file for each individual domain you have. This is done in the container with an entry like this:


DocumentRoot "/home/sites/domain1/html/"
ServerName domain1.com
ErrorLog /home/sites/domain1/logs/error.log

If you are responsible for reviewing error log files as a server administrator, it is recommended that you maintain a single error log. If you're hosting for clients, and they are responsible for monitoring the error logs, it's more convenient to specify individual error logs they can access at their own convenience.

The setting that controls the level of error logging to capture follows below.

LogLevel warn

Apache's definitions for their error log levels are as follows:

Tracking Website Activity

Often by default, Apache will generate three activity logs: access, agent and referrer. These track the accesses to your Website, the browsers being used to access the site and referring urls that your site visitors have arrived from.

It is commonplace now to utilize Apache's "combined" log format, which compiles all three of these logs into one logfile. This is very convenient when using traffic analysis software as a majority of these third-party programs are easiest to configure and schedule when only dealing with one log file per domain.

Let's break down the code in the combined log format and see what it all means.

LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined

LogFormat starts the line and simply tells Apache you are defining a log file type (or nickname), in this case, combined. Now let's look at the cryptic symbols that make up this log file definition.




To review all of the available configuration codes for generating a custom log, see Apache's [1] docs on the module_log_config , which powers log files in Apache.

Apache Log Tip: You could capture more from the HTTP header if you so desired. A full listing and definition of data in the header is found at the World Wide Web Consortium [2] .

For a single Website, the default entry would suffice:

CustomLog logs/access_log combined

However, for logging multiple sites, you have a few options. The most common is to identify individual log files for each domain. This is seen in the example below, again using the log directive within the container for each domain.


DocumentRoot "/home/sites/domain1/html/"
ServerName domain1.com
ErrorLog /home/sites/domain1/logs/error.log
CustomLog /home/sites/domain1/logs/web.log



DocumentRoot "/home/sites/domain2/html/"
ServerName domain2.com
ErrorLog /home/sites/domain2/logs/error.log
CustomLog /home/sites/domain2/logs/web.log



DocumentRoot "/home/sites/domain3/html/"
ServerName domain3.com
ErrorLog /home/sites/domain3/logs/error.log
CustomLog /home/sites/domain3/logs/web.log


In the above example, we have three domains with three unique Web logs (using the combined format we defined earlier). A traffic analysis package could then be scheduled to process these logs and generate reports for each domain independently.

This method works well for most hosts. However, there may be situations where this could become unmanageable. Apache recommends a special single log file for large virtual host environments and provides a tool for generating individual logs per individual domain.

We will call this log type the cvh format, standing for "common virtual host." Simply by adding a %v (which stands for virtual host) to the beginning of the combined log format defined earlier and giving it a new nickname of cvh, we can compile all domains into one log file, then automatically split them into individual log files for processing by a traffic analysis package.

LogFormat "%v %h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" cvh

In this case, we do not make any CustomLog entries in the containers and simply have one log file generated by Apache. A program created by Apache called split_logfile is included in the src/support directory of your Apache sources. If you did not compile from source or do not have the sources, you can get the Perl script [3] .

The individual log files created from your master log file will be named for each domain (virtual host) and look like: virtualhost.log.

Log Rotation

Finally, we want to address log rotation. High traffic sites will generate very large log files, which will quickly swallow up valuable disk space on your server. You can use log rotation to manage this process.

There are many ways to handle log rotation, and various third-party tools are available as well. However, we're focusing on configurations native to Apache, so we will look at a simple log rotation scheme here. I'll include links to more flexible and sophisticated log rotation options in a moment.

This example uses a rudimentary shell script to move the current Web log to an archive log, compresses the old file and keeps an archive for as long as 12 months, then restarts Apache with a pause to allow the log files to be switched out.

mv web11.tgz web12.tgz
mv web10.tgz web11.tgz
mv web9.tgz web10.tgz
mv web8.tgz web9.tgz
mv web7.tgz web8.tgz
mv web6.tgz web7.tgz
mv web5.tgz web6.tgz
mv web5.tgz web6.tgz
mv web4.tgz web5.tgz
mv web3.tgz web4.tgz
mv web2.tgz web3.tgz
mv web1.tgz web2.tgz
mv web.tgz web1.tgz
mv web.log web.old
/usr/sbin/apachectl graceful
sleep 300
tar cvfz web.tgz web.old

This code can be copied into a file called logrotate.sh , and placed inside the folder where your web.log file is stored (or whatever you name your log file, e.g. access_log, etc.). Just be sure to modify for your log file names and also chmod (change permissions on the file) to 755 so it becomes an executable.

This works fine for a single busy site. If you have more complex requirements for log rotation, be sure to see some of the following sites. In addition, many Linux distributions now come with a log rotation included. For example, Red Hat 9 comes with logrotate.d , a log rotation daemon which is highly configurable. To find out more, on your Linux system with logrotate.d installed, type man logrotate .

Log Rotation Sites

For more information on log roation, see:

Continue reading

What is APF (Advanced Policy Firewall)?

APF Firewall
APF is a policy based iptables firewall system designed for ease of use and configuration. It employs a subset of features to satisfy the veteran Linux user and the novice alike. Packaged in tar.gz format and RPM formats, make APF ideal for deployment in many server environments based on Linux. APF is developed and maintained by R-fx Networks: http://www.rfxnetworks.com/apf.php

This guide will show you how to install and configure APF firewall, one of the better known Linux firewalls available.10

Limit SSH connections to one IP with APF in this advanced tutorial

Requirements:

- Root SSH access to your server

Lets begin!
Login to your server through SSH and su to the root user.


1. cd /root/downloads or another temporary folder where you store your files.

2. wget http://www.rfxnetworks.com/downloads/apf-current.tar.gz

3. tar -xvzf apf-current.tar.gz

4. cd apf-0.9.5-1/ or whatever the latest version is.

5. Run the install file: ./install.sh


You will receive a message saying it has been installed

Installing APF 0.9.5-1: Completed.

Installation Details:
Install path: /etc/apf/
Config path: /etc/apf/conf.apf
Executable path: /usr/local/sbin/apf
AntiDos install path: /etc/apf/ad/
AntiDos config path: /etc/apf/ad/conf.antidos
DShield Client Parser: /etc/apf/extras/dshield/

Other Details:

Listening TCP ports: 1,21,22,25,53,80,110,111,143,443,465,993,995,2082,2083,2086,2087,2095,2096,3306

Listening UDP ports: 53,55880

Note: These ports are not auto-configured; they are simply presented for information purposes. You must manually configure all port options.

6. Lets configure the firewall: pico /etc/apf/conf.apf
We will go over the general configuration to get your firewall running. This isn't a complete detailed guide of every feature the firewall has. Look through the README and the configuration for an explanation of each feature.

We like to use DShield.org's "block" list of top networks that have exhibited
suspicious activity.
FIND: USE_DS="0"
CHANGE TO: USE_DS="1"

7. Configuring Firewall Ports:

Cpanel Servers
We like to use the following on our Cpanel Servers

Common ingress (inbound) ports
# Common ingress (inbound) TCP ports -3000_3500 = passive port range for Pure FTPD
IG_TCP_CPORTS="21,22,25,53,80,110,143,443,2082,2083, 2086,2087, 2095, 2096,3000_3500"
#
# Common ingress (inbound) UDP ports
IG_UDP_CPORTS="53"


Common egress (outbound) ports
# Egress filtering [0 = Disabled / 1 = Enabled]
EGF="1"

# Common egress (outbound) TCP ports
EG_TCP_CPORTS="21,25,80,443,43,2089"
#
# Common egress (outbound) UDP ports
EG_UDP_CPORTS="20,21,53"



Ensim Servers
We have found the following can be used on Ensim Servers - although we have not tried these ourselves as I don't run Ensim boxes.

Common ingress (inbound) ports
# Common ingress (inbound) TCP ports
IG_TCP_CPORTS="21,22,25,53,80,110,143,443,19638"
#
# Common ingress (inbound) UDP ports
IG_UDP_CPORTS="53"


Common egress (outbound) ports
# Egress filtering [0 = Disabled / 1 = Enabled]
EGF="1"

# Common egress (outbound) TCP ports
EG_TCP_CPORTS="21,25,80,443,43"
#
# Common egress (outbound) UDP ports
EG_UDP_CPORTS="20,21,53"


Save the changes: Ctrl+X then Y


8. Starting the firewall
/usr/local/sbin/apf -s

Other commands:
usage ./apf [OPTION]
-s|--start ......................... load firewall policies
-r|--restart ....................... flush & load firewall
-f|--flush|--stop .................. flush firewall
-l|--list .......................... list chain rules
-st|--status ....................... firewall status
-a HOST CMT|--allow HOST COMMENT ... add host (IP/FQDN) to allow_hosts.rules and
immediately load new rule into firewall
-d HOST CMT|--deny HOST COMMENT .... add host (IP/FQDN) to deny_hosts.rules and
immediately load new rule into firewall


9. After everything is fine, change the DEV option
Stop the firewall from automatically clearing itself every 5 minutes from cron.
We recommend changing this back to "0" after you've had a chance to ensure everything is working well and tested the server out.

pico /etc/apf/conf.apf

FIND: DEVM="1"
CHANGE TO: DEVM="0"

10. Configure AntiDOS for APF
Relatively new to APF is the new AntiDOS feature which can be found in: /etc/apf/ad
The log file will be located at /var/log/apfados_log so you might want to make note of it and watch it!

pico /etc/apf/ad/conf.antidos

There are various things you might want to fiddle with but I'll get the ones that will alert you by email.

# [E-Mail Alerts]
Under this heading we have the following:

# Organization name to display on outgoing alert emails
CONAME="Your Company"
Enter your company information name or server name..

# Send out user defined attack alerts [0=off,1=on]
USR_ALERT="0"
Change this to 1 to get email alerts

# User for alerts to be mailed to
USR="your@email.com"
Enter your email address to receive the alerts

Save your changes! Ctrl+X then press Y
Restart the firewall: /usr/local/sbin/apf -r

11. Checking the APF Log

Will show any changes to allow and deny hosts among other things.
tail -f /var/log/apf_log

Example output:
Aug 23
01:25:55 ocean apf(31448): (insert) deny all to/from 185.14.157.123
Aug 23
01:39:43 ocean apf(32172): (insert) allow all to/from 185.14.157.123


12. New - Make APF Start automatically at boot time
To autostart apf on reboot, run this:

chkconfig --level 2345 apf on

To remove it from autostart, run this:

chkconfig --del apf


13. Denying IPs with APF Firewall (Blocking)

Now that you have your shiny new firewall you probably want to block a host right, of course you do! With this new version APF now supports comments as well. There are a few ways you can block an IP, I'll show you 2 of the easier methods.

A) /etc/apf/apf -d IPHERE COMMENTHERENOSPACES
> The -d flag means DENY the IP address
> IPHERE is the IP address you wish to block
> COMMENTSHERENOSPACES is obvious, add comments to why the IP is being blocked
These rules are loaded right away into the firewall, so they're instantly active.
Example:

./apf -d 185.14.157.123 TESTING

pico /etc/apf/deny_hosts.rules

Shows the following:

# added 185.14.157.123 on
08/23/05 01:25:55
# TESTING
185.14.157.123

B) pico /etc/apf/deny_hosts.rules

You can then just add a new line and enter the IP you wish to block. Before this becomes active though you'll need to reload the APF ruleset.

/etc/apf/apf -r

14. Allowing IPs with APF Firewall (Unblocking)

I know I know, you added an IP now you need it removed right away! You need to manually remove IPs that are blocked from deny_hosts.rules.
A)
pico /etc/apf/deny_hosts.rules

Find where the IP is listed and remove the line that has the IP.
After this is done save the file and reload apf to make the new changes active.

/etc/apf/apf -r

B) If the IP isn't already listed in deny_hosts.rules and you wish to allow it, this method adds the entry to allow_hosts.rules

/etc/apf/apf -a IPHERE COMMENTHERENOSPACES
> The -a flag means ALLOW the IP address
> IPHERE is the IP address you wish to allow
> COMMENTSHERENOSPACES is obvious, add comments to why the IP is being removed These rules are loaded right away into the firewall, so they're instantly active.
Example:

./apf -a 185.14.157.123 UNBLOCKING

pico /etc/apf/allow_hosts.rules

# added 185.14.157.123 on 08/23/05 01:39:43
# UNBLOCKING
185.14.157.123


Thanks to R-fx networks for developing and maintaining APF Firewall. Written by Steven Leggett of WebHostGear.com Need help with APF? Visit the WebHostGear Forums

Continue reading What is APF (Advanced Policy Firewall)?

10 Steps to Securing your Server



So many people are getting their own dedicated servers but are completely clueless about security. Usually they leave it up to the company where they purchase it or hire someone. That's fine but make sure you have these 10 items covered.

1) Use a Firewall
Make absolutely sure that your server has a firewall running all the time. A firewall is like a screen door to your porch. It blocks out flies, rodents and other pests but you can still walk out and use your BBQ. If someone ever were to get into your server, which is very very likely, the first thing they're going to try and do is upload something to start a daemon or their own service like an IRC server or use a port to launch attacks to other systems. A firewall with egress and ingress protection can stop both incoming and outgoing attacks even when you're not aware of it. I recommend using APF on Linux systems or TinyFirewall on Windows Servers. These are software firewalls so there's no extra monthly cost like a hardware firewall. For very busy systems a hardware firewall is recommended so it takes the burden off your system CPU/RAM and resources to do the work.

Know what ports are open and why, know how to block and unblock an IP. These are basic things you need to understand in the daily security of your system. If someone from an IP begins a brute force attack you want to know how to stop them, right away. Installing APF Firewall, Preventing Brute Force Attacks, Installing KISS Firewall

2) Update your kernel and OS
Make sure your server is using current, updated software. Use the stable version which has been tested more than any beta and update as soon as possible. An old kernel can lead to an easy target for your server. If you're not sure then ask your provider for the latest update.

3) Monitor Logs
Do you know what logs record which activities? How often are they updated and rotated?
LogWatch is a great tool to email you the daily reports of your systems activity of anything it determines unusual, EG repeated failed logins. Besides using this you should check your logs manually to see what’s up. Tail –f /var/log/messages and view your Apache logs as well. Apache Log Files Explained

4) Backups
I still never understand why no one backs up their data yet you spend hundreds of hours working on your website or application then you absolutely must have a second hard drive for backups or use a remote back up system or a combination of these. Second Hard Drive Means Life or Death

5) Limit Access to a Minimum
Do not give users more access than the absolute minimum they require. Never give them shell access, restrict file access to a bare minimum and leave other services turned off by default until specifically requested and you determine that its safe to do so.

6) Lock down PHP and use Mod_Security with Apache
PHP is actually a large security risk but there are a few things to do to help lock it down. CGI has Suexec,which helps runs proccesess as the user and PHP has something similar called PHPSuexec but there are a few downfalls. You should also use open_base directory protection, have safe_mode on system wide, turn off register_globals, enable_dl and allow_url_open to help lock things down further.

You can use server wide protection with mod_security, a web server filter that can watch all requests to see if they match a rule and react by logging, denying the request or other programs. I highly recommend this on Apache based servers and can be extremely useful in blocking attacks and stopping hackers before they do any damage. Securing Safe Mode , Installing Mod_Security


7) Lock /tmp /var/tmp and /dev/shm partitions
On Linux each partition can have certain access restrictions. Since /tmp /var/tmp and /dev/shm are world writable directories they’re often home to uploads, sessions storage and hacker executables. Since anyone can read-write-excute anything from these directories it becomes a major security concern. With /etc/fstab however you can limit what can be done in these locations. If you see defaults beside the /tmp line remove it and replace it with noexec,nosuid this will stop any executables from being allowed to run. Do the same for /dev/shm and make /var/tmp and shortcut (symbolic link) to /tmp. Securing Your TMP Partition

8) Intrusion Detection System (IDS)
An intrusion detection system or IDS is like a burglar alarm on your server. It keeps a record of which files were changed when and alerts you of anything new or altered. This is critical because hackers usually try to replace binary applications like ps, top, netstat and others. This means when you run this new version of ps or top to see processes running they make it so it actually HIDES their hacker software, even though its running it won’t show up. Some IDS systems include TripWire, Snort and AIDE. Installing Chkrootkit

9) Review Processes Running and Remove Extra Software
You can’t protect a system if you don’t know what’s on it. If a hacker adds an extra process that you see in PS but you wouldn’t notice if you didn’t know what should be there usually. Know what runs on your system and why which user. How does Perl or Apache run, under which user? You can check your processes usually with top or ps auxfww which gives you a tree view. Check these every time you login to your server. Getting started with Shell (SSH) , Common Shell Commands

10) Keep an Eye on the Servers Performance
Know what speed your server is running at and how much bandwidth it uses on a daily basis. If an attacker compromises your system and you don’t know you’ll probably notice the system responding slowly or using a lot of bandwidth. If you don’t know what your system is usually like how will you notice something out of the ordinary. This is all common sense but some people never bother to check until they ask their provider after a system has been slow for 2 weeks – it’s usually to late then. Server Loads Explained

Knowing your system makes you one step ahead of an intruder. Check it often and ask an expert if you’re ever over your head. There are MANY other things you can and should do to ensure your server is secure but these are a few basics that everyone should use.

If you have anything you’d like to add please comment on this article.

Continue reading 10 Steps to Securing your Server

Secure your Server with iptables


Central to securing a Linux server that's connected to the Internet is having a good firewall and specific policies in place. Numerous options exist for those considering firewalls for Linux, however, a free and included solution is onoffer through Netfilter and iptables.

Stateful Firewall

As of Linux kernel 2.4 and above, Netfilter has been included as a kernel extension by the majority of (if not all) Linux distributors. iptables is its counterpart and the tool for managing firewall rules. The duo, which I call simply "iptables", creates a stateful firewall on a Linux desktop or server. "Stateful" refers to the firewall's ability to track the state of packets moving in and out of a server and/or network.

This is an improvement on the former ipchains, through which packet state was not available. Thus, iptables can distinguish between new and existing connections and keep track of traffic. iptables recognizes four kinds of packet states: new, established, related and invalid.

The developer can take any number of routes and options when deploying an iptables firewall: via prepackaged solutions like APF, from within a control panel such as Webmin, which has an iptables module, or by way of a GUI configuration tool such as Firestarter.

For the purpose of this article, we'll focus on securing a single development Web server environment where multiple services are offered. This will be accomplished via configuring iptables manually in a command line text editor (which is traditionally stored at /etc/sysocnfig/iptables).

This also means we will only be discussing the filter table, which is one of three tables in the firewall system (others include Mangle, which manages quality of services issues with packet traffic, and the NAT (network address translation) table).

How iptables Works

iptables executes its rules based on the TCP protocol handshake. When a remote device connects to your server, a packet is sent with a SYN (short for synchronization) bit, which is generally acknowledged with a SYN/ACK (synchronization acknowledged) sent from your server back to the client. The client then acknowledges receipt of this with an ACK, and the network relationship is established.

This terminology has also become more familiar to non-network administrators in recent years due to some well-publicized cases of SYN flooding, which is used to execute denial-of-service attacks. This occurs when a remote malicious host (or hosts) repeatedly sends SYN packets to multiple ports on a server, which the server acknowledges. However, instead of sending an ACK back to open a legitimate connection, the remote malicious host(s) continues sending SYN packets and the server repeatedly attempts to acknowledge them, ultimately clogging bandwidth and system resources, and either severely hampering or blocking all other traffic.

We will look at an option to protect against SYN flooding later, when we configure our server's firewall.

Getting Started

Only the root user can manage iptables, so the usual precautions -- taking action as root -- can cause damage to your server's health if a user is not careful.

iptables may or may not be running on your system. You can check by issuing '/etc/rc.d/init.d/iptables status', which will either list the status of your firewall rules, or return something along the lines of 'firewall is stopped'.

Controlling iptables operations is simple, with options such as start, stop, status and others using the above command.

At this point, we'll assume that you don't have an iptables configuration, and we'll build the rules file from scratch. First, we need to identify the services you wish to enable (i.e. FTP, SSH, mail and HTTP), identify areas of concern (i.e. like SYN flooding) and potentially note any IP addresses whose access you may seek to ban.

If you are using a Red Hat-flavored system, as I am (Fedora Core 3 on a development server), you may find some generic rules in the /etc/sysconfig/iptables file. You will want to back up an existing iptables file if it has been in use. This can be done on the command line via 'cp /etc/sysconfig/iptables /etc/sysconfig/iptables.backup'.

To start building your rules, open that file in your favorite command line editor. I issue 'vi /etc/sysconfig/iptables'; you will press the Insert key or letter I key to start editing. Remember that when you're finished editing, you'll want to press the ESC key and type ':wq' to save the file in Vi.

Allowing Targeted Access

Let's build a set of firewall rules that will allow ftp, and allow ssh only to the IP addresses you specify and some additional ports you may need for other services. We'll break each section down and discuss the details as we go.

One caveat: this firewall example will not be a completely hardened overview for the truly paranoid production box; it's meant to serve as a primer to help you get used to handling basic rules with a solid level of packet filtering.

With the iptables file open in your favorite text editor, begin by setting some basic parameters. Use the following entry:

#My firewall config in /etc/sysconfig/iptables
#It is good practice to comment, initial, and date your config files for the sake of shared #administrative environments and, also, so you remember what has been done in a file.
*filter
:OUTPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:FWALL-INPUT - [0:0]
:INPUT ACCEPT [0:0]
-A INPUT -j FWALL-INPUT

This allows outgoing access from your server, and allows forwarding as well as accepting all incoming traffic (if passing packets through your server is not needed, simply change the FORWARD from ACCEPT to DROP). However, this code forwards all incoming traffic to our firewall rules (FWALL-INPUT) for filtering.

As SSH is a critical factor for system management, user access and other options such as requiring SFTP from your clients, let's enable this service. Depending on how you manage your clients/users, you may simply allow all incoming SSH traffic:

#accept all incoming ssh traffic
-A FWALL-INPUT -p tcp -m tcp -s 0/0 --dport 22 -j ACCEPT

Alternatively, SSH can be restricted to identified static IP address hosts:

#accept incoming ssh traffic from user John Doe
-A FWALL-INPUT -p tcp -m tcp -s x.x.x.x --dport 22 -j ACCEPT
#end specific ssh access – this commenting is handy of you have multiple users here as #you can start and end sections if users have multiple IPs from which they can access

In breaking down those lines of code, we see:

  • -A appends the rule to the firewall rule set
  • -p represents protocol (which can be tcp, udp and icmp in varying cases)
  • -m is for match and opens up options for extending packet management, for example to have granular control over SYN bits, defining destination and source ports. This is better explained at length in 'man iptables' than here, as multiple levels of options are available.
  • -s signifies the source address, where 0/0 stands for any host, a specific host IP address can be used (as in the example above), or a network segment can be denoted, such as 10.0.1.0/24.
  • --dport points to the destination port; in the case of SSH, it's 22.
  • -j selects the target (or jump target), which may be a custom target, or one of the common built-in targets such as ACCEPT or DROP.

Next, let's consider FTP, an entry for the Webmin control panel, and a host of commonly used ports that are important to your server's operation on the Internet.

# manage ftp port traffic
-A FWALL-INPUT-p tcp -m tcp --dport 21 -j ACCEPT
# end ftp port

#My webmin custom port
-A FWALL-INPUT-p tcp -m tcp --dport 42009 -j ACCEPT
# end webmin

#SNMP monitoring so I can use a remote monitoring tool
-A FWALL-INPUT-p udp -m udp --dport 161 -j ACCEPT
-A FWALL-INPUT-p udp -m udp --sport 1023:2999 -j ACCEPT
#end SNMP

A quick security note: when enabling remote access to SNMP, please be sure to have invested time in securing your SNMP configuration file(s), including changing community strings and using authentication.

# some standard out ports with port definition
#POP mail
-A FWALL-INPUT-p tcp -m tcp --dport 110 -j ACCEPT --syn
#HTTPS
-A FWALL-INPUT-p tcp -m tcp --dport 443 -j ACCEPT --syn
#SMTP Traffic
-A FWALL-INPUT-p tcp -m tcp --dport 25 -j ACCEPT --syn
#HTTP
-A FWALL-INPUT-p tcp -m tcp --dport 80 -j ACCEPT --syn
#In my case - Urchin
-A FWALL-INPUT-p tcp -m tcp --dport 9999 -j ACCEPT --syn
#MySQL database server
-A FWALL-INPUT-p tcp -m tcp --dport 3306 -j ACCEPT --syn
-A FWALL-INPUT-p udp -m udp --dport 3306 -j ACCEPT
#IMAP mail services
-A FWALL-INPUT-p tcp -m tcp --dport 143 -j ACCEPT --syn
#DNS
-A FWALL-INPUT-p tcp -m tcp --dport 53 -j ACCEPT --syn
-A FWALL-INPUT-p udp -m udp --dport 53 -j ACCEPT
-A FWALL-INPUT-p udp -m udp -s 0/0 -d 0/0 --sport 53 -j ACCEPT
#Localhost traffic
-A FWALL-INPUT-i lo -j ACCEPT
#The below commits the rules to production for iptables to execute
COMMIT

You will notice we added the --syn flag. This is part of the previously mentioned -m (for matching) option in iptables. Here, we are specifically ensuring that only new connections with a SYN bit, and for which no ACK is set, are accepted.

At this point, you have a working development firewall. You can add and remove services to meet your own requirements. However, we can make some additional entries. We can add a final rule that drops all packets that do not qualify for any of our preceding ports.

#Drop all other new requests not meeting any existing rule requirements applied to traffic
-A FWALL-INPUT -p tcp -m tcp -j REJECT --syn
-A FWALL-INPUT -p udp -m udp -j REJECT

SYN Flood Protection

For some added protection, we can also seek to prevent the flooding of new requests (packets with the SYN bit set and no ACK, as discussed earlier in the article) by limiting the amount of requests to 5 seconds, which allows the system time to apply the rules.

-A FWALL-INPUT –p tcp --syn -m limit --limit 5/second -j ACCEPT

This should appear at the top of your rules, just above the first SSH entry.

Banning Access

If there are troublesome hosts you have discovered in your logs, these can be banned via iptables; however, be cautious in light of IP masquerading. Do some research on the IP address you wish to block, to ensure it is not a legitimate SMTP server, or worse: one of your clients who has been spoofed.

To block a specific host:

#Block malicious system
-A FWALL-INPUT -p tcp -m tcp -s x.x.x.x -j DROP

Checking Firewall Logs

iptables traditionally logs basic entries to /var/log/messages. However, specific logging needs to be noted in your firewall rules if you'd like to track and research traffic. Many prefer to log only drop/reject actions, as this allows them to see any potential malicious behavior that's being attempted.

This can be handled with an entry like the following:

#Option 1 logging drop/reject actions
-A FWALL-INPUT -j LOG --log-level alert
#Option 2 logging with a prefix for easy search/grep of log file
-A FWALL-INPUT -j LOG --log-prefix "Dropped: "

Finally, a nice open source iptables log analyzer is available; it provides an interface similar to those commonly used to view Web traffic statistics. Found online at gege.org, this daemon can be implemented into a LAMP (specifically PHP and MySQL) environment and used to log all iptables actions in place of the default /var/log/messages.

Setup and configuration is straightforward and only a minor edit to your iptables file will start the reporting process.

Next Steps

The man pages for iptables are extensive and it is recommended to spend some time getting accustomed to the various options before moving a firewall into production. For example, options exist for using the -m (matching) option to manage packet states - i.e. allowing only new and established connections for specific services.

There are endless documents related to iptables on the Web, however, the best place to start is at the source: Netfilter's Website. Tutorials range from basic networking concepts and packet filtering to setting up network address translation and advanced connection tracking options.

Finally, as noted before, this firewall does not represent the be-all and end-all configuration. It is a great place to start when exploring your options with iptables. Administrators, based on their environment, will have varying levels of paranoia to accommodate. Some systems I manage are locked as tight as possible, while others have fairly open doors for testing and development.

Continue reading Secure your Server with iptables

20 ways to Secure your Apache Configuration

Here are 20 things you can do to make your apache configuration more secure।

Disclaimer: The thing about security is that there are no guarantees or absolutes. These suggestions should make your server a bit tighter, but don't think your server is necessarily secure after following these suggestions.

Additionally some of these suggestions may decrease performance, or cause problems due to your environment. It is up to you to determine if any of the changes I suggest are not compatible with your requirements. In other words proceed at your own risk.

First, make sure you've installed latest security patches

There is no sense in putting locks on the windows, if your door is wide open. As such, if you're not patched up there isn't really much point in continuing any longer on this list. Go ahead and bookmark this page so you can come back later, and patch your server.

Hide the Apache Version number, and other sensitive information.

By default many Apache installations tell the world what version of Apache you're running, what operating system/version you're running, and even what Apache Modules are installed on the server. Attackers can use this information to their advantage when performing an attack. It also sends the message that you have left most defaults alone.

There are two directives that you need to add, or edit in your httpd.conf file:

ServerSignature Off
ServerTokens Prod

The ServerSignature appears on the bottom of pages generated by apache such as 404 pages, directory listings, etc.

The ServerTokens directive is used to determine what Apache will put in the Server HTTP response header. By setting it to Prod it sets the HTTP response header as follows:

Server: Apache

If you're super paranoid you could change this to something other than "Apache" by editing the source code, or by using mod_security (see below).

Make sure apache is running under its own user account and group

Several apache installations have it run as the user nobody. So suppose both Apache, and your mail server were running as nobody an attack through Apache may allow the mail server to also be compromised, and vise versa.

User apache
Group apache

Ensure that files outside the web root are not served

We don't want apache to be able to access any files out side of its web root. So assuming all your web sites are placed under one directory (we will call this /web), you would set it up as follows:

  Order Deny,Allow
  Deny from all
  Options None
  AllowOverride None
  Order Allow,Deny
  Allow from all

Note that because we set Options None and AllowOverride None this will turn off all options and overrides for the server. You now have to add them explicitly for each directory that requires an Option or Override.

Turn off directory browsing

You can do this with an Options directive inside a Directory tag. Set Options to either None or -Indexes

Options -Indexes

Turn off server side includes

This is also done with the Options directive inside a Directory tag. Set Options to either None or -Includes

Options -Includes

Turn off CGI execution

If you're not using CGI turn it off with the Options directive inside a Directory tag. Set Options to either None or -ExecCGI

Options -ExecCGI

Don't allow apache to follow symbolic links

This can again can be done using the Options directive inside a Directory tag. Set Options to either None or -FollowSymLinks

Options -FollowSymLinks

Turning off multiple Options

If you want to turn off all Options simply use:

Options None

If you only want to turn off some separate each option with a space in your Options directive:

Options -ExecCGI -FollowSymLinks -Indexes

Turn off support for .htaccess files

This is done in a Directory tag but with the AllowOverride directive. Set it to None.

AllowOverride None

If you require Overrides ensure that they cannot be downloaded, and/or change the name to something other than .htaccess. For example we could change it to .httpdoverride, and block all files that start with .ht from being downloaded as follows:

AccessFileName .httpdoverride
    Order allow,deny
    Deny from all
    Satisfy All

Run mod_security

mod_security is a super handy Apache module written by Ivan Ristic, the author of Apache Security from O'Reilly press.

You can do the following with mod_security:

  • Simple filtering
  • Regular Expression based filtering
  • URL Encoding Validation
  • Unicode Encoding Validation
  • Auditing
  • Null byte attack prevention
  • Upload memory limits
  • Server identity masking
  • Built in Chroot support
  • And more

Disable any unnecessary modules

Apache typically comes with several modules installed. Go through the apache module documentation and learn what each module you have enabled actually does. Many times you will find that you don't need to have the said module enabled.

Look for lines in your httpd.conf that contain LoadModule. To disable the module you can typically just add a # at the beginning of the line. To search for modules run:

grep LoadModule httpd.conf

Here are some modules that are typically enabled but often not needed: mod_imap, mod_include, mod_info, mod_userdir, mod_status, mod_cgi, mod_autoindex.

Make sure only root has read access to apache's config and binaries

This can be done assuming your apache installation is located at /usr/local/apache as follows:

chown -R root:root /usr/local/apache
chmod -R o-rwx /usr/local/apache

Lower the Timeout value

By default the Timeout directive is set to 300 seconds. You can decrease help mitigate the potential effects of a denial of service attack.

Timeout 45

Limiting large requests

Apache has several directives that allow you to limit the size of a request, this can also be useful for mitigating the effects of a denial of service attack.

A good place to start is the LimitRequestBody directive. This directive is set to unlimited by default. If you are allowing file uploads of no larger than 1MB, you could set this setting to something like:

LimitRequestBody 1048576

If you're not allowing file uploads you can set it even smaller.

Some other directives to look at are LimitRequestFields, LimitRequestFieldSize and LimitRequestLine. These directives are set to a reasonable defaults for most servers, but you may want to tweak them to best fit your needs. See the documentation for more info.

Limiting the size of an XML Body

If you're running mod_dav (typically used with subversion) then you may want to limit the max size of an XML request body. The LimitXMLRequestBody directive is only available on Apache 2, and its default value is 1 million bytes (approx 1mb). Many tutorials will have you set this value to 0 which means files of any size may be uploaded, which may be necessary if you're using WebDAV to upload large files, but if you're simply using it for source control, you can probably get away with setting an upper bound, such as 10mb:

LimitXMLRequestBody 10485760

Limiting Concurrency

Apache has several configuration settings that can be used to adjust handling of concurrent requests. The MaxClients is the maximum number of child processes that will be created to serve requests. This may be set too high if your server doesn't have enough memory to handle a large number of concurrent requests.

Other directives such as MaxSpareServers, MaxRequestsPerChild, and on Apache2 ThreadsPerChild, ServerLimit, and MaxSpareThreads are important to adjust to match your operating system, and hardware.

Restricting Access by IP

If you have a resource that should only by accessed by a certain network, or IP address you can enforce this in your apache configuration. For instance if you want to restrict access to your intranet to allow only the 176.16 network:

 
Order Deny,Allow
Deny from all
Allow from 176.16.0.0/16
 

Or by IP:

Order Deny,Allow
Deny from all
Allow from 127.0.0.1

Adjusting KeepAlive settings

According to the Apache documentation using HTTP Keep Alive's can improve client performance by as much as 50%, so be careful before changing these settings, you will be trading performance for a slight denial of service mitigation.

KeepAlive's are turned on by default and you should leave them on, but you may consider changing the MaxKeepAliveRequests which defaults to 100, and the KeepAliveTimeout which defaults to 15. Analyze your log files to determine the appropriate values.

Run Apache in a Chroot environment

chroot allows you to run a program in its own isolated jail. This prevents a break in on one service from being able to effect anything else on the server.

It can be fairly tricky to set this up using chroot due to library dependencies. I mentioned above that the mod_security module has built in chroot support. It makes the process as simple as adding a mod_security directive to your configuration:

SecChrootDir /chroot/apache

There are however some caveats however, so check out the docs for more info.

Acknowledgments

I have found the book Apache Security to be a highly valuable resource for securing an apache web server. Some of the suggestions listed above were inspired by this book.

Suggestions

Please post any suggestions, caveats, or corrections in the comments and I will update the post if necessary.

Continue reading 20 ways to Secure your Apache Configuration