In part two of this series we’re going to discuss adding firewall rules to the router.  Everyone knows that adding ingress (or incoming) firewall rules is important to securing your network.  However, the same can be said for adding egress rules for traffic leaving your network.  For instance, aside from an email server, no client should ever send traffic to the Internet via TCP port 25.  If you see traffic like this, it could mean that you have an infected computer within your network.  Egress firewall rules, along with logging of those rules, will help track down problems before it gets out of hand.

First lets up the ingress rules to protect the router from incoming traffic we do not want.

    iptables -A INPUT -m state –state INVALID -j DROP

    iptables -A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT

    iptables -A INPUT -s -p icmp -j ACCEPT

    iptables -A INPUT -i lo -j ACCEPT

    iptables -A INPUT -s -p tcp -m state –state NEW -m tcp –dport 22 -j ACCEPT

    iptables -A INPUT -i eth0 -j LOG –log-prefix ” *** IPTABLES DENY IN *** “

    iptables -A INPUT -j REJECT

The first rule allows us to configure the stateful firewall.  Any connections that are already established on the server is allowed through, new connections will not be allowed by this line.  The second rule allows for internal clients to ping their default gateway.  Third rule is VERY IMPORTANT as it allows server traffic to be allowed on the loopback interface.  Most Linux communication including X and service daemons use the loopback for internal communication.  If you do not allow this rule then you could kill everything.  The fourth line allows internal traffic to connect through SSH for remote administration.  We can further restrict SSH by only allowing SSH keys, or if you have a monitor hooked up to the router you could skip this rule altogether.  And the last rule blocks all other incoming traffic to the router.

Now lets setup the egress rules on the router.  To do this, we will use the forward table in iptables.  This is used to forward traffic from one interface to another.

    iptables -A FORWARD -m state –state INVALID -j DROP

    iptables -A FORWARD -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT

    iptables -A FORWARD -i eth1 -p tcp -m tcp –dport 22 -j ACCEPT

    iptables -A FORWARD -i eth1 -p tcp -m tcp –dport 80 -j ACCEPT

    iptables -A FORWARD -i eth1 -p tcp -m tcp –dport 443 -j ACCEPT

    iptables -A FORWARD -i eth1 -p tcp -m tcp –dport 465 -j ACCEPT

    iptables -A FORWARD -i eth1 -p tcp -m tcp –dport 587 -j ACCEPT

    iptables -A FORWARD -i eth1 -p tcp -m tcp –dport 993 -j ACCEPT

    iptables -A FORWARD -i eth1 -j LOG –log-prefix " *** IPTABLES DENY OUT *** "

    iptables -A FORWARD -j REJECT

    iptables -A FORWARD -s -i eth0 -j DROP

The first rule for this is similar to the first rule to the last set.  The next set of rules allow internal clients to connect to any server on the Internet using SSH, HTTP/HTTPS, and email.  The last few lines are important as first we log dropped packets, then drop packets that do not meet the lines above, and then an anti-spoofing line.  We will talk about logging in a minute, I just want to point out one additional thing.  Be extremely careful when creating egress firewall rules as this will break things.  For instance, if someone needs to establish an outgoing VPN connection then you will need to add those rules in or it will not work.

To get IPTABLES to log dropped packets to a log file, we use rsyslog.  In the /etc/rsyslog.conf file add the following lines:

    :msg,startswith,” *** IPTABLES DENY OUT *** ” /var/log/iptables-egress

    :msg,startswith,” *** IPTABLES DENY IN *** ” /var/log/iptables-ingress


Now start the rsyslog daemon and restart iptables and you’ll be all set.

​This will be part 1 in a series of configuring CentOS/Red Hat 6 as a secured firewall. Though I am a huge fan of pfSense (which can be found here pfSense), I wanted to build my own from scratch. So, the first part of this series will consist of setting up PAT (or NAT overload for the Cisco geeks) on Linux.

