Dynamic routing in Linux and BSD

Dynamic routing are becomming more and more common these days, but not on the server side. Actually, Windows 2008 Server no longer supports Open Shortest Path First (OSPF), even though 2003 server did. The most common way of implementing dynamic routing in larger networks, are in the Wide Area Network (WAN) between firewalls. In this guide I will show how to use OSPF in Linux by using the Quagga Software Routing Suite.

As usual I use Debian linux, so let’s start by installing Quagga.

apt-get install quagga

That was not very hard. Let’s take a look at the different configuration files located in /etc/quagga/.


This file enables and disables the different services available in the routing suite. There are several supported protocols such as RIP, BGP and OSPF.



Zebra is the service that transfers configuration from Quagga to the operating system. Zebra takes care of updating interface addresses, routing tables, hostname, etc.

hostname server01
log file /var/log/quagga/zebra.log
password cliSecretPassword
interface bond0
    ip address
interface eth0
interface eth1
interface lo

As you can clearly see from this configuration file, the server has hostname server01 and has bonded the eth0 and eth1 to a new bond0 interface.


This file configures the OSPF service. This is not a very advanced setup.

service advanced-vty
log file /var/log/quagga/ospfd.log
interface bond0
        ip ospf authentication message-digest
        ip ospf message-digest-key 1 md5 SECRETPASS

# Loopback
#interface lo
#    ip ospf priority 0

router ospf
        redistribute static
        network area
        area authentication message-digest

Here the OSPF service is instructed to join area with key 1 set as SECRETPASS. Also, the service redistributes all static routes. In this example, the server is a stub area.

I will be posting more configuration later.

Automating your iptables

Ever wondered how to use iptables on debian, without using any GUI solution? Let me explain how I do it.

Usually I use two files /etc/iptables_secure.sh and /etc/iptables_open.sh. The secure script has firewall enabled, while the open script makes iptables accept all connections. Also, I use /etc/init.d/firewall to start and stop the firewall at boot.

First, start by creating the following three files.




# Flush old rules, old custom tables
$IPT --flush
$IPT --delete-chain

# Set default policies for all three default chains

# Enable free use of loopback interfaces

# All TCP sessions should begin with SYN
# $IPT -A INPUT -p tcp ! --syn -m state --state NEW -s -j DROP

# Accept established connections

echo "Opening CARP"
$IPT -A INPUT --protocol 112 -j ACCEPT

# Brute force
# Limit the number of ssh connections to 6 per minute
$IPT -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
$IPT -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 6 --rttl --name SSH -j DROP

# Limit the number of ftp connections to 10 per minute
# $IPT -A INPUT -i eth0 -p tcp --dport 21 -m state --state NEW -m recent --set --name FTP
# $IPT -A INPUT -i eth0 -p tcp --dport 21 -m state --state NEW -m recent --update --seconds 60 --hitcount 10 --rttl --name FTP -j DROP

echo "Opening FTP"
$IPT -A INPUT -p tcp --dport 20 -m state --state NEW -j ACCEPT
$IPT -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT
$IPT -A INPUT -p tcp --sport 1024: --dport 1024:  -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p tcp --sport 1024: --dport 1024:  -m state --state ESTABLISHED,RELATED -j ACCEPT

echo "Opening HTTP(S)"
$IPT -A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT
$IPT -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT

echo "Opening SSH"
$IPT -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

echo "Opening MySQL"
$IPT -A INPUT -p tcp --dport 3306 -m state --state NEW -j ACCEPT

echo "Opening port 7777 - ocfs2"
$IPT -A INPUT -p tcp --dport 7777 -m state --state NEW -j ACCEPT
$IPT -A INPUT -p udp --dport 7777 -j ACCEPT

echo "Opening NTP"
$IPT -A INPUT -p udp --dport 123 -j ACCEPT
$IPT -A INPUT -p tcp --dport 123 -m state --state NEW -j ACCEPT

# echo "Opening all from same subnet"
# $IPT -A INPUT -p tcp -s -m state --state NEW -j ACCEPT

