Published on (
 See this if you're having trouble printing code examples

FreeBSD Basics Securing FreeBSD

by Dru Lavigne

In the past few days, I've been sorting through my piles of notes and organizing the security tips I've gathered from various resources over the years. I thought some of them might interest you, so this week, I'll take a break from the archiving series and write a bit about securing your FreeBSD system.

Obviously, I won't be able to give a thorough coverage of such a broad topic in the confines of one article. Which is just as well, since it is impossible to create a one-size-fits-all list that will guarantee the security of any system.

As I sort through my notes, I notice that most are geared toward tightening the security of a FreeBSD system that acts as some sort of server (e.g. Web server, mail server). Which isn't so great, if you are instead using your FreeBSD system as your personal system, and desire full desktop functionality. You would be a very unhappy camper if a security setting broke some functionality that took you a week of struggle to learn how to get working in the first place.

For this reason, you'll note that, unlike most security tutorials, this article will not address changing any of the permissions on your FreeBSD system. This is intentional. Unless you're securing a production server and you know what you're doing, never change the permissions of any file. (If you must practice with permissions, stick to the files in your home directory). Otherwise, things might stop working; things you might miss like email, X Window System, sound. Strange things will happen at strange times, making it harder to clue in that they are related to the permission setting you played with a week ago Tuesday.

We all know that the Internet isn't always a friendly place and that you probably don't want to give the rest of the world the same access to your system as you give yourself. This means you don't want to be on the Internet without being protected by some sort of firewall. Fortunately, your FreeBSD system supports two firewalls: ipfw and ipfilter. Even better, the amount of easy-to-follow documentation has steadily improved over the last year. If you're not behind a firewall, dedicate a Saturday afternoon to do some reading and configure firewall functionality on your system. You'll be glad you did. Here are some resources to get you started:

man ipfw
FreeBSD Handbook: Section 10.7 -- Firewalls
Setting Up a Dual-Homed Host using IPFW and NATD

man ipf
IPFilter and PF resources

Good security is always "defense in depth," meaning that if one mechanism fails, there is a backup mechanism. Even though your system is now protected by a firewall, you should also disable all services except for those you absolutely need. On a desktop system, you need very few services.

To see which services are listening for connection attempts on your system, use this command:

sockstat -4

Your output will vary, depending upon what settings you selected during the final installation phase of FreeBSD and what ports and packages you have built since then.

It is very common to see port 6000 (X Window Server) in the output; if you don't, start an X Window session and rerun sockstat -4. Unfortunately, there have been many X Window exploits over the years; fortunately, you don't need to leave port 6000 open in order to use X on your system. Don't worry, you'll still have a GUI if you close this port!

There are several ways to close this port; I've found the easiest is to become the superuser and edit /usr/X11R6/bin/startx. Find the serverargs line and change it so that it looks like this:

serverargs="-nolisten tcp"

Once you've saved your changes, start X as a regular user and rerun sockstat -4. If you didn't have any typos, X will start as usual, but port 6000 will be missing in your sockstat -4 output.

If you'd like to read up on some of the security issues of leaving port 6000 open, here is a Crash Course in X Window Security.

Okay, that's one less service in your sockstat -4 output. You probably still have two ports that deal with email: ports 25 (smtp) and 587 (submission). You don't need port 587 to send/receive email; to close it you can edit /etc/mail/ Find this line:

O DaemonPortOptions=Port=587, Name=MSA, M=E

and put a # in front of it to comment it out. Then, to tell sendmail about your change:

killall -HUP sendmail

The -HUP won't stop sendmail, but will tell it to read the changes you made to /etc/mail/ Repeat sockstat -4 and it should no longer show port 587.

What about port 25? You may or may not need to leave this port open, depending upon which program you use to send and read your email. If you're running FreeBSD 4.6-RELEASE or higher, put this line in /etc/rc.conf:


This will tell sendmail to only listen on the localhost, which will allow any mail client to be able to send email. If you know that your mail client has its own built-in SMTP agent or you're feeling adventurous, you can try this line instead:


which will close port 25 completely. To see if you've broken the ability to send email, make sure you've closed all of your terminals and saved all of your work. Then, as the superuser:

shutdown now

Press enter when prompted, then type exit. Once you've logged back in, see if you can send a test message to your email account. If you can't, go back to the word "NO" and repeat the above to re-open port 25 for the localhost.

If port 111 (portmap) shows up in your "sockstat" output, remove it by adding the following lines to /etc/rc.conf (or, if a line already exists in that file, change the YES to a NO):


Portmap is only needed if you are running NFS, which you won't be on a stand-alone FreeBSD desktop. It also has a long history of security issues, so if you don't absolutely need it, disable it.

syslog (port 514) will probably also show in your output. You don't want to disable syslog completely, as you do want to receive logging messages. However, you don't need to have this port open to do so. In your /etc/rc.conf file, make sure syslog is enabled and add a second line with some options:


Those two sses (make sure you have two, not just one) in the flags will disable logging from remote hosts and close that port, but still allow your localhost to keep its logging capabilities.

Next, make sure inetd_enable is not set to YES in /etc/rc.conf. If inetd is showing up in your sockstat output, something has been uncommented out in /etc/inetd.conf. If you don't need it, put a # back in front of that line, and do a killall inetd.

If you get your address from your ISP's DHCP server, keep dhclient (port 68) open, or you won't be able to renew your IP address.

If you find anything else in your sockstat output, skim through man rc.conf to see if there is an option to disable it. If there isn't, it was most likely started with a startup script that was installed with a package or a port. If this is the case:

cd /usr/local/etc/rc.d

to see which startup scripts have been added to your system. Most packages/ports will install a sample script with a "sample" extension. As long as it ends in "sample," that script will not run at startup. Other packages/ports install a working script that is read at bootup and you will find the culprit in this directory. The easiest way to disable the script is to rename it with a "sample" extension, and then kill the daemon so that its port number no longer shows up in sockstat -4. For example, I recently installed ethereal and noticed that snmpd showed up in my sockstat -4 output. The snmp daemon has a long history of exploits and I didn't want it listening on my system, so I became the superuser and did this:

cd /usr/local/etc/rc.d
killall snmpd

You might also want to consider adding the following options to /etc/rc.conf:


This option prevents something known as OS fingerprinting, which is a scan technique used to determine the type of operating system running on a host. If you decide to enable this option, you will also have to rebuild your kernel with the following option included in your kernel configuration file:


Two related options are:


ICMP redirects can be used to launch a DOS attack, as explained in the ICMP redirect portion of this ARP and ICMP redirection games article.

Be very careful if you decide to include the icmp_log_redirect option, as it will log every ICMP redirect, which has the potential of filling up your logging directory if you ever are the victim of this type of attack.

When you built your firewall, you probably included this option:


If you didn't, it is a good option to include, as it logs all attempts to closed ports.

An interesting option is:


This will enable system accounting. If you're new to system accounting, read man sa and man lastcomm to decide whether this option would be useful to you or not.

Finally, this is a good option to include:


as it will clear /tmp at startup, which is always a good thing.

Let's leave /etc/rc.conf and see what else we can do to tighten up your system. I like to change the default algorithm used when encrypting a user's password to the Blowfish algorithm, as it provides the highest security at the greatest speed. Here is a quick comparison of algorithms.

Also, if you're interested in this sort of stuff, check out the Cryptogram newsletter written by the author of Blowfish.

To implement Blowfish hashes, edit /etc/login.conf and change the passwd_format line so that it looks like this:


Save your change, then rebuild the login database with this command:

cap_mkdb /etc/login.conf

You'll then have to change all of your user's passwords so they will get a new Blowfish hash. You can do this by typing:

passwd username

as the superuser. Whatever username you use, that will be the user whose password will be updated. Repeat for all of your users, including the root account.

Once you're finished, double-check that it worked and you didn't forget any users:

more /etc/master.passwd

All of the passwords for your users should begin with $2.

Finally, configure the adduser utility to use Blowfish whenever you create a new user by editing /etc/auth.conf. Change the crypt_default line so that it looks like this:


You've probably noticed when you log in to your FreeBSD system that your login prompt reminds you that you are running FreeBSD. And that after you log in, you receive the FreeBSD copyright information, which is followed by the version of FreeBSD and the name of your kernel, and finally, a useful (but rather boring) motd which again reminds you that you are running FreeBSD. You probably already know what version of FreeBSD you are running and might not want to share that information with the rest of the world. And the motd is a good place to remind the rest of the world that they shouldn't be messing with your system anyways.

You can edit /etc/motd to say whatever suits your purposes, be it anything from your favorite sci-fi excerpt to all the nasty things that will happen to someone if they continue to try to log in to your system.

Next, to remove the copyright info:

touch /etc/COPYRIGHT

Then to change the text that appears at the login prompt, edit /etc/gettytab. Find the line in the default:\ section that starts with


Carefully, change the text between \r\n\ \r\n\r\nr\n: to whatever text you wish to appear. Double-check that you have the right amount of \rs and \ns and save your change. For example, my login prompt looks like this:

I'm a node in cyberspace. Who are you?

You can test your changes by going to another terminal and logging in.

Finally, even though you've edited your motd to remove your version and kernel information, by default FreeBSD will still re-add it to /etc/motd every time you log in. To prevent this behavior, add the following line to /etc/rc.conf:


This change requires a reboot, so make sure you've first tested your previous changes and have saved all of your work on any other terminals.

There are a few edits that will also restrict logins to your system in the first place. Since these changes modify the behavior of the login program, you'll want to carefully test your changes. Keep one terminal open and go to another terminal to log out and ensure that you can still log in. If for some reason you're unable to log in (this shouldn't happen, but you can't be too careful), you can return to the other terminal and look for typos in the file you just edited.

No one (including you) should ever log in to your system using the root account. To prevent this from happening, edit /etc/ttys. Once you get past a page's worth of comments, you'll notice a section that goes from ttyv0 to ttyv8. Change the word secure on each of those lines to insecure. This is a file you don't want a typo in, so double-check your changes carefully. Test your change by trying to log in as root on one of your terminals. You should receive a "Login incorrect" message.

Personally, I tend to use all nine terminals on my desktop. If you don't, you can also change the word "on" to "off" on some of the ttys in /etc/ttys. Remember to leave at least one terminal "on," or else you won't be able to log in, which will severely hamper the usefulness of your system. You'll also note that ttyv8 is "off" by default, which means you have to manually start an X Window session. If you'd like X to start automatically at bootup, change that "off" to "on."

The last edit I'll mention in today's article allows you to restrict who can log in to your system and from where. This is done by editing /etc/login.access.

If you want to prevent all remote logins (meaning you can only log in if you are physically sitting at your system), remove the # from this line:


and remove the so that the line now looks like this:


If you plan on accessing your system remotely, replace with the IP address(es) or hostname(s) of the system(s) you'll be logging in from. If there are multiple addresses, separate them with a single space.

If you have only one or two user accounts that you wish to be able to log in to your system, you can prevent all other logins like so:

-:ALL EXCEPT user1 user2:ttyv0 ttyv1 ttyv2 ttyv3 ttyv4

Replace user1 user2 with the names of the user accounts to which you wish to give access. Put in as many ttys as you wish to restrict.

Alternatively, you can place the users in a group and give login access to that group. This example adds the users genisis, biko, and dlavigne6 to a group called mygroup and allows only the members of that group to log in to my FreeBSD system. First, I'll edit /etc/group and carefully add this line:


When you add your own group, make sure you use a GID (in my case, 100) that is not being used by any other lines in your /etc/group file.

Then, change /etc/login.access to:

-:ALL EXCEPT mygroup:ttyv0 ttyv1 ttyv2 ttyv3 ttyv4 ttyv5

It is very important you test this change. Leave one terminal logged in, just in case something goes wrong. Go to another terminal and try to log in as each of the users in your group. That should work. Then try to log in as another user; if need be, create a test account and try to log in as that test account. That login attempt should result in a "Permission denied" message.

That's all the space I have for this week. In the next article, I'll resume the archiving series by demonstrating the little-known but very handy pax utility.

If you've tried to email me lately, you've noticed that my address has changed. I can now be reached at

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.

Read more FreeBSD Basics columns.

Return to the BSD DevCenter.

Copyright © 2009 O'Reilly Media, Inc.