Category Archives: Linux

Enabling ModSecurity protection in Apache2 on Ubuntu

 

This post documents how to add ModSecurity protection in Ubuntu's Apache. It has been tested on Ubuntu 11.04 but might work on earlier or latter issues with few modifications.

Installation of base packages

ModSecurity is a open source Web Application Firewall (WAF). It offers an array of request filtering and other security features to the Apache HTTP Server.

Fortunately, ModSecurity is already part of the Ubuntu package repositories. Therefore, installing the necessary stuff is rather straightforward:

apt-get install libapache2-mod-security mod-security-common
a2enmod mod-security
/etc/init.d/apache2 force-reload

Activation of the core rule set

The mod-security-common-package contains the core rule set (crs) which will not be configured automatically. In order to activate the crs, /etc/apache2/conf.d/mod-security.conf has to be created with the following content:


    Include /usr/share/doc/mod-security-common/examples/rules/*conf
    Include /usr/share/doc/mod-security-common/examples/rules/base_rules/*conf

Now the web server has to be restarted by the following line:

service apache2 restart

Testing the setup

In order to prove the setup is working, a test file called test.php with the following content can be used:

It's supposed to be placed in the root of your web server, so that it can be accessed by http://yourserver.tld/test.php. To run the actual test, the following address will do:

http://yourserver.tld/test.php?secret_file=/etc/passwd

If the content of /etc/passwd is displayed, ModSecurity is not working. A working installation will show a "403 Forbidden" error message.

Hardening PHP on Ubuntu with Suhosin patches

This post documents how to enable the Suhosin protection system for PHP on Ubuntu installations. It has been tested on Ubuntu 11.04 but might work on earlier or latter issues with few modifications.

Apparently, Ubuntu repositories already contain the patches as an additional package. They are installed by the following line:

aptitude install php5-suhosin

After that, the patches are available but not yet configured. The central config file for the protection system is located at /etc/php5/conf.d/suhosin.ini. For a basic configuration uncomment the following lines:

[suhosin]
suhosin.executor.include.max_traversal = 4
suhosin.executor.disable_emodifier = on
suhosin.mail.protect = 2

; Filtering Options   
suhosin.cookie.max_vars = 2048
suhosin.get.max_array_index_length = 256
suhosin.post.max_array_index_length = 256
suhosin.post.max_totalname_length = 8192
suhosin.post.max_vars = 2048
suhosin.request.max_totalname_length = 8192
suhosin.request.max_varname_length = 256

Defining the latter options keeps phpMyAdmin working. After editing the file, the changes are activated by restarting the Apache daemon:

service apache2 restart

Now you may play around with the other config options in order to harden your webserver even more.

GPG secured Backups

 

There are some situations in which it becomes useful to store important and crucial data in non-trustworthy environments. One example can be an off-site backup at an external hoster where full control over the infrastructure can not be maintained. Then, encrypting your files comes in handy so that in an emergency the data can be restored and only the according key has to stay save.

Key creation

A new public/private key pair is generated by running

gpg --gen-key

Just follow the prompts. Depending on the use case and level of later automation it can be useful to skip the definition of a passphrase. Keep the key ID in mind for the next step (you can display it again with gpg --list-keys). The keys are now stored in the user's home directory in ~/.gnupg/secring.gpg and ~/.gnupg/pubring.gpg. Remember to keep these files save.

Encryption of data

Now, tar is used to archive directories and files and pipe the resulting package into gpg:

tar -c {dirs_and_files_to_backup} | gpg -r {gpg_key_id} -e -o backup.tar.gpg

The resulting backup.tar.gpg can savely be stored at some non-confidential place. If your data can be compressed, it may be useful to replace tar -c by tar -cz in order to compress the data during archiving.

Decryption of data

To retrieve your data from the encrypted archives, the previous process is basically reversed:

gpg -d backup.tar.gpg | tar xf -

If you compressed your data in the encryption process you need to replace tar xf by tar xzf.

Setup of Roundcube Webmail 0.5.x on Ubuntu 10.10

 

[Sieve]: Sieve: filtering language
[Openmailadmin]: IMAP management frontend
[IMAP Idle]: Immediate notification of users about any mailbox changes
[IMAP]: IMAP: Internet message access protocol
[Roundcube]: Roundcube: browser-based IMAP client
[SASL]: Simple Authentication and Security Layer
*[MTA]: Mail Transfer Agent

This is a follow-up article on the previous post on how to Migrate IMAP Accounts from one Server to another.

Roundcube is a very decent browser-based IMAP client with an application-like UI.

Retrieving Roundcube package

As Roundcube is under heavy development, the Ubuntu packages are quickly outdated. Therefore, we download the most recent package from the Roundcube project page http://roundcube.net/download.

Download the linked tar.gz-archive into /var/www:

cd /var/www && wget {copied_download_link}
tar xzf {downloaded_file}.tar.gz && mv roundcubemail-0.5.1 roundcubemail

Creating necessary SQL tables

The next step is to create the SQL tables. Do is as follows:

cd /var/www/roundcubemail
mysql -u root -p # enter MySQL's root-user password 
  CREATE DATABASE roundcubemail /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
  GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost \
  IDENTIFIED BY '{choose_your_password}';
  quit
mysql -u root -p roundcubemail < SQL/mysql.initial.sql

Adjusting Roundcube config-files

Now, the Roundcube configuration needs to know about the whereabouts of its database. Therefore, edit the according file config/db.inc.php. First create a local copy of the dist file:

cd /var/www/roundcubemail
cp config/db.inc.php.dist config/db.inc.php

Replace "pass" with Roundcube's database password in the following line:

$rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';

Now, create the second relevant configuration file, main.inc.php:

cp config/main.inc.php.dist config/main.inc.php

To use Roundcube for your locally installed server, enter localhost in the following line:

$rcmail_config['default_host'] = '';

There are loads of other configuration options in main.inc.php, giving the possibility to tweak the very last bit of Roundcube. You might want to read the according comments in the config file which describe them in detail.

Install Openmailadmin for Cyrus 2.2 in Ubuntu 10.10

 

[Sieve]: Sieve: filtering language
[Openmailadmin]: IMAP management frontend
[IMAP Idle]: Immediate notification of users about any mailbox changes
[IMAP]: IMAP: Internet message access protocol
[Roundcube]: Roundcube: browser-based IMAP client
[SASL]: Simple Authentication and Security Layer
*[MTA]: Mail Transfer Agent

This is a follow-up article on the previous post on how to Migrate IMAP Accounts from one Server to another.

Openmailadmin is an administrative interface to IMAP mailservers including cyrus-imapd. It requires a webserver (we use Apache), a database (MySQL in our case) and PHP of version 5.1 or later. Openmailadmin features a generic administration hierarchy and is fairy easy to use -- especially compared to a rarely used and rather cryptic cyradm cli-command.

Required Ubuntu packages

To setup Openmailadmin, this line needs to be run in order to install the necessities:

aptitude install apache2-mpm-prefork php5-mysql mysql-server-5.1 \
                 libphp-adodb php-log php5-idn

You might want to enable SSL in Apache2. If so follow the Simple activation of SSL for Apache2 in Ubuntu 10.10.

Get Openmailadmin

Now, it's time to get the Openmailadmin package. Create it's directory, download the package and extract it like this:

mkdir -p /var/www/ && cd /var/www/
wget http://static.ossdl.de/openmailadmin/downloads/openmailadmin-1.0.1.tbz2
tar xjf openmailadmin-1.0.1.tbz2
mv openmailadmin-1.0.1 openmailadmin && rm openmailadmin-1.0.1.tbz2
chown -R www-data:www-data /var/www/openmailadmin

Set up Openmailadmin

The next step is to access setup.php by opening https://www.{your_server_name}.tld/openmailadmin. If you installed all dependencies in the first step, you should be good to go to set up the Openmailadmin backend.

The second step in the setup frontend is a bit more complicated, yet quite well inline-documented.

Configuration of PAM

To make saslauthd work with your new databased authentication system, you will need to install the appropiate package:

aptitude install libpam-mysql                   

Also, you neet to adjust /etc/pam.d/imap. Replace these lines:

@include common-auth
@include common-account 

with these (don't forget to set the variables in the curly brackets with your settings):

auth    sufficient pam_mysql.so user={db_user} passwd={db_password} host=localhost db={db_name} table=user usercolumn=mbox passwdcolumn=password crypt=3 sqlLog=0
account required   pam_mysql.so user={db_user} passwd={db_password} host=localhost db={db_name} table=user usercolumn=mbox passwdcolumn=password crypt=3 sqlLog=0

This configuration uses MD5 for password hashes. To use SHA1, you may want to replace crypt=3 with crypt=4 and edit /var/www/openmailadmin/inc/config.local.inc.php accordingly.

After entering all your config data, you may use your new administrative frontend to cyrus-imapd at https://www.{your_server_name}.tld/openmailadmin.

Migrate IMAP Accounts from one Server to another

There is a easy to use tool that facilitates the quick'n dirty move of the content of one IMAP account to a new server. Its name is imapsync. In Ubuntu, you may install it as this:

aptitude install imapsync

Now, set two files for the old and the new account in your home, containing the respective passwords of the two accounts. They are called passfile_1 and passfile_2 from now on.

Now run imapsync with the following options:

imapsync --host1 {old_imap_host} --user1 {old_imap_user} --authmech1 LOGIN \
         --passfile1 passfile_1 --port1 993 --ssl1 \
         --host2 {new_imap_host} --user2 {new_imap_user} --authmech2 LOGIN \
         --passfile2 passfile_2 --port2 993 --ssl2

You just need to adjust the ports (143 vs. ssl) and the authentication mechanisms to your needs and you're set.

Setup Cyrus IMAP-Server on Ubuntu 10.10

 

[Sieve]: Sieve: filtering language
[Openmailadmin]: IMAP management frontend
[IMAP Idle]: Immediate notification of users about any mailbox changes
[IMAP]: IMAP: Internet message access protocol
[Roundcube]: Roundcube: browser-based IMAP client
[SASL]: Simple Authentication and Security Layer
*[MTA]: Mail Transfer Agent

This article describes the installation of Cyrus IMAP-server v2.2. It will use SSL for secure access and SASL for user authentication.

Follow-up articles will explain how to add the Exim 4 as MTA, the IMAP administrative management system Openmailadmin, the spamfilter SpamAssassin and Roundcube as the webfrontend to the IMAP-server for the users.

Necessary packages

In order to set up Cyrus IMAP-server, some necessary packages have to be installed:

aptitude install cyrus-imapd-2.2 cyrus-common-2.2 sasl2-bin cyrus-admin-2.2

Activation of Saslauthd auth-daemon

In order for saslauthd to start, the following line in /etc/default/saslauthd has to be set:

# Should saslauthd run automatically on startup? (default: no)
START=yes

Now, start saslauthd:

service saslauthd start

Configuration of /etc/cyrus.conf

Now, open the file /etc/cyrus.conf in which some changes should be made. It is divided into three sections called START, SERVICES and EVENTS`.

We start with IMAP Idle. To enable it, uncomment the following line in the START section:

idled          cmd="idled"

To activate secure IMAP access and to disable NNTP the SERVICES section has to be set:

# --- Normal cyrus spool, or Murder backends ---
# add or remove based on preferences
#imap            cmd="imapd -U 30" listen="localhost:imap" prefork=0 maxchild=100
imaps           cmd="imapd -s -U 30" listen="imaps" prefork=0 maxchild=100
#pop3           cmd="pop3d -U 30" listen="pop3" prefork=0 maxchild=50
#pop3s          cmd="pop3d -s -U 30" listen="pop3s" prefork=0 maxchild=50
#nntp           cmd="nntpd -U 30" listen="nntp" prefork=0 maxchild=100
#nntps          cmd="nntpd -s -U 30" listen="nntps" prefork=0 maxchild=100

In the EVENTS section, we want to enable the SQUAT indexes for mailboxes, enabling significantly reduced search times:

# reindex changed mailboxes (fulltext) approximately every other hour
squatter_1      cmd="/usr/bin/nice -n 19 /usr/sbin/squatter -s" period=120

Configuration of /etc/imapd.conf

In /etc/imapd.conf you first need to declare the cyrus' admin user:

admins: cyrus

Now, define the authentication mechanism by setting sasl_mech_list and sasl_pwcheck_method:

sasl_mech_list: LOGIN PLAIN
sasl_pwcheck_method: auxprop saslauthd
sasl_auxprop_plugin: sasldb

To activate SSL for secure IMAP access, set the following variables and place your certificates and key accordingly:

tls_cert_file:          /etc/ssl/certs/{your_server_name}.cert.pem
tls_key_file:           /etc/ssl/private/{your_server_name}.key.pem
tls_ca_file:            /etc/ssl/{your_ca_chain}.pem 

Make sure Cyrus can read the SSL files by running this:

chmod 640 /etc/ssl/certs/{your_server_name}.cert.pem \
          /etc/ssl/private/{your_server_name}.key.pem \
          /etc/ssl/{your_ca_chain}.pem

chown :mail /etc/ssl/certs/{your_server_name}.cert.pem \
            /etc/ssl/private/{your_server_name}.key.pem \
            /etc/ssl/{your_ca_chain}.pem

Also in this file, the IMAP Idle functionality has to be set defining idlemethod:

idlemethod: idled

Activate your setting by restarting the Cyrus daemon:

service cyrus2.2 restart

Initial user creation

First, create an inital SASL password in order to enable cyrus' administrative user:

saslpasswd2 -c cyrus

Now, authenticate yourself as the user cyrus to cyradm with the previous password:

cyradm --user cyrus localhost

As user cyrus in cyradm, you may do maintenance tasks like creating a new user:

cm user.{username}

Test your authentication by running:

testsaslauthd -u username -p password

If that worked, you may now connect to your new IMAP account by accessing your server on port 993 and using the set username and password as authentication.

Install Transmission in Ubuntu 10.10 from PPA

This article explains installation of most recent Transmission versions into Ubuntu 10.10.

Ubuntu's Personal Package Archive (https://launchpad.net/ubuntu/+ppas) allows to install packages from a package repository that is managed by individual package maintainers. It contains software that is not part of the standard Ubuntu repository or that is more recent than packages in regular Ubuntu flavors.

In order to use PPAs, the package python-software-properties has to be available on the system:

aptitude install python-software-properties

Now, the transmission-ppa can be installed using the following command:

add-apt-repository ppa:transmissionbt/ppa

After updating the local package information the new transmission-daemon can be installed:

aptitude update && aptitude install transmission-daemon 

Install a new Drive with LUKS Disk Encryption

 

*[LUKS]: Linux Unified Key Setup
This article describes the process of setting up a physical drive with LUKS encrypted filesystem. The process is tested on Ubuntu 10.10.

Prepratations

First, one necessary package needs to be installed:

aptitude install cryptsetup

Setup of the partition

Initialisation of the encrypted partition is done like this:

cryptsetup -h sha256 -c aes-cbc-essiv:sha256 -s 256 luksFormat /dev/{physical_partition}

Now, the newly encrypted partition needs to be introduced to the system i.e. to the device mapper. Do this as follow with cryptfs being the device's mapping name, i.e. name it as you like:

cryptsetup luksOpen /dev/{physical_partition} cryptfs

The next step is to set up a filesystem on the partition. I prefer xfs, but you are free to choose what suits you best:

mkfs.xfs /dev/mapper/cryptfs

Now, mount your new partition:

mount /dev/mapper/cryptfs /{mount_point}

If that worked, you may want to add your encrypted partition to /etc/fstab by adding the following line. Replace {mount_point} with the location where you wish to mount your device:

/dev/mapper/cryptfs /{mount_point} xfs defaults 0 2

Set up mount at boot time

In order to let the device get mounted at boot time, you may want to add these lines to /etc/rc.local. Bear in mind that now you'll have to enter the cryptfs passphrase at boot:

cryptsetup luksOpen /dev/{crypt_partition} cryptfs
mount /dev/mapper/cryptfs

If you wish to easily mount the device from shell after boot, save the following lines as /usr/local/bin/crypt-start:

#!/bin/sh
cryptsetup luksOpen /dev/{crypt_partition} cryptfs
mount /dev/mapper/cryptfs

Make the file executable:

chmod +x /usr/local/bin/crypt-start

... and run the command crypt-start after boot.

Change LUKS passphrase

Changing an existing LUKS passphrase seems a bit odd on first sight. That is, because you first need to add a new passphrase before you can remove the old one. Yet, this helps to only change your passphrase at a point where you can be absolutely certain that you do know the new passphrase. The relevant commands look like this:

cryptsetup luksAddKey /dev/{physical_partition}
cryptsetup luksRemoveKey /dev/{physical_partition}

KVM: Migrate from qcow2 to raw Format

The qcow2 disk format has some decent features like encryption, compression and -- as its abbreviation indicates -- copy to write support. Yet, its growing size is difficult to predict. In addition, the compression and the copy processes make it quite a bit slower than raw disk images. A simple and non-representative benchmark (bonnie++ -b -u root -d /mnt) shows it:

qcow2:

Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
<host>           2G   856  94 33126   7 30392   7  4727  92 739753  70 300.4  20
Latency             51096us    2473ms     972ms    5240us    1516us     382ms
Version  1.96       ------Sequential Create------ --------Random Create--------
<host>              -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16    35   0 +++++ +++    46   0    34   0 +++++ +++    44   0
Latency               338ms     808us    2136ms     341ms     155us    2016ms

Raw:

Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
<host>           2G   885  97 18719  15 75344  70  3993  88 1663036  81 351.6 138
Latency             12763us   34358ms     273ms    4526us     520us     310ms
Version  1.96       ------Sequential Create------ --------Random Create--------
<host>              -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16    35   0 +++++ +++    49   0    35   0 +++++ +++    47   0
Latency              1324ms     797us     915ms     452ms     156us     823ms

So if you're like me and still refrain from using LVM as underlying disk layout but prefer images which can be copied and moved in a quick'n dirty way, you might want to migrate your qcow2 images to raw ones. This article describes the necessary steps.

Shutdown of the VM

First, shutdown the vm which disks you wish to convert:

virsh shutdown {vm_name}

Conversion of the image files

Each of the image files of the virtual machine have to be converted by running the following for the respective files:

qemu-img convert {image_name}.qcow2 {image_name}.raw 

Adapt the virtual machine's xml config

Now, two lines of the vm's xml configuration have to be adjusted. Do this by running:

 virsh edit {vm_name}

The lines are:

  
  

Change them to match: