Why does this matter? If you monitor your server you will notice that there will be daily automated checks for security loopholes on ssh or http ports on your server (assuming it is accessible from the Internet).
The following steps will help you create a basic security setup for your ubuntu server (I tested this on 11.04, 12.04 and 14.04, 10.04 should probably be similar). Assuming your server is hosted at a provider, you will probably get the IP of your server and the password for the root user.
Before you start: You also might want to check out the harden ubuntu section here! Most of the topics below are also covered there - and quite a lot more (But beware: At the time of writing some don't apply anymore, e.g. the heartbleed bug in openssl was fixed in 1.0.1f-1ubuntu2, so no need anymore ot switch to -dev version. Others like ListenAddress in sshd_config seem to be misunderstood).
Ideally you would start securing the server before your server gets connected to the Internet. Second best right after you get the credentials from your provider. Totally not advisable would be weeks afterwards - in this case you should really consider starting with a clean installation.
That said: Starting from there you can login to your server via ssh:
ssh root@yourServerIp
First thing would be to create your own user and remove this nasty world-wide-root access to your server.
adduser yourUserName
Now make your user part of the sudoers group
usermod -a -G sudo yourUserName
And give it a try --> login as your newly created user and run some sudo commands - e.g. sudo apt-get update
If everything worked out, remove the root passwd - thereby avoiding that someone can login as root
sudo passwd -dl root
Try to use strong passwords, store them in a safe location and avoid reusing them (especially don't use the same password for your admin user & applications or databases on your server).
A good point - easy to forget - mentioned here: Don't trust your users. If other users are using the server make sure to lock down their privileges accordingly and always make sure that you have a separate account with root/admin privileges. This also goes for admin users for applications or a database.
Now about your ssh connection. We start with basic security. To my experience it already helps to change the ssh port (many of the automated port scans simply search for standard ports - like 22) and to set a limit rule in the firewall (see next chapter).
sudo vi /etc/ssh/sshd_config
# change the port from 20 a higher number
# (try to avoid ports used by applications like 8080 or 5432)
Port 1044
PermitRootLogin no
# you can explicitly list users which are allowed to connect through ssh
# this would be the following setting:
AllowUsers yourUserName
Now leave vim with :wq and reload your ssh service:
sudo reload ssh
Afterwards logout (or even better open a new ssh connection - so that you don't loose access to the server with your first connection) and reconnect with your new user and port:
ssh yourUserName@yourServerIp -p 1044
If it is feasible you also might want to start using public ssh-keys for login. Especially since it is really easy to set up.
On your local computer (not the server) navigate in your home directory to the hidden .ssh folder:
cd ~/.ssh
and run the following commands:
ssh-keygen
ssh-copy-id yourServerIp -p 1044
Thereby you created a public and a private rsa key and with the second command your public key was copied into the authorized_keys file in the .ssh directory of your home directory on the server. You might also want to backup these keys somewhere secure.
Now you can connect via ssh using these keys. If the private key of your local machine matched an authorized public key on the server you can login. Lets try to login as suggested without your user name to see if it works:
ssh yourServerIp -p 1044
If everything worked now you can disable password login on the server:
sudo vi /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
ChallengeResponseAuthentication should be set to "no" as a default anyways - just make sure it is.
As you can see client computers which connect to the server now have to have the private key in the .ssh folder - adding additional security to your ssh connection. On the other hand this can be bothersome if too many users from too many different clients want to access the server.
If you happen to have a fixed IP address (or manage your server from the same local area network) you can even go one step further and limit the IP range which can access your server via ssh.
In /etc/hosts.allow add your IP or local address range e.g.:
sshd : 192.168.1.
(depending of course on your actual IP - be very careful to get this right :)
In /etc/hosts.deny block all the other ones (for sshd) by adding the following line:
sshd : ALL
Alternatively you could configure this in your firewall settings.
Now about configuring a firewall. If you want have the real deal - use IP tables. Otherwise just use ufw.
It comes with every Ubuntu installation and configures those nasty IP tables for you.
If you activate the firewall and are logged in remotely (e.g. over your ssh port 1044) make sure you allow connections on this port. Otherwise you will get locked out and have to deal with resetting your server or using an emergency console access which some providers offer.
For application ports of your server (e.g. 80) you might want to use an allow rule (e.g. sudo ufw allow 80). For ssh you might prefer a limit rule. Limit means if 6 or more connections are initiated in the last 30 seconds, the origin IP will be blocked. So this offers additional protection against brute force attacks on your ssh port.
sudo ufw status
sudo ufw limit 1044
now lets activate the firewall
sudo ufw enable
You just activated a firewall! Meaning: if you install applications on your server - remember to configure rules to make them accessible.
You really want your server to be able to send emails. This way you won't forget about your server since you receive server logs or alerts per email.
If you don't need it - I would suggest try to avoid running a full-blown mailserver due to the additional security risk. A lightweight alternative is ssmtp. This provides the mail and sendmail command without running your own mail server.
sudo apt-get install ssmtp
sudo vi /etc/ssmtp/ssmtp.conf
Configure ssmtp with an existing email account:
mailhub=yourEmailProvidersSmtpServer:Port
UseSTARTTLS=YES
AuthUSER=yourEmailUser
AuthPass=yourEmailPassword
Now set your aliases
sudo vi /etc/ssmtp/revaliases
The syntax is as follows:
yourUserName:yourEmail:yourSMTPServer:PortNumber
Send a test email with the following command:
ssmtp -v your@email.de
The -v option is really helpful to find errors in your configuration. Send mail with Ctrl-D
You can also use the mail or sendmail command.
Since this description is a little bit short - you might want to have a look at more elaborate descriptions like here or here (in German).
Having just configured our mail command we now can use it to get notified when someone is logged into the server as root.
sudo su
vi .bashrc
add
echo 'Uh oh - root access on:' `date` `who` | mail -s "Alert: Me Access from `who | cut -d"(" -f2 | cut -d")" -f1`" your@email.de
Oh - wait: as gutermann pointed out --> you would probably want to add this to a user rc file /root/.ssh/rc instead of your .bashrc.
Actually you might want to skip this step alltogether.
Logwatch is one of the most helpful tools for server administration since you get automatically informed about what's happening on your server.
sudo apt-get install logwatch
sudo mkdir /var/cache/logwatch
sudo cp /usr/share/logwatch/default.conf/logwatch.conf /etc/logwatch/conf/
sudo vi /etc/logwatch/conf/logwatch.conf
Here you should at least set the following:
MailTo = your@email.de
(or the username for which a revalias was created: see ssmtp)
Output = mail
(doesn't seem to be necessary anymore)
You can test it by running "sudo logwatch". Don't be surprised if you don't get any output if you did a fresh install and set Detail to "low" and Range to "yesterday" (default settings).
sudo logwatch --range today --mailto your@mail
Also you really want to install fortune!
sudo apt-get install fortune
Also a really helpful feature is to configure automatic upgrades. Keeping your server up to data with security patches is one of the most important parts of administration.
sudo apt-get install unattended-upgrades
sudo vi /etc/apt/apt.conf.d/50unattended-upgrades
and configure the Allowed-Origins here.
sudo vi /etc/apt/apt.conf.d/10periodic
and add for example the following configuration:
APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Download-Upgradeable-Packages "1"; APT::Periodic::AutocleanInterval "7"; APT::Periodic::Unattended-Upgrade "1";
There are some people who are worried that their applications might get messed up if the updates are installed automatically (e.g. new jre version) but hey - you can easily exclude packages from the automatic updating. And in my opinion it is often the case that you become lazy with manual updates after some time has passed - therefore I would recommend enabling automatic updates.
You probably should only stick with the default or very trusted software repositories. Also keep in mind that software repositories are only good if they are kept up-to-date, so even if you trust a repository but it is not updated recently try to avoid it since there won't be any security patches.
A fact you might be interested in: in Ubuntu LTS versions only packages from the main repository get patches over the whole LTS time period as reported by heise (in German). Packages from partner or universe repository are not necessarily patched. You can search the maintenance status of your packages here.
Of course also try to avoid running untrusted scripts you found on the Internet :)
In case you use the default repositories you can check the integrity of your packages with debsums.
sudo apt-get install debsums
List installed packages with no checksums.
sudo debsums -l
List changed package files from all installed packages with checksums.
sudo debsums -ca
List changed configuration files.
sudo debsums -ce
Get the details here. Open fstab:
sudo vi /etc/fstab
and add the following line:
none /run/shm tmpfs defaults,ro 0 0
This will mount shared memory in read-only mode and thereby prevent attacks trying to exploit this. You can test if this worked by trying to create a file in /run/shm/ afterwards.
Compilers can be used from an attacker to compile root kits and therefore some people will advise you to disable them - though this is a matter of discussion.
You can check which compilers are installed by running:
dpkg --list | grep compiler
and afterwards set the permissions restrictive, e.g.:
sudo chmod 000 /usr/bin/cc
sudo chmod 000 /usr/bin/gcc
sudo chmod 000 /usr/bin/*c++
sudo chmod 000 /usr/bin/*g++
In case use want to use a compiler yourself you can chmod it back to 755.
AppArmor is an application firewall with the purpose to limit the access rights of applications in order to protect them against unkown or unpatched exploits.
Since around Ubuntu 11.04 AppArmor comes with the basic installation and not as a separate kernel module anymore.
Therefore you can just check if it is working with:
sudo aa-status
Of course you can still define your own profiles, as described for example here or here.
Whereas if you are working with debian you have to install and configure apparmor as described for example here. But beware - for example a profile for apache2 is only available by default in ubuntu apparmor-profiles-extra and not yet integrated in the debian package.
rkhunter
sudo apt-get install rkhunter
Update the database with:
sudo rkhunter --propupd --update
Now run a system check with:
sudo rkhunter -c
Check the warnings in rkhunters log file - and if they are valid - add them to the whitelist in
/etc/rkhunter.conf
If you don't encounter any warnings anymore, you can automate the rkhunter test run.
sudoedit /etc/default/rkhunter
CRON_DAILY_RUN="true"
CRON_DB_UPDATE="true"
DB_UPDATE_EMAIL="true"
REPORT_EMAIL="<username>@localhost" # <username>
APT_AUTOGEN="true"
chkrootkit
Install chkrootkit with the following command
sudo apt-get install chkrootkit
Now edit
/etc/chkrootkit.conf
and set
RUN_DAILY="false"
to true
To run chkrootkit weekly create a cron job:
sudo crontab -e
0 0 * * 7 root (cd /usr/sbin; ./chkrootkit 2>&1 | /usr/sbin/sendmail your@mail)
This howto is not really about securing a database - but if you run a database on the server make sure none the less that your database is not accessible from the internet but only from localhost and of course that you changed default passwords (don't use the root password)!
Services should be always run as separate, unprivileged users. If you stick with standard software from repositories this should mostly be the case. Just keep it in mind that this is important, since a hijacked service will get the privileges of the user it is run by.
Since applications on the server probably should be accessible from the Internet they pose one of the greatest security risks. Often automated checks search for example for certain PHP versions, CGI connectors or admin interfaces of applications in order to exploit them. Since securing them is application specific this guide won't cover it - but you probably should read the docs about hardening them and of course keep them up-to-date.
Lynis is a security auditing tool for UNIX derivatives. You can download it here
Check the integrity of your download
sha1sum lynis-2.3.3.tar.gz
Perform an audit
sh lynis audit system --quick
Keep up the reading of security related IT news. This will make you aware of potential threads to your server.
... as soon as I find some time :P
Further topics are: