Forward ports in Ubuntu Server 12.04 using ufw

We needed to forward port 3307 to port 3306 to get around a new company wide firewall restriction blocking access to port 3306 (our MySQL server). It was a pain to find how to get port forwarding working in Ubuntu Server 12.04, which uses “ufw” as a front end to “iptables”. I couldn’t get it working without specifically forwarding to my IP, which I shouldn’t need to do (but at least it works).

This will forward port 3307 to 3306 so you can connect to your.ip.add.ress:3307 and have it automatically connect to a server (such as MySQL) on port 3306.

To do this you need “ufw” to be enabled, which you can check with “sudo ufw status”.

Make sure the ports you need are allowed:

sudo ufw allow 3307

Now open up “/etc/ufw/before.rules”:

sudo nano /etc/ufw/before.rules

Go to the bottom of the file and put:

# nat Table rules
-A PREROUTING -i eth0 -p tcp -m tcp -d your.ip.add.ress –dport 3307 -j DNAT –to-destination your.ip.add.ress:3306

Restart “ufw” to make sure everything worked ok:

sudo ufw disable
sudo ufw enable

Now when you connect to port 3307 it will forward to 3306.

Fix iptables error “Loading additional iptables modules: ip_conntrack_netbios_n[FAILED]” in XenServer 6 (and others)

As part of setting up and testing routing rules in XenServer 6 I used the built in “lokkit” tool to temporarily turn off the firewall. Unfortunately, just opening the tool overwrote our custom “/etc/sysconfig/iptables” rules and cleared the file. This wasn’t a huge problem as we had a backup and just recreated it (you shouldn’t really be editing iptables manually anyway). On restarting iptables using “/etc/init.d/iptables restart” we received the error:

Loading additional iptables modules: ip_conntrack_netbios_n[FAILED]

This is very easy to fix and is due to a setting in “/etc/sysconfig/iptables-config” which was set by “lokkit” by default. The issue is that iptables is trying to load the “ip_conntrack_netbios_ns” kernel module, which doesn’t exist by default in XenServer (and other linux distributions).

Find the following line at the top of “/etc/sysconfig/iptables-config”:


And set to:


A few people have said to also set “IPTABLES_MODULES_UNLOAD” to =”no”:


But I found that “/etc/init.d/iptables restart” still failed so I left it as “yes”. You may be able to set to “no” so try this first.

This will stop the missing kernel module being loaded and allow iptables to start properly.

If you get any other errors about loading modules when restarting iptables, check “/etc/sysconfig/iptables-config” isn’t trying to load something in “IPTABLES_MODULES=” that you don’t have installed.

Quick Subversion (SVN) Server Setup on Ubuntu Server 12.04

Setting up an Apache Subversion (SVN) server for access using svn:// with client applications like TortoiseSVN is actually pretty simple. The official Ubuntu Documentation covers a lot more than this simple setup but this is enough to get something up and running quickly without worrying about WebDAV or HTML access. The tutorial is also really useful and provides the init.d startup script I used to make the SVN server run at boot.

The steps are; install subversion, create the repository directories, set access control, set subversion to run at boot.

To install subversion in ubuntu just run:

sudo apt-get install subversion

Now create a directory to hold your subversion repositories, in my case I used “/home/svn”:

sudo mkdir /home/svn

Create a repository folder, for example “svnrepo1″, within this directory:

sudo mkdir /home/svn/svnrepo1

Now you can use the “svnadmin” program that comes as part of the subversion package to create a SVN repository within this folder:

sudo svnadmin create /home/svn/svnrepo1

The configuration file for the repository is created as “/home/svn/svnrepo1/conf/svnserve.conf” and contains the option to enable password protection as well as a lot of other useful settings. The important lines to uncomment to force password access are:

anon-access = none
auth-access = write

By setting “anon-access” to “none” you force people to enter passwords on connecting to the SVN. Now set up password protected access by uncommenting the following:

password-db = passwd

