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

FreeBSD Basics

Scanning Your Network


Also in FreeBSD Basics:

Fun with Xorg

Sharing Internet Connections

Building a Desktop Firewall

Using DesktopBSD

Using PC-BSD

In the last few articles, we've spent a fair bit of time examining IP packets and TCP/IP connections. In the next few articles, I'd like to demonstrate putting some of this knowledge together in order to increase the security of your FreeBSD system.

In my home network, I have a computer running FreeBSD 4.2; it has a constant connection to the Internet using a cable modem. Up to this point, the only security change I've made to this system was to configure TCP wrappers, which I demonstrated in "Securing BSD Daemons." However, since I now have a constant Internet presence, I should be aware of the information my FreeBSD system is willing to give to anyone who tries to find out. Once I know this, I can decide which IP packets from the Internet I am willing to allow into my machine.

The ports collection includes the nmap utility, which is a valuable tool for determining which services your FreeBSD system is advertising to other TCP/IP hosts. However, like most useful utilities, it should only be used to test the computers in your own network. You should also be aware that it is very common for unscrupulous users to use this utility to scan for insecure hosts on the Internet. It is preferable for you to find out first what they'll be able to discover about your system so you can take measures to ensure they'll only be able to see what you want them to see.

I'll become the superuser, connect to the Internet, and install nmap; once the build is finished, I'll leave the superuser account:

cd /usr/ports/security/nmap
make install clean

The nmap utility comes with several different scan types so you can test your network daemons for several different behaviours. Since I'll be running nmap on the same machine that I wish to scan, I'll run my scans against the "localhost." If you wish to scan another host in your network, substitute that host's IP address for the word "localhost."

Let's start by not specifying a scan type; this will tell the nmap utility to determine which daemons are listening for TCP connections:

nmap -v localhost

Starting nmap V. 2.53 by ( )
No tcp,udp, or ICMP scantype specified, assuming vanilla tcp connect() scan. Use -sP
if you really don't want to portscan (and just want to see what hosts are up). Host localhost ( appears to be up ... good.
Initiating TCP connect() scan against localhost (
Adding TCP port 515 (state open).
Adding TCP port 22 (state open).
Adding TCP port 80 (state open).
Adding TCP port 6000 (state open).
Adding TCP port 111 (state open).
Adding TCP port 25 (state open).
Adding TCP port 587 (state open).
The TCP connect scan took 7 seconds to scan 1523 ports.
Interesting ports on localhost (
(The 1517 ports scanned but not shown below are in state: closed)

Port       State       Service
22/tcp     open        ssh                     
25/tcp     open        smtp    
80/tcp	   open        http                
111/tcp    open        sunrpc                  
515/tcp    open        printer                 
587/tcp    open        submission              
6000/tcp   open        X11

Nmap run completed -- 1 IP address (1 host up) scanned in 8 seconds

You may have noticed from this output that I've disabled telnet, have added Apache to my system (http), and that I've been playing with NFS (sunrpc).

If I now use Alt-F1 to look at the console, I'll see something interesting:

icmp-response bandwidth limit 364/200 pps
icmp-response bandwidth limit 335/200 pps
icmp-response bandwidth limit 380/200 pps
icmp-response bandwidth limit 482/200 pps
icmp-response bandwidth limit 418/200 pps
icmp-response bandwidth limit 246/200 pps
icmp-response bandwidth limit 317/200 pps

If you ever see this type of message at your console and you weren't running the nmap utility, someone else was scanning your machine looking for open ports. When nmap scanned my ports, it tried to connect to 1523 of my ports, and my FreeBSD system responded by sending out an ICMP Type 3 Code 3 response for each non-listening port. (See the last article on ICMP.) By default, FreeBSD limits itself to only sending 200 of these types of packets per second; this limit is a good thing, as it prevents your kernel from trying to respond to more packets than it can handle. There is a FAQ on this console message here


Now, what do I want to do with the results from this nmap scan? A good rule of thumb is to DISABLE all the ports that you don't use. Since you can't disable the ports you do want to use, you'll need to SECURE those ports.

In my example, I don't want to disable ssh, smtp, http, or X11, since I do use these services, so I'll have to keep these in mind when I create my firewall rules so only appropriate hosts will have access. I'm no longer using NFS, so I should disable sunrpc; this computer does not have access to any printers, so I should disable the printer; finally, my mail client does not use the submission port, so I should get rid of that as well.

I can disable the sunrpc and printer daemons by becoming the superuser and adding the following lines to /etc/rc.conf:


Before I save my changes, I'll doublecheck for typos.

Things are a bit more complicated to get rid of the submission port. (If you're unsure what the submission port is used for, a good explanation was given in the mailing list archives here.)

I don't want to mess up Sendmail on this computer, since I use it to send my e-mail; I'll be extra careful and back up my original Sendmail configuration file before making any changes. Still as the superuser, I can do this by typing:

cp /etc/mail/ /etc/mail/

When I installed FreeBSD, a file called was used to create that Sendmail configuration file. I'll back up this file as well, as I need to modify it in order to disable the submission port:

cd /usr/src/etc/sendmail

If this directory does not exist on your FreeBSD system, you'll have to first add the /src/etc distribution using /stand/sysinstall.

Once you've backed up, use your favourite editor to add the following line just before the two last MAILER lines at the end of the file:


Again, check for typos and save your change. Now type:

make install
cp /etc/mail/

We now need to tell rc and sendmail to read our configuration changes. Since rc only reads its configuration file at boot time, the easiest way to accomplish both tasks is to type:

killall init

When I receive the prompt back, I'll press Enter and then type:


If all went well, I won't see any error messages, and when I rerun the nmap scan, I should only see ssh, smtp, http, and X11 in the output.

Let's return for a moment to that original nmap scan. This "vanilla tcp connect() scan" read a file called /usr/local/share/misc/nmap-services and then attempted to reach the connect system call for every port listed in that file. The connect request failed for every port that wasn't listening for TCP connections and succeeded for the ports that were listening. However, this scan does not check for daemons that might be listening for UDP requests.

All of the other scan types require superuser privileges; I'll become the superuser and use the sU switch to scan for the daemons that are willing to accept UDP connections:

nmap -sU localhost

Starting nmap V. 2.53 by ( )
Interesting ports on localhost (
(The 1447 ports scanned but not shown below are in state: closed)

Port       State       Service
68/udp     open        bootpc

Nmap run completed -- 1 IP address (1 host up) scanned in 11 seconds

Remember that UDP does not create a connection, as it is the connection-less transport. UDP Port 68 is used by the DHCP client, which I need to keep open so I can renew my DHCP lease with my service provider. This does not mean that I'm running a DHCP server on my computer, as DHCP servers use UDP port 67 instead.

Before we go any farther, let's run the sockstat utility and compare the results to the nmap scan:

sockstat -4

                                    LOCAL    FOREIGN
root    XF86_SVG  15769   0  tcp4   *:6000   *:*                  
nobody  httpd     14592  16  tcp4   *:80     *:*                  
root    sendmail  12873   4  tcp4   *:25     *:*                  
nobody  httpd     12410  16  tcp4   *:80     *:*                  
nobody  httpd     12409  16  tcp4   *:80     *:*                  
nobody  httpd     12408  16  tcp4   *:80     *:*                  
nobody  httpd     12407  16  tcp4   *:80     *:*                  
nobody  httpd     12406  16  tcp4   *:80     *:*                  
root    httpd     12382  16  tcp4   *:80     *:*                  
root    sshd      12336   3  tcp4   *:22     *:*                  
root    dhclient  12269   3  udp4   *:*      *:*                  
root    dhclient  12269   6  udp4   *:68     *:*

You'll note that both utilities show the same port information: My machine is willing to accept TCP connections on ports 22, 25, 80, and 6000 and UDP connections on port 68. Why would someone use nmap instead of sockstat? If you only need to secure one machine and you are sitting at it, it's easier to use the built-in sockstat utility. However, if you need to test the security of your entire network, you can scan every host at once using the nmap utility; you can even save your results to a file and have a record of which ports are enabled on each machine. It also saves you sitting down at every machine in order to run the sockstat utility. Finally, once you've built a firewall, you can test its reactions to your firewall rules by using the other types of nmap scans.

Now that I know which ports are open on my computer, I can start sketching out how I'll give appropriate access to each listening service. Before I start creating any type of firewall or packet filtering rules, there are a few points I should consider.

The first thing I need to decide is what types of packets I wish to allow IN to my system. Since this is a stand-alone computer that is only connected to the Internet, any packets coming in will be one of two types.

The first type is packets from users on the Internet trying to connect to one of my daemons.

Remember, if these packets are trying to make a TCP connection, they will have the SYN flag set but not the ACK flag.

Since I now know which of my ports are willing to accept connections, I should carefully re-examine each and see if I really want someone from the Internet trying to connect to these daemons. Let's look at each one at a time:

port 22 or ssh
The only person I'd want to use a secure shell into my machine would be me, and I don't plan on doing this over the Internet. Therefore, I don't want to let IN these types of packets.

port 25 or smtp
While I do use smtp to send e-mail OUT of my system, I'm not running an e-mail server that accepts mail from other smtp servers, so I don't want to let IN these types of packets. However, I do want to be able to pick up my e-mail from my service provider, so I'll have to remember to let IN POP3 packets. (Forget how SMTP and POP3 work? See "Understanding E-Mail.")

port 80 or http
Since I'm still creating my web site, I'll hold off on allowing IN http requests for the moment. When my web site is ready, I'll have to remember to change my firewall rules to allow IN http connection requests.

port 6000 or X Window protocol
I don't want anyone from the Internet using my Xterminal, so I won't be letting IN these packets either.

UDP port 68 or DHCP client
I do need to let IN these packets so I can renew my DHCP lease. I'll have to remember that UDP doesn't use flags, so there will not be a SYN or ACK flag on these packets.

OK, now for the second type of incoming packets: responses from the Internet for packets I sent out.

There's not much sense in me sending OUT packets to the Internet unless I remember to tell the firewall to allow back IN the responses to my packets. For example, it would be very frustrating to send out an HTTP request to a web server but never receive a response back that could be displayed in my web browser.

If I don't want to restrict myself to the types of packets I'm allowed to send OUT to the Internet, I can still tell the firewall to not let IN packets that aren't a response to my request. There are several ways to do this, and I'll demonstrate how when we make the actual firewall rules.

The last thing I should do is sketch out a list of activities I do over the Internet. This list will prove useful when I create my rules, as some applications require extra considerations so they will continue to work properly through a firewall. This is a good time to do some free association; creating a list will invariably remind me of related applications and possibly some tidbits of information that will be helpful in my firewall rules. Here's a rough sketch of my list:

I'm sure I'll think of more when I actually start creating the firewall rules, but this rough sketch is a start.

Let's wait til next week to see what options are available for creating a firewall on a FreeBSD system.

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.