Building your firewall, Part 2

Unix Insider –

Last month's column was devoted to planning the architecture of your firewall. While some administrators may consider such planning a management responsibility, it will become an administrator's responsibility if it's not properly addressed before the firewall is implemented. This article focuses on setting up the environment that supports your firewall software. Next month I'll conclude with advice on firewall deployment.

Operating system platform

Choosing a platform becomes almost a religious debate with some people, and it's not one I want to get into here. My choice is always a Unix system, and for this article I will describe a Solaris system (this is Unix Insider,after all).

Be sure to check the requirements for your firewall software. My partner and I once went through the effort of installing Solaris 7 on a box and hardening the system, only to discover that the firewall software had not yet been ported to Solaris 7. We had to backtrack to Solaris 2.6. Read the firewall documentation before you start installing the platform.

Hardening the operating system

It would be foolish to rely on the firewall software alone to protect the system. Before installing the firewall software, the system should be hardened to limit potential exposure. If you purchase a "black box" firewall, the vendor should harden the system, though you have no way to be certain that everything is in order. If you're installing the firewall yourself, you can strip all unnecessary services from the OS. Peter Galvin and Hal Pomeranz offered guidelines for hardening your OS in two previous Unix Insider columns. Peter's tips in his Solaris Security FAQ are more up-to-date (and I hear he will be updating the FAQ page again soon).

I've used Peter's guidelines quite often myself, with the following modifications:

Installation options

Some firewall applications will not work with just the core system support option, and it becomes very time-consuming to install libraries piecemeal. I install the developer system support and remove binaries I don't need.

Filesystem mounts

I used to make

