I’m going to keep some tips here for users looking to improve their security, when I update it I’ll tweet about it, so feel free to follow me @insanitybit. This is aimed at desktop users but naturally lots of it can apply to a Linux server. Some of this will be simple, trivial, and some of this will be quite a bit more difficult. I’m focusing specifically on Ubuntu but other distros will have similar features (replace Apparmor with SELinux). I will try to make this as comprehensive as possible, though I’m specifically avoiding items like Fail2Ban as it’s not really useful for users. You can consider this an extension of my ‘definitive guides‘ – The Definitive Guide For Securing Linux Ubuntu.
A lot of users believe that a distro such as Ubuntu will be so much more secure than Windows, purely through virtue of obscurity. As Linux popularity continues to grow you’ll see attackers begin to take notice. Just because attackers don’t care to hack Linux desktop systems does not by any means imply they aren’t capable of it, or ready to when it seems profitable.
Thankfully, Linux is really easy to secure. Despite some problems there are a lot of powerful projects that give users the power to secure themselves against many threats.
Securing Your Browser
First I’d like to start by linking to my guides for locking down Chrome and Firefox As a user your most exploitable area is your browser, it’s constantly taking in untrusted content, often over an insecure connection. I personally love Chrome’s Linux sandbox, but Firefox with NoScript is very powerful as well – I leave it to you to decide between the two based on your needs.
Enabling Ubuntu’s Firewall
Ubuntu comes with a firewall utility called UFW, but it isn’t enabled by default. The reason is that, by default, Ubuntu doesn’t have any open ports open (except for system services that are typically necessary for the average user). So is a Firewall strictly necessary? Well, if you’re behind a NAT router not so much, any open ports will expose you to local attacks, but you’re ‘hidden’ from the internet. Still, if you’re looking to secure your system you can simply run this command:
ufw default deny incoming
And it should prevent inbound access. You can create complex rules via iptables to restrict or relax your rules. You can also check out GUFW for a graphic interface to UFW. GUFW makes everything very easy to use.
You can use UFW/GUFW to create outbound rules for applications. Due to the amount that applications within a user ID can interfere with one another I do not feel that an outbound firewall is worthwhile for security, and it can be quite a bit of a pain. If you’re serious about setting up an outbound firewall I suggest you make strict use of user separation and apparmor, though even then the benefits are questionable (there is a reason programs like Comodo on Windows bundle their firewall components with strict HIPS software).
See this guide for further information on setting up firewalls. Courtesy of a very smart guy, Dangertux.
Run a Program As A Separate User
While the simplest way to restrict a program is AppArmor (see below) you can also make use of the native user/group Linux permissions in order to run an application as a different user. I’ve written a guide with Pidgin as the example. Separated programs will have less access to one another and they’ll live in a different user directory, with access only to that directory.
By separating a program to a new user we can also write more powerful firewall rules, as the program won’t be able to bypass an outbound rule as trivially.
For a risky program that doesn’t need to access other programs this may be a very viable option. For example, I run Xchat, which hasn’t been updated in about two years. For a program like this throwing as much security as possible at it isn’t a bad idea, since it doesn’t get patches, doesn’t use modern security techniques, and is internet facing.
By default unprivileged users can read a lot of your systems logs. These logs can contain critical information for an attacker hoping to exploit your system further.
This is useful for debugging, but you’re not likely to have to do that. Running this command will prevent access by unprivileged users:
echo kernel.dmesg_restrict = 1 >> /etc/sysctl.conf
This feature is also included in the Grsecurity patch.
DNSCrypt is a DNS resolver that encrypts the content of your request between you and the first level resolver. It prevents an attacker from hijacking or viewing your DNS resolution and the program itself is hardened quite a lot.
For a guide to install.
For a guide to harden further.
Removing Attack Surface
One of the first steps to harden any operating system should always be disabling unnecessary programs/ services. Desktop operating systems don’t come “default secure” they come “default compatible” and that means meeting the needs of every person, generically. So while John may use his network printer Jane may not, but Jane’s system still comes with all of the attack surface necessary for network printing.
The network printing service is cupsd. It comes, by default, in an Apparmor profile, so it’s not like you should be incredibly worried about being exploited. And if you’re behind NAT you’re only exposed to local attacks. But, if you’re like me, you don’t print over a network and you have no need for this service. Are you likely to be attacked over it? Maybe, maybe not, but it’s not needed. So go ahead and remove that service.
You can check for programs listening on your system with the following command:
Look up any services and carefully consider the benefit/ necessity of them. If you don’t need them or want them, remove them.
Another tip is to use checksec.sh. Run the following command: (You must first set the file as executable)
It will provide you with a list of running services along with information about their security – whether they use NX, stack canaries, and if they’ve been compiled as Position Independent Executables (PIE). This may help you make a more informed decision about removing a service.
Mount /tmp With noexec,nodev,nosuid
Many programs require read/write access to /tmp but, for the most part, no programs actually need to be able to execute from there. Mounting this area with the noexec, nodev, nosuid can provide some level of security. Rather than creating a new partition for /tmp I find it’s just easier to use RAM (it expands as needed and doesn’t require partitioning , one benefit being a (potential) performance increase, though I wouldn’t bet on it.
Copy the following into your /etc/fstab file.
tmpfs /tmp tmpfs mode=1777,nosuid,nodev,noexec 0 0
If you want to create a new partition for /tmp you can find a guide online for that. It’s kinda a pain. The downside to running it in RAM is, obviously, you lose some RAM. If you want to limit the amount of RAM it can use (tmpfs expands as needed) you can change the line to (for 512M):
tmpfs /tmp tmpfs size=512M,mode=1777,nosuid,nodev,noexec 0 0
I recommend that if you follow the above you make use of AppArmor to improve the level of security this adds. If you use /tmp in RAM one benefit is that, in your AppArmor profiles, you should be able to remove map rules for some programs that map /tmp for performance reasons.
AppArmor is the Linux Security Module of choice for Ubuntu. It implements Mandatory Access Control on a per-process basis. It’s very simple to learn how to use AppArmor and I’ve written a guide. In the guide I provide tips for creating strong AppArmor profiles and avoiding potential pitfalls.
A program like Pidgin has a lot of access to your system. It runs as the same user as many other programs on your system and therefor is granted a fair amount of control over them. It can read many areas of the system that it doesn’t need to read, it can write to quite a few too. AppArmor restricts it to only the resources it needs, making both remote and local privilege exploits more difficult to pull off.
I’ve written a few very strict AppArmor profiles myself that you’re welcome to use as a starting point. [Xchat][Pulseaudio] [Java]
32bit users will have to adjust as needed, though it should be as simple as replacing the x86_64 with i386 (I’ll add variables for this at some point so you won’t have to).
Every internet facing program deserves an AppArmor profiles. It’s the simplest way to implement least privilege on a per application basis.
PaX and Grsecurity
PaX and Grsecurity are patches for the Linux kernel (the Grsecurity patch contains both, don’t just use PaX). PaX and Grsecurity have been at the forefront of security for more than a decade, bringing some of the most important security mitigation techniques to systems today, such as Address Space Layout Randomization (ASLR). ASLR is a great example of a mitigation technique that doesn’t have a great implementation in typical vanilla systems. The ASLR in your average distro, like Ubuntu, introduces far less entropy into the system, which degrades its use. The ASLR is also missing critical features, such as brute force deterrence, among others. PaX and Grsecurity bring these features and many many others to Linux. No operating system has as complete ASLR as PaX and, really, nothing else compares.
Not all of these features are compatible for desktop users, or even necessary, but a number of them will work on an Ubuntu desktop. You can see my guide for patching and compiling a Grsecurity Linux kernel, with notes about compatibility issues for desktop users.
Many of these security features directly relate to desktop security. Many applications and services use chroot to run programs in a separate environment. Chroot is incapable of restricting programs that can run as root, multiple bypasses are possible. Chrome is one such program, along with many other services (like avahi-daemon), so using the chroot hardening features of Grsecurity will provide a considerably more secure environment.
PaX and Grsecurity can be implemented with very little performance overhead, and very few stability issues if configured properly. If you’re really looking to secure your Linux system and you’re willing to take the time to compile it you should give it a try.
Learn how to compile your own Grsecurity Linux kernel here.
None of the above will make up for a system that is out of date and unpatched. If you’re using an older kernel and userland applications an attacker will be able to chain together enough exploits to bypass any restrictions/ measures you’ve taken, no matter how powerful. Make sure to stay up to date for all applications.
You can push patch time further by hardening the system – time to develop an exploit for a hardened system is longer. This does not mean you can postpone indefinitely, it just buys you time to test patches and improve your patch management.
Something To Keep In Mind
This all works best in conjunction. Grsecurity and PaX are honestly the best security software there is, in my opinion, but they can’t make up for a completely insecure userland. If you’re running programs that opt out or don’t make use of modern technology there’s only so much they can do. It’s very unfortunate but, even on 64bit, Ubuntu ships with a lot of services not using Position Independent Executable code – at this point it’s necessary to harden the programs in other ways.
And the same goes both ways. If you’re not using Grsecurity and PaX then your kernel is less secure, meaning that even if you harden a userland application with apparmor an attacker will have a much easier time exploiting the kernel and escaping the profile.
If you’re annoyed about your distro coming with insecure settings email them about it. You can reach Canonical:
you have suggestions for canonical.com or ubuntu.com, please email us email@example.com or firstname.lastname@example.org.
And if you have any suggestions for this guide please let me know in a comment. I’ll happily include any relevant information.
Follow me @insanitybit for updates and more articles like this.