These documents are a work in progress. This one was last updated .
I've still got a bunch to add.

 

First things first - the firewall
Once I got over the euphoria of a fast, always on internet connection, paranoia kicked in. My firewall is a dual boot system - Solaris and Windows 98. I booted up in Windows 98 and pointed a browser to the Gibson Research "Shields UP!" product. While the Hybrid modem has a little security in it you realize how open Windows is - and I don't mean that in the good way. I wonder how many people in my neighborhood have their Windows machine directly connected to the Sprint network without any firewall type software. (I soon learned that by looking at the log files from Apache - alot of people were and are infected with Code Red and or Nimda) And, by default, Solaris runs even more services. I had to do something - and sooner rather than later.

I got my copy of IPF from the website. It compiles easily and installs as a package.

Once you install it the instructions at http://www.obfuscation.org/ipf/ are incredibly helpful. These docs get updated regularly and I make it a point to try to read them with any upgrades to IPF. As of March 17, 2002, IPF is on version 3.4.25.

 

Compiling and installing IPF
IPF is easy to compile, but its build environment isn't like most other tools out there today. You must use the "make" that comes with Solaris (in /usr/ccs/bin) rather than GNU make. There is no "./configure" step where the build environment is setup. Note that, depending on how you installed Solaris, the tools in /usr/ccs may not have been installed. My Solaris install is a full install without OEM support.

To compile and install under Solaris, simply do the following:

Now that you've got IPF installed, it must be configured. The default configuration file is /etc/opt/ipf/ipf.conf for the firewall related configuration and /etc/opt/ipt/nat.conf for the NAT configuration. The first file I had to deal with is ipf.conf. It tells IPF what traffic to allow in and out of the firewall. The format is a little rough at first but makes sense once you understand it. Again, the docs at http://www.obfuscation.org/ipf/ are pretty much a requirement to help you get it set up.

My IPF setup is pretty straight forward. I allow anything sensible out and don't allow too much unsolicited traffic in. By sensible I really only mean that my internal network address, along with a list of other address that should never be seen on the internet are not allowed out. Realistically this should never happen but it doesn't hurt much other than using a little CPU time on my firewall.

ipf.conf
Below is a copy of my ipf.conf. I've annotated in bold areas that are a little more interesting. The interface name internal is the physical name assigned to the interface that is internal to my home network. The interface name external is hooked to the broadband modem. The address external_addr is the IP address that is assigned to me by Sprint - it is not the modem address.


#
#
# --------------------------------------------------------------
# Nasty Packets:
#       Block any packets which are too short to be real.
block in log quick all with short
#       Block any packets with source routing set
block in log quick all with opt lsrr
block in log quick all with opt ssrr
#
# --------------------------------------------------------------
# Private Network:
#       Allow traffic on internal and lo0 to pass unimpeded
pass in on internal all
pass out on internal all
pass in on lo0 all
pass out on lo0 all
#
# --------------------------------------------------------------
# Public Network (external):
#       That which is not explicitly allowed is forbidden
block in log on external all
block out log on external all
#
#       Invalid Internet packets
#               Deny reserved addresses

These are straight from http://www.obfuscation.org/ipf/

block in log quick on external from 0.0.0.0/7 to any
block in log quick on external from 2.0.0.0/8 to any
block in log quick on external from 5.0.0.0/8 to any
block in log quick on external from 10.0.0.0/8 to any
block in log quick on external from 23.0.0.0/8 to any
block in log quick on external from 27.0.0.0/8 to any
block in log quick on external from 31.0.0.0/8 to any
block in log quick on external from 69.0.0.0/8 to any
block in log quick on external from 70.0.0.0/7 to any
block in log quick on external from 72.0.0.0/5 to any
block in log quick on external from 82.0.0.0/7 to any
block in log quick on external from 84.0.0.0/6 to any
block in log quick on external from 88.0.0.0/5 to any
block in log quick on external from 96.0.0.0/3 to any
block in log quick on external from 127.0.0.0/8 to any
block in log quick on external from 128.0.0.0/16 to any
block in log quick on external from 128.66.0.0/16 to any
block in log quick on external from 169.254.0.0/16 to any
block in log quick on external from 172.16.0.0/12 to any
block in log quick on external from 191.255.0.0/16 to any
block in log quick on external from 192.0.0.0/19 to any
block in log quick on external from 192.0.48.0/20 to any
block in log quick on external from 192.0.64.0/18 to any
block in log quick on external from 192.0.128.0/17 to any
block in log quick on external from 192.168.0.0/16 to any
block in log quick on external from 197.0.0.0/8 to any
block in log quick on external from 201.0.0.0/8 to any
block in log quick on external from 204.152.64.0/23 to any
block in log quick on external from 224.0.0.0/3 to any

#
# block out anything internal that is invalid
#
block out log quick on external from any to 0.0.0.0/7
block out log quick on external from any to 2.0.0.0/8
block out log quick on external from any to 5.0.0.0/8
block out log quick on external from any to 10.0.0.0/8
block out log quick on external from any to 23.0.0.0/8
block out log quick on external from any to 27.0.0.0/8
block out log quick on external from any to 31.0.0.0/8
block out log quick on external from any to 69.0.0.0/8
block out log quick on external from any to 70.0.0.0/7
block out log quick on external from any to 72.0.0.0/5
block out log quick on external from any to 82.0.0.0/7
block out log quick on external from any to 84.0.0.0/6
block out log quick on external from any to 88.0.0.0/5
block out log quick on external from any to 96.0.0.0/3
block out log quick on external from any to 127.0.0.0/8
block out log quick on external from any to 128.0.0.0/16
block out log quick on external from any to 128.66.0.0/16
block out log quick on external from any to 169.254.0.0/16
block out log quick on external from any to 172.16.0.0/12
block out log quick on external from any to 191.255.0.0/16
block out log quick on external from any to 191.255.0.0/16
block out log quick on external from any to 192.0.0.0/19
block out log quick on external from any to 192.0.48.0/20
block out log quick on external from any to 192.0.64.0/18
block out log quick on external from any to 192.0.128.0/17
block out log quick on external from any to 192.168.0.0/16
block out log quick on external from any to 197.0.0.0/8
block out log quick on external from any to 192.168.0.0/16
block out log quick on external from any to 197.0.0.0/8
block out log quick on external from any to 201.0.0.0/8
block out log quick on external from any to 204.152.64.0/23
block out log quick on external from any to 224.0.0.0/3


This is probably a little insecure but I like ping (type 8 in, type 0 out) to
work (see this list for all the numbers)

pass in log quick on external proto icmp from any to external_addr icmp-type 8
pass out log quick on external proto icmp from external_addr to any icmp-type 0
#
#       ICMP Protocols
#               Allow pings out
pass out log on external proto icmp all keep state
#
#       TCP/UDP Protocols
#               Allow TCP/UDP requests to go out and keep the results
#               flowing back in.
pass out on external proto tcp from any to any keep state
pass out on external proto udp from any to any keep state

The protocol esp is not particularly well documented in the IPF stuff but
it is used for IP tunneling.  My work uses a VPN that uses this protocol.  It
took me a while to figure this out but it's great now because I can work at
home using the broadband connection to work.  The IP address of my work's VPN
server goes into VPN_SERVER below.

#
# My work's VPN server
#
pass out quick on external proto esp from any to VPN_SERVER
pass in quick on external proto esp from VPN_SERVER to any
pass in quick on external proto udp from VPN_SERVER to any port = 500


Pass in traffic for my web server.  Note that even though this says I do I've stopped
logging traffic to port 80.  I get hundreds of hits per day from idiots who don't know that
they are still infected with the code red worm.  I've given up logging it as it really
doesn't tell me a whole lot other than there are alot of morons in the world.

#
# pass in port 80 (normal web port) and 443 (ssl web port)
#
pass in log quick on external proto tcp from any to 192.168.1.2 port = 80 flags S keep state
pass in log quick on external proto tcp from any to 192.168.1.2 port = 443 flags S keep state
#
# pass in port 22 (ssh)
#
pass in log quick on external proto tcp from any to 192.168.1.2 port = 22 flags S keep state
#
# pass in port 25 (sendmail)
#
pass in log quick on external proto tcp from any to 192.168.1.2 port = 25 flags S keep state
#
#       Reset/Error for TCP/UDP services, send back TCP-Reset or
#       Network unreachable to attempts to initiate connections.
block return-rst in log on external proto tcp from any to any flags S/SA
block return-icmp-as-dest(port-unr) in log on external proto udp from any to any

Again, none of my ipf.conf is particularly difficult. The NAT stuff isn't bad either:


map external 192.168.1.0/24 -> 0/32
rdr external 0.0.0.0/0 port 80 -> 192.168.1.2 port 80 tcp
rdr external 0.0.0.0/0 port 443 -> 192.168.1.2 port 443 tcp
rdr external 0.0.0.0/0 port 22 -> 192.168.1.2 port 22 tcp
rdr external 0.0.0.0/0 port 25 -> 192.168.1.2 port 25 tcp

The first line is the most important. It says to map my internal network to anything on the outside. The next two lines are for my web server. One of the cool things that IPF can do is, in addition to network address translation (that is, translate IP addresses), port address translation. Let's say that I didn't like my Apache server running on port 80. Why? Because under Unix you are required to be root to bind() to any port under 1024. If I changed the second line above to be

rdr external 0.0.0.0/0 port 80 -> 192.168.1.2 port 8080 tcp

then, as far as the outside world is concerned my web server is running on the standard port of 80. Internally IPF redirects request destined for port 80 to port 8080 on my web server machine. I could now start Apache as a non-root user.

Two very important safety notes: under Solaris none of this will work the unless I had IP forwarding enabled on my firewall. To check this I ran (as root):

/usr/sbin/ndd /dev/ip ip_forwarding

A "1" means that I was good to go. Otherwise I would have had to enable it (and make sure that it stays around after I rebooted). First I'd enable it on the command line:

/usr/sbin/ndd -set /dev/ip ip_forwarding 1

and then make sure that /etc/init.d/inetinit has the above line in it right after where it echos that the machine is an IPv4 router. The Sun docs are a little misleading here. They say that the default is "0" or off. That's true if there is only one interface on the machine. The inetinit script (o.k. really /etc/rc2.d/S69inet - /etc/init.d/inetinit is a hard link over to it) automatically turns on IP forwarding on a machine if it detect multiple interfaces.

The second important note is to add the IP address of the modem to be the default router for my firewall. I did this by hand first by running:

/usr/sbin/route add default IP address of modem

So that the machine remembers this setting on reboot, I added the IP address of my broadband modem to the file /etc/defaultrouter. On reboot the system will pick up this and make it the default. It's important to note that none of the other machines in my network use the modem as the default route - only the firewall.

Problems with the installation
There have been two real problems with the installation to this point. When my firewall machine reboots the NAT service doesn't seem to come up. It's in /etc/init.d/ipfboot as ipnat -CF -f /etc/opt/ipf/ipnat.conf but it doesn't come up after a reboot. I manually run this command after a reboot and everything seems to work ok.

The second problem has been with the default Solaris ftp client. No matter what I do to the firewall configuration I can't get it to work from any machine but the firewall. I've tried to get the ftp proxy set up, I've tried to allow the ftp data channel back in, but none of it works. Yet, I noticed that I could do ftp downloads via the Netscape browser with no problem. After digging into the FTP RFC a little and looking on the net, I found that the Solaris ftp client uses the PORT transfer mode only. This simply means that the ftp server expects to be able to open a return socket connection to the ftp client on a port assigned by the client. This doesn't play well with firewalls in general. Netscape uses the PASV (passive) mode which means that the client asks the server to open another port and tell it what it is. Then the client connects to that port on the server and the transfer takes place over that socket. If you want a command line ftp client that supports passive transfers, go to ncftp.com to get the NcFTP Client. This is a pretty good program that defaults to passive mode, making your firewall configuration simpler and safer. It has other benefits too like bookmarks that make it a great replacement for the default ftp client.

Another minor problem is that the default logging goes through syslog. This means that you have to modify /etc/syslog.conf to get any "normal" messages out of the logger. An alternative (and what I ended up doing) is modifying the ipmon -s line in /etc/init.d/ipfboot to put your IPF log file somewhere else. The advantage of this is that your /var/adm/messages files don't get filled up with IPF log messages. The disadvantage is that you need to decide what to do with the log file that IPF generates.

So what I did is modify the line ipfmon -s to say ipmon -D /var/log/ipf.log. Then I created a shell script in /opt/ipf/bin that I named "newipflog". The script looks like this:


#!/bin/sh
#
#
LOGDIR=/var/log
LOG=ipf.log

if test -d $LOGDIR
then
        cd $LOGDIR
        if test -s $LOG
        then
                test -f $LOG.6 && mv $LOG.6  $LOG.7
                test -f $LOG.5 && mv $LOG.5  $LOG.6
                test -f $LOG.4 && mv $LOG.4  $LOG.5
                test -f $LOG.3 && mv $LOG.3  $LOG.4
                test -f $LOG.2 && mv $LOG.2  $LOG.3
                test -f $LOG.1 && mv $LOG.1  $LOG.2
                test -f $LOG.0 && mv $LOG.0  $LOG.1
                cp $LOG    $LOG.0
                cat /dev/null > $LOG
                chmod 644    $LOG
        fi
fi

I then added "13 3 * * 0 /opt/ipf/bin/newipflog" to the root crontab. This replaces the existing IPF log file once a week at 3:13AM. After seven weeks the oldest log file disappears. Why 3:13AM? Well, by default I had an entry for two things at 3:10AM (/etc/cron.d/logchecker and /usr/lib/newsyslog) and one thing at 3:15AM (/usr/lib/fs/nfs/nfsfind) so I just put mine in there to run at around the same time as other system maintenance.

Again, having a log file for just IPF is a matter of preference. I like it but it may not be the way other people would want to do it.

Next, Configuring DNS and Bind

[Line]
Copyright © 2002 Xigole Systems, Inc. Questions or problems? Send mail to scott@xigole.com