14.2. Introduction

Security is everyone's responsibility. A weak entry point in any system could allow intruders to gain access to critical information and cause havoc on an entire network. In most security training, they discuss the security triad CIA which stands for the confidentiality, integrity, and availability of information systems.

The CIA triad is a bedrock concept of computer security, customers and end users expect privacy of their data. They expect orders they place to not be changed or their information altered behind the scenes. They also expect access to information at all times. Together they make up the confidentiality, integrity, and availability of the system.

To protect CIA, security professionals apply a defense in depth strategy. The idea of defense in depth is to add several layers of security to prevent one single layer failing and the entire security system collapsing. A systems administrator cannot simply turn on a firewall and consider the network or system secure, they must audit accounts, check the integrity of binaries, and ensure malicious tools are not installed. To do this, they must understand what the threats are.

14.2.1. Threats

What is a threat as pertaining to computer security? For years it was assumed that threats are remote attackers, people whom will attempt to access the system without permission, from a remote location. In today's world, this definition has been expanded to include employees, malicious software, rogue network devices, natural disasters, security vulnerabilities, and even competing corporations.

Every day thousands of systems and networks are attacked and several hundred are accessed without permission. Sometimes by simple accident, others by remote attackers, and in some cases, corporate espionage or former employees. As a system user, it is important to prepare for and admit when a mistake has lead to a security breach and report possible issues to the security team. As an administrator, it is important to know of the threats and be prepared to mitigate them.

14.2.2. A Ground Up Approach

In security, it is sometimes best to take a ground up approach, whereas the administrator begins with the basic accounts, system configuration, and then begins to work with third party utilities and work up to the network layer. It is in these latter configuration aspects that system policy and procedures should take place.

Many places of business already have a security policy that covers the configuration technology devices in use. They should contain, at minimal, the security configuration of end user workstations and desktops, mobile devices such as phones and laptops, and both production and development servers. In many cases, when applying computer security, standard operating procedures (SOPs) already exist. When in doubt, ask the security team.

14.2.3. System and User Accounts

In securing a system, the best starting point is auditing accounts. Ensure that the root account has a strong password, disable accounts that do not need shell access, for users who need to augment their privileges, install the security/sudo and only allow them access to applications they need. The root user password should never be shared.

To deny access to accounts, two methods exist. The first one is to lock an account, for example, to lock the toor account:

# pw lock toor

This command will change the account from this toor:*:0:0::0:0:Bourne-again Superuser:/root: to toor:*LOCKED**:0:0::0:0:Bourne-again Superuser:/root:

In some cases, this is not possible, perhaps because of an additional service. In those cases, login access could be prevented by changing the shell to /sbin/nologin like in this example:

# chsh -s /usr/sbin/nologin toor


Only super users are able to change the shell for other users. Attempting to perform this as a regular user will fail.

The account structure will now look like this, with the nologin shell as the last entry:

toor:*:0:0::0:0:Bourne-again Superuser:/root:/usr/sbin/nologin

The /usr/sbin/nologin shell will block the login(1) command from assigning a shell to this user.

14.2.4. Permitted Account Escalation

In some cases, system administration access needs to be shared with other users. FreeBSD has two methods to handle this. The first one, which is not recommended, is a shared root password and adding users to the wheel group. To achieve this, edit the /etc/group and add the user to the end of the first group. This user must be separated by a comma character.

The correct way to permit this privilege escalation is using the security/sudo port which will provide additional auditing, more fine grained user control, and even lock users into running only single, privileged commands such as service(8)

After installation, edit /usr/local/etc/sudoers using the visudo interface. In this example, a new webadmin group will be added, the user trhodes to that group, and then give the user access to restart apache24, the following procedure may be followed:

# pw groupadd webadmin -M trhodes -g 6000
# visudo
%webadmin ALL=(ALL) /usr/sbin/service apache24 *

The security/sudo provides an invaluable resource when it comes to local user management. It is also possible to not require passwords and just default to the ssh(1) key method. To disable password login via sshd(8) and only use local passwords for sudo, see Section 14.8, “OpenSSH”.

14.2.5. Passwords

Passwords are a necessary evil of technology. In the cases they must be used, not only should the password be extremely complex, but also use a powerful hash mechanism to protect it. At the time of this writing, FreeBSD supports DES, MD5, Blowfish, SHA256, and SHA512 in the crypt() library. The default is SHA512 and should not be changed backwards; however, some users like to use the Blowfish option. Each mechanism, aside from DES, has a unique beginning to designate the hash mechanism assigned. For the MD5 mechanism, the symbol is a $ sign. For the SHA256 or SHA512, the symbol is $6$ and Blowfish uses $2a$. Any weaker passwords should be re-hashed by asking the user to run passwd(1) during their next login.


