Category Archives: Linux Server

Backups for your linux server

In this guide I describe how to setup backups for your Linux server. We will backup both locally and remotely for extra security. We will backup…

  • MySQL-databases using automysqlbackup.
  • Normal files using rdiff-backup.
  • Special large folders per weekday using rsync.
  • To a remote server using rsync.

Setting up the folder structure

We start out with creating a folder structure like this:

mkdir /backup
chmod 755 /backup
mkdir /backup/local
mkdir /backup/local/mysql
mkdir /backup/local/files

The new root-level folder “backup” is the storage location we will use for any kind of backups. The folder “local” inside it is where we will save the backup-files for that computer itself. Later on we will add sibling folders that contain backups from other computers.

Note that the folder “/backup” not necessarily need to be a folder on your main storage device. It could for example be a mount point or a symlink to a folder on another storage device. This makes a lot of sense if you main storage device is an SSD. Do not backup to an SSD.

Backup MySQL-databases

For MySQL-databases we will use the tool automysqlbackup. This tool is in the Ubuntu repositories. The versions are Ubuntu 12.04 with automysqlbackup 2.5 right now when I write this.

apt-get install automysqlbackup

We need to make two changes in the config file “/etc/default/automysqlbackup”:

DBNAMES=`mysql --defaults-file=/etc/mysql/debian.cnf --execute="SHOW DATABASES" | awk '{print $1}' | grep -Ev '^phpmyadmin|test|information_schema|performance_schema|mysql|Database$' | tr \\\r\\\n ,\ `
 
...
 
BACKUPDIR="/backup/local/mysql"

The grep part in DBNAMES is to exclude databases. You may want to add additional databases there that you don’t want to backup. You should now run it once to make sure it works:

automysqlbackup

Look through the contents in “/backup/local/mysql” to verify it looks the way you want it to.

Question: When will these backups run?
Answer: When installing automysqlbackup the file “/etc/cron.daily/automysqlbackup” was created. Check the content of “/etc/crontab” to see when daily cron runs. In my case it looks like this:

# m h dom mon dow user    command
17 *    * * *    root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *    root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7    root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *    root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

So it seems daily cron-tasks run at 06:25 on my system (Ubuntu 12.04).

Backup normal files

For backing up normal files we are going to use a tool called rdiff-backup that creates incremental backups.

apt-get install rdiff-backup

Question: How often should I backup?
Answer: I personally enjoy backing up once a day.

Question: How long should I save the backups?
Answer: I personally enjoy saving the backups for three months.

Question: What files should I backup?
Answer: A good start is “/home”, “/etc” and “/root”. You will however often need to setup some special exclude and include rules.

With this in mind I should create the file “/etc/cron.daily/backupfiles” with the following content:

#!/bin/bash
 
rdiff-backup \
--include /home \
--include /etc \
--include /root \
--exclude / \
/ /backup/local/files
 
rdiff-backup --force --remove-older-than 3M /backup/local/files

Ensure that file has the right permissions:

sudo chmod 755 /etc/cron.daily/backupfiles

Say however that I would like to ignore all home-files for the user “derp” and only want the folders “a” and “b” from the user “herp”.

The file would then look like this instead:

#!/bin/bash
 
rdiff-backup \
--include /home/herp/b \
--include /home/herp/a \
--exclude /home/herp \
--exclude /home/derp \
--include /home \
--include /etc \
--include /root \
--exclude / \
/ /backup/local/files
 
rdiff-backup --force --remove-older-than 3M /backup/local/files

It is important to consider that:

Multiple include and exclude options take precedence in the order they are given.
- http://www.nongnu.org/rdiff-backup/examples.html#exclude

I prefer looking at the include/exclude order like this:

  • The deeper the directory paths – the higher up in that cron-file they should be written.
  • We can visualize the end result by imagining we apply the includes/excludes from bottom up.

Backup normal files using crontab

I actually prefer having more fine grained control over when backups are run. For this we will use crontab. Start out with creating a folder for your cron-scripts:

