The reason why Linux and open source will always be more secure than Windows is because you can build advanced security right in. This guide’s going to show you how to do that. I’ll be explaining how to compile your own kernel with PaX and Grsecurity patches. (I’m actually compiling 3.3.6 for myself but this guide covers 3.2.18.)
First let’s explain a few things…
What Is A Kernel?
Well, if you don’t know what a kernel is this guide is probably a bit too advanced but far be it from me to turn you away. The kernel is essentially the core of the operating system. It is the lowest level of software on the system running with the highest rights. Linux runs on “The Linux Kernel” and that kernel is common to all Linux distributions.
What Is PaX?
PaX is a series of patches that can be applied to the Linux kernel. These patches provide functionality and improvements to built in features such as ASLR (Address Space Layout Randomization), which help mitigate and deter exploits.
PaX features can be daunting so for a per-feature explanation see this link. I highly suggest you take a look at these features and research both PaX and Grsecurity so you can fully understand what they provide.
What Is Grsecurity?
Grsecurity is another series of patches that can be applied to the Linux kernel. These patches will allow changes to policy, provide a tool for RBAC, and add new policies. Grsecurity and PaX are built to work together and reinforce one another.
Why Are We Doing This?
Well, to get the most secure system that you can possibly get you’re going to want to start compiling your own kernel. The kernel is, for various reasons, where security belongs (more on this in future posts.) Now, on a default install of some distro like, say, Ubuntu you’re fairly secure and the tools already provided can be used to really lock the system down (think AppArmor) but if you’re looking to secure your system against sophisticated and targeted attacks PAX and Grsecurity are the way to go.
Keep in mind that the settings I use are for my own system. A server would be able to use more settings because it wouldn’t have to worry about, for example, the sound working.
You will also need to do this for new updates from kernel.org in order to get the latest security patches, among other things. Not even Grsecurity will keep an unpatched system safe.
So, since we’re done with the intro…
Setting Up Our System
Before we even download source code we need to make sure we have everything necessary to actually compile and configure our kernel. Let’s start by installing some software: (I’ll assume sudo/root for this guide.)
# apt-get install patch bin86 kernel-package build-essential libncurses5-dev gcc-*-plugin-dev
That’s (hopefully) everything you need to compile, package, and configure the kernel. (You may need to install gcc and plugins.)
Now let’s set up a working folder and cd to it.
# mkdir /usr/src/linux/
# cd /usr/src/linux/
That’s it for now.
Downloading The Linux Kernel And Patches
In this example I’ll be using the Linux Kernel 3.2.18 (the same steps will work for any kernel, just change the patches) and the Grsecurity patch that goes along with it. I’m assuming you’re still in /usr/src/linux/.
# wget https://grsecurity.net/stable/grsecurity-2.9-3.2.18-201205301835.patch
# wget https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.2.18.tar.bz2
Once the download has completed you can extract linux-3.2.18.tar.bz2 to ./linux-3.2.18.
Patching The Kernel
This part is fairly simple, move to your new linux-3.2.18 folder and patch.
# cd ./linux-3.2.18
# patch -p1 < /usr/src/linux/grsecurity-2.9-3.2.18-201205301835.patch
This should patch the kernel without any interaction necessary.
Configuring The Kernel
(note: I am taking screenshots of a 3.3.6 kernel with my own configuration, yours may vary. Once size does not fit all – do research!)
You’ll be brought to this screen:
Note: If you want to enable KERNEXEC you must go to Processor Features and disable Xen/Paravirtualization.
Navigate (arrow keys) to Security Options and hit ‘Enter’ and…:
As you can see there are many options here. You can use preconfigured options (Low, Medium, High) or, as I suggest, Custom.
The following settings are suggestions that work for me. They can make or break systems depending on usage. A server might need completely different settings, for example. You’ll probably be compiling a few kernels just to see what breaks when.
[*] Deny reading/writing to /dev/kmem, /dev/mem, and /dev/port
[ ] Disable privileged I/O
[*] Harden ASLR against information leaks and entropy reduction
[*] Deter exploit bruteforcing
[*] Harden module auto-loading
[*] Hide kernel symbols
[*] Active kernel exploit response
Role Based Access Control (RBAC): I’ll post later about configuring RBAC.
[ ] Disable RBAC system
[*] Hide kernel processes
(3) Maximum tries before password lockout
(30) Time to wait after max password tries, in seconds
[*] Proc restrictions
[*] Restrict /proc to user only
[*] Additional restrictions
[*] Linking restrictions
[*] FIFO restrictions
[ ] Sysfs/debugfs restriction -Breaks Sound on Ubuntu
[ ] Runtime read-only mount protection -For servers, not users.
[*] Chroot jail restrictions
[*] Deny mounts
[*] Deny double-chroots
[*] Deny pivot_root in chroot
[*] Enforce chdir(“/”) on all chroots
[*] Deny (f)chmod +s
[*] Deny fchdir out of chroot
[*] Deny mknod
[*] Deny shmat() out of chroot
[*] Deny access to abstract AF_UNIX sockets out of chroot
[*] Protect outside processes
[*] Restrict priority changes
[*] Deny sysctl writes
[*] Capability restrictions
Your choice, this is more useful for servers. As a user I don’t need any of this.
[*] Dmesg(8) restriction
[*] Deter ptrace-based process snooping
[*] Require read access to ptrace sensitive binaries
[*] Enforce consistent multithreaded privileges
[*] Trusted Path Execution (TPE)
[*] Partially restrict all non-root users -This is one option that I use. It may break things and it’s not a critical feature so you may consider removing it.
[*] Larger entropy pools
[*] TCP/UDP blackhole and LAST_ACK DoS prevention
[ ] Socket restrictions
[ ] Sysctl support
[ ] Turn on features by default
As with Grsecurity we’re presented with quite a few options. PAX settings can very easily break things so my settings will likely vary from what your settings could be. I will note specific areas where there are known conflicts.
For details on PaX features see this link.
[ ] Support soft mode By leaving this off we have PaX system wide.
[ ] Use legacy ELF header marking
[ ] Use ELF program header marking
[ ] Use filesystem extended attributes marking
[*] Enforce non-executable pages
[*] Paging based non-executable pages
[*] Emulate trampolines
[*] Restrict mprotect() This will break X.
[ ] Use legacy/compat protection demoting (read help)
[ ] Allow ELF text relocations (read help)
[*] Enforce non-executable kernel pages (Requires you disabled Xen)
Return Address Instrumentation Method (bts) —>
Address Space Layout Randomization:
[*] Address Space Layout Randomization
[*] Randomize kernel stack base
[*] Randomize user stack base
[*] Randomize mmap() base
Miscellaneous Hardening Features: (Note: Users of ATI SPUs must use my settings here. Users with other GPUs should enable all ** settings.)
[*] Sanitize all freed memory
[*] Sanitize kernel stack
[*] Prevent various kernel object reference counter overflows **
[*] Harden heap object copies between kernel and userland **
[*] Prevent various integer overflows in function size parameters
**As of version 12.8 the closed source ATI FGLRX drivers are compatible with the above. Earlier versions will NOT work.
Other Security Settings
Exit your PaX options and go back to the security settings.
Set ” Low address space for LSM to protect from user allocation” to 65536 or 32768:
This is the portion of low virtual memory which should be protected
from userspace allocation. Keeping a user from writing to low pages
can help reduce the impact of kernel NULL pointer bugs.
For most ia64, ppc64 and x86 users with lots of address space
a value of 65536 is reasonable and should cause no problems.
On arm and other archs it should not be higher than 32768.
Programs which use vm86 functionality or have some need to map
this low address space will need the permission specific to the
systems running LSM.
Time To Compile And Install
(Note: You may want to see the last section ‘Other Tips’ before you compile.)
# make-kpkg clean
# make-kpkg --initrd --append-to-version "grsec1.0" kernel_image
The above command might give you an error in which case you’ll need to type it out. It’s a wordpress issue where it combines the –‘s.
Compiling will take a while. Probably a half hour, potentially multiple hours depending on the hardware. When you’re done there will be a package in /usr/src/linux.
# cd /usr/src/linux
# dpkg -i ./<name.of.deb>
Reboot into the new kernel and that’s it.
It’s a lot of work to set it up but it should only take you a few minutes after the first time. Compiling is what takes the longest but it can be done in the background.
If something breaks just boot into the last kernel you used. Simple.
Since you’re taking the time to compile this thing you may as well get the most out of it. I suggest you go through the settings and disable any drivers not related/ enable or disable features.
You should also open /usr/src/linux/linux-3.2.18/makefile and find the line:
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
And have the following line as: (add the -march=native -pipe -mtune=native)
KBUILD_CPPFLAGS += $(KCPPFLAGS) -march=native -pipe -mtune=native
pipe will speed up compile time significantly for systems with lots of RAM. march=native will optimize the kernel for your specific CPU. Don’t use -march=native if you are compiling for another system with a different CPU (same for mtune).
Take the time to disable drivers that you won’t use. It’ll speed up compile time and produce a smaller kernel.
The highlights of this new kernel are:
1) Improved ASLR
3) Hardened Chroots (if you use Chromium or Google Chrome the sandbox makes use of Chroots so you’ve just made it more secure.)
4) Exploit bruteforcing is much harder
5) A generally more secure system with stricter policies and checks
6) Optimized kernel if you followed the “notes.”
This was a long post so if I’ve left anything out or misrepresented something leave a comment and let me know. RBAC is worth its own full post so I’ll get to that later (setting it up on any user-oriented OS is difficult.) For now you can see this wiki page to learn how to set RBAC up, but it’s not so simple.