Firewall/Packetfilter (iptables)

For kernels prior to 2.4, ipchains (see above) is used to do packet filtering. For kernels from 2.4 and up, iptables is used instead.

For iptables, some sort of firewall script (such as Lokkit or NARC) is the way to go, since many iptables commands must be issued to actually get a working packet filter going. This note describes how to set up NARC.

Get a copy of NARC from http://www.knowplace.org/netfilter/narc.html. Untar the distribution and follow the install steps in INSTALL.

You'll need to start NARC, either at boot time or when the external interface is brought up, through some sort of startup script, since the install does not make firewall startup automatic. If you want to always start NARC at boot time, you can use the iptables script supplied in the NARC distribution to replace the default iptables script (in /etc/init.d) supplied with the OS (typically, for RedHat distros, this runs the Lokkit firewall).

Before you replace the iptables script, you might want to consider changing the startup number from 11 to 08 in the script so that the firewall starts before the network comes up. Change:

     # chkconfig: 2345 11 92
to
     # chkconfig: 2345 08 92

This will ensure that there's no exposure to malicious traffic from the external interface during the brief time while the external interface is up but before the firewall has been started. However, if you'll be using diald to manage demand dialing for a telephone connection to the internet, you should change the startup number to something like:

     # chkconfig: 2345 64 36

This will give diald a chance to start up and define sl0, which can the be used by NARC to set up the firewall.

An alternative to trying to figure out when to start the firewall, during boot time, is to let the external interface handler (e.g. diald or ppp) start the firewall when it brings up the external interface. In this scenario, the iptables script is invoked by a script such as ip_up or ip_up.local in the /etc/ppp directory. In order for this to work, the iptables script must be altered to accept a couple of parameters.

We have found that full flexibility is provided if the iptables script is altered to accept two extra parameters (by convention, the first parameter passed to the script tells it what to do: start, stop, restart). The first extra parameter should be the external interface name. This can be used by startup scripts such as ip_up.local to start the firewall on external interfaces such as ppp0 or sl0.

The second extra parameter should be an optional IP address. If it isn't supplied, the firewall will start using masquerading on the dynamic external interface named by the first optional parameter. If it is supplied, the firewall will start using snat on the dynamic external interface named by the first optional parameter, using the supplied IP address as the snat address.

/etc/rc.d/init.d/iptables:

Here is the complete iptables script for NARC with diald/ppp support and snat support for other external interfaces such as eth0:

     #! /bin/sh
     #
     # iptables      This script loads the firewall rules and starts iptables,
     #               using those rules to filter all packet traffic on the server.
     #
     # chkconfig: 2345 08 92
     # description: Netfilter Automatic Rules Configurator (packet filtering \
     #              firewall with iptables).
     #
     # Revision History:
     #
     # Burchard Steinbild <bs@suse.de>   1996       Initial coding.
     # Ulrich Hecht <uli@suse.de>        1999       Adapted to scanlogd.
     # Shane Chen <shane@knowplace.org>  2001       Re-adapted to iptables.
     # ewilde                            2009Feb19  Add clustering support.
     #
     #
     # If there's no NARC configuration, we're all done.
     #
     if [ ! -f /etc/narc/narc.conf ]; then
         exit 0
     fi
     #
     # Source the clustering configuration.
     #
     if [ -f /etc/sysconfig/clustering ] ; then
         . /etc/sysconfig/clustering
     else
         WANCONNECTION=ADSL
     fi
     #
     # If this cluster doesn't use ADSL, Diald, or an ISP's WAN router for its WAN
     # connection, we're outta here.
     #
     DEVICE=`echo $WANCONNECTION | grep -e "eth[0-9]\+," -o`
     if [ x"$WANCONNECTION" != xADSL ] && [ x"$WANCONNECTION" != xDiald ] \
         && [ ! -n "$DEVICE" ]; then
         exit 0
     fi
     #
     # Load the NARC configuration.
     #
     . /etc/narc/narc.conf
     #
     # Set up to load iptables.
     
     base=${0/}
     link=${base[SK][0-9][0-9]}
     test $link = $base && START_IPTABLES=yes
     test "$START_IPTABLES" = "yes" || exit 0
     rc_done="  done"
     rc_failed="  failed"
     return=$rc_done
     #
     # Based on which operation we were asked to perform, have at it.
     #
     case "$1" in
         start)
             echo -n "Starting iptables"
             $NARC start $2 $3 || return=$rc_failed
             echo -e "$return"
             ;;
         stop)
             echo -n "Stopping iptables"
             $NARC stop || return=$rc_failed
             echo -e "$return"
             ;;
         restart|reload)
             $0 stop && $0 start $2 $3 || return=$rc_failed
             ;;
         status)
            $NARC status && echo OK || echo No process
             ;;
         *)
             echo "Usage: $0 {start|stop|restart|status}"
             exit 1
     esac
     test "$return" = "$rc_done" || exit 1
     exit 0