<font face="Courier">/tmp</font>
a separate filesystem from swap so that I could mount it
<font face="Courier">nosuid</font>
and protect the system from denial-of-service attacks that would fill up
<font face="Courier">/tmp</font>
and cause the system to run out of swap space. Thanks to input from Casper Dik, Sun's Solaris security architect, I no longer have to do so. The
<font face="Courier">/tmp</font>
filesystem can be mounted
<font face="Courier">nosuid</font>
even as part of swap. This procedure is not documented, though it does work. Following are the data from some testing I did (on Solaris 2.6). Irrelevant text has been omitted for clarity (as indicated by a period [
<font face="Courier">.</font>

Entry from

<font face="Courier">/etc/vfstab</font>

<font face="Courier">#device         device          mount           FS      fsck    mount
#to mount       to fsck         point           type    pass    at boot
.....[other mount info here]

swap    -       /tmp    tmpfs   -       yes     size=100m,nosuid

#df -k
swap                  102400     364  102036     1%    /tmp


The line above shows that

<font face="Courier">/tmp</font>
has 100 MB of available space. The following lines show there is 256 MB available to swap:

<font face="Courier"># swap -l
swapfile             dev  swaplo blocks   free
/dev/dsk/c0t3d0s1   32,25      8 524392 524392

From disk format:

<font face="Courier">1       swap    wu     270 -  614      256.05MB    (345/0/0)   524400

To test the

<font face="Courier">nosuid</font>
option, I copied the
<font face="Courier">sendmail</font>
binary into
<font face="Courier">/tmp</font>
, retaining the set-user-id permissions:

<font face="Courier">#cp -p /usr/lib/sendmail /tmp
#ls -l /tmp/sendmail
-r-sr-xr-x   1 root     bin       346996 Jun  9 04:31 /tmp/sendmail

Running the binary as root will work because I am already root, not because of the suid permission:

<font face="Courier">#/tmp/sendmail -d fennelly < /dev/null > /tmp/out

# more /tmp/out
Non-setuid binary: RunAsUid = RealUid = 0
drop_privileges(0): Real[UG]id=0:1, RunAs[UG]id=0:1

This is the message logged in

<font face="Courier">/var/adm/messages</font>

<font face="Courier">Sep 27 09:32:53 firebox unix: NOTICE: sendmail, uid 0: setuid execution not
allowed, dev=1

I get the following output when I run the same test as a nonprivileged user. Note that I am unable to queue the mail message and unable to create files in

<font face="Courier">/tmp</font>
through the
<font face="Courier">sendmail</font>
program, although I am able to do so through the standard shell:

<font face="Courier">$/tmp/sendmail -d fennelly < /dev/null > /tmp/out
ksh: /tmp/out: cannot create
$/tmp/sendmail -d fennelly < /dev/null > /home/fennelly/out
$ more /tmp/fennelly/out
Non-setuid binary: RunAsUid = RealUid = 1002
drop_privileges(0): Real[UG]id=1002:10, RunAs[UG]id=1002:10

Output from

<font face="Courier">/var/adm/messages</font>

<font face="Courier">Sep 27 09:46:18 firebox unix: NOTICE: sendmail, uid 1002: setuid execution
not allowed, dev=1

Sep 27 09:47:18 firebox sendmail[328]: NOQUEUE: SYSERR(fennelly): queuename:
Cannot create "qfJAA00328" in "/var/spool/mqueue" (euid=1002): Permission

The following shows that I can create files in

<font face="Courier">/tmp</font>
as a nonprivileged user:

<font face="Courier">$ cat /etc/hosts > /tmp/hosts

Aside from the lack of documentation of that feature, pre-Solaris 7 systems also have a bug in the

<font face="Courier">/etc/mnttab</font>
entry. As far as I can see, it does not affect the operation:

<font face="Courier">$ /usr/sbin/mount
/export/home on /dev/dsk/c0t1d0s0 setuid/read/write/largefiles on Mon Sep 27
09:00:00 1999
/tmp on swap @ on Mon Sep 27 09:26:15 1999

$ grep tmp /etc/mnttab
swap    /tmp    tmpfs   @,dev=1 938438775


For other filesystems, I use the following mount options:

<font face="Courier">/usr read only, nosuid
/opt read write, nosuid
/var read write, nosuid

If you need to have optional packages such as

<font face="Courier">sudo</font>
to be suid, you can make a separate filesystem just for these.

Strip down the OS

Follow the guidelines in the Solaris Security FAQ for stripping out unnecessary services and binaries. There is more to remove if you install the developer system support.

Prevent TCP sequence prediction attacks

In the file

<font face="Courier">/etc/default/inetinit</font>
<font face="Courier">TCP_STRONG_ISS=2</font>
is used to generate the initial sequence numbers suggested in RFC 1948. The manual page for TCP states that
<font face="Courier">/etc/default/inetinit</font>
might not be the interface used in future releases, so be forewarned. There might be a small performance hit in connection setup time. Then again, performance always takes a hit when security is applied!

Prevent buffer-overflow attacks

Buffer-overflow attacks are becoming very popular. You can protect the OS from some of them by adding the following lines to

<font face="Courier">/etc/system</font>

<font face="Courier">	set noexec_user_stack=1
	set noexec_user_stack_log=1


You will need to force a kernel rebuild by rebooting for the code to take effect. Theoretically, some programs that rely on an executable stack may not work at this point, though I do not know of any. Programs generated from objective C are potential candidates for problems (programs compiled from C or C++ source will not have a problem). Because objective C is not in widespread use, it's unlikely to be a problem for most applications.

Newer versions of GNU C Compiler (later than 2.95) take a nonexecutable stack into account. As with any kernel modification, test your application before putting it into production, and please let me know if you come across problems. As noted in the following comments from Casper Dik, the

<font face="Courier">noexec_user_stack</font>
option does not protect against all types of buffer overflows, nor does it work on all Sun hardware:

A typical buffer overflow exploits work by doing two things to the stack: the return addresses are overwritten, and some code is added. The return addresses are made to point to the code, so the next return from function jumps into the hacker's code.
<font face="Courier">noexec_user_stack</font>
protects against the simple form of attack, where the code to be executed lives on the stack; the OS will not allow the code to be executed. Since this requires hardware support, it's only effective on sun4u/sun4d/sun4m systems.

Dr. Mudge of L0pht Heavy Industries adds that the

<font face="Courier">noexec_user_stack</font>

... is a very useful flag that protects against many stack overflows. However, one must be cautious as this is not a panacea. Heap overflows and return to library functions are still quite exploitable. This flag also has no functionality on sun4c (or whatever the IPXs were) CPUs. In addition, this might cause problems with compilers that use trampolining in rare situations. One should also use the set
<font face="Courier">noexec_user_stack_log=1</font>
. Everyone should thank Casper Dik for these cute little hacks.

Padded cells

I use the

<font face="Courier">chroot</font>
system call for firewall applications, such as
<font face="Courier">sendmail</font>
, that are susceptible to exploits. See my January 1999 column (in Resources) for specific details. Note: even if you are not using
<font face="Courier">sendmail</font>
on the firewall and have the daemon disabled, turn off the suid bit on the binary. It is not needed on a firewall.

For everything else, I follow the Solaris Security FAQ noted above.

Network issues

Just when you thought it was safe to start installing your firewall software, you need to address some networking issues before you go ahead.

Routers are designed primarily to route packets. They also support access control lists (ACLs). You may be tempted to overcomplicate the ACLs to a point where the router acts like a firewall. Such complexity can be difficult to support and adds overhead to the router. Keep ACLs simple.

Firewalls are designed primarily to enforce a security policy by inspecting the data stream. They can laos serve as a router. Using a firewall to route packets makes the firewall serve in a capacity that it was not designed for and adds complexity and overhead.

Routers should just route, and firewalls should just perform packet inspection.

Administration issues

It doesn't matter how tight the firewall software is if an administrator installs a back door. Back doors are much more common than you might think. The reality is that most administrators work long hours, and it is much easier to log in from home to take care of problems than commute to work. There are secure methods for remote administration that provide strong authentication, access control, and encryption. A combination of those enables administrators do their job without compromising security.

Authentication to the firewall

On inbound connections, I definitely want some kind of token or one-time password authentication. I also believe in encrypting the pipe coming in (to avoid session hijacking).

Token cards

Quite a few companies offer devices to generate one-time passwords. The theory is to combine something you know, such as a personal identification number, with something you have, such as a card. The SecurID card from Security Dynamics is one example.


S/Key is a one-time password program that allows for single-use passwords. It is incorporated in several manufacturers' software packages as a cheap token. You can also download the source and incorporate it into your own programs.

Access control

  • <font face="Courier">tcpd</font>

    TCP Wrappers is one of my favorite packages. It's simple, free, and easy to implement. Logging is very concise. In fact, I will look at the

    <font face="Courier">tcpd</font>
    log before looking at the firewall software logs.

    TCP Wrappers allows you to impose service limitations based on IP addresses. The wrappers consist of a binary (

    <font face="Courier">tcpd</font>
    ) and uses two files,
    <font face="Courier">/etc/hosts.allow</font>
    <font face="Courier">/etc/hosts.deny</font>
    (logging goes to
    <font face="Courier">/var/log/tcpd.log</font>
    ). Obviously,
    <font face="Courier">/etc/hosts.allow</font>
    is the file to allow services and
    <font face="Courier">/etc/hosts.deny</font>
    to deny services.

    One word of caution with this tool: by default, a service that is not specifically denied is implicitly allowed. Therefore, I always create an

    <font face="Courier">/etc/hosts.deny</font>
    file with the entry
    <font face="Courier">ALL: ALL</font>
    to deny everything that is not defined in
    <font face="Courier">/etc/hosts.allow</font>
    . Otherwise, you may unwittingly allow something that you don't want to allow.

    Some daemons (such as

    <font face="Courier">sendmail</font>
    ) incorporate TCP functionality (see my series on
    <font face="Courier">sendmail</font>
    in Resources below). You can also add TCP functionality to any program by including
    <font face="Courier">tcpd.h</font>
    in the program, compiling with
    <font face="Courier">libwrap.a</font>
    , and following the documentation provided with TCP Wrappers.

  • <font face="Courier">wu-ftpd</font>

    The Washington University

    <font face="Courier">ftpd</font>
    is a very nice replacement for the standard
    <font face="Courier">ftp</font>
    daemon. It provides much better access control and padded cell usage than the standard
    <font face="Courier">ftp</font>
    . I use it on my public FTP server to allow users to come in and pick up files; but at the same time, they are not allowed to see other people's files. There have been a few security problems with older versions of
    <font face="Courier">wu_ftpd</font>
    , so make sure you have the current one.

  • SSH

    With Secure Shell you can construct a secure communication mechanism between machines. The package provides several encryption methods (including RSA and IDEA) and authentication methods. I have not evaluated the commercial version of SSH that seems to have more features.

    The open source version (for noncommercial use only) does have a couple of drawbacks. It only supports a secure shell (replacing

    <font face="Courier">rsh</font>
    <font face="Courier">rlogin</font>
    ), and a secure copy program (replacing
    <font face="Courier">rcp</font>
    , though it doesn't support recursive copy), and an FTP client. The noncommercial SSH does not directly support X services. If you need to run an xterm, you have to set up a mechanism to allow X back through your firewall. That is not always feasible. It might be better to use a virtual private network (VPN) for this function.

    My partner, Jonathan Klein, used SSH to construct a mechanism for synchronizing Web pages from an internal Web server (the preproduction environment) to a production server outside the firewall. He had to give the developers the ability to push their pages outside without providing them with real logins on the machine. The problem was that

    <font face="Courier">scp2</font>
    (Secure Shell Copy) does not provide for recursive copying. Klein wrote a C program that wrapped around the Secure Shell commands. It queried a simple access list to verify that the user was permitted to update the files. Then it scanned the directory to find all the directories that needed to be created on the other machine, and generated a shell script to create them.

    The C program ran a premove script that created a temporary head directory on the production server. Then it used

    <font face="Courier">scp</font>
    to copy the directory script to the production machine and used SSH to run it. Next, the program generated a script of
    <font face="Courier">scp2</font>
    commands to copy all the files to the appropriate place on the production machine. The script was then executed, and the files were copied over. Finally, a postmove script was run through SSH to move out the old files, move in the new files, and set the ownership and permissions properly for the Web server.

  • VPNs

    Virtual private networks are useful when you want to create a pipe to your network to allow administrators outside the network access to the network as if they were local. VPNs are very useful for remote administration through the Internet. Most remote dial servers are too slow and expensive to maintain. Administrators usually have Internet access from their homes anyway -- and at much faster speeds than the 28.8K modems that many remote dial servers provide.

    I happen to use VTPCSecure from InfoExpress to handle administrative functions. It allows me to enter the remote network through the Internet. I use triple DES encryption with keys that change every 15 minutes and SecurID rather than static passwords for authentication. The tunnel allows me to use Telnet, FTP, and X Windows (the VPN provides other functionality I haven't used yet). Those three are sufficient for me to maintain my firewall remotely. It sure beats commuting through New York City tunnels!

Final thoughts

Next month, I'll conclude this series with a discussion of firewall software deployment.


Much appreciation to Casper Dik of Sun Microsystems and Dr. Mudge of L0pht Heavy Industries for their contributions. Also to Jonathan Klein (Wizard's Keys), who contributed extensively throughout, and to Brian Martin ( for his review and suggestions.

What’s wrong? The new clean desk test
You Might Like
Join the discussion
Be the first to comment on this article. Our Commenting Policies