The [Ubuntu Server Edition](http://www.ubuntu.com/server “Ubuntu Server”) [LTS](https://en.wikipedia.org/wiki/Long-term_support#Software_with_separate_LTS_versions “Long Term Support”) is a highly reliable server system and comes with reasonable security defaults. Still there are additional steps to take if we want to enhance its security.
> *These steps will only help make your server more secure but they will not make it bulletproof! Security is an evergoing process and you should always be alert for new security issues.*
1. [Install a fresh Ubuntu Server 14.04](?p=49 “How to set up your own LAMP server on Ubuntu 14.04”) (Preferable 64 bit).
2. Use the following command to install SSH, if not already installed:
$ sudo apt-get -y install openssh-server
3. Make sure you have a sudo enabled user:
$ id | grep sudo uid=1000(theoadm) gid=1000(theoadm) groups=1000(theoadm),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),117(sambashare),1006(gitusers)
If the above is not true, you will have to login as root with ***su -*** and execute all the commands as the root user.
1. Block remote logins as root. Set the value of the ***PermitRootLogin*** keyword, in */etc/ssh/sshd_config*, to ***without-password*** or ***no***. This will disable password based authentication for the user root and only allow [Public Key Authentication](https://help.ubuntu.com/community/SSH/OpenSSH/Keys “Public Key Authentication”).
* First check what is the value of the ***PermitRootLogin*** keyword:
$ grep PermitRootLogin /etc/ssh/sshd_config PermitRootLogin without-password
* If the value is ***yes***, it is considered a very bad practice, especially on a public server. Use your favorite editor or the following command to change it:
$ sudo sed -i 's/^\(PermitRootLogin\s\)[yY][eE][sS]/\1without-password/' /etc/ssh/sshd_config
* Don’t forget to restart SSH:
$ sudo service ssh restart
2. Change the SSH listening port from 22 to something else. This is not the ultimate security measure but, since most ssh attack bots target the default port, it will largely minimize the attacks.
* First select a port not used by a well known service. Let’s assume that we decided to use port 4547:
$ grep 4547 /etc/services ; echo $? 1
A return value of *1* indicates that no well known service is using that port.
* Then change the value of the ***Port*** keyword to ***4547***. Use your favorite editor or the following *sed* command to do so:
$ sudo sed -i 's/^\(Port\s\)22/\14547/' /etc/ssh/sshd_config
* Restart your SSH server:
$ sudo service ssh restart
* Verify that the port has been changed:
$ sudo netstat -lnpt | grep ssh tcp 0 0 0.0.0.0:4547 0.0.0.0:* LISTEN 11979/sshd tcp6 0 0 :::4547 :::* LISTEN 11979/sshd
1. Enable the firewall functionality. We will be using the pre-installed *Uncomplicated Firewall* (ufw) which is just a front-end to the, more complicated, iptables.
* First allow port 4547. Make sure you type the correct port or you will be locked out of your server! Use the following command to allow traffic to our chosen port:
$ sudo ufw allow 4547/tcp
* Then enable the firewall:
$ sudo ufw enable
* Verify that is working:
$ sudo ufw status Status: active
To Action From -- ------ ---- 4547/tcp ALLOW Anywhere 4547/tcp (v6) ALLOW Anywhere (v6)
2. Setup the Fail2ban intrusion prevention software. [Fail2ban](http://www.fail2ban.org/wiki/index.php/Main_Page “Fail2ban”) is an excellent tool to block attacks against SSH and many other services.
* Install fail2ban:
$ sudo apt-get -y install fail2ban
* SSH protection is enabled by default but we need to reconfigure the ssh port to 4547. In the file */etc/fail2ban/jail.conf* change the ***port = ssh*** value to ***4547***:
enabled = true port = 4547 filter = sshd logpath = /var/log/auth.log maxretry = 6
* Enable protections against distributed attacks. Edit the ***[ssh-ddos]*** section in */etc/fail2ban/jail.conf*:
enabled = yes port = 4547 filter = sshd-ddos logpath = /var/log/auth.log maxretry = 6
Enabling unattended upgrades may not be a very good idea on mission critical servers. On such scenarios you may want to test the upgrades on a test server before you apply them on the production. Nevertheless it may be a good practice to enable this functionality on machines that are expected to run unattended for long periods of time. This will help to automatically patch vulnerabilities of your machine. Note, however, that patches do not automatically apply on the Linux kernel or the glibc library, because a restart is needed in these cases. So even on *mostly unattended* scenarios, you still need to check occasionally whether your machine needs a restart.
1. Make sure that the *unattended-upgrades* package is installed. It is usually pre-installed but if not, you can use the following command to install it:
$ sudo apt-get -y install unattended-upgrades
2. Then we must configure automatic upgrades. Answer ***Yes*** when asked in the following command:
$ sudo dpkg-reconfigure updates unattended-upgrades
Alternatively you can edit the */etc/apt/apt.conf.d/20auto-upgrades* configuration file as follows:
APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1";
As we said earlier, security is an ongoing process. Some further info to make your site more secure:
*  **Hardening Ubuntu**:
*  **Applied Crypto Hardening**: Don’t forget to read the OpenSSH section of the [Better Crypto](https://bettercrypto.org/ “bettercrypto.org”) draft paper: https://bettercrypto.org/static/applied-crypto-hardening.pdf
*  **Block port scanning**: The article below explains how to use Fail2ban to block [port scanning](https://en.wikipedia.org/wiki/Port_scanner “Port Scanning”).
*  **Port knocking**: [Port knocking](https://en.wikipedia.org/wiki/Port_knocking “Port knocking”) is another interesting technique where you can open your SSH ports, or ports for other services, on demand. Strictly for paranoids!