Settings “password-db” to “passwd” means the list of users and passwords in the “/home/svn/svnrepo1/conf/passwd” file will be used to check if someone has access. In a lot of cases it makes sense to keep this “passwd” file somewhere else so it can be used for all your repositories. In my case I set it to:

password-db = /home/svn/passwd

Just make sure to set the passwd file to be only readable by root:

sudo chmod 600 /home/svn/passwd

The “passwd” file is actually a very simple text file and looks something like:

harry = harrypassword
sally = sallypassword

Once the SVN server is configured and a repository set up as above you can run the SVN server using:

svnserve -d –foreground -r /home/svn

To make sure the SVN server starts at boot you need to set up init.d. Do this by creating and editing a file “/etc/init.d/svnserve” (I use “nano” to do my text editing on the command line):

sudo nano /etc/init.d/svnserve

Now paste in the contents of the init.d script. This script covers everything you need to start, stop and restart the “svnserve” program at boot so your SVN server can listen to all svn:// connections. There are alternatives to using this script, but this works and is simple to set up. Make sure you change the line with “DAEMON_ARGS” to point to the right place of “/home/svn”:

DAEMON_ARGS=”-d -r /home/svn”

Now tell Ubuntu to update its startup routine to include this new script:

sudo update-rc.d svnserve defaults

Reboot the server to make sure everything is working as expected.

You can now start, stop or restart the automatically booted SVN server using the following commands:

sudo /etc/init.d/svnserve start
sudo /etc/init.d/svnserve stop
sudo /etc/init.d/svnserve restart

Connecting to your SVN server can be done using something like TortoiseSVN and the URL you use to connect to the “svnrepo1″ repository you just set up is:


There is a lot more you can do with the SVN configuration, such as adding group support etc, but this is the quickest way to set up a standard SVN server on Ubuntu to accept svn:// connections using “svnserve”.

Simple and secure MySQL database backup to gzip using mysqldump in Linux

As part of a larger daily backup cron job script I needed to quickly backup my MySQL databases to individual compressed “gzip” .GZ files. The command to do this is very easy, just run the command and pipe it to “gzip”:


This requires you to actually put in the USERNAME and PASSWORD on the command line, which is obviously a bad idea due to logging of commands and other security reasons.

The MySQL recommended way of doing this is to instead use a separate file containing the login details. You use “mysqldump” with the argument “–defaults-extra-file” and specify the location of a configuration file such as “/root/mysqldetails.cnf”. It is a good idea to create this file and “chown” as root and “chmod” it to be “0400″ which will make it read-only by the “root” user.

chown root:root /root/mysqldetails.cnf
chmod 0400 /root/mysqldetails.cnf

The file itself is a very simple text file and just looks something like:

host = localhost
password = PASSWORD

So now this file has been created and the permissions set correctly, the mysqldump command looks like:

mysqldump –defaults-extra-file=/root/mysqldetails.cnf DATABASENAME | gzip > OUTPUTFILE.gz

The result is OUTPUTFILE.gz which is a compressed copy of your DATABASENAME database, without showing anyone the username and password required to access the database. The “mysqldump” command is very useful and more information can be found in the MySQL documentation.

Encrypt a USB drive in linux and automatically mount it on startup using a keyfile and dm_crypt

The easiest way of doing this is to use dm_crypt‘s “cryptsetup” on your USB drive, create a keyfile then set the options in “/etc/fstab” and “/etc/crypttab”. By using a keyfile you can get the drive to automatically mount without having to type in your encryption password. I was doing this on a bare install of CentOS 6.3 but the steps should be similar on other distros with “cryptsetup” installed.

I needed to back up some important (and confidential) files to a USB portable drive that I wanted to encrypt with full disk encryption. You can do this in a variety of ways but the method here was the easiest I found. More information can be found at Brad’s Blog and HowtoForge.

Encrypting and mounting your USB drive

