This post is based on my notes for an initial configuration for an Ubuntu 9.04 Virtual Private Server with a focus on security. At that time I searched for a number of references on security, and while I have not kept the note of all their URLs, most of what I write below is as a result of other documents even though I cannot specifically cite them (in other words, there is little originality except perhaps for attempting to cover the entire gamut of configuration activities into one article).
Keep in mind that these steps are based on my notes which might be a little incomplete especially around the part where acidbase is installed.
- Initial Configuration : Basic configuration when getting started up.
- Setting up basic security : Basic Security configuration
- Setting up rootkit detection : Setting up rootkit detection
- Setting up Bastille : Setting up Bastille
- Setting up the lamp stack : Set up the LAMP stack including mysql and apache
- Setting up Snort and acidbase : Configure Intrusion detection using Snort and Acidbase.
- Setting up File Integrity using AIDE : Setting up File integrity checks using AIDE
Initial Configuration
These steps cover the initial setup of a server
Setup the hostname
Lets say the hostname we want to setup is vps.
$ hostname -F /etc/hostname
Now update the /etc/hosts file to reflect the hostname and the fully qualified domain name
Replace 12.34.56.78 with the IP address of your host
12.34.56.78 vps.mydomain.com vps
Updating the ubuntu repositories
You will need to update your ubuntu repositories to include jaunty-updates and universe repositories. This is so that you may install additional packages as required from these repositories as well. In my case, the earlier version of the file /etc/apt/sources.list was as follows.
However please note, that repository selection and its update strategy may be linked to your company or application strategy. Please make sure these steps are consistent with your policy. If not, kindly adapt consistent with your team / organisations policy. Also instead of us.archive.ubuntu.com, you may find other country specific server names. In that case you may want to continue to use the other server name as already listed in your file.
deb-src http://us.archive.ubuntu.com/ubuntu/ jaunty main restricted
deb http://security.ubuntu.com/ubuntu jaunty-security main restricted
deb-src http://security.ubuntu.com/ubuntu jaunty-security main restricted
Upon adding jaunty-updates and the universe repositories, the resultant file is as follows.
deb-src http://us.archive.ubuntu.com/ubuntu/ jaunty main restricted universe
deb http://security.ubuntu.com/ubuntu jaunty-security main restricted universe
deb-src http://security.ubuntu.com/ubuntu jaunty-security main restricted universe
deb http://us.archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe
deb-src http://us.archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe
Now update the sources. This will scan all the repositories
Finally upgrade ie. replace any existing packages which have a newer upgrade
Download the language pack
To add the necessary for the preferred language of your choice add the appropriate language pack. In my case I add support for english (en)
Set the timezone
Set the timezone of the server. You may choose to set it based on server location, or typical user location or to UTC.
That will start a small app, from which you can select the timezone. I selected None of the Above which offered me a choice of timezones based on UTC offsets and subsequently selected UTC.
Setting up Mail sending
I do not need this VPS to act as a mail server. However I do need to have capabilities to send email from this machine. Many unix tools routinely assume the existence of sendmail or equivalent MTA. However that is an overkill in this context. So we shall not be installing sendmail or postfix or exim or any other equivalent. Instead we shall configure this server to be only able to send out mail using an SMTP account on another mail server. For this we shall install a tool called mailx. Note: If you have mailx already installed through another ubuntu package called mailutils, you may either continue with the same (in which case you will need to configure the remainder of the mail stack correspondingly eg. sendmail) or remove mailutils and add heirloom-mailx
We shall also configure a global configuration for sending out mail. In my case its all right to always send mail using only one account irrespective of the process or user who is sending it.
Note that in the above configuration, we shall be placing the mail account password in clear text. Make sure it is a mail account you do not use for any other purposes and that its password is not the same as used for any other purposes. Now enter the following as contents of the /etc/nail.rc file. Obviously change the relevant fields to appropriate values. Note that this file is configured for sending mail via gmail. You may need to configure it differently based on your own SMTP configurations.
set from=my_user_id@gmail.com
set smtp=smtp.gmail.com:587
set smtp-auth-user=my_user_id@gmail.com
set auth-login=my_user_id@gmail.com
set smtp-auth-password=my_password
You can try testing whether this got set up successfully. Enter the following (replace youremailid@youremaildomain.com by the email id where you would like the mail to be sent to)
Subject: This is a test mail
Hello
.
Basic Security
In this section we shall make some basic configuration changes with a view to enhance the system security.
Mounting the shared memory as read only
Open and edit the file /etc/fstab to add an entry to mount shared memory in read only mode. The reason we do it is because many exploits use shared memory to attack other running services.
If you have a good reason to make shared memory writeable skip this step.
Now add the following line at the end of the file
Tightening the passwords
One of the easiest exploits is to attempt a brute force login using dictionary based attacks. In order to ensure strong ie. non-guessable passwords we shall update the password checking policy so that it allows only strong passwords. A simple way to ensure that is to ensure a reasonable minimum length and to ensure multiple character classes.
First lets install a new pam authentication module pam_cracklib. To install the same run the following
Answer ‘Y’ to the prompt it asks for regarding continuing.
Note: if you did not add the universe repository to your sources.list file, you will not be able to install libpam-cracklib. In that case you will need to skip this step.
This should’ve resulted in the file etc/pam.d/common-password having an entry for pam_cracklib.so and pam_unix.so. Update the pam_cracklib.so entry to add one more requirement ie. minclass=4.
In my case, the resultant two lines in /etc/pam.d/common-password are as follows. Note that I added the minclass=4 clause manually.
password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass sha512
There. You now have a strong password scheme which will conduct a whole range of password checks in addition to ensuring that the password has a minimum length of 8 and each new password has at least one each of the four character classes. The four character classes are lower_case, upper_case, digit and special_characters (the last one being any non alpha-numeric character)
Creating the first user
Note: if you have already created at least one more non root user this step is not required. We are primarily creating the new user so that we shall eventually allow sudo and remote ssh login privileges to the user and disable remote ssh privileges for the root user.
Setup the first new user. One of the reasons you should create a new user is so that it will afford you the ability to allow him to perform root actions through sudo, and thus subsequently allow you to disable root access over ssh. By default when one creates a new user, another group gets created with the same name as well. In this case we shall create a new group “dev” and then create a new user associated with that group “someuser“. Use the groupname and the username as you would like to setup when executing the commands below. In the commands below we create a new home directory for the user, associate the /bin/bash shell with his account instead of the default /bin/sh, (I just prefer bash to the plain sh) and finally set the password for him.
$ mkdir /home/someuser
$ useradd -d /home/someuser -s /bin/bash -g dev someuser
$ chown someuser.dev /home/someuser
$ passwd someuser
We shall also create the .ssh directory for the user which we shall be using later
$ chmod 700 /home/someuser/.ssh
$ touch /home/someuser/.ssh/authorized_keys
$ chmod 600 /home/someuser/.ssh/authorized_keys
$ chown -R someuser.dev /home/someuser
Now we shall create the keypair for the user to log in to the host remotely. Note that if you are going to do this for multiple users, then you might want to have each user run the next step locally and then copy over his public key onto the server before continuing to the ssh tightening operations described later.
The user should do the following on his local workstation from which he is most frequently likely to connect to the server (not the server that we are hardening).
Note: the part after -C in ssh-keygen is just a comment to identify the keys – enter something to identify the user and his machine.
Also make sure not to keep the passphrase blank though ssh-keygen will allow a blank passphrase. The reason is that if the user’s local machine is compromised the attacker can then get an easy access to the server being hardened.
change someuser and some.host.com below based on the user id and vps name correspondingly
$ ssh-keygen -t dsa -b 1024 -C “some user on his desktop”
$ scp ~/.ssh/id_dsa.pub someuser@some.host.com:/home/someuser/.ssh/someuser.pub
Now the user should himself ssh to the remote server and on the remote server move his public key into the authorized_keys file. So execute the following command after being connected to the VPS
$ cat someuser.pub >> authorized_keys
$ rm someuser.pub
At this stage the user can disconnect from the VPS and attempt to reconnect using ssh. If all works well, he should get connected to the vps in a manner where it does not prompt him for a password but instead he does get prompted for the passphrase to his private key (assuming he did set one).
This stage of updating the authorized_key file can also be performed by an administrative user / root once we later reconfigure ssh to only allow public key based logins.
Enabling the user to perform sudo operations
We shall enable any group who belongs to the group ‘admin‘ to be able to conduct root operations through using sudo.
First create a group ‘admin‘. subsequently associate the user with that group as well. Note : For best security ensure you allow associate only a very small number of users with the ‘admin’ group since that will effectively allow them control over the whole machine (assuming you setup the privileges as I subsequently describe below).
$ adduser someuser admin
Now we shall enable any user who belongs to the admin group to perform root actions by using sudo. To edit the sudo policy file do the following
At the end of the file which is now opened up – add the following line
Note this grants all superuser privileges to the users who belongs to admin group when conducting operations using sudo. You can use the sudo policy configurations to set up far more fine grained set of privileges, but thats beyond the scope of this document.
To test whether the configuration worked successfully, you can login as someuser and execute the following command.
Tightening up ssh
To create the group and associate the users with them perform the following command (use the appropriate username instead of someuser for each user who you would like to allow SSH access).
sudo adduser someuser sshlogin