/usr/sbin/narc:

If you took our advice and modified the iptables script so as to pass an external interface name and IP address as the second and third parameters, you'll need to add some lines (around line 104) that read:

     # See if there is an interface specified on the command line.  If so, use it
     # instead.
     if test x"$2" != x; then
             EXTERNAL_INTERFACE=$2
     fi
     # See if there is an IP address for a static route specified on the command
     # line.  If so, use it instead.
     if test x"$3" != x; then
             DYNAMIC_EXTERNAL_IP="no"
             EXTERNAL_INTERFACE_IP=$3
     fi

Actually, this change is harmless. If no interface or no ip address parameter(s) are passed, nothing happens. Therefore, it is safe to make it under all circumstances.

You might need to change the command that calls ifconfig to include the path of your ifconfig (e.g. /sbin/ifconfig), if this script fails to work properly. After line 8, add a variable that defines the path to ifconfig:

     IFCONFIG="/sbin/ifconfig"
     At approximately line 193, change:
     EXTERNAL_INTERFACE_IP=`ifconfig $EXTERNAL_INTERFACE | grep inet \
       | cut -d : -f 2 |cut -d " " -f 1`

to

     EXTERNAL_INTERFACE_IP=`$IFCONFIG $EXTERNAL_INTERFACE | grep inet \
       | cut -d : -f 2 |cut -d " " -f 1`

If you wish to include shell variables in the custom configuration, you'll need to change the lines around 1179 from:

     grep -v "^ *#" $CUSTOM_SCRIPT | \
         ( while read line ; do
             if [ "$line" != '' ] ; then
                 $line && $ECHO "$BOLD$line$DEF - $RCOK" \
                     || $ECHO "$BOLD$line$DEF - $RCFAIL"
             fi
         done )
     $ECHO "Finished executing custom commands"

to

     grep -v "^ *#" $CUSTOM_SCRIPT | \
         ( while read line ; do
          linesub=`eval echo $line`
          if [ "$linesub" != '' ] ; then
              $linesub && $ECHO "$BOLD$linesub$DEF - $RCOK" \
                  || $ECHO "$BOLD$linesub$DEF - $RCFAIL"
          fi
      done )

$ECHO "Finished executing custom commands"

/etc/narc/narc.conf:

Hack the narc.conf file as described in the config file itself.

If you'll be starting NARC at boot time, in conjunction with diald, to enable masquerading and thereby allow locally-networked nodes to bring up the link, you should change:

     START_IPTABLES="no"
to
     START_IPTABLES="yes"

If you don't do this, NARC will not start at boot time, although it will say that it did in the log file.

Also, change:

     EXTERNAL_INTERFACE="eth0"               # Example: "eth0"
to
     EXTERNAL_INTERFACE="sl0"                # Slip must be masqueraded for
                                             # diald to work

Otherwise, if you are using some other dynamic firewall arrangement, set:

     EXTERNAL_INTERFACE=""                   # Use what we are passed.

This will allow the PPP up and down scripts to pass the interface name to NARC so that the firewall rules can be applied both when the PPP link is up and when it is down. You can also make this change, if you are using PPPoE over a DSL modem or a cable modem.

While you're at it, make sure to set the following:

     DYNAMIC_EXTERNAL_IP="yes"               # If this is set to "no", you'll need
                                             # to enter an IP address below
     EXTERNAL_INTERFACE_IP=""                # If DYNAMIC_EXTERNAL_IP is "yes",
                                             # NARC will attempt to auto-obtain
                                             # this

If you are making your WAN connection through an external router, this will allow you to pass the interface name and IP address to NARC from the startup script, if it is configured this.

Here is a sample of the NARC config file with no EXTERNAL_INTERFACE set and DYNAMIC_EXTERNAL_IP set to "yes", so that it can be modified by an ip-up script (which would be a typical DSL with PPPoE setup):

     #
     # NARC - Netfilter Automatic Rules Configurator v0.6.3
     #
     # Copyright (c) 2001, Shane Chen (shane@knowplace.org).  See the LICENSE
     # file for the (BSD) license.
     #
     CONF_VERSION=0.6.3    # DO NOT edit this line.
     EDITED="yes"                            # Edit the options below and change
                                             # this option to 'yes' once you're
                                             # satisfied with the changes
     #
     # Config options
     #
     # Start Iptables at boot up?
     START_IPTABLES="no"
     USE_COLOR="yes"                         # When possible
     # Path to the executables
     NARC="/usr/sbin/narc"                   # Location of the narc bash script
                                             # - edit this if the path is
                                             #   incorrect
     IPTABLES="/sbin/iptables"               # Make sure the path is correct!
     ECHO="/bin/echo"                        # Make sure the path is correct!
     # Load Netfilter modules - only necessary if you compiled netfilter as
     # modules
     LOAD_MODULES="yes"
     # Network parameters.
     #
     # If you're using PPPoE to connect through an ethernet card and then a DSL
     # modem, you should specify the PPP interface (e.g. ppp0) instead of the
     # ethernet interface, since the packet traffic gets routed through the PPP
     # interface (its all done with mirrors).
     #
     # But, note that, if you're using a startup script (e.g. /etc/ppp/if-up or
     # /etc/ppp/if-up.local) that starts NARC when the interface is brought up,
     # and this script passes the external interface to NARC, you should set
     # EXTERNAL_INTERFACE to "".  This will prevent NARC from starting, except
     # when it is invoked from the if-up script and passed the interface
     # information.
     #
     # Also, if your startup script can start either a dynamic external interface
     # (e.g. ppp0) or a static interface (e.g. eth0), depending on the state of
     # the network, and it will pass NARC the IP address to use on the static
     # interface, you should set DYNAMIC_EXTERNAL_IP to "yes" and then leave
     # EXTERNAL_INTERFACE_IP set to "".
     EXTERNAL_INTERFACE=""                   # Example: "eth0"
     DYNAMIC_EXTERNAL_IP="yes"               # If this is set to "no", you'll need
                                             # to enter an IP address below
     EXTERNAL_INTERFACE_IP=""                # If DYNAMIC_EXTERNAL_IP is "yes",
                                             # NARC will attempt to auto-obtain
                                             # this
     # The options immediately below control server services that you're offering
     # to the outside world - they do not limit the services available to your
     # localhost.
     #
     # Use comma separated names or numeric values from /etc/services.  If the
     # port is > 1024, use the numeric value instead of the name.
     #
     # Note: limited to 15 services - you shouldn't need more than 15 ports open,
     # especially on a firewall.
     ALLOW_TCP_EXT="ntp"                     # Example "ssh,smtp,http" - note the
                                             # lack of spaces
     ALLOW_UDP_EXT="ntp"                     # Example "domain,ntp" - note the
                                             # lack of spaces
     CHECK_SYN_PACKET_LENGTH="yes"           # Do not disable unless you must use
                                             # a stock kernel that does not
                                             # support length checking
     # The options immediately below here are similar to above, except that they
     # allows you to enter port ranges (and single ports) using space separated
     # numeric values. Enter as many as necessary (i.e. not limited to 15
     # entries).  Unless needed, use the above instead.
     #
     # The ports 8180, 8280 and 8380 are used by Apache to provide mirrors for
     # external Web sites.
     ALLOW_TCP_EXT_RANGE="8180 8280 8380"    # Example "6000:6010 6660:6669 3128"
     ALLOW_UDP_EXT_RANGE=""                  # Example "6000:6010 6660:6669 3128"
     # Note: If you simply wanted to firewall a single host, you can ~safely skip
     # the rest of the config options below.
     # MASQuerading section - This is the Linux equivalent of "Internet Connection
     # Sharing".  Don't turn on ALWAYS_FORWARD unless you know what you're doing.
     # ALWAYS_FORWARD will keep forwarding (and masq'ing) traffic even when there
     # are no firewall rules loaded.
     MASQUERADE="yes"                        # Turning this on will enable IP
                                             # forwarding automatically
     LAN_INTERFACE="eth0"                    # Example: "eth1"
     ALWAYS_FORWARD="no"                     # Don't turn this on unless you want
                                             # to forward traffic even when not
                                             # firewalling.
     PROTECT_FROM_LAN="no"                   # "yes" or "no" - Protect firewall
                                             # from internal network
     # The options immediately below control server services that you're offering
     # to your internal LAN - they do not limit the services available to your
     # localhost.  These are only needed if "PROTECT_FROM_LAN" is set to "yes",
     # above.
     #
     # Use comma separated names or numeric values from /etc/services.  If the
     # port is > 1024, use the numeric value instead of the name.
     #
     # Note: limited to 15 services - you shouldn't need more than 15 ports open,
     # especially on a firewall.
     #AL1="ftp,telnet,http,smtp,pop3,ntp"
     #AL2="netbios-ns,netbios-dgm,netbios-ssn"
     #ALLOW_TCP_LAN=${AL1}","${AL2}          # Example "ssh,smtp,http" - note the
                                             # lack of spaces
     #ALLOW_UDP_LAN=""                       # Example "domain,ntp" - note the
                                             # lack of spaces
     # The options immediately below here are similar to above, except that they
     # allows you to enter port ranges (and single ports) using space separated
     # numeric values. Enter as many as necessary (i.e. not limited to 15
     # entries).  Unless needed, use the above instead.
     #ALLOW_TCP_LAN_RANGE=""                 # Example "6000:6010 6660:6669 3128"
     #ALLOW_UDP_LAN_RANGE=""                 # Example "6000:6010 6660:6669 3128"
     # PortForwarding section - Requires masquerading and forwarding.
     PORT_FORWARD="no"                       # This will not have any effect
                                             # unless MASQUERADE is enabled
     DMZ_INTERFACE=""                        # DMZ interface (technically, you can
                                             # use your LAN interface as well -
                                             # bad security practice)
     PROTECT_FROM_DMZ=""                     # "yes" or "no" -  Protect firewall
                                             # from DMZ network
     FORWARD_LAN_TO_DMZ="no"                 # Forward traffic from LAN to DMZ
     FORWARD_CONF="/etc/narc/narc-forward.conf"
                                             # Edit this file for port forwarding
     # The options immediately below control server services that you're offering
     # to your DMZ network - they do not limit the services available to your
     # localhost.
     #
     # Use comma separated names or numeric values from /etc/services.  If the
     # port is > 1024, use the numeric value instead of the name.
     #
     # Note: limited to 15 services - you shouldn't need more than 15 ports open,
     # especially on a firewall.
     ALLOW_TCP_DMZ=""                        # Example "ssh,smtp,http" - note the
                                             # lack of spaces
     ALLOW_UDP_DMZ=""                        # Example "domain,ntp" - note the
                                             # lack of spaces
     # The options immediately below here are similar to above, except that they
     # allows you to enter port ranges (and single ports) using space separated
     # numeric values. Enter as many as necessary (i.e. not limited to 15
     # entries). Unless needed, use the above instead.
     ALLOW_TCP_DMZ_RANGE=""                  # Example "6000:6010 6660:6669 3128"
     ALLOW_UDP_DMZ_RANGE=""                  # Example "6000:6010 6660:6669 3128"
     # To enable traceroute from MS Windows to your firewall, enable ANSWER_PING.
     # To enable traceroute from UNIX hosts, turn enable ANSWER_TRACEROUTE.  Use
     # of either option is discouraged.
     ANSWER_PING="yes"
     PING_RATE="1/s"                         # Leave this alone unless you happen
                                             # to like flood pings
     ANSWER_TRACEROUTE="yes"
     # Auth port responds with reject instead of drop
     AUTH_REJECT="yes"                       # Disable this if you're running
                                             # identd or using IRC
     # Drop broadcasts
     DROP_BROADCASTS="yes"
     BROADCAST_NETWORKS="0.0.0.0/8 255.255.255.255 224.0.0.0/4"
     # Logging options.
     #
     # Logs to "kern.debug".  You must add "kern.=debug -/var/log/firewall.log" to
     # /etc/syslog.conf to actually write log entries to the firewall log file.
     LOG_DROPS="yes"                         # If this is turned off, the rest of
                                             # the log options have no effect.
     NORM_LOG_LEVEL="debug"                  # Log everything to "kern.debug"
     WARN_LOG_LEVEL="debug"                  # Change to "warning" if you want
                                             # more urgent logging to show up in
                                             # /var/log/warn
     LOG_PROBES="yes"                        # Uses the TCP/UDP_PROBE (below) to
                                             # monitor certain ports
     LOG_ILLEGAL="yes"                       # Logs packets defined by
                                             # ILLEGAL_TCP_FLAGS in the advanced
                                             # section below.
     LOG_INVALID="yes"                       # Logs packets that do not belong to
                                             # a valid connection
     LOG_SPOOF="no"                          # Logs packets defined by the
                                             # anti-spoof options in the advanced
                                             # section below.
     LOG_ICMP="no"                           # Logs packets not accepted by
                                             # ALLOW_ICMP_MESSAGE (below)
     LOG_PACKET_LENGTH="yes"                 # Logs TCP SYN packets that have bad
                                             # header length (PACKET_LENGTH)
     LOG_LIMIT_EXCEED="yes"                  # Logs TCP connections that exceed
                                             # LIMIT_RATE
     LOG_IPLIMIT_EXCEED="yes"                # Logs TCP connections that exceed
                                             # IPLIMIT_MAX_ACCEPT
     LOG_ALL_ELSE="yes"                      # This logs everything that we didn't
                                             # explicitly match (recommeded)
     BURST_MAX="5"                           # default is 5
     LOG_RATE="1/s"                          # not impl (may not be a good idea)
     # Probable probes - Note: Add or remove entries as necessary but do not
     # exceed 15 ports per line!  Use comma separated values with no spaces (common
     # trojans - see http://www.simovits.com/sve/nyhetsarkiv/1999/nyheter9902.html).
     TCP_PROBE="113,135,137,138,139,161,445,515,524,555,666,1000,1001,1025,1026"
     TCP_PROBE2="1234,1243,1433,2000,2001,6346,8080"
     UDP_PROBE="22,135,137,138,139,161,445,1025,1026,1081,1082,1083,1085,1089,1093"
     UDP_PROBE2="1095,1096,1433,2000,2001"
     # Advanced options below - DO NOT edit unless you know what you are doing
     # Executes a custom script
     EXECUTE_CUSTOM_SCRIPT="yes"             # Default is "no"
     CUSTOM_SCRIPT="/etc/narc/narc-custom.conf"
     PRELOAD_IP_MODULES="ip_tables ip_conntrack ip_conntrack_ftp"
     NAT_MODULES="iptable_nat ip_nat_ftp"
     # Illegal TCP flag combinations
     IF1="SYN,FIN PSH,FIN SYN,ACK,FIN SYN,FIN,PSH SYN,FIN,RST"
     IF1="SYN,FIN,RST,PSH SYN,FIN,ACK,RST SYN,ACK,FIN,RST,PSH ALL"
     ILLEGAL_TCP_FLAGS=${IF1}" "${IF2}
     FINSCAN="FIN"
     XMASSCAN="URG,PSH,FIN"
     NULLSCAN="NONE"
     # SYN packet length (range in bytes)
     PACKET_LENGTH="40:68"
     # General rate limit
     ENABLE_LIMIT_RATE="no"
     LIMIT_RATE="30/s"
     LIMIT_BURST="50"
     # IP based TCP rate limit (requires CONFIG_IP_NF_MATCH_IPLIMIT/iplimit patch)
     ENABLE_IPLIMIT="no"                     # You better know what you're doing
                                             # - change the values below.
     IPLIMIT_MAX_ACCEPT="16"                 # accept only UP TO this many
                                             # connections per the netmask below.
     IPLIMIT_NETMASK="24"                    # netmask value
     # Drop "unclean" packets, packet sanity checking (EXPERIMENTAL - don't use
     # this)
     DROP_UNCLEAN_PACKETS="no"
     # Allowable ICMP messages -
     # see http://www.iana.org/assignments/icmp-parameters
     # Note: will accept numeric or name value - 'iptables -p icmp -h' to list
     AI1="echo-reply network-unreachable host-unreachable"
     AI2="port-unreachable fragmentation-needed time-exceeded"
     ALLOW_ICMP_MESSAGE=${AI1}" "${AI2}
     # Anti-spoofing options
     # see http://www.sans.org/dosstep/cisco_spoof.htm
     # and http://www.isi.edu/in-notes/rfc1918.txt
     #
     # 0.0.0.0/8                 - Broadcast (old)
     # 255.255.255.255(/32)      - Broadcast (all)
     # 127.0.0.0/8               - Loopback
     # 224.0.0.0/4               - Multicast
     # 240.0.0.0/5               - Class E reserved
     # 248.0.0.0/5               - Unallocated
     # 192.0.2.0/24              - NET-TEST (reserved)
     # 169.254.0.0/16            - LinkLocal (reserved)
     # 10.0.0.0/8                - Class A (private use)
     # 172.16.0.0/12             - Class B (private use)
     # 192.168.0.0/16            - Class C (private use)
     RESERVED_NETWORKS="127.0.0.0/8 240.0.0.0/5 248.0.0.0/5"
     PRIVATE_NETWORKS=" 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16"
     # Accept traffic to loopback
     LOOPBACK_ACCEPT="yes"
     LOOPBACK_MODE="normal"                  # values are paranoid|normal|loose.
     # Self-referenced firewall DNS workaround - leave this alone; if you're
     # having DNS problems on the firewall itself, but not from behind it, this
     # should probably make sense to you.  Otherwise, leave this blank.
     #
     # Use space separated dotted quad IP addresses if you need more than one.
     BIND_IP=""
     #
     # Kernel options - do not change unless you're sure what you're doing
     #
     SYNCOOKIES="no"
     ANTI_SMURF="yes"
     ACCEPT_SOURCE_ROUTE="no"
     # Ingress filtering: 1 for simple, 2 to comply with RFC1812 section 5.3.8.
     # See http://andrew2.andrew.cmu.edu/rfc/rfc1812.html
     INGRESS_FILTER="2"
     LOG_MARTIANS="yes"
     # TCP congestion notification - depreciated
     ENABLE_TCP_ECN="no"

