Firewall/Packetfilter (ipchains)

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

/etc/rc.d/init.d/packetfilter:

Turns packet filtering on/off, using ipchains.

Will reload saved rules from /etc/ipchains.rules or run /etc/rc.d/init.d/firewall-rules, if it exists.

     "start" - Looks for firewall-rules and runs it or, if not found, restores
               previously-stored ipchains rulesets.
     "stop"  - Saves ipchains rules (just in case) and shuts down ipchains.

You must create the packetfilter script, a sample of which, is shown below:

     #! /bin/sh
     # Script to start/stop packet filtering.
     #
     # If there is a set of firewall rules in "/etc/rc.d/init.d/firewall-rules"
     # then this shell script is invoked.  Otherwise, any saved rules that are
     # found in "/etc/ipchains.rules" are reinstated.
     #
     #
     # Set the name of the external network interface here.  If you are using
     # "diald", this should be "sl0".  For PPP, use "ppp0".  For a DSL line or
     # cable modem, use the ethernet card that they are connected to.  Usually
     # this will be "eth1" but for PPPoE it will be "ppp0".
     extint="sl0"
     #
     # If there are no firewall rules and no store ipchains rules, do nothing.
     #
     [ -f /etc/rc.d/init.d/firewall-rules ] || [ -f /etc/ipchains.rules ] \
       || exit 0
     case "$1" in
         #
         # Upon startup, invoke the firewall rules or reinstate the ipchains
         # rules.
         #
         start)
          if [ -f /etc/rc.d/init.d/firewall-rules ]; then
              echo -n "Turning on the firewall:"
              /etc/rc.d/init.d/firewall-rules $extint start
          else
              echo -n "Turning on packet filtering and masquerading:"
              /sbin/ipchains-restore < /etc/ipchains.rules || exit 1
              echo 1 > /proc/sys/net/ipv4/ip_forward
          fi
             touch /var/lock/subsys/packetfilter
          echo "."
          ;;
         #
         # Upon shutdown, save the ipchains rules, then, turn of packet
         # filtering.
         #
         stop)
          echo -n "Turning off firewalling, packet filtering and masquerading:"
          echo 0 > /proc/sys/net/ipv4/ip_forward
          /sbin/ipchains-save >/etc/ipchains.rules
          /sbin/ipchains -X
          /sbin/ipchains -F
          /sbin/ipchains -P input ACCEPT
          /sbin/ipchains -P output ACCEPT
          /sbin/ipchains -P forward ACCEPT
             rm -f /var/lock/subsys/packetfilter
          echo "."
          ;;
         #
         # For all other cases, give help.
         #
         *)
          echo "Usage: /etc/rc.d/init.d/packetfilter {start|stop}"
          exit 1
          ;;
     esac
     exit 0

/etc/ipchains.rules:

File where previously existing ipchains rulesets are stored upon system shutdown.

/sbin/ipchains-save >/etc/ipchains.rules

Will save the current ipchains rulesets in /etc/ipchains.rules. This is done automatically at system shutdown by the packet filter.

/etc/rc.d/init.d/firewall-rules:

Setup rules for the firewall. Define which packets are to be filtered, how packets are to be routed, etc.

     "start"    - Perform a normal startup of packet filtering.
     "register" - Used to reregister the filtering rulesets when the IP address
                  of any of the links to the outside world is changed (e.g. when
                  diald brings up a PPP connection).