mkdir /root/cron

And then create the file “/root/cron/backupfiles.sh” instead of the file “/etc/cron.daily/backupfiles”. Next we add a crontab entry as root:

crontab -e

If we want it to run the same time as automysqlbackup (06:25) the crontab entry would look like this:

#m      h       dom     mon     dow     command
25      6       *       *       *       /root/cron/backupfiles.sh

Backup special large folders per weekday

To be more precise I run a few minecraft servers. The map files are huge and change often because they are compressed natively. If we took incremental backups (rdiff-backup) those increments would be very large due to the compression. I prefer creating this setup instead:

mkdir /backup/local/server
mkdir /backup/local/server/1
mkdir /backup/local/server/2
mkdir /backup/local/server/3
mkdir /backup/local/server/4
mkdir /backup/local/server/5
mkdir /backup/local/server/6
mkdir /backup/local/server/7

Monday is “1″ and Sunday is “7″. Next we create the script “/root/cron/backupserver.sh”.

#!/bin/bash
rsync -avz --delete /home/mc/files/server/ /backup/local/server/$(date '+%u')

Note that after the first week the old backups will start getting overwritten.
Lets add it to the root crontab as well:

#m      h       dom     mon     dow     command
25      6       *       *       *       /root/cron/backupfiles.sh
35      6       *       *       *       /root/cron/backupserver.sh

Backup to a remote server

For extra security it makes sense to backup to a remote computer as well. Lets call the local computer “torkel” and the remote computer “berit”. Let’s also assume entries for those are added to the file “/etc/hosts” so they resolve into actual ip-addresses.

For this we could simply rsync the folder “torkel:/backup/local” to “berit:/backup/torkel” but in our case the folder “torkel:/backup/local/server” will be huge. We thus only synchronize “torkel:/backup/local/1″ (the monday server backup).

Create a user for torkel@berit and create the backup folder:

ssh root@berit
adduser torkel
* give it a password for now *
mkdir /backup/torkel
chown torkel.torkel /backup/torkel

Create a private key for root@torkel and transfer it to torkel@berit:

ssh root@berit
ssh-keygen
ssh-copy-id torkel@berit

Remove the password from torkel@berit:

ssh root@berit
passwd -d torkel

Create the script “/root/cron/backupremote.sh”.

