Hardening FreeBSD
Updated: 06/27/2005
General Information
After a fresh install, it is important to harden the security on a server before it hits your network for use. Not only making configuration changes aid in the security of your box, but there are some practical rules to abide by. These are some hardening tips to make your FreeBSD box more secure and will apply to both the 5.x and 4.x branches, but I will assume you are running 5.x. If a 4.x change is different, I will note it.Note: Please do not apply these changes carelessly on a production server. Make sure you test, test, test on a separate box to note the effects of the changes.
Requirements
Hardening
Filesystem Structure
On a default install, you will find two places for temporary files -- /tmp and /var/tmp. Different packages and daemons use the different directories and there really isn't any need to use two different partitions for temporary files. Here we will replace /var/tmp with a link to /tmp.|
# # # |
mv /var/tmp/* /tmp/ rm -rf /var/tmp ln -s /tmp /var/tmp |
Disable Local root Access
The first rule to securing your box is to never treat the root account as a regular user. Never conduct mundane business while you are logged in as root. As the superuser, there are no restrictions as to what root can do, so always log in with a normal user and su to root only when needed./etc/ttys with your editor and change every occurence of "secure" to "insecure" as this will prevent root from logging in locally. *Note: changing the console entry will result in being prompted for the root password when booting into single-user mode; thus, making the recovery of the root password more difficult.|
# nano -w /etc/ttys ***output omitted*** console none unknown off insecure # ttyv0 "/usr/libexec/getty Pc" cons25 on insecure # Virtual terminals ttyv1 "/usr/libexec/getty Pc" cons25 on insecure ttyv2 "/usr/libexec/getty Pc" cons25 on insecure ttyv3 "/usr/libexec/getty Pc" cons25 on insecure ttyv4 "/usr/libexec/getty Pc" cons25 on insecure ttyv5 "/usr/libexec/getty Pc" cons25 on insecure ttyv6 "/usr/libexec/getty Pc" cons25 on insecure ttyv7 "/usr/libexec/getty Pc" cons25 on insecure ttyv8 "/usr/X11R6/bin/xdm -nodaemon" xterm off insecure # Serial terminals # The 'dialup' keyword identifies dialin lines to login, fingerd etc. ttyd0 "/usr/libexec/getty std.9600" dialup off insecure ttyd1 "/usr/libexec/getty std.9600" dialup off insecure ttyd2 "/usr/libexec/getty std.9600" dialup off insecure ttyd3 "/usr/libexec/getty std.9600" dialup off insecure # Dumb console dcons "/usr/libexec/getty std.9600" vt100 off insecure ***output omitted*** |
SSH Logins
By default, FreeBSD prevents root from logging in via ssh, but it gives anyone else with a valid user account access. If you are not running a shell server, it is a good idea to restrict ssh access to only members of the wheel group -- or you can create a separate group if you want some people to log in but not be able to su to root, say a group named "sshlogins." Let's add the following to the end of the sshd configuration file:|
# # # # # # # |
cat << EOF >> /etc/ssh/sshd_config PermitRootLogin=no AllowGroups wheel sshlogins Protocol 2 X11Forwarding=no VersionAddendum EOF |
|
# # # # # # # # # # # # # # # # |
echo "Banner /etc/welcomemsg" >> /etc/ssh/sshd_config cat << EOF > /etc/welcomemsg !!WARNING!!! READ THIS BEFORE ATTEMPTING TO LOGON This System is for the use of authorized users only. Individuals using this computer without authority, or in excess of their authority, are subject to having all of their activities on this system monitored and recorded by system personnel. In the course of monitoring individuals improperly using this system, or in the course of system maintenance, the activities of authorized users may also be monitored. Anyone using this system expressly consents to such monitoring and is advised that if such monitoring reveals possible criminal activity, system personnel may provide the evidence of such monitoring to law enforcement officials. EOF |
Password Rules
By default, FreeBSD uses md5 for password hashing and encryption. It's not bad, but blowfish is much better suited for passwords and we need to update some files to reflect blowfish. *Note: Passwords will not be converted to blowfish until they have been changed.| # | echo "crypt_default=blf" >> /etc/auth.conf |
/etc/login.conf and change the password format in the default class to blf. We should also modify the default password policy to put a minimum password length requirement and mix upper and lower case. Let's also cause passwords to expire after 90 days and to automatically log users out if they are idle for 30 minutes. It's also a good idea to set the default umask to prevent global access. The umask is the inverse to the chmod. So in this case when new files and directories are created, they will get the permissions of 0750.|
# nano -w /etc/login.conf ***output omitted*** default:\ :passwd_format=blf:\ :copyright=/etc/COPYRIGHT:\ :welcome=/etc/motd:\ :setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES:\ :path=/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin /usr/X11R6/bin ~/bin:\ :nologin=/var/run/nologin:\ :cputime=unlimited:\ :datasize=unlimited:\ :stacksize=unlimited:\ :memorylocked=unlimited:\ :memoryuse=unlimited:\ :filesize=unlimited:\ :coredumpsize=unlimited:\ :openfiles=unlimited:\ :maxproc=unlimited:\ :sbsize=unlimited:\ :vmemoryuse=unlimited:\ :priority=0:\ :ignoretime@:\ :minpasswordlen=8:\ :mixpasswordcase=true:\ :passwordtime=90d:\ :idletime=30:\ :umask=027: ***output omitted*** |
| # | cap_mkdb /etc/login.conf |
Restrict User Access
Scheduling jobs is a powerful feature in *nix, but at the same time, it can pose a security concern for your system if you allow users to schedule jobs -- especially if they are set up incorrectly. The potential harm could be looping a process endlessly, running malicious code (though this wouldn't pose too big of a problem if it's not run as root), or incorrect schedules. It is recommended to restrict cron and at to only root.|
# # # # # # # # |
echo "root" > /var/cron/allow echo "root" > /var/at/at.allow chmod o= /etc/crontab chmod o= /usr/bin/crontab chmod o= /usr/bin/at chmod o= /usr/bin/atq chmod o= /usr/bin/atrm chmod o= /usr/bin/batch |
|
# # # # # # # # # # # # # # # # |
chmod o= /etc/fstab chmod o= /etc/ftpusers chmod o= /etc/group chmod o= /etc/hosts chmod o= /etc/hosts.allow chmod o= /etc/hosts.equiv chmod o= /etc/hosts.lpd chmod o= /etc/inetd.conf chmod o= /etc/login.access chmod o= /etc/login.conf chmod o= /etc/newsyslog.conf chmod o= /etc/rc.conf chmod o= /etc/ssh/sshd_config chmod o= /etc/sysctl.conf chmod o= /etc/syslog.conf chmod o= /etc/ttys |
Note: Applying these changes to the log files will also mean logs can no longer be rotated.
|
# # # |
chmod o= /var/log chflags sappnd /var/log chflags sappnd /var/log/* |
|
# # # # # # # |
chmod o= /usr/bin/users chmod o= /usr/bin/w chmod o= /usr/bin/who chmod o= /usr/bin/lastcomm chmod o= /usr/sbin/jls chmod o= /usr/bin/last chmod o= /usr/sbin/lastlogin |
|
# # |
chmod ugo= /usr/bin/rlogin chmod ugo= /usr/bin/rsh |
|
# # |
chmod o= /usr/local/bin/nmap chmod o= /usr/local/bin/nessus |
System Configuration for Daemon Startup
Now it is time to enable or disable certain services by editing/etc/rc.conf. Here we will disable sendmail as it is an insecure MTA. If you want to run a mail server, I recommend using qmail.| # | echo 'sendmail_enable="NONE"' >> /etc/rc.conf |
|
# # |
echo 'kern_securelevel_enable="YES"' >> /etc/rc.conf echo 'kern_securelevel="3"' >> /etc/rc.conf |
| # | echo 'portmap_enable="NO"' >> /etc/rc.conf |
| # | echo 'inetd_enable="NO"' >> /etc/rc.conf |
| # | echo 'clear_tmp_enable="YES"' >> /etc/rc.conf |
| # | echo 'syslogd_flags="-ss"' >> /etc/rc.conf |
|
# # |
echo 'icmp_drop_redirect="YES"' >> /etc/rc.conf echo 'icmp_log_redirect="YES"' >> /etc/rc.conf |
| # | echo 'log_in_vain="YES"' >> /etc/rc.conf |
Set Kernel States
There are some kernel states we need to change and we'll add them to/etc/sysctl.conf to make them permanent. The first one is to prevent users from seeing information about processes that are being run under another UID.| # | echo "security.bsd.see_other_uids=0" >> /etc/sysctl.conf |
Note: 4.x users use the following instead:
| # | echo "kern.ps_showallprocs=0" >> /etc/sysctl.conf |
|
# # |
echo "net.inet.tcp.blackhole=2" >> /etc/sysctl.conf echo "net.inet.udp.blackhole=1" >> /etc/sysctl.conf |
Note: This setting is only for 5.3 and beyond. If you are running any older version of FreeBSD, you will need to compile your kernel with this option.
| # | echo "net.inet.ip.random_id=1" >> /etc/sysctl.conf |
Kernel Entries
There are a couple of security settings we can fix at the kernel level. One security hole we need to plug is disabling ctrl+alt+del so somebody can't walk up to your box and reboot your server with the three-finger solute. Add the following lines to the options:Note: The RANDOM_IP_ID option is only for versions of FreeBSD that are older than 5.3.
|
# nano -w /usr/srs/sys/i386/conf/MYKERNEL ***output omitted*** options SC_DISABLE_REBOOT # Disable Ctrl+Alt+Del options RANDOM_IP_ID # Enables random IP ID generation ***output omitted*** |
Optional Settings For a Stealthier System
The following options may be used, but are only recommended for system that are gateways, log servers, or dedicated firewalls. You may apply these to normal servers if you would like, but they may decrease performance -- especially on web servers.| # | echo 'tcp_drop_synfin="YES"' >> /etc/rc.conf |
|
# nano -w /usr/src/sys/i386/conf/MYKERNEL ***output omitted*** options TCP_DROP_SYNFIN # Enables the ability to drop SYN/FIN packets options IPSTEALTH # Enable stealth forwarding ***output omitted*** |
Author: Jon LaBass
jon at bsdguides dot org