At the time of this writing, Blowfish is not part of AES nor is it considered compliant with any FIPS (Federal Information Processing Standards) standard and its use may not be permitted in some environments.

For any system connected to the network, two factor authentication should be used. This is normally considered something you have and something you know. With OpenSSH being part of the FreeBSD base system and the use of ssh-keys being available for some time, all network logins should avoid the use of passwords in exchange for this two factor authentication method. For more information see the Section 14.8, “OpenSSH” section of the handbook. Kerberos users may need to make additional changes to implement OpenSSH in their network. Password Policy and Enforcement

Enforcing a strong password policy for local accounts is a fundamental aspect of local system security and policy. During password enforcement, things like password length, password strength, and the likelihood the password could be guessed or cracked can be implemented through the system pam(8) modules.

The PAM system, or Pluggable Authentication Modules, will enforce the password policy by setting a minimum and maximum password length. They will also enforce mixed characters. In particular the pam_passwdqc(8) will be discussed.

To proceed, add the following line to /etc/pam.d/passwd:

password        requisite       pam_passwdqc.so         min=disabled,disabled,disabled,12,10 similar=deny retry=3 enforce=users

There is already a commented out line for this module and it may be altered to the version above. This statement basically sets several requirements. First, a minimal password length is disabled, allowing for a password of any length. Using only two character classes are disabled, which means that all classes, including special, will be considered valid. The next entry requires that passwords be twelve characters in length with characters from three classes or ten byte (or more) passwords with characters from four character classes. This also denies passwords that are similar to the previously used password. A user is provided three opportunities to enter a new password and finally only enforce this requirement on users. That is, exempt super users. This statement is probably confusing so reading the manual page is highly recommended, in particular to understand what character classes are.

After this change is made and the file saved, any user changing their password will see a message similar to the following. This message might also clear up some confusion about the configuration.

% passwd
Changing local password for trhodes
Old Password:

You can now choose the new password.
A valid password should be a mix of upper and lower case letters,
digits and other characters.  You can use a 12 character long
password with characters from at least 3 of these 4 classes, or
a 10 character long password containing characters from all the
classes.  Characters that form a common pattern are discarded by
the check.
Alternatively, if noone else can see your terminal now, you can
pick this as your password: "trait-useful&knob".
Enter new password:

If a weak password is entered, it will be rejected with a warning and the user will have an opportunity to try again

In most password policies, a password aging requirement is normally set. This means that a every password must expire after so many days after it has been set. To set a password age time in FreeBSD, set the passwordtime in /etc/login.conf. Most users when added to the system just fall into the default default group which is where this variable could be added and the database rebuilt using:

# cap_mkdb /etc/login.conf

To set the expiration on individual users, provide a day count to pw(8) and a username like:

# pw usermod -p 30-apr-2014 -n trhodes

As seen here, an expiration date is set in the form of day, month, year. For more information, see pw(8)

14.2.6. Backdoors and Rootkits

Backdoors and rootkits are only a threat after they have been installed. Once installed, this malicious software will normally open up another avenue of entry for an attacker. Realistically, once a system has been compromised, and an investigation has been performed, it should be erased. There is tremendous risk that even the most prudent security or systems engineer will miss something an attacker left behind.

A backdoor or rootkit software does do one thing useful for administrators - once detected, it is a sign that a compromise happened at some point. But normally these types of applications are hidden very well. Tools do exist to detect backdoors and rootkits, one of them is security/rkhunter.

After installation, the system may be checked using the following command. It will produce a lot of information and will require some manual pressing of the ENTER key:

# rkhunter -c

After the process completes, a status message will be printed to the screen. This message will include the amount of files checked, suspect files, possible rootkits, and more. During the check, some generic security warnings may be produced about hidden files, the OpenSSH protocol selection, and occasionally known vulnerable versions of installed software. These can be handled now or later after a more detailed analysis has been performed.

Every administrator should know what is running on the systems they are responsible for. Using tools like rkhunter, lsof and native commands such as netstat(1) and ps(1) can show a great deal of information on the system. Take notes on what is normal, ask questions when something seems out of place and be paranoid. And remember, preventing a compromise is ideal but detecting a compromise is a must.

14.2.7. Binary Verification

Verification of system files and binaries is important because it provides the system administration and security team with information about system changes. In any system, no internal command or application should change without the system admin team knowing. A software application that monitors the system for changes is called an Intrusion Detection System or IDS.

FreeBSD provides native support for a basic IDS system. In fact, as part of the nightly periodic(8) security emails will notify an administrator of changes. Since the information is stored locally, there is a chance a malicious user could modify and spoof the information. As such, it is recommended to create a separate set of binary signatures and store them on a read only, root owned directory or, preferably, off system such as a USB disk or rsync server.