First you need to physically plug in your USB drive to the machine and then unmount it if it automatically mounts. I performed all the commands here using the root user. In my case, when I plugged in the USB drive it was found as “/dev/sdb” and automatically mounted by CentOS. To unmount:

umount /dev/sdb

Now the USB drive needs to be formatted using “cryptsetup” and the “luksFormat” command:

cryptsetup luksFormat /dev/sdb

The tool will give you a warning about overwriting data, which you need to confirm by typing an uppercase “YES”. You then type in and confirm your LUKS passphrase, which will be used to unlock the drive in future. This passphrase is also used later when creating the keyfile.

Now you can create a device mapper for the drive using “cryptsetup” and the “luksOpen” command. I called my mapper “secretvol” in this example so the drive will be mapped to “/dev/mapper/secretvol”. You will be prompted for the passphrase:

cryptsetup luksOpen /dev/sdb secretvol

Now before you can mount your newly mapped device you need to format the file system (I used ext3):

mkfs.ext3 /dev/mapper/secretvol

Now you can mount the USB drive. Make sure you have created the mount point (in my case “/mnt/encrypteddrive”) first then mount it with:

mkdir /mnt/encrypteddrive
mount /dev/mapper/secretvol /mnt/encrypteddrive

To test this all works properly reboot your machine before unlocking and mounting your USB drive manually (requiring entry of the passphrase):

cryptsetup luksOpen /dev/sdb secretvol
mount /dev/mapper/secretvol /mnt/encrypteddrive

To unmount and lock the drive by closing the device mapper with the “luksClose” command:

umount /dev/mapper/secretvol
cryptsetup luksClose secretvol

Creating a keyfile to avoid entering your passphrase manually

A keyfile is good as it means you can unlock your USB drive without having to manually type the passphrase. To create a keyfile “/root/keyfile” for your device using “cryptsetup” and the “luksAddKey” command enter the following (you will need to enter your passphrase). The first command creates a random 4096 byte file, the second makes it read only to root and the third stores your passphrase in the keyfile using “luksAddKey”:

dd if=/dev/urandom of=/root/keyfile bs=1024 count=4
chmod 0400 /root/keyfile
cryptsetup luksAddKey /dev/sdb /root/keyfile

Now you can unlock your previously created drive without manually entering the passphrase using:

cryptsetup luksOpen –key-file /root/keyfile /dev/sdb secretvol

And mount with:

mount /dev/mapper/secretvol /mnt/encrypteddrive

Automatically unlock and mount your encrypted USB drive at system startup

Now that you have a keyfile you can set up your linux install to automatically unlock and mount the USB drive by editing a couple of files.

Edit your “/etc/crypttab” file:

nano /etc/crypttab

Add the line below to add the “/dev/mapper/secretvol” device:

secretvol /dev/sdb /root/keyfile luks

NOTE: You can also use the UUID of your drive in “/etc/crypttab” to make sure that the right disk as detected by the kernel is used. In cases where you may be adding or removing disks this is really important as you may have “sdb” or “sdc” or “sdX” depending on what order the disks are detected by your linux install. To find the right UUID type:

ls -l /dev/disk/by-uuid

Which in my case told me that my UUID for “sdb” (my USB drive) was “6858274d-2370-4377-9426-d786c3e7a410″. The line in “/etc/crypttab” that you should use in this case to add “/dev/mapper/secretvol” is:

secretvol /dev/disk/by-uuid/6858274d-2370-4377-9426-d786c3e7a410 /root/keyfile luks

Now edit your “/etc/fstab” file:

nano /etc/fstab

Add the line below to automatically mount the device to “/mnt/encrypteddrive”:

/dev/mapper/secretvol /mnt/encrypteddrive ext3 defaults 0 2

Now to test this, reboot your machine and navigate to “/mnt/encrypteddrive” where your USB drive will be mounted automatically for you. Easy!

Simple setup of Oracle 11g Release 2 on CentOS 6.3, including pdksh and all dependencies, in VirtualBox

I’ve installed Oracle Database 11g Release 2 a few times on various Linux installs and apart from a few quirks it is a pretty similar process on most. The absolute bare bones default install, as described here, is easy to set up and doesn’t take that long. You can see more detail, including all the recommended steps if you follow the instructions in the Oracle install guide. I will describe installing 32bit Oracle Database 11g Release 2 on CentOS 6.3 32bit with the UI installed so we can use the Oracle installer directly. My computer’s name was “localhost.localdomain” as I was testing this in a development VirtualBox install.

First download Oracle 11g Release 2 from their website. For a linux install it comes as 2 zip files which you must first accept the license for before downloading. The exact version I downloaded was “Oracle Database 11g Release 2 ( for Linux x86″.

Now you need to prepare your CentOS install by adding the required users and user groups for the install process. In my setup I am following oracle and running the following commands to add the “oinstall” and “dba” user groups:

groupadd oinstall
groupadd dba

Now add the “oracle” user, who we will be using to run the Oracle 11g install and give the user the correct group membership:

useradd -g oinstall -G dba oracle

Now create a directory and set the appropriate permissions where you are going to install Oracle. In my case I have installed it in the “oracle” user’s home directory under “/home/oracle/app”:

mkdir -p /home/oracle/app
chown -R oracle:oinstall /home/oracle/app/
chmod -R 775 /home/oracle/app/

Now extract the Oracle ZIP files downloaded earlier into somewhere sensible. I chose “/home/oracle/database”. Navigate to the directory and run the install script as your new oracle user:

su oracle

cd /home/oracle/database

NOTE: In my case, because this CentOS install was a VirtualBox virtual machine I needed to explicitly set the $DISPLAY variable to the local machine before the UI for the installer would run. This is done by running the following command and restarting my shell:

export DISPLAY=:0.0

Now the installer will start up. You can ignore entering your email in the first step “Configure Security Updates” and leave the default setting of “Create and configure a database” in the second step “Installation Option”.

For the “System Class” step of the install I just left it as the default “Desktop Class” and in the “Typical Installation” step I left everything as default apart from setting the Administrative password. The default settings puts the oracle base in “/home/oracle/app/oracle” with a global database name of “orcl.localdomain”. For the “Create Inventory” step I left the default folder of “/home/oracle/app/oraInventory” and the group name “oinstall”.

Now we get on to the interesting part of the install, which is the “Prerequisite Checks” stage. If you are running the install on a brand new copy of CentOS you will need to set a few system variables and install a set of prerequisites.

NOTE: You may not need to, but I needed to add more swap space to my CentOS install this time around in order to meet the prerequisites. Run the following commands as root to create a 2048mb swap file called “/swapfile” on your harddrive and set CentOS to use it for swap space:

dd if=/dev/zero of=/swapfile bs=1024 count=2097152
mkswap /swapfile
swapon /swapfile

Now set CentOS to always use this swap space at boot by editing your “/etc/fstab” file using the command:

nano /etc/fstab

And add the following line:

/swapfile  swap  swap  defaults  0  0

So if you have passed the swap space test in the “Prerequisite Checks” in the Oracle install you can start to fix all those “Failed” messages. Click on the button “Fix & Check Again” and a window will pop up to tell you about the handy “” script that will be placed in “/tmp/CVU_11.”. So in your shell, navigate to the directory as root and run the script:

cd /tmp/CVU_11.

The “” script will fix all the system variables for you so you don’t need to set them manually. Now all that remains is to fix the dependencies, most of which can be installed using “yum” with the following command:

yum install gcc gcc-c++ compat-libstdc++-33 elfutils-libelf-devel libaio-devel libstdc++-devel unixODBC unixODBC-devel

Now the only remaining prerequisite that causes a “Failed” message is “pdksh-5.2.14″ which has been removed from the CentOS repositories after CentOS 5 (see here). The replacement is “ksh” but if you install this package using “yum install ksh” you will get the same dependency check “Failed” in the Oracle install for “pdksh-5.2.14″ and “ksh” will conflict with “pdksh” if you then go to install it.

The solution is to install “pdksh” manually from RPM, which can be found at a variety of mirrors. I used the following command to install the “pdksh” package:

rpm -q

Now Oracle should pass all the prerequisite checks and you will see the “Summary” step of the install where you can click the “Finish” button. It may take a while but Oracle Database will install with all the required settings ready for you to use out of the box.

The final step is to execute the configuration scripts as root, which will pop up after you have unlocked any users you might need other than the defaults (you don’t need to though at this stage). The two scripts can be run as follows:

cd /home/oracle/app/oraInventory/

cd /home/oracle/app/oracle/product/11.2.0/dbhome_1/

To test your install worked you can log in to the web based management interface for your computer “localhost.localdomain” with the user name “SYS” connecting as “SYSDBA” and using the password you set during the install of Oracle. Remember to open port 1158 on your firewall if you need to:


Now you can start to use Oracle. I highly recommend looking through the documentation from Oracle themselves to help get yourself used to the Oracle way of doing things. There are loads of client applications that can help, like the command line based Oracle Instant Client and the Oracle SQL Developer UI program. Oracle have a lot of good walkthroughs for working with their tools which are available as part of their Learning LIbrary.

Easily set up and automatically start Apache Tomcat 7 Java web server in Ubuntu Linux

Apache Tomcat is actually easier than the standard Apache webserver to set up, which is great news if you are working with Java based web applications. All you need to do is download it and make sure it starts with whichever linux distribution you are using. Deploying applications in standard WAR format is really easy as well due to the simple web based management interface.

In my case I wanted Tomcat to start with Ubuntu and sit on the default port 8080 so I could have it running alongside my standard Apache webserver for PHP. We were developing a Spring application and used Maven to build and compile to a single deployable WAR file. You must have Java installed and set up for this to work. To check you have Java set up type:

java -version

This should tell you what version of java you have installed (hopefully Java 1.7). You also need to check that the “JAVA_HOME” variable is set by typing:


If you don’t get something like “/usr/lib/jvm/jdk1.7.0_09″ please install Java following my installation instructions in a previous post.

To install Apache Tomcat first of all I downloaded the latest copy of Tomcat 7 from using wget run from my home directory:


Please note that the version I downloaded may not be available or there may be a newer version so check first before running the wget.

“wget” will download the file, which then needs to be extracted:

tar xvzf apache-tomcat-7.0.32.tar.gz

Now you will have a folder “apache-tomcat-7.0.32″ in your home directory. This needs placing somewhere sensible so copy it to “/usr/share/tomcat7″ using:

sudo mv apache-tomcat-7.0.32/ /usr/share/tomcat7

Now you can test your Tomcat install works with its default settings by starting it up. Note: before you do this you need to set the “JAVA_HOME” variable otherwise you will get errors (see my previous post).

To start up Tomcat navigate to “/usr/share/tomcat7″ and run “”:

cd /usr/share/tomcat7


With the default settings you should now be able to reach your Tomcat server home page by navigating to “http://your.ip.add.ress:8080″ where you should hopefully see the homepage and a nice message saying:

“If you’re seeing this, you’ve successfully installed Tomcat. Congratulations!”

Now we need to set up management users for the manager app so we can easily deploy our WAR files containing our Java web applications. You need to edit “/usr/share/tomcat7/conf/tomcat-users.xml”:

sudo nano /usr/share/tomcat7/conf/tomcat-users.xml

Now add the following lines within the “<tomcat-users>” block to give access to the manager GUI:

<role rolename=”manager-gui”/>
<user username=”MANAGERUSER” password=”YOURPASSWORD” roles=”manager-gui”/>

Now you will be able to log in to the manager GUI at “http://your.ip.add.ress:8080/manager/html” using the login details MANAGERUSER and password YOURPASSWORD. You can deploy applications and generally manage your Tomcat install from here.

The final thing to do is to set up Tomcat so that it starts every time your server starts. This is pretty easy as all you need to do in Ubuntu is edit the “/etc/init.d/tomcat7″ file:

sudo nano /etc/init.d/tomcat7

Now enter the following lines:

# Tomcat auto-start
# description: Auto-starts tomcat
# processname: tomcat
# pidfile: /var/run/

case $1 in
sh /usr/share/tomcat7/bin/
sh /usr/share/tomcat7/bin/
sh /usr/share/tomcat7/bin/
sh /usr/share/tomcat7/bin/
exit 0

Set the permissions for the file:

sudo chmod 755 /etc/init.d/tomcat7

Add Tomcat to system startup as a service using the command:

sudo update-rc.d tomcat7 defaults

Now you can test that Tomcat is set up as a service using:

sudo service tomcat7 restart

Now to check everything is working on system startup reboot your machine using:

sudo reboot now

Navigate to “http://your.ip.add.ress:8080″ where the Tomcat home page should appear with no problems. Note: If you are having problems reaching your Tomcat home page make sure you have opened port 8080 on your server’s firewall.

It’s definitely worth reading some of the documentation on Tomcat, plenty of which is linked off your newly installed Tomcat home page. You should now have all you need to deploy your Java web applications as WAR files which is really easy using the manager GUI provided by Tomcat.

Upgrade PHP from 5.1.6 to 5.2.17 on CentOS

The default install of PHP on our CentOS 5.5 box was 5.1.6, which is very out of date (we are currently using PHP 5.3 elsewhere while we figure out how to get around some very serious problems with 5.4). Unfortunately, we needed to upgrade to PHP 5.2 and no further as 5.3 meant upgrading MySQL and potentially breaking compatibility with our web application.

It used to be that you could add the CentOS testing repositories and just update PHP but as PHP 5.2 is depreciated this option is no longer available. The solution is to use the Atomic repositories which can be added to your CentOS install by typing:

wget -q -O – | sh

This will add a new repository file “/etc/yum.repos.d/atomic.repo” which means we can use their packages as well as those from CentOS. Now we need to make sure that we don’t upgrade our PHP beyond 5.2 so we add a single line to “/etc/yum.conf” under the [main] section:


The exclusion means we will include packages from all repositories other than anything that matches “php-*5.3*” so PHP 5.3 won’t be installed as part of an upgrade.

Now just upgrade PHP and restart Apache:

yum update php

service httpd restart

You can check which PHP version you have using:

php -v

Now obviously you want to use a more recent version of PHP than 5.2 but in the rare case where you have to, the previous commands make things very easy.

Check for large directories in linux (and check Apache logging!)

We had a problem where a server wasn’t allowing us to upload any more files using our web application’s interface. This was due to an enormous “error.log.1.txt” in “/var/log/apache2/” caused by setting our log level to warnings rather than errors. Thanks to Josh at I could run a command and quickly find directories over 1GB in size:

du -h / | grep ^[0-9.]*G

This quickly showed up our 12GB log file..

Set Linux Firewall Rules for a Range of IP Addresses using Webmin

Network address ranges are set slightly differently to standard wildcards. For example, to describe a range of IP addresses from to you use:

Where 16 describes the number of bits in the IP address that are used for comparison. In this case the 16 describes the first 2 bytes of the address: 192.168. You can read more about IP addressing at Rhyshaden’s Data Network Resource (and various other places).

To set your linux firewall up in webmin to use a range of IP addresses, just use the wildcard notation above. So in Webmin – Networking – Linux Firewall, when you are editing a rule in iptables you can put in to describe a range of IPs (e.g. in the “source address or network” field to restrict access to a certain IP range). Manually setting these rules is more tricky but there are resources out there like Linux Home Networking and the Easy Firewall Generator to help. We just used Webmin as it makes this kind of work very easy indeed.