Apr 082011

Welcome to the first part of my Quick Secure Setup series.  This series serves to accomplish a primary goal.  To help one quickly and efficiently configure their ubuntu server in such a way that it is very secure, WHILE still providing great usability and maintainability.  A lot of people have great intentions to secure their server, SELinux, detailed ip-tables configurations, log audits, etcetera.  I’ve found that after a short while because of the maintenance involved or the complexity of the configurations, your average user will not keep up with such a configuration and their server ends up exposed in one way or another.  The first part in this series will give you the initial, basic things you should configure or customize to get you on the road to an extremely secure server.  Future parts will go into more depth with varying applications to help you with their configurations.  Each will be straightforward and something you can implement very quickly and maintain quite easily.  Finally I’ll be referencing all this using the Lucid Lynx LTS 10.04 Ubuntu server, however much of this will apply to any distribution or Ubuntu version with minor tweaks.

Congratulations, you’ve built your Ubuntu Server.  First things first.  Don’t “enable” root.  Simply edit the /etc/group file and add your account(for this article’s sake your account = ‘myuser’) to the admin group. This will allow you to run any command with sudo or just sudo -i and you will drop into root’s shell as if you logged in as root. If you had set a password for the root account I suggest you fix it by doing the following:

  • sudo usermod -p '!' root
  • Then check the /var/log/auth.log over the next couple days for  entries like: CRON[14357]: pam_unix(cron:account): account root has expired (account expired)
  • If you see those then run: sudo passwd --unlock root followed by sudo usermod --lock root

Ok so we have a sudo enabled user, you need to securely login to this box without exposing/advertising your server to the internet so let’s lock up ssh a bit. First create a sshlogin group: groupadd sshlogin and add your 'myuser' account to that group with: usermod -a -G sshlogin myuser. Now edit the /etc/ssh/sshd_config file.
Starting near the top you’ll see a line with Port 22. I strongly suggest changing this to another port. Changing this port alone will stop a lot of attacks on your server (you’ll learn more of that in Part II).  For the sake of being easy to remember set that to Port 2222 now.  Most of the defaults are pretty good in the rest of the file but there are a few others we should change so ensure the following are set:

  • PermitRootLogin no
  • X11Forwarding no
  • UseDNS no
  • AllowGroups sshlogin

This last line ensures that only the users in the sshlogin group are allowed to even attempt to login over SSH to your server. This is a good extra bit of security as there are a lot of other default accounts on ubuntu and you don’t want script kiddies trying to utilize an exploit with known user names to get into a system.  Check this ubuntu community page, StricterDefaults for a few other nice tidbits in increasing your default security and apply what fits for your server.  At this point you now have one user, whose user name is not a known default, that is allowed ssh access to your system, on a non-standard ssh port.  Very nice, you are already more secure than most servers out there!  I strongly recommend leveraging this ssh for file transfers (scp) as the data will be encrypted automatically for you.  Just remember using the non-standard port you’d have to specify scp -P 2222 ....first.  In Part II In another article, I’ll introduce a secure way to configure FTP as most people find it easier than scp.

Now let’s address something that is frequently overlooked.  Keeping the system or user installed packages updated. There is a concern that automatically updating packages could break something on your system that was previously working.  Although this is a valid concern, one nice feature of Ubuntu’s package system is the concept of “safe-upgrades” and “full-upgrades”.  Safe-upgrades are meant to be just that, rather safe to do at any time.  Now that doesn’t mean there is zero chance of a safe-upgrade package causing an issue but I’d say that the scale of risk is tipped in favor of applying these versus NOT and leaving your server at risk to needed patches, especially security based ones.  So what we should do is configure a system such that every night it will check for those security updates and apply them to your server.  To get started:
aptitude install unattended-upgrades update-notifier-common
To configure the settings for unattended-upgrades vi /etc/apt/apt.conf.d/50unattended-upgrades
Pay close attention to the first two sections of that file:

// Automatically upgrade packages from these (origin, archive) pairs
Unattended-Upgrade::Allowed-Origins {
"Ubuntu lucid-security";
// "Ubuntu lucid-updates";

// List of packages to not update
Unattended-Upgrade::Package-Blacklist {
// "vim";
// "libc6";
// "libc6-dev";
// "libc6-i686";

What you can see is that I am only allowing updates from lucid-security which is quite safe. You could also add lucid-updates by removing the // from the front of the line and then in the second section enter the packages you do not want to be automatically upgraded. My issue with this is that you need to get the exact package name for the blacklist to work. The blacklist doesn’t support regex’s although unattended-upgrades is written in python and I have seen a simple edit to allow it to support regular expressions, but we won’t be doing that here. I see a lot of forum posts online where people thought they were blocking kernel upgrades but it didn’t match and so their server upgraded its kernel. I’d recommend just automatically doing the lucid-security updates and logging into your server to manually do any others.
Now before any of this will run automatically we need to create/edit one more file: vi /etc/apt/apt.conf.d/10periodic and add this to it:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

Finally we are on our last main section for Part I. You don’t want to be blind to what is going on with your server, but realistically you won’t log in everyday and scour through the logs (linux logs can be insanely detailed!). There is a good program I’ve used for years called logwatch that can easily help you out with this by giving you filtered logs all in one easy to “human brain parse” output. To install simply aptitude install logwatch. Now to tweak its settings a bit go to vi /usr/share/logwatch/default.conf/logwatch.conf. The main thing to decide is how you want to check this. If you’ve configured your server to be able to send outbound emails which is very handy then I recommend having the output of logwatch emailed to you. Otherwise you can set it to output to a file and just check that everyday which is still easier than checking multiple log files and scouring through their content. I find the html output harder to read than the text output so I just have it set to email me once a day. I also like the detail level set to Med. It provides much more valuable information than the default while not giving so much that you end up not reading it.

Finally, before we end Part I you need to make sure some sort of firewall is running. We’ll want to use iptables but one main complaint regarding it is that it can be difficult to maintain and setup if you aren’t accustomed to the way the rules need to work. I find people start with good intentions and configure it, then somewhere down the line they can’t get something working just right, they turn off iptables and the program works. Instead of figuring it out they leave iptables off. So for Part II we’ll go over an easy way to get iptables under your control but in the meantime you should apply some basic rules. You can copy and paste this as a script on your system and run it. You can even easily add a few other ports you have to the script and re-run it. It will always flush all rules and then re-apply based on what’s in the script. Currently it will allow our customized ssh port of 2222, and the two web ports of 80 and 443 which you’ll want open if you are running a web site.
So now create a script like vi iptables_config and paste in the following:

# iptables example configuration script
# Flush all current rules from iptables
iptables -F
# Set default policies for INPUT, FORWARD and OUTPUT chains
iptables -P INPUT ACCEPT
iptables -N MY-Firewall-1-INPUT
# Setup new chain
iptables -A INPUT -j MY-Firewall-1-INPUT
iptables -A FORWARD -j MY-Firewall-1-INPUT
# Set access for localhost
iptables -A MY-Firewall-1-INPUT -i lo -j ACCEPT
# Accept packets belonging to established and related connections
iptables -A MY-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow SSH connections on tcp port 2222
# This is essential when working on remote servers via SSH to prevent locking yourself out of the system
iptables -A MY-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 2222 -j ACCEPT
# Allow web
iptables -A MY-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
iptables -A MY-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
# Reject everything else
iptables -A MY-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
# Save settings
# List rules
iptables -L -v

To install iptables if you don’t have it aptitude install iptables iptables-persistent
Run the script to set the rules.

That’s it! This is a tremendous start. As a quick security review here is what you now have:

  • non-default ssh port to stop script kiddies from hammering user login/password guesses
  • per sshlogin group only one non-default user is even allowed to ssh in even if someone were to target you and find your open ssh port
  • daily security updates being applied to minimize risk of an exploitable package causing any harm
  • daily log reports being emailed to you for review
  • nice, concise iptables script to ensure only the ports you intend are open to the outside world

Look out for the Quick Secure Setup Part II, where we will protect our server more by blocking attacks and managing our firewall easier.

  2 Responses to “Ubuntu Server Initial Security – Quick Secure Setup Part I”

  1. […] to Part II of the Quick Secure Setup Series.  Be sure to check out Quick, Secure Setup Part I first, although this can be taken on its own if you’d just like to configure UFW with […]

  2. […] little series.  First let’s quickly look at what we have so far if you’ve gone through Quick Secure Setup Part I and Quick Secure Setup Part II.  From the security standpoint your server has every non-essential […]

 Leave a Reply