To being, a seed needs to be generated. This is a numeric constant that will be used as to help generate the hash values and to check the hash values. Lacking this seed value will make faking or checking the checksum values of files difficult it not impossible. In the following example, the key will be passed with the -s flag. First, generate a set of hashes and checksums for /bin using the following command:

# mtree -s 3483151339707503 -c -K cksum,sha256digest -p /bin > bin_chksum_mtree

This should have produced something similar to:

# mtree: /bin checksum: 3427012225

Viewing bin_cksum_mtree should yield output similar to the following:

#          user: root
#       machine: dreadnaught
#          tree: /bin
#          date: Mon Feb  3 10:19:53 2014

# .
/set type=file uid=0 gid=0 mode=0555 nlink=1 flags=none
.               type=dir mode=0755 nlink=2 size=1024 \
    \133        nlink=2 size=11704 time=1380277977.000000000 \
                cksum=484492447 \
    cat         size=12096 time=1380277975.000000000 cksum=3909216944 \
    chflags     size=8168 time=1380277975.000000000 cksum=3949425175 \
    chio        size=18520 time=1380277975.000000000 cksum=2208263309 \
    chmod       size=8640 time=1380277975.000000000 cksum=2214429708 \

Notice the machine's hostname, the current date and time, and the user who executed mtree(8) are all included in this report. There is also a checksum, size, time and SHA256 digest for each binary that was found.

To verify binary signatures, the following command will read in the current list of signatures and provide an output:

# mtree -s 3483151339707503 -p /bin < bin_chksum_mtree >> bin_chksum_output

This should produce the same checksum for /bin that was produced when the command was originally ran. Since no changes occurred in the time these commands were ran, the bin_chksum_output output will be empty. To simulate a change, change the date on /bin/cat using touch(1) and run the verification command again:

# touch /bin/cat
# mtree -s 3483151339707503 -p /bin < bin_chksum_mtree >> bin_chksum_output
# cat bin_chksum_output
cat changed
	modification time expected Fri Sep 27 06:32:55 2013 found Mon Feb  3 10:28:43 2014

More advanced IDS systems exist, such as security/aide but in most cases, mtree(8) provides the functionality administrators need. It is important to keep the seed value and the checksum output hidden from malicious users.

14.2.8. System Tuning for Security

Many of the systems features may be tuned through the use of sysctl(8). This is also true for a few security features which could be used to prevent denial of service (DOS) style attacks. Some of the more important will be covered here. Any time a setting is changed with sysctl(8), the chance to cause undesired harm is increased affecting the availability of the system. Considering the CIA of the system should be done during any system-wide configuration change.

The following is a list of sysctl(8)'s and a short description of what effects the changes will have on the system.

By default, the FreeBSD kernel boots with a security level of -1. This is called insecure mode because immutable file flags may be turned off and all devices may be read from or written to. The security level will remain at -1 unless it is altered, either by the administrator or by init(8), because of a setting in the startup scripts. The security level may be raised during system startup by setting kern_securelevel_enable to YES in /etc/rc.conf, and the value of kern_securelevel to the desired security level. See security(7) and init(8) for more information on these settings.


Increasing the securelevel can break Xorg and cause other issues. Be prepared to do some debugging.

Next sysctl(8)s to change is the net.inet.tcp.blackhole and net.inet.udp.blackhole. When these are set, incoming SYN packets on closed ports will be dropped with no return RST response. The normal behavior is to return an RST to show a port is closed. These will provide some level of protection against stealth scans against a system. Set the net.inet.tcp.blackhole to 2 and the net.inet.udp.blackhole to 1 and review the information in blackhole(4) for more information.

Additionally the net.inet.icmp.drop_redirect and net.inet.ip.redirect should be set as well. These two sysctl(8)s will help prevent against what are called redirect attacks. Redirect attacks are the purposeful mass issuing of ICMP type 5 packets which should not be required in a normal network. As such, set net.inet.icmp.drop_redirect to 1 and set net.inet.ip.redirect to 0.

Source routing is method of detecting and accessing non-routable addresses on the internal network. This should probably be disabled as non-routable addresses are normally not routable on purpose. To disable this feature, set net.inet.ip.sourceroute and net.inet.ip.accept_sourceroute to 0.

Drop all ICMP echo requests to the broadcast address. When machine on the network need to send messages to all hosts on a subnet, the message is sent to the broadcast address. There is no reason an external host should need to perform such an action so set net.inet.icmp.bmcastecho to 0 to reject all external broadcast requests.

Some additional sysctl(8)s are documented in security(7) and it is recommended it be consulted for additional information.

All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.