A sample of the firewall-rules script is shown below:

     #!/bin/sh
     #
     # /etc/rc.d/init.d/firewall-rules: Semi-Strong IPCHAINS firewall ruleset.
     #
     # This script takes two arguments.  The first is the name of the device that
     # connects to the Internet (e.g. ppp0, eth1, etc.).  The second is a
     # parameter that indicates whether we are initially starting the firewall or
     # just reregistering it because the link to the outside world changed (e.g.
     # in the case of diald bringing up the link).  By setting this parameter to
     # anything other than "start", the overhead of loading the masquerade modules
     # and creating the firewall chain can be avoided when the new link is simply
     # being registered.
     #
     # Note that the file /etc/rc.d/init.d/firewall-off may be defined to cause
     # this script to set up masquerade but leave the rest of the firewall off.
     # This may be useful for debugging.
     #
     PATH=/sbin:/bin:/usr/sbin:/usr/bin
     #
     # Specify your Static IP address here.
     #
     # If you have a DYNAMIC IP address, you need to tell this script about your
     # IP address everytime you get a new one.  To do this, enable the following
     # line which sets "extip" from the ifconfig results of querying the PPP link.
     # (Please note that the different single and double quote characters MATTER).
     #
     #
     # DHCP users:
     # -----------
     #
     # If you get your TCP/IP address via DHCP, you will need to enable the
     # comented out command in the PPP/DHCP section AND replace the word "ppp0"
     # with the name of your EXTERNAL Internet connection (eth0, eth1, etc.) on
     # the lines for "ppp-ip" and "extip".  It should be also noted that the DHCP
     # server can change IP addresses on you.  To fix this, users should configure
     # their DHCP client to re-run the firewall ruleset everytime the DHCP lease
     # is renewed.
     #
     # NOTE #1: Some newer DHCP clients like "pump" do NOT have this ability to
     # run scripts after a lease-renew.  Because of this, you need to replace them
     # with something like "dhcpcd" or "dhclient".
     #
     # NOTE #2: The syntax for "dhcpcd" has changed in recent versions.
     #
     # Older versions used syntax like:
     #
     #      dhcpcd -c /etc/rc.d/init.d/firewall-rules eth0
     #
     # Newer versions use syntax like:
     #
     #      dhcpcd eth0 /etc/rc.d/init.d/firewall-rules
     #
     #
     # PPP users:
     # ----------
     #
     # If you aren't already aware, the "/etc/ppp/ip-up script" is always run when
     # a PPP connection comes up.  Because of this, we can have "ip-up" invoke the
     # firewall ruleset script with the new PPP IP address and thereby update
     # the strong firewall ruleset.
     #
     # If the /etc/ppp/ip-up file already exists, you should edit it and add a
     # line containing "/etc/rc.d/init.d/firewall-rules $1 register" near the end
     # of the file.
     #
     # If you don't already have a /etc/ppp/ip-up sccript, you need to create one
     # that invokes "/etc/rc.d/init.d/firewall-rules $1 register".
     #
     # If you use "diald", you need to create an "addroute" script that will be
     # invoked whenever the PPP link is brought up or taken down.  In the
     # "addroute" script, use:
     #
     #      /etc/rc.d/init.d/firewall-rules $1 register
     #
     # At initialization time, the rules should be set up using "sl0".  This will
     # cause masquerade to aim outbound packets at "sl0" which will cause "diald"
     # to dial up the link.  Once PPP is up and running, the "addroute" script
     # will change masquerade to point to the active link on  "ppp0".  When the
     # link is dropped, the "addroute" script will again be invoked to change
     # masquerade so that it points back at "sl0", thereby restoring the initial
     # configuration that waits for more outbound packets.
     #
     #
     # PPP and DHCP Users:
     # -------------------
     #
      Remove the '' on the shell line below and place a '#' in front of the
     # shell line after that, unless you have a static IP address.
     #
     extip="`/sbin/ifconfig $1 | grep 'inet addr' | awk '{print $2}' \
       | sed -e 's/.*://'`"
     #
     #
     # Users with STATIC IP addresses:
     # -------------------------------
     #
     # For PPP with a static IP address or for any other Internet connection that
      uses a static IP address (e.g. DSL or cable modem on eth1), place a '' in
      front of the shell line above and remove the '' from the shell line below.
     # Also, fill in your correct static IP address.
     #
     # extip="your.static.PPP.address"
     #
     # Set the correct internal network information below.  Usually this is the
     # device "eth0" and the network defined by "192.168.1.0" (if you've been
     # following all of the examples).  The "24" indicates that the network
     # addresses have the top 24 bits on in their netmask (i.e. 255.255.255.0).
     #
     intint="eth0"
     intnet="192.168.1.0/24"
     #
     # Perform startup processing, if this is the first time.
     #
     case "$2" in
         #
         # Upon startup, load all required IP MASQ modules.  Any other time, the
         # modules will still be loaded so there's no need to redo this.
         #
         # NOTE: Only load the IP MASQ modules you need.  Most current IP MASQ
         #       modules are shown below but are commented out to prevent loading.
         #
         # Set up the firewall rules once.  They will get reused from that point
         # on so that repeating the set up is superfluous.
         #
         start)
           #
           # Needed to initially load modules
           #
           depmod -a
           #
           # Supports the proper masquerading of FTP file transfers using the
           # PORT method
           #
           modprobe ip_masq_ftp
           #
           # Supports the masquerading of RealAudio over UDP.  Without this
           # module, RealAudio WILL function but in TCP mode.  This can cause a
           # reduction in sound quality
           #
           modprobe ip_masq_raudio
           #
           # Supports the masquerading of IRC DCC file transfers
           #
           #modprobe ip_masq_irc
           #
           # Supports the masquerading of the CuSeeme video conferencing software
           #
           #modprobe ip_masq_cuseeme
           #
           # Supports the masquerading of the VDO-live video conferencing software
           #
           #modprobe ip_masq_vdolive
           #
           # Set up the firewall chain to filter inbound packets.  Only packets
           # coming off of the external interface to the world are passed to this
           # chain so there's no need to check the interface or addresses.  All
           # that we check are port numbers.  Our aim is to only let through the
           # good stuff and reject all of the dangerous stuff.
           #
           ipchains -N fw-chain
           #
           # Start by letting responses to any of the previously masqueraded
           # packets through.
           #
           ipchains -A fw-chain -p TCP --dport 61000:65096 -j ACCEPT
           ipchains -A fw-chain -p UDP --dport 61000:65096 -j ACCEPT
           #
           # Also, let through packets bound for ports in the dynamic port
           # assignment range.  Any programs that are running on this machine
           # which send packet traffic out to the world will do so from ports
           # in this range (e.g. if you run the Netscape browser on this
           # machine).  In order for such programs to receive responses from
           # the Internet we must let the responses back in to the dynamic
           # ports that they are using.  This is akin to letting the masquerade
           # responses back in (above) but for programs on this machine instead
           # of for those on the local net.
           #
           # Make sure that you do not run any services that listen on these
           # ports.  Look at /etc/services and see which services use port
           # numbers > 1023.  Disable these services, either by editing the
           # startup files in /etc/rc.d or editing /etc/inetd.conf (for those
           # services run by inetd.  If you wish to be really paranoid and
           # don't care about running stuff from this machine (i.e. its only
           # being used for routing), comment out these lines.
           #
           # Note that you can check the ports that your system will use in the
           # dynamic port assignment range by executing the following command:
           #
           #      cat /proc/sys/net/ipv4/ip_local_port_range
           #
           ipchains -A fw-chain -p TCP --dport 1024:4999 -j ACCEPT
           ipchains -A fw-chain -p UDP --dport 1024:4999 -j ACCEPT
           #
           # Let inbound DNS requests pass.  This is perfectly safe because
           # DNS is pretty well behaved.
           #
           ipchains -A fw-chain -p TCP --dport 53 -j ACCEPT
           ipchains -A fw-chain -p UDP --dport 53 -j ACCEPT
           #
           # Let returning DNS querries pass.  Note that if you didn't comment
           # out the lines above that pass packets to ports 1024-4999, you
           # needn't do anything here.
           #
           # You can uncomment the two lines below that accept general network
           # traffic from source port 53 (DNS).  This will certainly allow DNS
           # to work.  However, allowing traffic from a particular source port
           # is dangerous, since a spoofer can claim to be anything they want.
           # It is much safer to only allow traffic to a particular destination
           # port on our machine (we know what's there and what it will do with
           # the inbound packets).
           #
           # My DNS always makes requests to the outside world from port 1024.
           # I allow packets through bound for port 1024.  You can do the same,
           # if you figure out which port your DNS is requesting on.  Look in
           # /var/log/messages for the rejected packets coming from port 53.
           # The port that they are bound to is the one your DNS is listening
           # on.
           #
     #     ipchains -A fw-chain -p TCP --sport 53 -j ACCEPT
     #     ipchains -A fw-chain -p UDP --sport 53 -j ACCEPT
     #     ipchains -A fw-chain -p TCP --dport 1024 -j ACCEPT
     #     ipchains -A fw-chain -p UDP --dport 1024 -j ACCEPT
           #
           # Allow access to the Web server.  Depending on the holes in Apache,
           # this could be dangerous.
           #
     #     ipchains -A fw-chain -p TCP --dport 80 -j ACCEPT
           ipchains -A fw-chain -p TCP --dport 8180 -j ACCEPT
           ipchains -A fw-chain -p TCP --dport 8280 -j ACCEPT
           ipchains -A fw-chain -p TCP --dport 8380 -j ACCEPT
           #
           # Let inbound NTP requests pass.  This is perfectly safe because
           # NTP is pretty well behaved.
           #
           ipchains -A fw-chain -p TCP --dport 123 -j ACCEPT
           #
           # Accept ping and responses to ping.
           #
           ipchains -A fw-chain -p icmp --icmp-type ping -j ACCEPT
           ipchains -A fw-chain -p icmp --icmp-type pong -j ACCEPT
           #
           # Packets which are one of the error ICMPs get accepted so that we can
           # see network errors being reported to us.
           #
           ipchains -A fw-chain -p icmp --icmp-type destination-unreachable \
             -j ACCEPT
           ipchains -A fw-chain -p icmp --icmp-type source-quench -j ACCEPT
           ipchains -A fw-chain -p icmp --icmp-type time-exceeded -j ACCEPT
           ipchains -A fw-chain -p icmp --icmp-type parameter-problem -j ACCEPT
           #
           # All other packets will reach the end of the chain.  Since it is a
           # user defined chain, it will return to the input chain from whence
           # it was called.  The input chain will deny and log the packets.
           #
           # By arranging the chain this way, we can dynamically add rules to
           # the end of the chain, where they can accept additional packets.
           # This allows us to determine which packets to accept on the fly.
           #
           ;;
         #
         # For all other cases, just fall through to the setting of IPCHAINS.
         #
         *)
           ;;
     esac
     #
     # It is CRITICAL that we enable IP forwarding since it is disabled by default
     #
     # Redhat users should also change the options in
     # /etc/sysconfig/network from:
     #
     #     FORWARD_IPV4=false to FORWARD_IPV4=true
     #
     echo "1" > /proc/sys/net/ipv4/ip_forward
     #
     # Set the masquerade timeouts:
     #
     #      2 hrs.    - for TCP session timeouts
     #      10 secs.  - for traffic after the TCP/IP "FIN" packet is received
     #      60 secs.  - for UDP traffic (masqueraded ICQ users must enable a
     #                  30 sec. firewall timeout in ICQ itself)
     #
     ipchains -M -S 7200 10 60
     #
     #                                RULE SETS
     #
     #############################################################################
     #
     # If the firewall is off, for incoming, flush and set the default policy of
     # accept.
     #
     if [ -f /etc/rc.d/init.d/firewall-off ]; then
         ipchains -F input
         ipchains -P input ACCEPT
     #
     # For incoming, flush and set the default policy of reject.  Actually the
     # default policy is irrelevant because there is a catch all rule at the end
     # of the chain which will reject and log all rejected packets.  However, the
     # default reject policy will prevent any packets from slipping through the
     # cracks while we are setting up the other rules.
     #
     else
         ipchains -F input
         ipchains -P input REJECT
         #
         # Any packets received from the fast Internet interface bound for local
         # addresses or with addresses that claim to be a local (i.e. IP
         # spoofing) can get lost.
         #
         # Note that you can comment out the following two lines to test the
         # fast Internet interface on the regular internal network to ensure
         # that it works prior to hooking it up to the Cable/DSL modem.
         #
         ipchains -A input -i $inetint -s 0.0.0.0/0 -d $intnet -l -j REJECT
         ipchains -A input -i $inetint -s $intnet -d 0.0.0.0/0 -l -j REJECT
         #
         # Any other packets from any source on the fast Internet interface bound
         # to any other destination are allowed.  The Internet is wide open
         # baby.  Let 'er rip!
         #
         # Actually, you should only use this rule for PPPoE.  In that case,
         # the inbound packets will get filtered by the rule for the PPP
         # interface.  If you aren't using PPPoE remove this rule and uncomment
         # the appropriate fw-chain rule (below).
         #
         ipchains -A input -i $inetint -s 0.0.0.0/0 -d 0.0.0.0/0 -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 fuck us.  If
         # it can't download the software, maybe it can't screw us.
         #
         ipchains -A input -i $intint -s 192.168.1.62 -d $intnet -j ACCEPT
         ipchains -A input -i $intint -s 192.168.1.62 -d 0.0.0.0/0 -j REJECT
         #
         # Any packets received on the local network interface, with local
         # addresses, going anywhere are allowed.
         #
         ipchains -A input -i $intint -s $intnet -d 0.0.0.0/0 -j ACCEPT
         #
         # Any packets received from the remote interface with addresses that
         # claim to be a local (i.e. IP spoofing) can get lost.
         #
         ipchains -A input -i $1 -s $intnet -d 0.0.0.0/0 -l -j REJECT
         #
         # Packets received from the loopback interface are always valid.
         #
         ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT
         #
         # Any packets received from the remote interface, with any source, that
         # are addressed to our externally visible IP address are generally valid
         # (that's how we receive incomming packets).  However, in the interest
         # of having a strong firewall, we will pass all of the inbound packets
         # through the firewall chain to apply the specific firewalling rules.
         #
         # This rule should appear second last, just before the catch all rule.
         # Any packets that are not specifically allowed by the firewall chain
         # will fall off the end of the chain and arrive at the catch all rule
         # when the return from falling of the end.  The catch all rule will
         # reject them.  Meanwhile, this allows us to dynamically add rules to
         # the firewall chain.
         #
         # Note that there is one rule for diald/PPPoE (the first) and one for
         # a bridging Cable/DSL modem (the second).  You should pick the one
         # that suits your purposes.
         #
         ipchains -A input -i $1 -s 0.0.0.0/0 -d $extip/32 -j fw-chain
         #ipchains -A input -i $inetint -s 0.0.0.0/0 -d $extip/32 -j fw-chain
         #
         # 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.
         #
         ipchains -A input -p 2 -d 0.0.0.0/0 -j REJECT
         ipchains -A input -p 103 -d 0.0.0.0/0 -j REJECT
         #
         # This is the catch all rule.  All other incoming packets are denied and
         # logged.  Pity there is no log option on the default policy but this
         # does the job instead.
         #
         ipchains -A input -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
     fi
     #############################################################################
     #
     # If the firewall is off, for outgoing, flush and set the default policy of
     # accept.
     #
     if [ -f /etc/rc.d/init.d/firewall-off ]; then
         ipchains -F output
         ipchains -P output ACCEPT
     #
     # For outgoing, flush and set the default policy of reject.  Actually the
     # default policy is irrelevant because there is a catch all rule at the end
     # of the chain which will reject and log all rejected packets.  However, the
     # default reject policy will prevent any packets from slipping through the
     # cracks while we are setting up the other rules.
     #
     else
         ipchains -F output
         ipchains -P output REJECT
         #
         # Any packet addressed to the local network but being sent via the fast
         # Internet interface is a result of a broken routing and any packet with
         # a local address being sent anywhere via the fast Internet interface
         # signifies broken masquerading so deny them.
         #
         # Note that you can comment out the following two lines to test the
         # fast Internet interface on the regular internal network to ensure
         # that it works prior to hooking it up to the Cable/DSL modem.
         #
         ipchains -A output -s 0.0.0.0/0 -d $intnet -i $inetint -l -j REJECT
         ipchains -A output -s $intnet -d 0.0.0.0/0 -i $inetint -l -j REJECT
         #
         # Packets from any source going to the fast Internet interface are
         # valid.
         #
         ipchains -A output -s 0.0.0.0/0 -d 0.0.0.0/0 -i $inetint -j ACCEPT
         #
         # Packets from any source going to the local net via the local interface
         # are valid.
         #
         ipchains -A output -s 0.0.0.0/0 -d $intnet -i $intint -j ACCEPT
         #
         # Any packet addressed to the local network but being sent via the remote
         # interface is a result of a broken routing so deny it.
         #
         ipchains -A output -s 0.0.0.0/0 -d $intnet -i $1 -l -j REJECT
         #
         # Any packet with a local address being sent anywhere via the remote
         # interface signifies broken masquerading so deny it (remember that
         # masquerade replaces all internal addresses with our externally visible
         # address before packets get to the output chain).
         #
         ipchains -A output -s $intnet -d 0.0.0.0/0 -i $1 -l -j REJECT
         #
         # Any packet addressed from our externally visible address outgoing on
         # the remote interface is valid (that's how we send packets to the
         # world).
         #
         ipchains -A output -s $extip/32 -d 0.0.0.0/0 -i $1 -j ACCEPT
         #
         # The loopback interface is always valid.
         #
         ipchains -A output -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT
         #
         # This is the catch all rule.  All other outgoing packets are denied and
         # logged.  Once again, its a pity there is no log option on the default
         # policy but this does the job instead.
         #
         ipchains -A output -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
     fi
     #############################################################################
     #
     # For forwarding, flush and set the default policy of reject.  Actually the
     # default policy is irrelevant because there is a catch all rule at the end
     # of the chain which will reject and log all rejected packets.  However, the
     # default reject policy will prevent any packets from slipping through the
     # cracks while we are setting up the other rules.
     #
     ipchains -F forward
     ipchains -P forward REJECT
     #
     # Masquerade all packets addressed from the local net bound to anywhere via
     # the remote interface.
     #
     ipchains -A forward -s $intnet -d 0.0.0.0/0 -i $1 -j MASQ
     #
     # This is the catch all rule.  All other forwarded packets are denied and
     # logged.  The usual story about it being a pity that there is no log option
     # on the default policy.  This does the job instead.
     #
     ipchains -A forward -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT