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:
/usr/ccs/bin/make solaris. This step
can run as any O/S user who has permission to write into the directory you're in. Using gcc version
2.95.3 I got a warning in /usr/include/sys/devops.h about struct aio_req. This
warning does not seem to harm the use of IPF.pkgrm ipf as
root. This will remove IPF from your system, but it doesn't mess with any existing IPF
configuration files. However, it does remove /etc/init.d/ipfboot so save a copy
of this if you have made any changes.SunOS5 directory.make package. This creates an install package and runs pkgadd to
install everything you need.
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