Nmap Announce mailing list archives

Linux ipfwadm howto


From: Lamont Granquist <lamontg () raven genome washington edu>
Date: Tue, 29 Dec 1998 10:29:41 -0800


I wrote the following howto on hardening your linux system with ipfwadm.
It seems relevant to post it here, since these measures are an attempt to
block things like nmap.  I'd be interested both in comments on how to make
this better, and in discussion of how nmap might adapt to this kind of
thing (for example using ftp-data as a source port might not be a bad
idea...).

I should note explicitly here in the introduction that the advantage of
this kind of "firewalling" vs. tcp_wrappers is that when a service is
blocked by a firewall rule it will appear in a portscan along with a
thousand other ports as being "firewalled" vs. tcp_wrappers where you can
still get a 3-way handshake and you know that either the service is
listening there behind tcp_wrappers or else its one of a handful of
trojans.

How to Implement Access Control in Linux via ipfwadm
----------------------------------------------------

INTRODUCTION
------------

The recent popularity of the Linux mountd exploit has highlighted the
fact that tcp_wrappers really isn't enough.  To their credit Red Hat 5.2
now has a mountd which is linked against libwrap, as is their
portmapper, which means that it implements access control via the
familiar hosts.allow and hosts.deny mechanism.  There are plenty of
other services, however, which do not yet have access control in them,
and at any rate it is much, much better to implement access control in
the TCP/IP stack than to do it on top of the stack in the application
layer.  The sooner that packets can be blocked, generally the better --
although to be secure blocking should be done both in the stack and in
the application layer.

How do you do this?  You need to use ipfw (IP Firewalling) on Linux,
which is controlled by the ipfwadm program.  The 'intended' use of this
program is on a machine with two Ethernet cards to implement a firewall
using input and output passing rules.  Instead what I'm going to attempt
to explain how to do is to use ipfwadm on a host machine (single
Ethernet card) to implement "tcp_wrappers" directly in the IP stack,
using mostly input rules.  The skills learned here, however, will form a
good foundation on how to also setup a dual-homed bastion host as part
of a firewall.

What we will be doing is basically setting up a firewall on a host,
which means that the system administrator must be aware of various
firewall issues.  In particular, the system administrator needs to start
thinking about a security policy, since the act of setting up a firewall
is the act of implementing a security policy.