The first step is to configure the network cards.  In this scenario we will use eth0 as the WAN connection and eth1 as the LAN connection.  Refer to the diagram below

 | ISP - | <--- | eth0(WAN) - | --- NAT Server --- | eth1(LAN) - | ---> Internal Network

Edit both the ifcfg-eth0 and the ifcfg-eth1 files located in /etc/sysconfig/network-scripts/, make sure both of the network cards are set to BOOTPROTO=”static”.

The second step is to setup IP forwarding which can be done by editing the /etc/sysctl.conf file and adding

    net.ipv4.ip_forward = 1

You can then either reload the server or issue the ‘sysctl -p’ command. Once that command is run, you will see the output of the command and you should see ‘net.ipv4.ip_forward = 1’ in the output. You can also verify by running ‘cat /proc/sys/net/ipv4/ip_forward’ and it will return a ‘1’. If it returns a 0 then the command did not run correctly and you need to try again.

The last step is to set up masquerade with IPTABLES. As eth0 is your outside (or WAN) connection, run

    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Connect a laptop to the eth1 NIC with a crossover cable, and statically set the IP address to with the default gateway of  You should now be able to ping out of the LAN to the Internet. If successful run,

    service iptables save

which will save the command to the /etc/sysconfig/iptables file when either the service or the server is reloaded.

​Mounting a USB device

 Attach the USB device to the Dom0 and run ‘dmesg’ to see if the device attached

Run ‘fdisk -l’ to see if the drive is partitioned the way you want it

For instance:

[[email protected] ~]# fdisk -l /dev/sdc

Disk /dev/sdc: 1000.2 GB, 1000204886016 bytes

255 heads, 63 sectors/track, 121601 cylinders

Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot Start End Blocks Id System

dev/sdc1 1 121601 976760001 8e Linux LVM

Now find a drive letter that is not being used on the DomU, in this instance we’ll use /dev/sde

To attach the USB device to the DomU run the following command

xm block-attach exampledomu phy:/dev/sdc sde w

You should now see the device on the DomU, run either ‘dmesg’ or ‘fdisk -l’ to verify

Mount the device as normal

mount /dev/sde1 /mnt/usb

Unmounting the device

You first need to get the device id number from the block list. Do this by running:

xm block-list exampledomu

This will return:

    Vdev BE handle state evt-ch ring-ref BE-path

    51712 0 0 4 9 8 /local/domain/0/backend/tap/23/51712

    2176 0 0 4 10 1338 /local/domain/0/backend/vbd/23/2176

The number you need to use to remove the device is 2176

Unmount the USB device from the DomU

umount /mnt/usb

 Now on the Dom0 run:

xm block-detach exampledomu 2176

You may now remove the USB device

As a part of the sys admin’s job, it is important to take a few extra minutes to go through and properly secure a newly installed Linux server. These steps include enabling SELinux on the machine, configuring the firewall, and setting user permissions. There are however additional steps one should take in order to secure their server. One would be to tune and secure kernel parameters, set limits on kernel dumps, prevent IPv6 from loading if you company is not using it, and turning off unnecessary services.


First, lets take a look at configuring kernel parameters to prevent network based attacks. These include disallowing intruders to alter routing tables and source routed packets, preventing an intruder from configuring the server to become a router, and turning on reverse path filtering. To change these settings edit the /etc/sysctl.conf file and enter:

    net.ipv4.conf.all.accept_source_route = 0 

    net.ipv4.conf.all.accept_redirects = 0 

    net.ipv4.conf.all.secure_redirects = 0 

    net.ipv4.conf.all.log_martians = 1 

    net.ipv4.conf.default.accept_source_route = 0 

    net.ipv4.conf.default.accept_redirects = 0 

    net.ipv4.conf.default.secure_redirects = 0 

    net.ipv4.icmp_echo_ignore_broadcasts = 1 

    net.ipv4.icmp_ignore_bogus_error_messages = 1 

    net.ipv4.tcp_syncookies = 1 

    net.ipv4.conf.all.rp_filter = 1 

   net.ipv4.conf.default.rp_filter = 1 

If you are currently running IPv6 at your company, here are a few kernel parameters to prevent network based attacks:

    net.ipv6.conf.default.router_solicitations = 0 

    net.ipv6.conf.default.accept_ra_rtr_pref = 0 

    net.ipv6.conf.default.accept_ra_pinfo = 0 

    net.ipv6.conf.default.accept_ra_defrtr = 0 

    net.ipv6.conf.default.autoconf = 0 

    net.ipv6.conf.default.dad_transmits = 0 

    net.ipv6.conf.default.max_addresses = 1 

To make these settings effective without rebooting the server type sysctl -p 

We can go a step further by disabling unused network functions such as IPv6 and prevent self assigned addressing.

To detect whether or not IPv6 is running on a server type: ifconfig | grep inet6 which will return:

    inet6 addr: fe80::240:5ff:fe32:ef19/64 Scope:Link 

    inet6 addr: ::1/128 Scope:Host 

    inet6 addr: fe80::200:ff:fe00:0/64 Scope:Link 

To prevent IPv6 from loading, run the following command:

echo install ipv6 /bin/true > /etc/modprobe.d/ipv6 

Then add the following lines to /etc/sysconfig/network:



This will deactivate the IPv6 protocol from running on the server.

To prevent self assigned addressing on network cards, open the /etc/sysconfig/network file and add:


Server security 

Turning off the ability to create core dumps is important as intruders can use this to gather information about running services and configurations in order to exploit them. To do so, edit the /etc/security/limits.conf file and insert:

* hard core 0 

We should also prevent setuid programs from creating these as well:

sysctl -w fs.suid_dumpable=0 

There are also built in kernel features which can help protect against buffer overflow attacks. These features are turned on by default, however these kernel parameters should be enabled in case they have been turned off:

    sysctl -w kernel.exec-shield=1 

    sysctl -w kernel.randomize_va_space=1 

These settings ensure randomization of the stack and memory regions, which are refereed to as the ExecShield.

There are many services which are running on a default installation which include cups, sendmail, isdn, bluetooth, and many others. If these services are not being used on the server then they should be turned off and configured not to start up on a reboot. To do so we can run the following bash script:

for i in acpid autofs avahi-daemon luetooth cups firstboot gpm hidd ip6tables sendmail exim xfs xinetd yum-updatesd rhnsd pcscd readahead_early readahead_later apmd hplip isdn ip6tables mcstrans 


    service $i stop 

    chkconfig $i off 


Your services will vary depending on the installation. We should also ensure that X does not run on reboot, placing the server in run level three. To do so, edit the /etc/inittab file and change id:5:initdefault: to id:3:initdefault:

​A great feature of Linux and Xen is the ability to run DomU’s on multiple networks. To do this we first need to set up the VLAN’s on a switch and then set the port the Dom0 is connected to allow for 802.1q traffic. On a Cisco switch, log into the IOS and change the interface that the server is sitting on and type:

switch(config-if) switchport trunk encapsulation dot1q

switch(config-if) switchport mode trunk

Once this is done we can then configure Dom0 to communicate to these networks. In CentOS, you need to change directories to /etc/sysconfig/network-scripts.

First copy the ifcfg-eth0 file to make a back up then edit the file as follows:





Next we create four new files which will define our VLAN and non-VLAN traffic. The first two files will define which VLANs the server should listen on:

Create the file: /etc/sysconfig/network-scripts/ifcfg-eth0.17. This will define VLAN 17.

Then enter in the following:







Make a secondary file which will sit on VLAN 192, VLAN 192 is where the IP of the Dom0 will reside.







The next two files will define the bridged interfaces. These are necessary to strip the 802.1q header so the server and DomU’s can communicate across the network. The first file will be for the publicly routable network:







The next file will be for the internal network.











After that reboot the server.

Next create a virtual instance with virt-install and run it as follows:

virt-install –name test –ram 1024 –location ‘centos mirror’ -f /dev/lvm/test -b xenbr17 -p

The ‘-b’ is important as it will define the bridge the new server will sit on.