FreeBSD securelevel is a security mechanism implemented in the kernel that restricts certain tasks depending on the level that is active. Not even the super user will be able to bypass this mechanism if well setup.
From securelevel man page :
-1 Permanently insecure mode - always run the system in level 0 mode.
This is the default initial value.
0 Insecure mode - immutable and append-only flags may be turned off. All devices may be read or written subject to their permissions.
1 Secure mode - the system immutable and system append-only flags may not be turned off; disks for mounted file systems, /dev/mem, and /dev/kmem may not be opened for writing; kernel modules (see kld(4)) may not be loaded or unloaded.
2 Highly secure mode - same as secure mode, plus disks may not be opened for writing (except by mount(2)) whether mounted or not. This level precludes tampering with file systems by unmounting them, but also inhibits running newfs(8) while the system is multiuser.
In addition, kernel time changes are restricted to less than or equal to one second. Attempts to change the time by more than this will log the message ``Time adjustment clamped to +1 second''.
To see the current securelevel you can use :
# sysctl kern.securelevel
This will display something like:
on a system with default configuration.
To raise the securelevel you use sysctl like this:
# sysctl kern.securelevel=2
Only the superuser can raise the securelevel, and no one can lower the securelevel, so if you just raised your securelevel and you want it back to -1 you have to make sure securelevel is not active at boot and then reboot.
If you want to activate securelevel at boot you have to edit /etc/rc.conf and add something like this:
kern_securelevel_enable="YES" # kernel security level
kern_securelevel="2" # range: -1..3 as above
But activating securelevel at boot is useless unless you protect your boot files. If an attacker gets root access to your server he will be able to modify the boot files is such a way that after a reboot the securelevel will be deactivated. So before you go and protect any files against changes you should protect /etc/rc.conf and the scripts that run on system startup.
chflags schg /etc/rc.*
This will block any changes on those files unless you remove the "schg" flag . But if you enable securelevel >= 1 then no one will be able to remove the schg flag.
Warning!: if you do this you will not be able to lower the securelevel once it was raised because you will not be able to modify /etc/rc.conf. This may create a problem especially if you are connected from a remote location and you need to do a change.
In order to escape from a secure level when needed I came up with the idea of using a password that the root user can write in a file and that password will be hashed with a sha algorithm and then compared to a sha hash stored on disk. If the hashes match then the securelevel will not be activated at boot.
To make this work you have to edit /etc/rc.d/securelevel and add the following lines right before the last line:
master= "$(cat /usr/local/.master)"
test="$(cat /usr/local/etc/.my_test_passwd |openssl sha1)"
if [ "$master" = "$test" ] ; then
Save the file and then you go to create /usr/local/.master like this:
cat <<EOF | openssl sha1 > /usr/local/.master
Type in your password and then on a single line type EOF and hit enter. This will create a sha1 hash on your password and store that hash in /usr/local/.master
Now every time you want to lower the securelevel just put your plain password in /usr/local/etc/.my_test_passwd and reboot. After reboot the securelevel should be -1
Some may argue that this solution lowers the security introduced by securelevel because if you put your password in .my_test_passwd and attacker may capture it but it's the only way I know how to do this if I work on a server where I don't have physical access.