The security policy should address the needs of the users on the
machine, the known security problems with various TCP/IP services and
then make suggestions on what rules to implement and should spell out
what the effects of those rules will be on the usability of the machine.
Unfortunately, going into how to write up such a policy is beyond the
scope of what I'm going to discuss.  I'm going to simply implement a
"typical" policy where one allows through most of the "typical" TCP/IP
services and where usability/flexibility tends to be favored a bit more
than security.  This actually makes the implementation a bit more
complex, and it should be easy to simplify the implementation to make
things more secure.  If things get more complicated for you, it's best
to start reading up on how to actually create and configure firewalls.

  For more information on building firewalls and writing up security
  policies for use in firewalls, consult D. Brent Chapman and Elizabeth
  D. Zwicky, "Building Internet Firewalls", O'Rielly & Associates,
  ISBN 1-56592-124-0.  Also see Brent Chapman's paper "Network (In)Security
  Through IP Packet Filtering" 
  (ftp://ftp.greatcircle.com/pub/firewalls/pkt_filtering.ps.Z)

To use ipfwadm, you need to have your kernel compiled with
CONFIG_IP_FIREWALL and CONFIG_IP_FIREWALL_VERBOSE turned on.  While
you're at it turn on CONFIG_IP_ALWAYS_DEFRAG for kicks, and turn off
CONFIG_IP_FORWARD.  CONFIG_IP_ALWAYS_DEFRAG is necessary for dual-homed
bastion hosts in a firewall but is not necessary (?) for our
single-homed example.  Turning off CONFIG_IP_FORWARD can prevent some
spoofing attacks.  RedHat 5.2 comes with CONFIG_IP_FIREWALL (and
CONFIG_IP_FIREWALL_VERBOSE) already turned on by default so there is no
need to recompile the kernel.

If you get error messages about "ipfwadm: cannot open file
/proc/net/ip_input" or if you cannot get any logging information then
you need to recompile your kernel.  Unfortunately, I can't help with
recompiling Linux kernels since I'm still trying to figure out how to
recompile mine with solar designer's non-executable-stack patch in it
(stay tuned).

  Consult ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Kernel-HOWTO for
  more info on rebuilding a Linux Kernel, or read the docs that came with
  your distribution.

If you don't have the ipfwadm program then RedHat Linux users will need
to install ipfwadm-2.3.0-6 (or the current appropriate RPM), and users
of other distributions will need to figure out where to find it --
consult the appropriate manuals.  If you aren't running Linux, then you
can't use ipfwadm, although there may be other packet filters that run
on your machine -- that, however, is well outside the scope of what I'm
writing about.

  Consult ftp:/ftp.xos.nl/pub/linux/ipfwadm,
  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Firewall-HOWTO and
  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/NET-3-HOWTO for more
  information on ipfwadm.

GETTING STARTED
---------------

Okay, if your machine is setup to do ipfwadm, then you should be able to
do some basic ipfwadm commands:

ipfwadm -Iln /* list (-l) the Input (-I) rules with numeric addresses (-n) */
ipfwadm -Oln /* list (-l) the Ouput (-I) rules with numeric addresses (-n) */

Both of these should tell you what the default rules are like:

% ipfwadm -Oln
IP firewall output rules, default policy: accept
%

If you have any existing explicit rules they will be listed looking
something like:

% ipfwadm -Oln
IP firewall output rules, default policy: accept
type  prot source               destination          ports
acc   icmp 0.0.0.0/0            128.95.73.166        0,4,8,11,12

To flush a rule set you issue a -f command:

ipfwadm -Of  /* flushes the Output rules */
ipfwadm -If  /* flushes the Input rules */

You can also set the default policy with a command like:

ipfwadm -I -p accept  /* accept all packets by default */

Note that your default policy is *not* flushed when you flush the rules.
That means that if you have at some time issued a command:

ipfwadm -I -p deny

And setup some rules to allow certain packets through, and then you
issue a flush command:

ipfwadm -If

You will now be blocking all incoming packets to your default interface,
and you might need to reboot the machine.  No packets will be getting
through, and this will lock the X11 console display since the machine
will not be able to talk to itself via the port 6000 X11 services (even
though these packets do not go over the wire, they are still TCP and
they are still blocked).

This highlights the fact that it's pretty easy to hose the machine when
you're trying to work the bugs out of your firewalling rules and that
it's best to mess with firewalling when you're not running X on the
console.  Don't play with installing firewalling rules if you're not
going to be able to tolerate an "oops, i didn't mean to do that"
followed by a power cycle.  However, if you do find yourself in this
mess it may work to get a virtual terminal from X11 with Alt-Shift-F1 or
by using Ctrl-Alt-Backspace to kill the X Server entirely.

In addition to the Input (-I) and Output (-O) rules there are also
Forwarding (-F) and Accounting (-A) and Masquerading (-M) rules.  For a
non-firewall host -F and -M are not needed, while -A is only needed if
you want to do accounting of packet counts (something like netstat -s,
only more detailed).  Instead of using -A we'll just be logging
everything suspicious to syslog.

A note on source and destination addresses.  It is very easy to mix up
the source and destination packet addresses with the source and
destination of a TCP connection.  When doing ipfwadm rules it is
important to think about the _packets_.  That means that you will need
to consider both the outgoing packets and the incoming ones.  And you
need to keep in mind that the Input and Output rules are applied to
incoming and outgoing _packets_, not the connections.  This simplifies
things a little bit, since I will for the most part be worried only
about blocking incoming packets, and will almost always stick to Input
rules, but the Input rules can also wind up blocking reply packets from
connections issued from the host machine.  I'll try to be explicit about
when I'm talking about packets and when I'm talking about connections,
but for ipfwadm rules it's important to always think about how they
apply to packets.

To implement the rules you would generally place them into a file like
/etc/rc.d/init.d/firewall and then make symlinks into the appropriate
rc.d subdirectories so that they are setup by default.  I'll assume from
now on that you're using /etc/rc.d/init.d/firewall, and so to set it up
so that this script is loaded on boot time, setup the following
symlinks:

 ln -sf ../init.d/firewall /etc/rc.d/rc2.d/S15firewall
 ln -sf ../init.d/firewall /etc/rc.d/rc3.d/S15firewall
 ln -sf ../init.d/firewall /etc/rc.d/rc4.d/S15firewall
 ln -sf ../init.d/firewall /etc/rc.d/rc5.d/S15firewall

It is probably a good idea to not setup the links initially and instead
manually run the installation of the firewall rules with:

 /etc/rc.d/init.d/firewall start

Similarly, with the script below it is setup to flush the firewall rules
with the command:

 /etc/rc.d/init.d/firewall stop

This is a useful command for when you inevitably will get yourself into
trouble by blocking something that you didn't really mean to block.

The actual format of a rule that I'll use looks like this (a simplified
subset of what ipfwadm is capable of):