/etc/narc/narc-custom.conf:

The narc-custom.conf file is executed by NARC at the end of firewall startup. You can add the following lines to this file to allow all packets from lo to be accepted. This is probably OK, since lo is one of the good guys. Changes are also shown to prevent the TiVos from calling home, and to quiet Samba down.

     # Allow all traffic from lo, not just that from 127.0.0.1
     $IPTABLES -R INPUT 4 -i lo -j ACCEPT
     #
     # Special rules for local TiVo digital recorders.  If the TiVo tries to send
     # anything to the outside world, don't let it.  Its probably calling home
     # for a new version of the software that will not make us happy.  If it
     # can't download the software, maybe it can't mess us around.
     #
     # Note that the rejected packets are logged with a prefix of TIVO.
     #
     $IPTABLES -N TIVO_REJECT
     $IPTABLES -A TIVO_REJECT -j LOG --log-level $NORM_LOG_LEVEL \
               --log-prefix \"TIVO \" --log-ip-options --log-tcp-options
     $IPTABLES -A TIVO_REJECT -j REJECT
     # Reject each of the known TiVo machines.
     $IPTABLES -I FORWARD -s tivo4.homeworld -o $EXTERNAL_INTERFACE -j TIVO_REJECT
     $IPTABLES -I FORWARD -s tivo3.homeworld -o $EXTERNAL_INTERFACE -j TIVO_REJECT
     $IPTABLES -I FORWARD -s tivo2.homeworld -o $EXTERNAL_INTERFACE -j TIVO_REJECT
     $IPTABLES -I FORWARD -s tivo1.homeworld -o $EXTERNAL_INTERFACE -j TIVO_REJECT
     #
     # If you are running Samba on this machine, it can generate a lot of
     # packets bound for the external interface (i.e. three every 30 seconds)
     # that will be rejected and logged.  These packets are employed in its
     # feeble attempt to discover any other Mickeysoft networks in the outside
     # world.  Needless to say, we don't care about filling our log up with
     # this incessant drivel.
     #
     # The following two rules should ditch this junk nicely.  Basically, we
     # were going to toss any packets that made it this far anyway.  We just
     # check to see if the protocol is either IGMP or Mickeysoft's network
     # discovery protocol and if it is, we reject the packet silently.  If
     # you don't care about keeping your log clean or don't use Samba, you can
     # safely comment out these two rules.
     #
     $IPTABLES -I OUTPUT -p pim -o $EXTERNAL_INTERFACE -j DROP
     $IPTABLES -I OUTPUT -p igmp -o $EXTERNAL_INTERFACE -j DROP

/etc/syslog.conf:

Add the following lines to the syslog configuration to cause the packet filter messages to be logged to their own file:

     # Log packet filter (firewall) messages to a special file.
     kern.=debug                                             -/var/log/firewall

/etc/logrotate.d/narc:

Add the file named above and include the following lines in it (or hack the /etc/logrotate.conf file itself):

     /var/log/firewall
         missingok
         notifempty
     }

If you need to customize the firewall rules, you can add individual rules to the /etc/narc/narc-custom.conf file. Therein, you simply add calls to iptables to create the rules that you want. If you go down this path, you may find this description of the Netfilter architecture useful:

     http://www.netfilter.org/documentation/HOWTO//netfilter-hacking-HOWTO-3.html

Knowing how packets are routed by the kernel may provide you with insight about where you want to filter or alter them so that they can be dropped, rerouted or marked as you wish.