# Accept inbound ICMP messages
echo "Opening ping and traceroute"
$IPT -A INPUT -p ICMP --icmp-type 8 -s -j ACCEPT
$IPT -A INPUT -p ICMP --icmp-type 11 -s -j ACCEPT


echo "Opening firewall"

# Flush old rules, old custom tables
$IPT --flush
$IPT --delete-chain

# Set default policies for all three default chains

# Enable free use of loopback interfaces


#! /bin/sh
# Provides:          firewall
# Required-Start:     $portmap
# Required-Stop:
# Should-Start:      udev-mtab
# Default-Start:     2
# Default-Stop:      0 6
# Short-Description:
# Description:

. /lib/init/vars.sh
. /lib/lsb/init-functions

case "$1" in
        sh /etc/iptables_script.sh
        echo "Error: argument '$1' not supported" >&2
        exit 3
        sh /etc/iptables_open.sh
        echo "Usage: $0 start|stop" >&2
        exit 3

Now use chmod to make /etc/init.d/firewall executable.

chmod +x /etc/init.d/firewall

You should now be able to issue /etc/init.d/firewall start and /etc/init.d/firewall stop in order to enable or disable the firewall. Also, in order to make the firewall start at boot time, issue the following command.

update-rc.d firewall defaults

Ask me if there is something you don’t understand!

Virtual hosting with Apache – the good way

There are so many amazingly bad guides to Apache and virtual hosting, so i decided to create a good one. This guide uses Apache2 running om Debian 6. I will not cover installation and stuff. Also, I cut right to the chase.

First, the NameVirtualHost property should just be declared once, and ports.conf is a good place to have it.


NameVirtualHost *:80
Listen 80

Second, do not place all virtual hosts in a single file, that’s not very dynamic. Look at this:

# ls /etc/apache2/sites-*
total 8
dr-xr-x--- 2 root           www-data     3896 Jun 26 15:33 .
dr-x------ 5 www-data        www-data     3896 Jun  8 13:15 ..
-rwxr-x--- 1 root           www-data     569  Apr 11 21:51 default
-rwxr-x--- 1 root           www-data     569  Apr 19 11:40 sub1.example.org
-rwxr-x--- 1 root           www-data     569  Apr 19 11:41 sub2.example.org
-rwxr-x--- 1 root           www-data     569  Jun 26 15:25 goodworkaround.com

total 0
dr-xr-x--- 2 www-data  www-data 3896 Jun 26 15:33 .
dr-x------ 5 www-data  www-data 3896 Jun  8 13:15 ..
lrwxrwxrwx 1 root   root  26 Apr 11 21:52 000-default -> ../sites-available/default
lrwxrwxrwx 1 root   root  41 Apr 19 11:49 sub1.example.org -> ../sites-available/sub1.example.org
lrwxrwxrwx 1 root   root  41 Apr 19 11:50 sub2.example.org -> ../sites-available/sub2.example.org
lrwxrwxrwx 1 root   root  37 Jun 26 15:29 goodworkaround.com -> ../sites-available/goodworkaround.com

So what am I doing that no one else is doing? I am symlinking, and I am splitting each domain or subdomain into separate files. Just use place all the domains in the sites-available folder, and symlink it from sites-enabled. This makes it easy to disable sites temporary, by just removing the symlink and reloading apache. Lets take a look one of those files.


<VirtualHost *:80>
        ServerAdmin webmaster@goodworkaround.com
        ServerName goodworkaround.com
        # ServerAlias www.goodworkaround.com

        DocumentRoot /home/mariussm/websites/goodworkaround.com

        <Directory />
                Options FollowSymLinks
                AllowOverride None

        <Directory /home/mariussm/websites/goodworkaround.com>
                Options FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all

        ErrorLog ${APACHE_LOG_DIR}/goodworkaround.com.error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/goodworkaround.com.access.log combined


As you can see, it listens on all interfaces (*:80) on port 80, cares only for the hostname goodworkaround.com and has a root folder. So hey, that’s the easy way.