Oct 20
Creating a Blackhole DNS with Bind 9

​Malware can be delivered many different ways from either advertisements (remember the NY Times malicous ads?) to hacked websites that contain malicious code.  One technique designed to help curb these infections is through the use of DNS blackhole.  This technique will redirect your internal users to an internal website to block their access.  To do so, first install Bind on your Linux server.  Then edit your named.conf file which should be located in /etc/bind and enter:

     include "/etc/named/blackhole.conf";

Create a new file called blackhole.conf.  This file will contain every website you wish to redirect to an internal site, effectivly blocking your users from accessing it:

     zone "" {type master; file "/etc/bind/blackhole.db";};

Each additional website that you want to block should containt he same format as the one stated above.
Next, create your zone file which will redirect all traffic destined to FQDN's listed in the blackhole.db file to your internal website:

$TTL 3600
@ IN SOA (
                                                                      20131020 ;
                                                                      3600  ;
                                                                      600  ;
                                                                      86400  ;
                                                                      600 )


* IN A

There are plenty of websites on the Internet that maintain an updated list of malware websites.  One that I use quite frequently is Malware Domain List

Aug 26
Part 2: Adding the firewall rules

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.

Aug 26
PyMyDB Backup 0.5.1

The first version of PyMyDB Backup has been released and is based on Python 2.4.3. This is a Python script that will back up your MySQL databases, calculate the size of the backed up files, tarball and compress the contents, then email the results.

To use:

    Download the EPEL RPM which can be found at:
     Install pymydb-0.5.1-1.noarch.rpm which can be found at: GitHub
         This script creates the necessary directories and user account
     After installation, there will be two scripts placed in /usr/local/bin which are and
     Run the script, this will configure the script
         Logs into the MySQL server
         Creates the backup user, sets a password, and gives him select and lock tables privileges
         Configures the email settings
     Change the permissions on the script
         chown root.pymydb
     Add the script into cron and make sure to add a password for the system user
 You can download it at my GitHub page

Aug 03
Setting up NAT with CentOS/Red Hat 6

​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.

Jun 09
Getting Linksys AE2500 to work with Fedora 17

​In order to get the AE2500 wireless USB adapter to work you must install ndiswrapper. First, the ndiswrapper-1.57 version is not compatible with the 3.3 or 3.4 version of the Linux kernel so you must install the ndiswrapper-1.58rc1 which is still in test as of this writing. Next, download the AE2500 Windows XP drivers from the Linksys website ( Link ). Unzip the drivers into a directory and load the bcmwlhigh5.inf file into ndis. Once this is done, you can run the 'ndiswrapper -l' command to verify that it is installed correctly. Finally, run 'modprobe ndiswrapper' to load the driver into the kernel. Once this is complete you should see the wireless USB device come up as wlan0 and ready for use.

Jun 09
Mounting a USB Device In a Xen Guest

​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:
[root@example ~]# 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

Jun 06
Calculate Free Space with Python

​import os
diskSpace = os.statvfs(‘/’)
(diskSpace.f_bavail * diskSpace.f_frsize) / (1024 * 1024)

Jun 05
MySQL Backup Script

I needed a place to host my scripts, so I opened an account on GitHub. If you are unaware of what GitHub is, its a great place to publish code to the public by using Git; they also offer private hosting for a fee. Even if you do not have a need for this I recommend looking through the site as its a great place to view open source projects.

There are a lot of examples and scripts out on the Internet to automate MySQL backups but not a whole lot written in Python. This was developed to use in a MySQL replication environment and should be run on the slave server. This is an optimal solution as backup’s can run without affecting production. The script dumps each database individually, calculates the size of the sql backup, tarball them up, and emails a log when its done.

To run this the MySQLdb module must be installed on the server. You should also create a user specifically designed to run backups. You can effectively do this by running:

    grant select, lock tables on *.* to backup@'localhost' identified by 'password';

The password is stored in base64 format. To encrypt the password for use in the script, run the following command within the Python terminal:

    >>> from base64 import b64encode as encode
    >>> encode("password")

Though this is not the most secure way to encrypt a password to use within a script, it will prevent shoulder surfers.

Here it is, enjoy –

May 01
Install mod_security on CentOS

​You will need to install the Extra Packages for Enterprise Linux (EPEL) rpm which can be found at:
'rpm -ivh for i386
or: 'rpm -ivh for 64bit.

Once the EPEL rpm has been installed, you will then be able to install mod_security by typing 'yum install mod_security' and restart the Apache service.

Make sure that the mod_security engine is turned on by going to
/etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf and look for 'SecRuleEngine On'

One of the coolest features is masking the server signature of Apache. This can be done by editing the httpd.conf and making sure that 'ServerTokens' is set to 'Full'. Then change 'SecServerSignature' in 'modsecurity_crs_10_config.conf' to whatever you want.

Mar 09
RHEL/CentOS Server Security
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:
1 - 10Next