Introduction
This post assumes an x86_64 system running FreeBSD 14.0-RELEASE-p6, which was the latest as of writing. These options may vary depending on system architecture (x86_64, ARM, etc…) and/or FreeBSD version.
Basic Hardening Options
During installation, the installer presents a few hardening options. After installation, if you want to check what those installation hardening options are, look at the file at /usr/libexec/bsdinstall/hardening
. This can be helpful if you didn’t select some or all of the options and want to see what they would’ve done so you can add them later.
We’re going to be adding a few additional options that are not presented during installation.
The descriptions for each sysctl
option can be gotten by running sysctl -d [sysctl_name]
.
/etc/sysctl.conf
Example:
security.bsd.see_other_uids=0
security.bsd.see_other_gids=0
security.bsd.hardlink_check_uid=1
security.bsd.hardlink_check_gid=1
security.bsd.see_jail_proc=0
security.bsd.unprivileged_read_msgbuf=0
security.bsd.unprivileged_proc_debug=0
security.bsd.allow_ptrace=0
kern.randompid=1
kern.elf32.allow_wx=0
kern.elf64.allow_wx=0
Breakdown:
security.bsd.see_other_uids=0
andsecurity.bsd.see_other_gids=0
- Prevent unprivileged processes from seeing subjects/objects with different real uid/gid.
- For example, unprivileged user
deku
won’t be able to seebakugo
’s processes.
security.bsd.hardlink_check_uid=1
andsecurity.bsd.hardlink_check_gid=1
- Prevent unprivileged processes from creating hard links to files owned by other users/groups.
- For example, unprivileged user
deku
won’t be able to create a hardlink to a file owned bybakugo
. - This might cause issues with Dovecot depending on the mail storage/locking mechanisms used.
security.bsd.see_jail_proc=0
- Prevent unprivileged processes from seeing subjects/objects with different jail ids.
- For example, unprivileged user
deku
won’t be able to see processes running in another jail.
security.bsd.unprivileged_read_msgbuf=0
- Prevent unprivileged processes from reading the kernel message buffer.
- For example, unprivileged user
deku
won’t be able to see the kernel message buffer by runningdmesg
.
security.bsd.unprivileged_proc_debug=0
- Prevent unprivileged processes from using process debugging facilities.
security.bsd.allow_ptrace=0
- Prevent usage of
ptrace(2)
.
- Prevent usage of
kern.randompid=1
- Use random PIDs, setting this to 1 chooses a random PID modulus for you.
- Some say this option may result in an increased chance of PID reuse, or that it might not really help security.
- Random PIDs are used by default in OpenBSD. 1
- It shouldn’t really hurt to enable.
kern.elf32.allow_wx=0
andkern.elf64.allow_wx=0
- WARNING: May break some programs! If some programs don’t work correctly, try removing/commenting out these values.
- Prevents pages from being mapped simultaneously writable and executable for ELF64 and ELF32 binaries.
- Notably breaks Java.
/boot/loader.conf
Example:
security.bsd.allow_destructive_dtrace=0
cpu_microcode_load="YES"
cpu_microcode_name="/boot/firmware/intel-ucode.bin"
Breakdown:
security.bsd.allow_destructive_dtrace=0
- One of the options in the FreeBSD installer.
- Prevents destructive use of
dtrace
.
cpu_microcode_load="YES"
andcpu_microcode_name="/boot/firmware/[intel/amd]-ucode.bin"
- Load updated CPU microcode. This loading happens early so the kernel can make use of new features.
- Updated microcode often contains mitigations for vulnerabilities, and/or fixes for errata. You should keep the system firmware (UEFI) up to date as it usually contains updated microcode, but sometimes the system vendor takes too long or stops providing firmware updates entirely.
- Install either the
cpu-microcode-intel
orcpu-microcode-amd
package depending on your CPU. It will place the microcode files in/boot/firmware/
. - Choose one of
/boot/firmware/intel-ucode.bin
or/boot/firmware/amd-ucode.bin
depending on CPU.
/etc/rc.conf
Example:
clear_tmp_enable="YES"
syslogd_flags="-ss"
kern_securelevel_enable="YES"
kern_securelevel="3"
#kld_list="nullfs if_epair fdescfs" #use if needed
Breakdown:
clear_tmp_enable="YES"
- Clears the
/tmp/
directory on startup. Helps clean up in case sensitive files were accidentally left behind.
- Clears the
syslogd_flags="-ss"
- Secure syslogd so it doesn’t open network sockets. This will disable remote syslog.
kern_securelevel_enable="YES"
andkern_securelevel="[level]"
- WARNING: This may break some programs, as well as be quite invasive to general system use/maintenance.
smartctl
from thesmartmontools
package isn’t useful when securelevel is 2 or higher.- System updates using
freebsd-update
cannot be installed when securelevel is enabled. Disable securelevel and reboot before installing updates, then re-enable and reboot afterwards. - Kernel modules cannot be loaded or unloaded, first check which kernel modules your system loads when running all the software you use and specify them in
kld_list="module1 module2 etc..."
before enabling securelevel. For example, check the output ofkldstat
on a fresh boot with nothing running, then start all your software and check the output again. In a case with VNET jails, you might neednullfs if_epair fdescfs
.
- Enable kernel securelevel feature and set the securelevel.
- Check
security(7)
usingman security
for valid securelevels and how tight each of them are.
- WARNING: This may break some programs, as well as be quite invasive to general system use/maintenance.
Vulnerability Mitigations
Depending on the system, FreeBSD enables certain mitigations. You can check these mitigations using sysctl machdep.mitigations
. Note that enabling most of these options will negatively impact system performance.
Another mitigation exists called Page Table Isolation (PTI) under the sysctl vm.pmap.pti
. This may be enabled by default but can come at a heavy performance cost depending on the system. If you want to set this option, it must be set in /boot/loader.conf
as it cannot be set during runtime.
Choosing whether to enable or disable mitigations is up to you. You may want to selectively enable mitigations depending on which ones are needed for your system, taking the performance impact into consideration. The package spectre-meltdown-checker
may be useful to determine this.
On a Xeon X3460 (Lynnfield) system, leaving vm.pmap.pti
enabled (set to 1) reduces the score of Unixbench from ~2800 to ~2300. Enabling all the mitigations by setting the appropriate sysctl options under machdep.mitigations
reduces the score further to just ~1100 for a whopping 60% decrease from the original performance! Real world applications may not be impacted as heavily as benchmarks, but the slowdown is very noticable on this system. More modern systems won’t be impacted as badly, and updated microcode can perform more efficient mitigations in some cases.
Conclusion
This basic hardening is just one way to increase security. Installing and running only what you need, using a firewall, using secure configurations for programs and staying up to date with security fixes are important ways to improve security.
Make smart decisions when setting up software. For example, when setting up a reverse proxy server for a website, consider securing the communication between the reverse proxy and the backend servers with TLS and/or using VLANs, or using UNIX Domain Sockets with tight permissions instead of just leaving it all out in the open. Think about file permissions, don’t leave things like private keys with 777 permissions lying around.