The grsecurity project, hosted on
As grsecurity's features are mostly kernel-based, the majority of this document explains the various kernel features and their respective sysctl operands (if applicable).
The
Throughout this document we will talk about kernel configuration using the
kernel variables like
When you configure your kernel through
You can therefore still configure your kernel as you like - with a bit of
thinking. And if you can't find a certain option, there's always the possibility
to edit
Of course, to be able to select the various grsecurity kernel options, you must enable grsecurity in your kernel:
CONFIG_GRKERNSEC=y CONFIG_GRKERNSEC_CUSTOM=y
PaX introduces a couple of security mechanisms that make it harder for attackers
to exploit software bugs that involve memory corruption (so don't treat PaX as
if it protects against all possible software bugs). The
One prevention method disallows executable code to be stored in writable memory. When we look at a process, it requires five memory regions:
The first PaX prevention method, called NOEXEC, is meant to give control over the runtime code generation. It marks memory pages that do not contain executable code as non-executable. This means that the heap and the stack, which only contain variable data and shouldn't contain executable code, are marked as non-executable. Exploits that place code in these areas with the intention of running it will fail.
NOEXEC does more than this actually, interested readers should focus their
attention to the
The second PaX prevention method, called ASLR (Address Space Layout Randomization), randomize the addresses given to memory requests. Where previously memory was assigned contiguously (which means exploits know where the tasks' memory regions are situated) ASLR randomizes this allocation, rendering techniques that rely on this information useless.
More information about ASLR can be found
The recommended kernel setting for PaX is:
# # PaX Control # # CONFIG_GRKERNSEC_PAX_SOFTMODE is not set CONFIG_GRKERNSEC_PAX_EI_PAX=y CONFIG_GRKERNSEC_PAX_PT_PAX_FLAGS=y CONFIG_GRKERNSEC_PAX_NO_ACL_FLAGS=y# CONFIG_GRKERNSEC_PAX_HAVE_ACL_FLAGS is not set # CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS is not set # # Address Space Protection # CONFIG_GRKERNSEC_PAX_NOEXEC=y# CONFIG_GRKERNSEC_PAX_PAGEEXEC is not set CONFIG_GRKERNSEC_PAX_SEGMEXEC=y CONFIG_GRKERNSEC_PAX_EMUTRAMP=y CONFIG_GRKERNSEC_PAX_MPROTECT=y# CONFIG_GRKERNSEC_PAX_NOELFRELOCS is not set CONFIG_GRKERNSEC_PAX_ASLR=y CONFIG_GRKERNSEC_PAX_RANDKSTACK=y CONFIG_GRKERNSEC_PAX_RANDUSTACK=y CONFIG_GRKERNSEC_PAX_RANDMMAP=y CONFIG_GRKERNSEC_PAX_RANDEXEC=y# CONFIG_GRKERNSEC_KMEM is not set # CONFIG_GRKERNSEC_IO is not set CONFIG_GRKERNSEC_PROC_MEMMAP=y CONFIG_GRKERNSEC_HIDESYM=y
If you are running a non-x86 system you will observe that there is no CONFIG_GRKERNSEC_PAX_SEGMEXEC. You should select CONFIG_GRKERNSEC_PAX_PAGEEXEC instead as it is the only non-exec implementation around.
Not all Linux applications are happy with the PaX security restrictions. These
tools include xorg-x11, java, mplayer, xmms and others. If you plan on using
them you can elevate the protections for these applications using
# emerge sys-apps/chpax # emerge sys-apps/paxctl
chpax provides an init script that handles most known application settings for you:
# rc-update add chpax default
# emerge pax-utils
Interesting tools include
Peter Busser has written a regression test suite called
# emerge paxtest # paxtest Executable anonymous mapping : Killed Executable bss : Killed Executable data : Killed Executable heap : Killed Executable stack : Killed Executable anonymous mapping (mprotect) : Killed Executable bss (mprotect) : Killed Executable data (mprotect) : Killed Executable heap (mprotect) : Killed Executable stack (mprotect) : Killed Executable shared library bss (mprotect) : Killed Executable shared library data (mprotect): Killed Writable text segments : Killed Anonymous mapping randomisation test : 16 bits (guessed) Heap randomisation test (ET_EXEC) : 13 bits (guessed) Heap randomisation test (ET_DYN) : 25 bits (guessed) Main executable randomisation (ET_EXEC) : 16 bits (guessed) Main executable randomisation (ET_DYN) : 17 bits (guessed) Shared library randomisation test : 16 bits (guessed) Stack randomisation test (SEGMEXEC) : 23 bits (guessed) Stack randomisation test (PAGEEXEC) : No randomisation Return to function (strcpy) : Vulnerable Return to function (memcpy) : Vulnerable Return to function (strcpy, RANDEXEC) : Killed Return to function (memcpy, RANDEXEC) : Killed Executable shared library bss : Killed Executable shared library data : Killed
In the above example run you notice that:
There are two basic types of access control mechanisms used to prevent unauthorized access to files (or information in general): DAC (Discretionary Access Control) and MAC (Mandatory Access Control). By default, Linux uses a DAC mechanism: the creator of the file can define who has access to the file. A MAC system however forces everyone to follow rules set by the administrator.
The MAC implementation grsecurity supports is called Role Based Access
Control. RBAC associates
The recommended kernel setting for RBAC is:
# # Role Based Access Control Options # CONFIG_GRKERNSEC_ACL_HIDEKERN=y CONFIG_GRKERNSEC_ACL_MAXTRIES=3 CONFIG_GRKERNSEC_ACL_TIMEOUT=30
When you install
# emerge gradm
By default, the RBAC policies are not activated. It is the sysadmin's job to determine when the system should have an RBAC policy enforced and not Gentoo's. Before activating the RBAC system you should set an admin password.
# gradm -P Setting up grsecurity RBAC password Password:(Enter a well-chosen password) Re-enter Password:(Enter the same password for confirmation) Password written in /etc/grsec/pw # gradm -E
To disable the RBAC system, run
# gradm -a admin Password:(Enter your admin role password) # gradm -D
If you want to leave the admin role, run
# gradm -u admin
The RBAC system comes with a great feature called "learning mode". The learning mode can generate an anticipatory least privilege policy for your system. This allows for time and money savings by being able to rapidly deploy multiple secure servers.
To use the learning mode, activate it using
# gradm -F -L /etc/grsec/learning.log
Now use your system, do the things you would normally do. Try to avoid rsyncing, running locate of any other heavy file i/o operation as this can really slow down the processing time.
When you believe you have used your system sufficiently to obtain a good policy,
let
# gradm -F -L /etc/grsec/learning.log -O /etc/grsec/learning.roles
Audit the
# mv /etc/grsec/learning.roles /etc/grsec/policy # chmod 0600 /etc/grsec/policy
You will now be able to enable the RBAC system with your new learned policy.
An interesting feature of grsecurity 2.x is
define objset1 { /root/blah rw /root/blah2 r /root/blah3 x } define somename2 { /root/test1 rw /root/blah2 rw /root/test3 h }
Here is an example of its use, and the resulting objects that will be added to your subject:
subject /somebinary o $objset1 & $somename2
The above would expand to:
subject /somebinary o /root/blah2 r
This is the result of the & operator which takes both sets and returns the files that exist in both sets and the permission for those files that exist in both sets.
subject /somebinary o $objset1 | $somename2
This example would expand to:
subject /somebinary o /root/blah rw /root/blah2 rw /root/blah3 x /root/test1 rw /root/test3 h
This is the result of the | operator which takes both sets and returns the files that exist in either set. If a file exists in both sets, it is returned as well and the mode contains the flags that exist in either set.
subject /somebinary o $objset1 - $somename2
This example would expand to:
subject /somebinary o /root/blah rw /root/blah2 h /root/blah3 x
This is the result of the - operator which takes both sets and returns the files that exist in the set on the left but not in the match of the file in set on the right. If a file exists on the left and a match is found on the right (either the filenames are the same, or a parent directory exists in the right set), the file is returned and the mode of the second set is removed from the first set, and that file is returned.
In some obscure pseudo-language you could see this as:
if ( ($objset1 contained /tmp/blah rw) and ($objset2 contained /tmp/blah r) ) then $objset1 - $objset2 would contain /tmp/blah w if ( ($objset1 contained /tmp/blah rw) and ($objset2 contained / rwx) ) then $objset1 - $objset2 would contain /tmp/blah h
As for order of precedence (from highest to lowest): "-, & |".
If you do not want to bother remembering precedence, parenthesis support is also included, so you can do things like:
(($set1 - $set2) | $set3) & $set4
Grsecurity2 includes many patches that prohibits users from gaining unnecessary
knowledge about the system. This includes restrictions on
We recommend the following grsecurity kernel configuration for filesystem protection:
# # Filesystem Protections # CONFIG_GRKERNSEC_PROC=y# CONFIG_GRKERNSEC_PROC_USER is not set CONFIG_GRKERNSEC_PROC_USERGROUP=y CONFIG_GRKERNSEC_PROC_GID=10 CONFIG_GRKERNSEC_PROC_ADD=y CONFIG_GRKERNSEC_LINK=y CONFIG_GRKERNSEC_FIFO=y CONFIG_GRKERNSEC_CHROOT=y CONFIG_GRKERNSEC_CHROOT_MOUNT=y CONFIG_GRKERNSEC_CHROOT_DOUBLE=y CONFIG_GRKERNSEC_CHROOT_PIVOT=y CONFIG_GRKERNSEC_CHROOT_CHDIR=y CONFIG_GRKERNSEC_CHROOT_CHMOD=y CONFIG_GRKERNSEC_CHROOT_FCHDIR=y CONFIG_GRKERNSEC_CHROOT_MKNOD=y CONFIG_GRKERNSEC_CHROOT_SHMAT=y CONFIG_GRKERNSEC_CHROOT_UNIX=y CONFIG_GRKERNSEC_CHROOT_FINDTASK=y CONFIG_GRKERNSEC_CHROOT_NICE=y CONFIG_GRKERNSEC_CHROOT_SYSCTL=y CONFIG_GRKERNSEC_CHROOT_CAPS=y
When you're using a kernel compiled with the above (or similar) settings, you
will get the option to enable/disable many of the options through the
The example below shows an excerpt of a typical
kernel.grsecurity.chroot_deny_sysctl = 1 kernel.grsecurity.chroot_caps = 1 kernel.grsecurity.chroot_execlog = 0 kernel.grsecurity.chroot_restrict_nice = 1 kernel.grsecurity.chroot_deny_mknod = 1 kernel.grsecurity.chroot_deny_chmod = 1 kernel.grsecurity.chroot_enforce_chdir = 1 kernel.grsecurity.chroot_deny_pivot = 1 kernel.grsecurity.chroot_deny_chroot = 1 kernel.grsecurity.chroot_deny_fchdir = 1 kernel.grsecurity.chroot_deny_mount = 1 kernel.grsecurity.chroot_deny_unix = 1 kernel.grsecurity.chroot_deny_shmat = 1
You can enable or disable settings at will using the
(Toggling the exec_logging feature ON) # sysctl -w kernel.grsecurity.exec_logging = 1(Toggling the exec_logging feature OFF) # sysctl -w kernel.grsecurity.exec_logging = 0
There is a very important sysctl setting pertaining to grsecurity, namely
# sysctl -w kernel.grsecurity.grsec_lock = 1
grsecurity adds extra functionality to the kernel pertaining the logging. With
grsecurity's
The following kernel configuration section can be used to enable grsecurity's Kernel Audit Settings:
# # Kernel Auditing # # CONFIG_GRKERNSEC_AUDIT_GROUP is not set CONFIG_GRKERNSEC_EXECLOG=y CONFIG_GRKERNSEC_RESLOG=y CONFIG_GRKERNSEC_CHROOT_EXECLOG=y CONFIG_GRKERNSEC_AUDIT_CHDIR=y CONFIG_GRKERNSEC_AUDIT_MOUNT=y CONFIG_GRKERNSEC_AUDIT_IPC=y CONFIG_GRKERNSEC_SIGNAL=y CONFIG_GRKERNSEC_FORKFAIL=y CONFIG_GRKERNSEC_TIME=y CONFIG_GRKERNSEC_PROC_IPADDR=y CONFIG_GRKERNSEC_AUDIT_TEXTREL=y
With grsecurity you can restrict executables. Since most exploits work through one or more running processes this protection can save your system's health.
Linux' TCP/IP stack is vulnerable to prediction-based attacks. grsecurity includes randomization patches to counter these attacks. Apart from these you can also enable socket restrictions, disallowing certain groups network access alltogether.
The following kernel settings enable various executable and network protections:
# # Executable Protections # CONFIG_GRKERNSEC_EXECVE=y CONFIG_GRKERNSEC_DMESG=y CONFIG_GRKERNSEC_RANDPID=y CONFIG_GRKERNSEC_TPE=y CONFIG_GRKERNSEC_TPE_ALL=y CONFIG_GRKERNSEC_TPE_GID=100# # Network Protections # CONFIG_GRKERNSEC_RANDNET=y CONFIG_GRKERNSEC_RANDISN=y CONFIG_GRKERNSEC_RANDID=y CONFIG_GRKERNSEC_RANDSRC=y CONFIG_GRKERNSEC_RANDRPC=y# CONFIG_GRKERNSEC_SOCKET is not set
Although it is outside the scope of this document we mention the use of the hardened toolchain which completes the grsec/PaX model from userspace. As a quickstart you can do:
# eselect profile list [1] default/linux/amd64/10.0 [2] default/linux/amd64/10.0/desktop [3] default/linux/amd64/10.0/desktop/gnome * [4] default/linux/amd64/10.0/desktop/kde [5] default/linux/amd64/10.0/developer [6] default/linux/amd64/10.0/no-multilib [7] default/linux/amd64/10.0/server [8] hardened/linux/amd64 [9] hardened/linux/amd64/no-multilib [10] selinux/2007.0/amd64 [11] selinux/2007.0/amd64/hardened [12] selinux/v2refpolicy/amd64 [13] selinux/v2refpolicy/amd64/desktop [14] selinux/v2refpolicy/amd64/developer [15] selinux/v2refpolicy/amd64/hardened [16] selinux/v2refpolicy/amd64/server # eselect profile set 8(replace 8 with the desired hardened profile) # emerge --oneshot binutils gcc virtual/libc # emerge -e system # emerge -e world
If you don't want to use this profile, add these