From Segfault
Jump to navigation Jump to search

Operating Systems



A good set of options[1][2] to GCC seems to be:

export   CFLAGS="-g -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fpie -Wl,-z,defs -Wl,-z,now -Wl,-z,relro"
export  LDFLAGS="-Wl,-z,relro,-z,now,-z,noexecstack -fPIC -fPIE"

Some options explained:

-Wall                    Enables all the warnings about constructions that some users consider questionable
-Wextra                  Enables some extra warning flags that are not enabled by -Wall
-Wconversion             Warn for implicit conversions that may alter a value
-Wsign-conversion        Warn for implicit conversions that may change the sign of an integer value (enabled by -Wconversion in C)
-Wformat=2               Check format types and conversations, plus additional format checks
-Wformat-security        Also warn about uses of format functions that represent possible security problems
-Werror=format-security  Turn -Wformat warnings into errors
-fstack-protector-strong Emit extra code to check for buffer overflows, such as stack smashing attacks
-Wstack-protector        Warn about functions that are not protected against stack smashing
 ssp-buffer-size=4       Minimum size of buffers that receive stack smashing protection
-pie                     Produce a position independent executable on targets that support it (randomization)
-fPIE                    Needed by -pie
-ftrapv                  Generates traps for signed overflow on addition, subtraction, multiplication operations
-D_FORTIFY_SOURCE=2 -O2  Compile-time protection against static sized buffer overflows, -O2 is needed (?)
-Wl,-z,relro,-z,now      Mark various ELF memory sections read­only before handing over the program execution[3]

In Debian, hardening-wrapper and hardening-includes can be installed. GCC will then be wrapped and the hardening options will be set automatically if DEB_BUILD_HARDENING=1 is set:

$ ls -go `which gcc gcc-4.9` 
lrwxrwxrwx. 1  7 Feb 25 13:13 /usr/bin/gcc -> gcc-4.9
lrwxrwxrwx  1 11 Sep 24  2014 /usr/bin/gcc-4.9 -> hardened-cc

Some binaries were already compiled with some hardening options:

$ hardening-check /usr/sbin/sshd
 Position Independent Executable: yes
 Stack protected: yes
 Fortify Source functions: yes (some protected functions found)
 Read-only relocations: yes
 Immediate binding: yes

This has been superseeded by setting default flags to the Debian build framework:

$ dpkg-buildflags --export=sh
export CFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security"
export LDFLAGS="-Wl,-z,relro"

Populate the environment with (some[4] of) these flags:

export   CFLAGS="-g -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fpie -Wl,-z,defs -Wl,-z,now -Wl,-z,relro"
export  LDFLAGS="-Wl,-z,relro,-z,now,-z,noexecstack -fPIC -fPIE"


Enforce SSH protocol 2 only, permit root-login with keys only, disallow empty passwords, disable password-authenticaton, enable PAM:

$ cat /etc/ssh/sshd_config
Protocol               2
PermitRootLogin        without-password
PubkeyAuthentication   yes
PermitEmptyPasswords   no
PasswordAuthentication no
UsePAM                 yes

Be sure to adjust the TCP wrapper for SSH access. Also, with PAM we can set per-host and/or per-user restrictions:

$ grep pam_access /etc/pam.d/sshd 
account  required     pam_access.so
$ grep -v \# /etc/security/access.conf 
+  : root   :
-  : root   : ALL
+  : bob    : ALL
+  : alice  : .example.com
-  : ALL    : ALL

Also, with public-key authentication, we can restrict connections on a per-key basis:

$ cat ~bob/.ssh/authorized_keys
from="*.example.com",command="/usr/local/sbin/validate-rsync.sh" [...]
$ cat ~alice/.ssh/authorized_keys
from="tunnel.example.com",no-agent-forwarding,no-pty,no-user-rc,no-X11-forwarding,permitopen="localhost:1234" [...]


Note: tcp_wrapper support is on its way out for many applications[5][6][7][8] so the settings mentioned here may no longer be applicable.

Many Some network daemons are linked against libwrap, implementing TCP wrapper functionality:

$ ldd `which mysqld` `which sshd`
       libwrap.so.0 => /lib/libwrap.so.0 (0x00007f7ebded8000)
       libwrap.so.0 => /lib/libwrap.so.0 (0x00007fe29bd05000)

With this in place, we can restrict access to these services:

$ cat /etc/hosts.allow
sshd    : /etc/hosts.allow.networks
mysqld  :
ALL     :
ALL     :

$ cat /etc/hosts.allow.networks

$ cat /etc/hosts.deny

Note that this is restricting access on a TCP level and does not replace an IP level firewall!

We can also restrict access to the hosts.allow* files:

chmod 0640 /etc/hosts.allow*
setfacl -m u:daemon:r /etc/hosts.allow*           # Allow portmap resp. rpcbind
setfacl -m u:bob:r /etc/hosts.allow*              # Allow user bob

See also