So you've provisioned a shiny new Ubuntu OS on Digital Ocean or Linode, and the first thing you will want to do is lock it down. It's scary how quickly automated bots will find the newly provisioned server, start scanning for open ports and attempting to log in so they can turn your shiny server into a spewer of Viagra emails and promises of millions of dollars if you'll just hand over your name, date of birth and passport number.
Once the machine has booted up, you need to
ssh to the server using it's IP address.
$ ssh root@SERVER_IP_ADDRESS
Once logged in the first thing to do is get any and all updates for the OS. So at the prompt run:
$ apt-get update
$ apt-get upgrade
Once all the updates have installed it may ask you to reboot.
A wild User has appeared
Now you want to create a new user account for all your normal use of the server. It's never good practise to be logged in as
root on your system. Given the supreme power that
root wields on a Linux server, it's far too easy to cause irreperable harm without meaning to.
In these examples we'll use the example username
bob (as it's small and easy to remember).
So at the terminal enter:
$ adduser bob
The system will ask you a few questions, one of which being what password you want. Make sure you enter a strong one.
The rest of the questions you will mostly leave blank if you are anything like me.
So this new user account just has standard user priviledges which won't be enough for those odd occasions when we do actually need to perform adminstration functions on the server.
To do this we will make use of the
sudo command. "Sudo" gets put in front of any command that you wish to run with root priviledges. But to make use of this command we first need to add the user to the
So still logged in as
root, enter the following:
$ gpasswd -a bob sudo
Before performing the next step you may want to log out of
root, log in with your normal account and ensure that the
sudo command works as expected.
Disable root SSH login
So now you have your normal user account with
sudo priviledges, you want to disable remote root access to the server.
Root is one of the first user names the bots will attempt to access when scanning your server. Disallowing anyone to log in as root remotely removes that risk entirely, as now the attacker needs to know your personal username (you didn't use something simple like
admin did you?) as well as your very strong password.
So enter the following:
$ sudo vim /etc/ssh/sshd_config
Then search the file for the section which says
PermitRootLogin and set it to
Save the file and exit vim. However, before restarting the
ssh service make double (or triple) sure that your normal account has
sudo priviledges otherwise you will have just locked yourself out of being able to admin your own server!
Once you are sure your account has the correct access, enter the following:
$ sudo service ssh restart
Public Key Authentication
The next step is to setup Public Key Authentication so you don't need to type in that pesky password every time you access the server.
If you don't already have an
ssh key setup, then creating one is simple. At the console of your local machine, enter the following:
$ ssh-keygen -t rsa -C "[email protected]" # Creates a new ssh key, using the provided email as a label # Generating public/private rsa key pair. # Enter file in which to save the key (/Users/you/.ssh/id_rsa): [Press enter]
This generates a private key,
id_rsa, and a public key,
id_rsa.pub, in the
.ssh directory of the localuser's home directory. The private key is exactly that, private; do not share it with anyone.
Then from the home directory on your local machine enter the following:
$ cat ~/.ssh/id_rsa.pub
This will print your newly generated public key to your console which you can then copy to your new server.
ssh back into your server using your normal user account, and make sure you are in your user's home directory. Which in this this example looks like:
$ pwd /home/bob
Now create a new folder called
.ssh. We also need to restrict the permissions so that if we have any other users on this system they can't access our ssh information.
$ mkdir .ssh $ chmod 700 .ssh
Now create a file in the
.ssh directory called
$ vim .ssh/authorized_keys
Paste your public key into the file, save it and exit. Then restrict access to it.
$ chmod 600 .ssh/authorized_keys
You should now be able to log out, and then log back in using your private key as authentication.
Next up is to setup a basic firewall. A firewall basically denies incoming traffic to every port on your server. Ubuntu has a simple one called
ufw already installed. All we need to do to make use of it is tell it which ports we actually want to open to accept traffic, and then turn it on.
ssh into this remote server, that's the first port we need to open, otherwise we will manage to lock ourselves out of our own server again.
$ sudo ufw allow ssh
This is the bare minimum you need to setup, but if you plan on using your server for additional services (such as a webserver) you will need to open each port required. Http(s) for example requires the following:
$ sudo ufw allow 80/tcp $ sudo ufw allow 443/tcp
And email would also require:
$ sudo ufw allow 25/tcp
Once you think you have finished adding enough services you can see the rules with the following:
$ sudo ufw show added
And if you're happy with everything, lets turn it on!
$ sudo ufw enable
You will be asked to confirm that you want to turn the firewall on - you did add the
ssh rule right? - and once accepted the firewall will apply all your rules to all incoming traffic.
Installing NTP will allow your computer to stay in sync with other servers. On Ubuntu all that is required to setup time synchronisation is type in the following:
$ sudo apt-get update $ sudo apt-get install ntp
Read only shared memory
A common exploit vector is going through shared memory (which can let you change the UID of running programs and other malicious actions). It can also be used as a place to drop files once an initial break-in has been made.
So the first thing we will do is secure the shared memory. Enter the following into the command prompt:
$ sudo vim /etc/fstab
Then add the following line at the bottom of the file:
tmpfs /dev/shm tmpfs defaults,ro 0 0
Exit and save the file, then reboot the system.
Lots of servers get a steady stream of attacks on
ssh. To make it harder for any would-be attacker we can use Fail2ban which makes use of iptables to block an attacker for a defined period of time.
$ sudo apt-get update $ sudo apt-get install fail2ban
The fail2ban service keeps its configuration files in the
/etc/fail2ban directory. The default configuration file is called
jail.conf. Since this file can end up getting modified by package upgrades, we shouldn't edit this file in-place, but rather copy it so that we can make our changes in relative safety.
In order for fail2ban to find the configuration file we need to copy the default file to
$ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Once the file is copied, we can open it for editing to see how everything works.
$ sudo vim /etc/fail2ban/jail.local
The first section in the file is labelled
[DEFAULT] and the settings listed in there are applied to all following services.
The first thing to change is the length of time that a ban is instituted for.
bantime = 1800
We also need to configure the email address to which all alert information will be sent to.
destemail = [email protected]
You can also set the
sendername to something else if you'd like. It's useful to have a value that can be easily filtered using your mail service though, else your inbox may get flooded with alerts if there are a lot of break in attempts from various places (and there will be).
Further down the file you will see a setting called
action = %(action_)s
You will want to change the line to look like the following:
action = %(action_mwl)s
This will enable the email of all reports and will also include the log files for easier debugging in the event that something does happen.
The last section of the file lists all the different services that fail2ban can be configured for. We want to ensure that fail2ban is setup for
ssh - and if for example you are running a blog or website on
nginx then you will also want to enable it for http authorisation attempts.
Simply locate both the
[nginx-http-auth] sections and set
enabled to true in both.
enabled = true
Once you're happy with your settings save and exit the file, then restart the fail2ban service.
$ sudo service fail2ban restart
It won't be long until you start receiving emails informing you of all the IP addresses that have been blocked.
Restrict access to "su"
We only want to allow admin users to use the
su command. This helps prevent privilege escalation attacks. Ubuntu may already have an admin group but if not, run the following:
$ sudo groupadd admin
Then add yourself to the group
$ sudo usermod -a -G admin bob
Now restrict access to /bin/su to admin group members
$ sudo dpkg-statoverride --update --add root admin 4750 /bin/su
You can then check these permission with the following:
$ ls -lh /bin/su
And you should see the following:
-rwsr-x--- 1 root admin 31k 2011-11-24 14:16 /bin/su
Now to harden the IP stack.
$ sudo vi /etc/sysctl.conf
Now locate the line:
You should just have to uncomment it. Then below it add the following line:
You could use the sysctl command to do these instead but this way they will persist beyond a reboot.
Check for rootkit presence
Chkrootkit scans the system for evidence that a rootkit has been installed. This is a confidence test to be used to check whether your system has been compromised. It’s worth running periodically.
$ sudo apt-get install -y chkrootkit
Then to run it:
$ sudo chkrootkit
At the time of writing there seems to be bug with
chkrootkit that lists
/sbin/init as containing a Suckit rootkit infection. This is a false positive.
Detect attempted intrusions
Psad is a collection of lightweight daemons that log attempted intrusions, in particular monitoring iptables.
$ sudo apt-get install -y psad
The daemons will run automatically once installation is complete. To check the current status:
$ sudo psad -S
You can modify the psad settings to e-mail the admin on the event of an intrusion detection.
Watch those logs
The most detailed and informative logs in the world are about as much use as a chocolate teapot if no one looks at them. Logwatch winnows the deluge down to a succinct report which hopefully you will look at.
$ sudo apt-get install -y logwatch
Then to produce the report:
$ sudo logwatch | less
Now that the server is more secure, once a week perform on-going maintenance like ensuring your software is up to date:
$ sudo apt-get update $ sudo apt-get upgrade
That's it. Your server should now be a lot more secure than it was before. However bear in mind, no matter how secure a system, a determined and skilled attacker will always find a way in; but at least now the job is a lot harder and this should protect you from the majority of bots out there.
Enjoy your new server!