Server Foundation for Ubuntu LTS

This is a guide roughly outlining how I would manually setup and configure a server after the first boot. I tend to go with Ubuntu LTS (long-term support). Ubuntu is a popular distribution with a lot of library support, and the LTS version is supported for a longer period of time than the current releases.

On first boot

On the first login via SSH, change the password of the root user.


If mounting a separate disk/image as /home, edit /etc/fstab and add the home partition.

/dev/xvdc  /home  ext3  defaults  0  0

Note: the disk might have a different file system name depending on host.

Then mount the disk.

mount -a

Set the time zone.

dpkg-reconfigure tzdata


Setup a new user to handle server administration, so the root user does not need to be used.

adduser deploy
usermod -a -G sudo deploy

Setup a public/private key pair on the server. This key could be used for checking out code from Github or connecting to other servers.

su deploy
ssh-keygen -t rsa -b 2048

On a local machine, a public/private key pair should also be setup (if not already).

ssh-keygen -t rsa -b 2048

Upload the public key to the server for logging in without a password.

scp ~/.ssh/ [email protected]:

Add the contents of the public key ( to the deploy user’s authorized_keys file and limit the permissions on the file.

cat >> ~/.ssh/authorized_keys
chmod 400 ~/.ssh/authorized_keys

Note: multiple public keys can be added to the file, one per line.

Change the following options in /etc/ssh/sshd_config.

PermitRootLogin no
PasswordAuthentication no
X11Forwarding no
UseDNS no


The apt-get sources list can have a lot of entries. Sometimes it is setup to have other repos like “multiverse” and “restricted”, or includes deb-src entries. I tend to clean up /etc/apt/sources.list file and replace content with the following:

deb precise main universe
deb precise-updates main universe
deb precise-security main universe

I think this makes it much easier to understand where apt-get is looking. After the file is changed, run the update and upgrade commands.

apt-get update && apt-get upgrade

I also remove whoopsie if it’s installed, but it can be left installed without issues. Whoopsie is an error tracking and reporting daemon that reports cashes to Canonical. The results it collects can be found on the Ubuntu Error Tracker.

apt-get --purge remove whoopsie

Install fail2ban. It’s a daemon that monitors login attempts and blocks suspicious ones, and it’s configured well out of the box.

apt-get install fail2ban


Unless using DHCP is okay, edit /etc/network/interfaces and set eth0 to static and add the parameters needed.

iface eth0 inet static

Note: multiple dns-nameservers values can be added by separating them with a space.


Setting up iptables can be a bit verbose mess, but using ufw (uncomplicated firewall) makes dealing with open ports much easier. ufw can get in the way a bit if more more control is needed, but in most cases, it’s “good enough.”

Install ufw and allow port 22 (ssh). Also, 80 (http), and 443 (https) if this will be a web server. Finally, enable the firewall.

apt-get install ufw
ufw allow 22
ufw allow 80
ufw allow 443
ufw enable

Finishing up

A restart for good measure.

shutdown -r now

When the server restarts, it should serve as a good foundation setting up any production stack. If by chance something went wrong and an SSH connection cannot be established, most VPS host have a console that can still access the machine.

If a lot of servers are going to need provisioning, look in to Chef. Chef is open source and can automate server setups and deployments. PeepCode has some great screencasts covering getting Chef up and running. Another option is Puppet.

Update: Also, be sure to checkout out Ansible for automated provisioning. I personally find it easier to use than Chef Solo.