#!/bin/bash
rsync -avz --delete \
--include server/1 \
--exclude server/* \
/backup/local/ torkel@berit:/backup/torkel

Note that the include/exclude syntaxes are different for rsync and rdiff-backup.
Lets add it to the root crontab as well:

#m      h       dom     mon     dow     command
25      6       *       *       *       /root/cron/backupfiles.sh
35      6       *       *       *       /root/cron/backupserver.sh
 0      7       *       *       *       /root/cron/backupremote.sh

Restoring MySQL-databases

TODO

Restoring normal files

TODO

Restoring special large folders

TODO

Adding a new storage-device

This guide covers how to add a new storage device (such as a platter or a solid state drive) to your Linux machine. All work is done from the command-line.

Selecting the right storage device

This guide does not cover selecting the right model or kind of storage device.

Plugging the device into the computer

This guide does not cover how to plug the device into the computer.

What’s the device name?

Now that the device is plugged into the computer we should figure out what name it got. It usually follows the pattern /dev/sdX where X is a letter (a, b, c, d…).

Step 1 is to find the names of all devices.

  • ls /dev/sd*

    Is a somewhat crude method that is often used and often works.

  • cat /proc/partitions

    /proc/partitions will list all the block devices and partitions that the system recognizes.

  • fdisk -l

    This will list the partition tables for the devices mentioned in /proc/partitions. I personally dislike fdisk since it can’t handle GPT partition tables. We will look into that subject later.

Step 2 is to figure out which of these devices is the new one.

  • A new storage-device almost never has a partition table setup. Perhaps you already know from the output of the previous two commands.
  • mount
    df

    Those two commands will give you info on what devices are mounted where and if they are filled with anything yet. Your device is probably not mounted already.

  • cat /etc/fstab

    A properly setup storage-device should have an entry in /etc/fstab. Your device is probably not in there.

You should now have figured out the device name and for the rest of the guide we will call the device /dev/sdX.

Partitioning and file system

You may skip this section if your storage device already has partitions and you want to keep them.

We use the application “parted” to setup a partition table.I personally prefer the partition table type “gpt” since it can handle disks larger than 2TB:

parted
select sdX
mktable gpt
quit

We now have a partition table but no partitions. You can view info on the storage-device at any time using parted “print” command:

parted
select sdX
print
quit

Lets create one large partition only:

parted
select sdX
mkpart primary 0% 100%
quit

We now have a partition covering all of the device. Note how we used %-notation and parted will then align the partition for best performance. If you try entering detailed values manually you may get the message “Warning: The resulting partition is not properly aligned for best performance.”. Now lets place an ext4 file system on that partition:

mkfs.ext4 /dev/sdX1

And that is pretty much it. The partitions and file systems are set up. This would be all the commands in a batch:

parted
select sdX
print
mktable gpt
print
mkpart primary 0% 100%
print
quit
mkfs.ext4 /dev/sdX1

Creating a mount-point

A mount point is simply a directory. We should create one using the mkdir command, but where should we put it? I do not know the best practice here but the folders /media and /mnt both seem to be used for temporary mount points. As our storage device is a permanent one I suggest creating a brand new top-level folder for it. For example:

mkdir /hdd

What file permissions should this new directory have? It does not matter. They will be changed as we mount something onto the directory.

Temporarily mounting the device partition

To temporarily mount the device partition we can run the command:

mount -t ext4 /dev/sdX1 /hdd

This will however only get it mounted once. We should create an entry in /etc/fstab to make it mount automatically on reboot.

Permanently mounting the device partition using fstab

Step 1 is to find the partition UUID. To add the filesystem by UUID is a good idea since you will be able to switch around with SATA hardware contacts and the system will still work. Find the UUID using any of these commands:

  • ls -l /dev/disk/by-uuid
  • blkid

It may also be fun to know the model number of the storage device. You may get this info using:

hdparm -I /dev/sdX

Step 2 is to add the info to /etc/fstab. Please read up more on fstab elsewhere since my info here is not complete.

Are you running on an SSD? In such case you should add the “discard” option to /etc/fstab. Doing that will enable automatic TRIM and works well on ext4 filesystems. You can also stop writing last access time for files and folders by adding the option “noatime”.

What you add could look something like either of these two:

#
# A "WDC WD1002FAEX-00Y9A0" for extra storage.
# The device was on /dev/sdb1 when added on 2012-07-16 (YYYY-MM-DD)
UUID=10e27590-16c0-44cd-9a61-07e03b97c46d /hdd ext4 defaults 0 0
#
# A Crucial M4 SSD for main storage.
# / was on /dev/sda1 during installation
UUID=6fbfc91d-e514-4bfe-a785-f3c207763dbe / ext4 noatime,discard,errors=remount-ro 0 1

Make sure you leave a blank line at the end of the file. If you do not you will get a warning message in the next step:

Step 3 is to test that the fstab entry is correct. First unmount the /hdd using:

umount /hdd

In case you get the warning message “umount: /hdd: device is busy.” you are probably standing in the device. Use “cd /” to get out of there and try again.

Now ensure everything in /etc/fstab is correct by mounting all of it:

mount -a

Persistent ramdisk with tmpfs and rsync

Minecraft reads and writes a lot from disk. In order to speed this up we can store the files in memory instead. If you google “minecraft tmpfs” you will find a lot of info on this.

The main issue is that ramdisks created using tmpfs are temporary. The content is wiped on a system reboot.

The script I created takes care of persisting the ramdisk. It is a general solution that can be used for any content. Minecraft servers included.

Download RamDriveTick
This is the content of the file:

#!/bin/bash
 
# QUESTIONG: What's the purpose of this script?
# ANSWER: 
# The purpose is to mount a part of the computers RAM to a folder on the harddrive.
# This will make IO to that folder VERY fast. However the content of such a folder
# will be erased on system restart. This script uses rsync to mirror the content of
# another folder on the harddrive. This way the persistance issue is solved as well
 
# QUESTIONG: How do I use this script?
# ANSWER: 
# Make sure this script runs 
#  - directly after system start
#  - directly before system shutdown
#  - every once in a while
#
# You whould not care about the hdd-folder (on the hard-drive).
# Work with the files in the ram-folder. This script will take care of the save and
# load to hdd. See the hdd-folder as a persistance backup you don't need to care about :)
 
# QUESTION: How do I install this? 
# QUESTION: Where should I put this script?
# QUESTION: How do I make it execute at those times you mentioned above?
# ANSWER: (For Ubuntu)
# Put this script here: /etc/init.d/ramdrivetick
# Then run this: chmod +x /etc/init.d/ramdrivetick
# Then run this: update-rc.d ramdrivetick defaults
# The script will now run on startup, reboot and shutdown.
# To make it run each other create a file /etc/cron.hourly/runramdrivetick with this content
# ---------
# #!/bin/bash
# . /etc/init.d/ramdrivetick
# ---------
# Then run this: chmod +x /etc/cron.hourly/runramdrivetick
# If you get this message: /bin/bash^M: bad interpreter: No such file or directory
# This means that you have incorrect line endings in the file. Make them linux line endings.
 
# QUESTION: How do I uninstall this? 
# Run this: rm /etc/cron.hourly/runramdrivetick
# Run this: update-rc.d -f ramdrivetick remove
 
# QUESTION: How can I trigger a manual "tick"?
# Run this: service ramdrivetick
 
# ===== Configuration START =====
SIZE="4000m" #Size of the RAM folder. This obviously can not be more than the RAM available on your system.
FOLDER_RAM="/ramdrive" # Path to the folder where the ram will be mounted
FOLDER_HDD="/ramdrivehdd" # Path to our backup hdd folder
PERMMODE="0755" # The permission for the folders. Used when creating non-existing folders and when mounting.
MARKFILE_INITIATED=".zz_ramdrive_initiated" # This file is used to mark if the initial move of items from hdd to ramdisk yet is done
MARKFILE_RUNNING=".zz_ramdrive_sync_is_running" # Marking that an action is running at the moment.
# ===== Configuration END =====
 
# Calculate folderpaths for the markers
MARKFILE_INITIATED_FOLDER="${FOLDER_RAM}/${MARKFILE_INITIATED}"
MARKFILE_RUNNING_FOLDER="${FOLDER_RAM}/${MARKFILE_RUNNING}"
 
# ===== Function Declarations START =====
func_sayhi()
{
	echo ""
	echo "====== RamDriveTick START ======"
}
 
func_exit()
{
	echo "====== RamDriveTick END ======"
	exit 0
}
 
func_mark_open()
{
	# Stop if a sync is running already
	if [ -e "${MARKFILE_RUNNING_FOLDER}" ]; then
		echo "A sync is already in progress. Exiting."
		func_exit
	fi
	# Otherwise mark this sync in progress
	touch ${MARKFILE_RUNNING_FOLDER}
}
 
func_mark_close()
{
	rm ${MARKFILE_RUNNING_FOLDER}
}
 
func_makefolders()
{
	# Create the folders if they don't exist :)
	if [ ! -d "${FOLDER_HDD}" ]; then
		echo "Creating hdd folder \"${FOLDER_HDD}\""
		mkdir -p ${FOLDER_HDD}
		chmod ${PERMMODE} ${FOLDER_HDD}
	fi
	if [ ! -d "${FOLDER_RAM}" ]; then
		echo "Creating ram folder \"${FOLDER_RAM}\""
		mkdir -p ${FOLDER_RAM}
		chmod ${PERMMODE} ${FOLDER_RAM}
	fi
}
 
func_mount()
{
	# Mount the tmpfs if it isn't already mounted
	if ! mountpoint -q "${FOLDER_RAM}"; then
		echo "Mounting a tmpfs with size ${SIZE} to the ram mountpoint folder \"${FOLDER_RAM}\"."
		mount -t tmpfs -o size=${SIZE},mode=${PERMMODE} tmpfs ${FOLDER_RAM}
	fi
}
 
func_sync()
{
	# Syncronize
	if [ -e "${MARKFILE_INITIATED_FOLDER}" ]; then
		echo "Saving from memory to disk."
		rsync -av --delete --exclude ${MARKFILE_INITIATED} --exclude ${MARKFILE_RUNNING} "${FOLDER_RAM}/" ${FOLDER_HDD}
	else
		echo "INIT! The ram drive content will now be synchronized to look like the hdd content."
		rsync -av "${FOLDER_HDD}/" ${FOLDER_RAM}
		touch ${MARKFILE_INITIATED_FOLDER}
	fi
}
# ===== Function Declarations END =====
 
# ===== Execute START =====
func_sayhi
func_makefolders
func_mount
func_mark_open
func_sync
func_mark_close
func_exit
# ===== Execute END =====

OR you could just move your whole server there :) That way you won’t need to mess with symbolic links at all. If you are using the dynmap plugin you should configure so the rendered tiles are stored elsewhere. Because all those images can easily reach over 10 gigabytes.

Creating a Minecraft SMP Bukkit Server

Get a VPS

In the long run you should use a VPS instead of hosting on your own computer. This way you can turn of your computer at home and still be able host the server 24/7.

  • The server should have at least one gigabyte ram.
  • The server should not use OpenVZ for virtualization. It would work but you might face memory allocation issues. You should go for Xen virtualization.

In the continuation I will assume the VPS is using Ubuntu as OS.

Install Java

sudo apt-get update
sudo apt-get install sudo apt-get install openjdk-7-jdk

That will install java for you.

Get the minecraft server

http://wiki.bukkit.org/Setting_up_a_server

Start it

You should get to know the terminal command screen if you does not already.

sudo apt-get update
sudo apt-get install screen

Now you can start the server in a screen and detach from it to keep the server running.

My server setup checklist

This is the checklist I follow when I create a new Linux Debian Server.
The goal is a safe shared hosting environment where every user can ssh to the server but no user can see the content of another users home folder.

Setup language

You need to setup language if you get error messages like this one

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = "en_US.UTF-8",
        LC_ALL = (unset),
        LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

Run the following two commands to solve the issue:

locale-gen en_US en_US.UTF-8
dpkg-reconfigure locales

File Permissions

Files should be restricted to the owner only. This must be the case for newly created files. Thus we set an umask that works both locally and over SSH. We also ensure the home folder for the current user, as well as future ones, has those strict permissions.

  1. In the file /etc/login.defs
    do: umask 077
  2. In the file /etc/profile
    do: umask 077
  3. In the file /etc/pam.d/common-session
    do: session optional pam_umask.so umask=077
    (you might just need to append ” umask=077″ at the end of an existing line)
  4. In the file /etc/adduser.conf
    do: DIR_MODE=0700
  5. run: chmod -r 700 /home/CURRENTUSER

Login security and Root login security and sudoers

You should not be able to log in as root using password. Instead we use key authentication for root.

  • Paste your public key into /root/.ssh/authorized_keys
  • Try to log in using your key to make sure this works.
  • passwd -d root
  • Modify /etc/sudoers to give your own account full sudo rights. My file looks like this somewhere in the middle:
    # User privilege specification
    root	ALL=(ALL) ALL
    UNAME	ALL=(ALL) ALL

    That is a kinda crude way to do it. On ubuntu the standard way to do is to add the user to the admin group:

    sudo adduser USERNAME admin

IP configuration

http://www.go2linux.org/add-second-ip-linux-ubuntu-etc-network-interfaces-709.html

http://www.cyberciti.biz/tips/howto-ubuntu-linux-convert-dhcp-network-configuration-to-static-ip-configuration.html

http://www.cyberciti.biz/faq/setting-up-an-network-interfaces-file/

  1. Make the changes to /etc/network/interfaces
  2. /etc/init.d/networking restart

Configure mounts and limit disk IO

Please start with reading my guide on how to add storage devices.

If you have loads of RAM available and want to limit disc IO you can tell the kernel to avoid swapping processes out of physical memory for as long as possible:

sudo sysctl vm.swappiness=0

Add/Remove new users

To add a new user use the command: adduser [username]
Note that usage of this command (adduser) is recommended compared to using the more lowlevel command useradd.

To remove a user use the command: userdel -fr [username]
The -fr part makes sure home folder and other files are delete.
Without it you will have to delete the files using another command.

To list the current users: cat /etc/passwd | cut -d”:” -f1

Install webserver packages

We instal:

  • Apache using the ITK mpm due to security reasons and mod macro
  • PHP and some must have extenstions
  • PHPMyAdmin
  • Postfix
sudo apt-get install apache2 apache2-mpm-itk
sudo apt-get install libapache2-mod-macro
sudo a2enmod macro proxy_http rewrite
sudo apt-get install php5 php5-gd php5-curl php5-mcrypt
sudo apt-get install mysql-server mysql-client libapache2-mod-auth-mysql php5-mysql
sudo apt-get install phpmyadmin
sudo apt-get install postfix

Configure PHP

Change the following values in /etc/php5/apache2/php.ini
To increase some limits

  • upload_max_filesize = 50M
  • post_max_size = 50M

Configure MySQL

We want mysql to use utf8 per default instead of latin1. Find your MySQL configuration file (on most Linux/BSD systems it’s /etc/mysql/my.cnf) and make sure it’s got the following statements under the relevant headers. None of these settings should be set per default so just paste them directly under the corresponding header:

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

Also make sure you only accept connections from localhost. This is good for security and is the default in Ubuntu 11.10:

[mysqld]
bind-address=127.0.0.1

If you scan your computer from the outside using nmap you will notice that port 3306 is actually closed from the outside world. With this setting there is no reason to add firewall rules for it.

Restart MySQL and make sure it’s working;

service mysql restart

TODO: query cache size etc.

Configure Apache2

Do you get this message?

apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
 ... waiting apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName

We just need to tell apache what the name of the server is. The name of my server is “berit”. So I “ServerName berit” to /etc/apache2/httpd.conf:

echo -e "\nServerName berit" | sudo tee --append /etc/apache2/httpd.conf
  • Upload the file default.conf as /etc/apache2/ssl/default.conf
  • Upload the file macro as /etc/apache2/conf.d/macro
  • Upload the file macrobased as /etc/apache2/sites-available/macrobased
  • Changes in /etc/apache2/conf.d/security
  • Add this to /etc/apache2/ports.conf:
    NameVirtualHost *:443
  • sudo a2enmod rewrite
    sudo a2enmod ssl
    sudo a2dissite 0*
    sudo rm /etc/apache2/sites-available/default
    sudo rm /etc/apache2/sites-available/default-ssl
    sudo a2ensite macrobased
    sudo service apache2 reload
  • Per default we do not log access. Uncomment the line in
    /etc/apache2/conf.d/other-vhosts-access-log so it reads:

    # Define an access log for VirtualHosts that don't define their own logfile
    # CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log vhost_combined

Configure PHPMyAdmin

Open the file /etc/phpmyadmin/config.inc.php

You may want to hide some system databases from the web interface. To do that you would add a row like this to the middle of the file:

  • $cfg['Servers'][$i]['hide_db'] = 'information_schema';
  • $cfg['Servers'][$i]['hide_db'] = '^information_schema|mysql|performance_schema|phpmyadmin|test$';

Add these rows to the end of the file to force SSL and increase the max rows per page:

$cfg['ForceSSL'] = true;
$cfg['MaxRows'] = 1000;

If you wan’t to be able to autologin as root (dangerous but handy on local installations):

$cfg['Servers'][$i]['AllowNoPassword'] = 'true'; 
$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = '';

Setting up Backups

I have written a separate guide on how to setup backups for your linux server.

Free SSL certificates without the browser warning? Yes! It’s possible!

When I need SSL encryption for some admin panel on one of my websites I usually use the snakeoil certificate that comes with the installation of the ubuntu OS (/etc/ssl/certs/ssl-cert-snakeoil.pem). But I can not use this method for a serious web page where I would like to provide ssl for the visitors. The browsers will warn as the certificate was not signed by a well known certificate authority (CA).

The reason you might not want a CA to sign your certificate is that it costs money, at least that is what I have been thinking till now.
I just found this CA: http://www.startssl.com

Their site looks like crap (sorry) and they do not seem to be that well known. But their site works very well and you can get your signed CA for free in just a few minutes!

Tell your webmaster friends! :D

This is how I generate my certificate signing request (CSR):

openssl genrsa -des3 -out website.com.key 2048
openssl rsa -in website.com.key -out website.com.key.insecure
openssl req -new -key website.com.key.insecure -out website.com.csr

Then I use the website.com.csr at the startssl.com website to get my certificate which I save as: website.com.crt
You also need some intermediate certificates installed on your server. Read more about that here: http://www.startssl.com/?app=25#31

After that my apache configuration for the website looks like this:

<VirtualHost *:80>
ServerName website.com
ServerAlias *.website.com

DocumentRoot /home/username/files/websites/website.com/webroot/
<Directory "/home/username/files/websites/website.com/webroot/" >
Order allow,deny
allow from all
AllowOverride All
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerName website.com
ServerAlias *.website.com

DocumentRoot /home/username/files/websites/website.com/webroot/
<Directory "/home/username/files/websites/website.com/webroot/" >
Order allow,deny
allow from all
AllowOverride All
</Directory>

SSLEngine on
SSLCertificateFile       /etc/apache2/certs/website.com.crt
SSLCertificateKeyFile    /etc/apache2/certs/website.com.key.insecure
SSLCertificateChainFile  /etc/apache2/certs/startcom/sub.class1.server.ca.pem
SSLCACertificateFile     /etc/apache2/certs/startcom/ca.pem
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>

Backup your database with mysqldump

Using Automysqlbackup

I recently decided to take backups of my mysql database and I found a very good solution for this:
http://sourceforge.net/projects/automysqlbackup/

Automysqlbackup is a bash script that uses mysqldump to take daily, weekly and monthly backups of your database. I found many bash-scripts while searching but this script was the best one I found and it is even in the Ubuntu repositories :)

To install:

apt-get install automysqlbackup

Per default it saves the backups to /var/lib/automysqlbackup but you can change that (and the other settings) in the config file /etc/default/automysqlbackup.

The script is run daily by cron but you can also take a manual backup if you wish by running

automysqlbackup

Great and simple :)

Using a single terminal command

If you do not feel like installing a cronscript and just want a one time solution you can use one of these lines:

All databases – Custom username and pass

mysqldump -u username -ppassword --all-databases | gzip -9 > all-databases-$(date +%Y-%m-%d_%Hh%M)-.sql.gz

The -9 argument to gzip tells it to compress as much as possible.

All databases – Using the debian system maintanance login

mysqldump --defaults-file=/etc/mysql/debian.cnf --all-databases | gzip -9 > all-databases-$(date +%Y-%m-%d_%Hh%M)-.sql.gz

This will only work if you are running some debian system i guess. However I like this approach as I can use the same command on all debian servers and I do not have to specify the username and password all the time.

One databaseUsing the debian system maintanance login

mysqldump --defaults-file=/etc/mysql/debian.cnf mydatabasename > mydatabasename-$(date +%Y-%m-%d).sql