ipfwadm [-I|-O] -a [accept|deny] [-P [tcp|udp|icmp]] [-S IP/net [port/icmp #]]
        [-D IP/net [port]] [-o]

You specify either the Input or Output rules, weither to accept or deny,
optionally specify a protocol (default matches *any* protocol, including
those which are not tcp, udp or icmp), optionally specify source and
destination addresses/ports (default matches any), and optionally log the
packets.

Appended to this is an 'actual' (sorta) /etc/rc.d/init.d/firewall which
sets up some typical rules for a linux machine which is used as a
workstation and which might nfs export some of its disks.  Hopefully it
should be useful as a template to use.  You should adapt this script to
your own site security policy.

At the top are some configuration variables which should be filled in
with the IP address of the host, the network address of the host, the
primary router for the host, and the broadcast address of the host.  The
format for IP addresses is IP/netbits, so that a single hostname is
going to be xxx.xxx.xxx.xxx/32, a class C is going to be
xxx.xxx.xxx.0/24 and a class B will be xxx.xxx.0.0/16.

Also note that the "MYBROADCAST2" address is necessary even if you're on
a class C since some machines put out broadcast packets apparently
thinking that their netmask is 255.255.0.0 -- these machines are
probably misconfigured.  Later we will be silently dropping all the
broadcast requests to this address, you might instead want to log these
requests and fix the configuration problems in these machines -- with
many different departments on the same subnet we've found that hunting
down admins with broken configurations and standing over them while they
fix them isn't worth our time...

THE DIRT
--------

Lets step through the actual rules to see what I did:

 # flush rules
 /sbin/ipfwadm -I -f
 /sbin/ipfwadm -O -f
 /sbin/ipfwadm -F -f
 /sbin/ipfwadm -A -f

That should hopefully be self-explanatory -- we're starting with a completely
fresh slate.

 # default is to allow all incoming packets
 /sbin/ipfwadm -I -p accept
 /sbin/ipfwadm -O -p accept

I setup the default rule to be accept.  Setting them to deny will mean
that if you flush the rules then you'll wind up pretty well hosing your
machine.  And if you rely on a default deny rule then you will not get
any logging.   For that reason I will actually implement an explicit
default deny rule which will also log all the packets that it drops --
so keep in mind that the default will eventually be set to deny packets
when we get to the final rule at the bottom of this file.

 #
 # TCP Rules
 #

 # allow incoming packets to sshd,identd,smtpd from anywhere
 /sbin/ipfwadm -I -a accept -P tcp -S any/0 -D $MYIP 22 25 113

These are the services which we allow anyone to connect to.  Some hosts
may need telnet added to this list, some may need ftp (*and* the
ftp-data port) added to this list, and you might have a webserver,
whatever.  This is probably where you will implement most of the public
part of your security policy.  Some lucky sites might need only this
rule, plus the a rule denying all other TCP connections.

 # accept X11, nfsd from our network
 /sbin/ipfwadm -I -a accept -P tcp -S $MYNET -D $MYIP 2049 6000:6025

This allows NFS requests from the local network, and allows X
connections from the local network.  You can delete the "2049" from this
line if the machine is not going to be serving NFS disks anywhere.  If
the machine does not do X11 you can remove the "6000:6025" (which,
incidentally defines the port range from 6000-6025).  If you use X11 you
must at least have a line which is similar only with "-S $MYIP -D $MYIP"
for X11 to work on the console and to be able to use locally-run
applications.

The portrange that I've defined may be way too small for other machines.
Each port in this range defines another virtual X server, which can be
accessed through a display environment variable via:

 setenv DISPLAY yyy.yyy.yyy.yyy:x.0

Where yyy.yyy.yyy.yyy is your IP address or hostname, and the x will
correspond to the port number 600x (and on up to 6010, 6011, etc).  For
multi-user hosts that allow ssh logins and allow X11 forwarding you will
need to allow for one virtual X server for each ssh login.  It may be 
appropriate in some circumstances to define a range as large as 6000-6100
or more depending on how many remote users you have.

The X11 firewalling rules are very important since otherwise anyone can
connect to your Xserver, and the only access controls are what X11 provides
through xhost and xauth.  The widely used mscan program will probe for
open Xservers on these ports.

If you need to allow access from anywhere other than your network simply
add more rules here.  We allow access from a single class C, plus a list
of about 5 other hosts which are each listed on their own rules.  In
general all of these rules need to be adapted to your particular network
and your particular needs.

 # deny+log X11, nfsd from everywhere else
 /sbin/ipfwadm -I -a deny -P tcp -S any/0 -D $MYIP 2049 6000:6025 -o

That rule crushes all packets coming from anywhere else.  You will not be
able to do X11 forwarding through SSH to these hosts and will not be able
to start up X programs on these hosts and have them forwarded to the 
console (this is like a hard-coded xhost command that your users cannot
override on the console).  The "-o" causes these packets to be logged.

An effect of this rule is that users will not be able to log into a
remote machine and start an X application on the remote machine to 
display on their console.  This will undoubtably annoy one of your users
sooner or later, but it's important that you not cave in and allow X
connections from anywhere.  Addressing X11 should be part of your site
security policy.

 # allow incoming packets to other high numbered ports from anywhere, but
 # only for machines with the ACK bit set (i.e. outgoing connections)
 /sbin/ipfwadm -I -k -a accept -P tcp -S any/0 -D $MYIP 1024:65535

This allows all connections originating on your machine with a high
numbered port to external machines.  It is necessary if you want the 
machine to be able to connect to any external services (e.g. web browsing,
telnet to external machines, ftp to external machines, ssh to external
machines).

The "-k" flag will only match packets with the ACK bit set.  According
to the TCP specs the first packet in a connection will be a SYN packet
with the ACK bit cleared, all the later packets will have the ACK bit
set.  This flag, then, will block incoming connections to high numbered
ports, but outgoing connections will not be blocked (since the SYN
packet would only be caught by the ipfwadm -O rules, and since the rest
of the packets in the connection which are inbound will all have the ACK
bit set).

X11 and nfs (and any other services that you are running on high
numbered ports) need to be treated specially apart from this rule
because they are accepting incoming connections.  The rules to deny
access to X11 and nfs should come before this rule for additional
security against exploit or port-scanning attempts that use invalid
packets with the ACK bit turned on.

 # allow ftp-data connections to high-numbered ports
 /sbin/ipfwadm -I -a accept -P tcp -S any/0 20 -D $MYIP 1024:65535

This is sort of a security hole, but it is necessary to be able to do
ftp transfers from external sites (e.g. to be able to connect to
anonymous FTP sites).  It also means that someone could use the ftp-data
port to probe and possibly break into services running on high-numbered
ports.  This is why we *need* to explicitly deny X11 and nfs prior to
this line.

 # allow outgoing rsh connections from low numbered ports
 /sbin/ipfwadm -I -k -a accept -P tcp -S any/0 513 -D $MYIP 1:1023

This is another potential hole since it lets in all packets to low
numbered ports which have the ACK bit turned on.  This is to let rsh out
of your machine to other machines to be able to work.  If you don't want
your users to use rsh to other machines then remove this line (and while
you're at it take the suid root bit off of your rlogin binary).

If you are going to be using ssh, then you need either a similar line
like this with a source port of 22, or else you need to strip the suid
root bit off of your ssh binary.  I prefer to take the latter course of
action -- doing so will break the ability of ssh to use
.shosts/.rhosts-style authentication and you will need to educate your
users about the .ssh/authorized_keys file.

 # allow daytime,finger,portmap from our network
 /sbin/ipfwadm -I -a accept -P tcp -S $MYNET -D $MYIP 13 79 111

Portmap/rpcbind (111) is necessary for things like NFS and other RPC
services to work (NIS, etc, etc).  I like to let TCP daytime through so
that I can check clock synchronization, and like to have time turned off
and instead use xntpd.  Let through here all the stuff that you want
people on your local network to be able to use.

 # allow 600:1023 port access (RPC services) from our network
 /sbin/ipfwadm -I -a accept -P tcp -S $MYNET -D $MYIP 600:1023

This should allow stuff like mountd, ypserv, ypbind, ypasswd, statd,
lockd, and whatever else you've got running on RPC.  In some cases you
might need to add some high numbered ports here -- you can check what
RPC services you're running and what ports they're running on with
'rpcinfo -p <machine>'

Keep in mind that RPC ports are not necessarily static and that if you
add a service and reboot it's possible that your portmap table will get
scrambled, so for usability and lack of headaches its better to define a
pretty wide range here (although obviously this makes you less secure,
but it only exposes you directly to your local network).

 #
 # UDP Rules
 #

 # allow portmap from machines on our network
 /sbin/ipfwadm -I -a accept -P udp -S $MYNET -D $MYIP 111

Now we switch to UDP (there's no reason for these to come after the TCP
rules other than it's just less of it).  This lets through portmapper
queries from the local network.  It's a mirror of the TCP rule.

 # allow 600:1023 port access (RPC services) from our network
 /sbin/ipfwadm -I -a accept -P udp -S $MYNET -D $MYIP 600:1023

Again, here we're letting in RPC services.  Do an 'rpcinfo -p <machine>' to
see if there's anything else which might need to be added.

 # allow nfs from machines on our network
 /sbin/ipfwadm -I -a accept -P udp -S $MYNET -D $MYIP 2049

 # deny nfs from other machines
 /sbin/ipfwadm -I -a deny -P udp -S any/0 -D $MYIP 2049 -o

Again, we're only selectively letting in NFS traffic.

 # allow ntp from cac machines
 # /sbin/ipfwadm -I -a accept -P udp -S 140.142.0.0/16 123 -D $MYIP 123

This is a University of Washington - specific rule to let through
packets coming from the campus NTP servers.  I'm probably being a bit
overly permissive by not mentioning them by name, but I don't want their
IP #s to get changed by the campus computing dept at some time in the
future and then have things mysteriously start to foul up.  UW sites
should uncomment this line, other sites should edit it to be appropriate
for their network.

 # allow responses to queries originating from high numbered ports
 /sbin/ipfwadm -I -a accept -P udp -S any/0 -D $MYIP 1024:65535

There's no ACK flag on UDP so you wind up letting through *anything* to
high numbered ports.  You should block any services which wind up on
high numbered ports *before* this line (therefore the NFS deny rule
comes before this line).

 # silently drop broadcast UDP stuff
 /sbin/ipfwadm -I -a deny -P udp -S $MYNET -D $MYBROADCAST1
 /sbin/ipfwadm -I -a deny -P udp -S $MYNET -D $MYBROADCAST2
 /sbin/ipfwadm -I -a deny -P udp -S $MYNET -D 255.255.255.255/32
 /sbin/ipfwadm -I -a deny -P udp -S 0.0.0.0/32 -D 255.255.255.255/32

There's all kinds of broadcast crud which tends to go over the wires.
Machines which boot up asking for a valid IP address and trying to find
NIS servers and god only knows what else.  I don't like getting all this
traffic logged so I drop it all here, without the '-o' switch so that I
don't see it.

The 2nd line with $MYBROADCAST2 (if you're on a class C and have set
this up similarly to how I've done it) will catch machines that have
netmasks of 255.255.0.0 (class B) and are misconfigured.  You might
instead want to comment this out and log all the broadcast messages that
you get from these machines and then hunt them down and fix them.

If you are on a class B you'll still want to have both broadcast
addresses defined since you'll probably wind up with machines that are
misconfigured for your network and are using the class C broadcast
address.

 # some machines use a screwy broadcast address to query portmap on boot
 /sbin/ipfwadm -I -a deny -P udp -S $MYNET -D any/0 111

I don't want to see these packets in my logs either, I keep seeing
"xxx.yyy.0.0" destination addresses (not a valid broadcast address) on
machines which are booting up and trying to contact portmappers.  I have
no idea what the misconfiguration is here, but I don't care and don't
want to see these packets in the logs.

 #
 # ICMP Rules
 #

 # allow incoming ICMP echo response, destination unreachable, source quench,
 # time exceeded and parameter problem
 /sbin/ipfwadm -I -a accept -P icmp -S any/0 0 3 4 11 12 -D $MYIP

ICMP is a different in that the ICMP packet type rather than the port
number is what gets specified, and the packet type must be associated
with the source address.  The important thing to note in this rule is
that we don't allow echo request packets (denying them later in the
default rule) which means that external machines will not be able to
ping this machine.

 # accept pings from our local network
 /sbin/ipfwadm -I -a accept -P icmp -S $MYNET 8 -D $MYIP

Except that we'll accept pings from the local network.

 # silently drop router advertisements from our router
 /sbin/ipfwadm -I -a deny -P icmp -S $MYROUTER 9 -D $MYBROADCAST1

I use static routing tables and know what the router's IP # is.  I don't 
need anything dynamic, so it gets dropped.  Since it's legitimate traffic
I drop it without logging it.

For the UW network generally everyone is on a leaf network with one
router, and static routing tables are appropriate.  UW sites should
setup static routing tables and kill routed or gated and take it out of
the startup files -- unless you have an unusual network topology which
requires dynamic routing.

 # allow outgoing ICMP echo request, echo reply, source quench, time
 # exceeded and parameter problem
 /sbin/ipfwadm -O -a accept -P icmp -S $MYIP 0 4 8 11 12 -D any/0

Note here that we are using an *output* rule and also note that we're
not allowing the host to send out ICMP destination unreachable messages,
which can be used in scanning.  ICMP isn't as much of a problem in what
it lets in as what information it leaks out, so that is why we need this
output rule.  Source quench and parameter problem potentially help us
more than they could be used by some other evil person to abuse us, and
outgoing echo request packet are fine.  For the echo reply packets,
we've already limited who we will accept an echo request from, so it's
okay to let out echo replies to everyone.

 #
 # Multicast Garbage
 #

 /sbin/ipfwadm -I -a deny -S any/0 -D 224.0.0.0/4

There's starting to be lots of multicast on my network.  I'm very tired
of looking for the hack attempts and probes in a flood of blocked
multicast stuff, so I silently drop all these packets.  The paranoid may
want to log and sift through here for unusual activity.

 #
 # Loopback interface
 #

 /sbin/ipfwadm -I -a allow -S 127.0.0.1/32 -D 127.0.0.1/32

This allows all connections via the loopback interface, which is probably
a good thing.

 # deny + log everything else
 /sbin/ipfwadm -I -a deny -o
 /sbin/ipfwadm -F -a deny -o
 /sbin/ipfwadm -O -a deny -P icmp -o

And now all the TCP UDP and ICMP packets that haven't either been allowed
or been silently dropped are here explicitly denied and are logged.  By
default we allow all outgoing packets except ICMP and deny all incoming
packets and *all* forwarding get denied (this machine isn't a router or
anything so packets should never be forwarded).

That's it!  =)

Of course, you can't hope to be able to impliment this if you don't
already have a pretty decent understanding of TCP/IP protocols.  It's
pretty unlikely that this script can be dropped into place on any
machine out there unmodified.  

  For more information about TCP/IP protocols, check out the "Building 
  Internet Firewalls" book previously referenced.  Also good are 
  W. Richard Stevens, "Unix Network Programming, Volume I.  Networking 
  APIs: Sockets and XTI" ISBN# 0-13-490012-X and Gary R. Wright and
  W. Richard Stevens, "TCP/IP Illustrated, Vol 2: The Implementation"
  ISBN# 0-201-63354-X, although both of these are more advanced and
  technical (and beware of the many different books by Stevens with 
  sometimes similar sounding titles...).

  Also good reading is SNIs paper on "Insertion, Evasion and Denial of
  Service: Eluding Network Intrusion Detection" http://www.secnet.com/ids
  and Yuri Volobuev's paper on "Redir games with ARP and ICMP"

If you are having problems, then check your logs and see which packets
are being denied.  If you're using something which relies on being able
to see broadcast packets (e.g. if your linux box is a bootp or rarp
server) then you're probably going to need to modify or remove all those
deny rules that I added in order to silently drop broadcast/multicast
packets.

If you're having trouble with logging, check your /etc/syslog.conf file.
Bad packets should be getting logged under the "kern" facility, and
remember that delimiters in the syslog.conf file are <tab> characters,
and that using spaces can make a syslog.conf file look "right" but parse
"wrong."  Also, strongly consider logging all syslog information to a
single logging host -- this is as simple as appending the line:

  *.debug<tab>   <tab>   <tab>   <tab>   <tab>   @loghost.domain.org


------------------------------- cut here -------------------------------

#!/bin/sh
#
# firewall        This shell script takes care of setting up the firewall
#

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

[ -f /sbin/ipfwadm ] || exit 0

# this should be the IP address of the host that you are configuring
MYIP="192.168.111.112/32"
# this should be the network that you're on.  if you're on a class B and
# your netmask is 255.255.0.0 you'll use something like 192.168.0.0/16.
MYNET="192.168.111.0/24"
# next is the IP address of your router
MYROUTER="192.168.111.100/32"
# then both the class C and class B broadcast addresses (you probably have
# traffic going to both on your network, even though you should only have
# one or the other).
MYBROADCAST1="192.168.111.255/32"
MYBROADCAST2="192.168.255.255/32"

# See how we were called.
case "$1" in
  start)
    echo -n "Setting up firewall rules: "

    # flush rules
    /sbin/ipfwadm -I -f
    /sbin/ipfwadm -O -f
    /sbin/ipfwadm -F -f
    /sbin/ipfwadm -A -f
    
    # default is to allow all incoming packets
    /sbin/ipfwadm -I -p accept
    /sbin/ipfwadm -O -p accept
    
    #
    # TCP Rules
    #
    
    # allow incoming packets to sshd,identd,smtpd from anywhere
    /sbin/ipfwadm -I -a accept -P tcp -S any/0 -D $MYIP 22 25 113 
    
    # accept X11, nfsd from our network
    /sbin/ipfwadm -I -a accept -P tcp -S $MYNET -D $MYIP 2049 6000:6025

    # deny+log X11, nfsd from everywhere else
    /sbin/ipfwadm -I -a deny -P tcp -S any/0 -D $MYIP 2049 6000:6025 -o
    
    # allow incoming packets to other high numbered ports from anywhere, but
    # only for machines with the ACK bit set (i.e. outgoing connections)
    /sbin/ipfwadm -I -k -a accept -P tcp -S any/0 -D $MYIP 1024:65535

    # allow ftp-data connections to high-numbered ports
    /sbin/ipfwadm -I -a accept -P tcp -S any/0 20 -D $MYIP 1024:65535

    # allow daytime,finger,portmap from our network
    /sbin/ipfwadm -I -a accept -P tcp -S $MYNET -D $MYIP 13 79 111
    
    # allow 600:1023 port access (RPC services) from our network
    /sbin/ipfwadm -I -a accept -P tcp -S $MYNET -D $MYIP 600:1023
    
    #
    # UDP Rules
    #
    
    # allow portmap from machines on our network
    /sbin/ipfwadm -I -a accept -P udp -S $MYNET -D $MYIP 111
    
    # allow 600:1023 port access (RPC services) from our network
    /sbin/ipfwadm -I -a accept -P udp -S $MYNET -D $MYIP 600:1023
    
    # allow nfs from machines on our network
    /sbin/ipfwadm -I -a accept -P udp -S $MYNET -D $MYIP 2049 
    
    # deny nfs from other machines
    /sbin/ipfwadm -I -a deny -P udp -S any/0 -D $MYIP 2049 -o
    
    # allow ntp from U of W CAC machines
    # /sbin/ipfwadm -I -a accept -P udp -S 140.142.0.0/16 123 -D $MYIP 123
    
    # allow responses to queries originating from high numbered ports
    /sbin/ipfwadm -I -a accept -P udp -S any/0 -D $MYIP 1024:65535
    
    # silently drop broadcast UDP stuff
    /sbin/ipfwadm -I -a deny -P udp -S $MYNET -D $MYBROADCAST1
    /sbin/ipfwadm -I -a deny -P udp -S $MYNET -D $MYBROADCAST2
    /sbin/ipfwadm -I -a deny -P udp -S $MYNET -D 255.255.255.255/32
    /sbin/ipfwadm -I -a deny -P udp -S 0.0.0.0/32 -D 255.255.255.255/32

    # some machines use a screwy broadcast address to query portmap on boot
    /sbin/ipfwadm -I -a deny -P udp -S $MYNET -D any/0 111
 
    # 
    # ICMP Rules
    #
    
    # allow incoming ICMP echo response, destination unreachable, source quench,
    # time exceeded and parameter problem
    /sbin/ipfwadm -I -a accept -P icmp -S any/0 0 3 4 11 12 -D $MYIP
    # accept pings from our local network
    /sbin/ipfwadm -I -a accept -P icmp -S $MYNET 8 -D $MYIP
    # silently drop router advertisements from our router
    /sbin/ipfwadm -I -a deny -P icmp -S $MYROUTER 9 -D $MYBROADCAST1
    
    # allow outgoing ICMP echo response, echo reply, source quench, time
    # exceeded and parameter problem
    /sbin/ipfwadm -O -a accept -P icmp -S $MYIP 0 4 8 11 12 -D any/0
    
    #
    # Multicast Garbage
    #
    
    /sbin/ipfwadm -I -a deny -S any/0 -D 224.0.0.0/4

    #
    # Loopback interface
    #

    /sbin/ipfwadm -I -a allow -S 127.0.0.1/32 -D 127.0.0.1/32

    #
    # Default
    #
    
    # deny + log everything else
    /sbin/ipfwadm -I -a deny -o
    /sbin/ipfwadm -F -a deny -o
    /sbin/ipfwadm -O -a deny -P icmp -o
   
    echo "done"
    ;;

  stop)
    echo -n "Flushing firewall rules: "

    /sbin/ipfwadm -I -f
    /sbin/ipfwadm -O -f
    /sbin/ipfwadm -F -f
    /sbin/ipfwadm -A -f

    echo "done"
    ;;

  *)
    echo "Usage: firewall {start|stop}"
    exit 1

esac

exit 0


-- 
Lamont Granquist                       lamontg () raven genome washington edu
Dept. of Molecular Biotechnology       (206)616-5735  fax: (206)685-7344
Box 352145 / University of Washington / Seattle, WA 98195
PGP pubkey: finger lamontg () raven genome washington edu | pgp -fka



Current thread: