Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Apr 2001 02:00:02 -0700 (PDT)
From:      Cyrille Lefevre <root@gits.dyndns.org>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: misc/26763: installing ipfilter sample files to share/examples
Message-ID:  <200104220900.f3M902J83661@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR misc/26763; it has been noted by GNATS.

From: Cyrille Lefevre <root@gits.dyndns.org>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: misc/26763: installing ipfilter sample files to share/examples
Date: Sun, 22 Apr 2001 10:57:45 +0200 (CEST)

 README file added.
 Makefile updated w/ more sample files and the ipf how-to.
 
 diff -urN share/examples/ipfilter.orig/Makefile share/examples/ipfilter/Makefile
 --- share/examples/ipfilter.orig/Makefile	Sun Apr 22 08:34:23 2001
 +++ share/examples/ipfilter/Makefile	Sun Apr 22 10:47:56 2001
 @@ -4,11 +4,25 @@
  
  BINDIR=	/usr/share/examples
  
 -FILES=	BASIC.NAT BASIC_1.FW BASIC_2.FW \
 +FILES=	README
 +
 +# dist sample files
 +FILES+=	BASIC.NAT BASIC_1.FW BASIC_2.FW \
  	example.1 example.2 example.3 example.4 example.5 \
  	example.6 example.7 example.8 example.9 example.10 \
  	example.11 example.12 example.13 example.sr firewall \
  	ftp-proxy ftppxy nat-setup nat.eg server tcpstate
 +
 +# ftp://ftp.OpenBSD.org/pub/OpenBSD/src/share/ipf/ sample files.
 +FILES+=	example.14 firewall.1 firewall.2 \
 +	ipf.conf.permissive ipf.conf.restrictive \
 +	ipf.conf.sample ipnat.conf.sample
 +
 +# http://www.obfuscation.org/ipf/ how-to
 +FILES+=	ipf-howto.txt
 +
 +# http://coombs.anu.edu.au/~avalon/ sample files
 +FILES+=	examples.txt rules.txt
  
  all:
  
 diff -urN share/examples/ipfilter.orig/README share/examples/ipfilter/README
 --- share/examples/ipfilter.orig/README	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/README	Sun Apr 22 10:40:18 2001
 @@ -0,0 +1,15 @@
 +# $FreeBSD$
 +
 +This directory contains various files related to ipfilter.
 +
 +For information on building ipf based firewalls, read the ipf-howto.txt.
 +
 +a more up to date version of this file may be found at:
 +
 +	http://www.obfuscation.org/ipf/
 +
 +Additional help may be found at the ipf home page:
 +
 +	http://coombs.anu.edu.au/~avalon/
 +
 +examples.txt and rules.txt come from this site.
 diff -urN share/examples/ipfilter.orig/example.14 share/examples/ipfilter/example.14
 --- share/examples/ipfilter.orig/example.14	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/example.14	Sun Apr 22 09:41:54 2001
 @@ -0,0 +1,61 @@
 +#
 +# log all inbound packet on le0 which has IP options present
 +#
 +log in on le0 from any to any with ipopts
 +#
 +# block any inbound packets on le0 which are fragmented and "too short" to
 +# do any meaningful comparison on.  This actually only applies to TCP
 +# packets which can be missing the flags/ports (depending on which part
 +# of the fragment you see).
 +#
 +block in log quick on le0 from any to any with short frag
 +#
 +# log all inbound TCP packets with the SYN flag (only) set
 +#  (NOTE: if it were an inbound TCP packet with the SYN flag set and it
 +#         had IP options present, this rule and the above would cause it
 +#         to be logged twice).
 +#
 +log in on le0 proto tcp from any to any flags S/SA
 +#
 +# block and log any inbound ICMP unreachables
 +#
 +block in log on le0 proto icmp from any to any icmp-type unreach
 +#
 +# block and log any inbound UDP packets on le0 which are going to port 2049
 +# (the NFS port).
 +#
 +block in log on le0 proto udp from any to any port = 2049
 +#
 +# quickly allow any packets to/from a particular pair of hosts
 +#
 +pass in quick from any to 10.1.3.2/32
 +pass in quick from any to 10.1.0.13/32
 +pass in quick from 10.1.3.2/32 to any
 +pass in quick from 10.1.0.13/32 to any
 +#
 +# block (and stop matching) any packet with IP options present.
 +#
 +block in quick on le0 from any to any with ipopts
 +#
 +# allow any packet through
 +#
 +pass in from any to any
 +#
 +# block any inbound UDP packets destined for these subnets.
 +#
 +block in on le0 proto udp from any to 10.1.3.0/24
 +block in on le0 proto udp from any to 10.1.1.0/24
 +block in on le0 proto udp from any to 10.1.2.0/24
 +#
 +# block any inbound TCP packets with only the SYN flag set that are
 +# destined for these subnets.
 +#
 +block in on le0 proto tcp from any to 10.1.3.0/24 flags S/SA
 +block in on le0 proto tcp from any to 10.1.2.0/24 flags S/SA
 +block in on le0 proto tcp from any to 10.1.1.0/24 flags S/SA
 +#
 +# block any inbound ICMP packets destined for these subnets.
 +#
 +block in on le0 proto icmp from any to 10.1.3.0/24
 +block in on le0 proto icmp from any to 10.1.1.0/24
 +block in on le0 proto icmp from any to 10.1.2.0/24
 diff -urN share/examples/ipfilter.orig/examples.txt share/examples/ipfilter/examples.txt
 --- share/examples/ipfilter.orig/examples.txt	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/examples.txt	Sun Apr 22 10:08:59 2001
 @@ -0,0 +1,514 @@
 +IP Filter Examples
 +
 +     [Image] Permissions
 +     [Image] Interface
 +     [Image] Netmasks and hosts
 +     [Image] IP Protocols
 +     [Image] IP Options
 +     [Image] IP Fragments
 +     [Image] TCP/UDP Ports
 +     [Image] ICMP type/code
 +     [Image] TCP Flags (established)
 +     [Image] Responding to a BAD packet
 +     [Image] IP Security Classes
 +     [Image] Packet state filtering
 +     [Image] Network Address Translation (NAT)
 +     [Image] Transparent Proxy Support
 +     [Image] Transparent routing
 +     [Image] Logging packets to network devices
 +     [Image] Rule groups
 +     Authenticating packets
 +     Pre-authenticating packets
 +
 +  ------------------------------------------------------------------------
 +
 +Permission Specifying.
 +
 +To specify where to pass through or to block a packet, either block or pass
 +is used. In and out are used to describe the direction in which the packet
 +is travelling through a network interface. Eg:
 +
 +# setup default to block all packets.
 +block in all
 +block out all
 +# pass packets from host firewall to any destination
 +pass in from firewall to any
 +
 +  ------------------------------------------------------------------------
 +
 +Select network Interfaces
 +
 +To select which interface a packet is currently associated with, either its
 +destination as a result of route processing or where it has been received
 +from, the on keyword is used. Whilst not compulsory, it is recommended that
 +each rule include it for clarity. Eg:
 +
 +# drop all inbound packets from localhost coming from ethernet
 +block in on le0 from localhost to any
 +
 +  ------------------------------------------------------------------------
 +
 +Netmasks and hosts
 +
 +As not all networks are formed with classical network boundaries, it is
 +necessary to provide a mechanism to support VLSM (Variable Length Subnet
 +Masks). This package provides several ways to do this. Eg:
 +
 +#
 +block in on le0 from mynet/26 to any
 +#
 +block in on le0 from mynet/255.255.255.192 to any
 +#
 +block in on le0 from mynet mask 255.255.255.192 to any
 +#
 +block in on le0 from mynet mask 0xffffffc0 to any
 +
 +Are all valid and legal syntax with this package. However, when regenerating
 +rules (ie using ipfstat), this package will prefer to use the shortest valid
 +notation (top down).
 +
 +The default netmask, when none is given is 255.255.255.255 or "/32".
 +
 +To invert the match on a hostname or network, include an ! before the name
 +or number with no space between them.
 +  ------------------------------------------------------------------------
 +
 +Protocol
 +
 +To filter on an individual protocol, it is possible to specify the protocol
 +in a filter rule. Eg:
 +
 +# block all incoming ICMP packets
 +block in on le0 proto icmp all
 +
 +The name of the protocol can be any valid name from /etc/protocols or a
 +number.
 +
 +# allow all IP packets in which are protocol 4
 +pass in on le0 proto 4 all
 +
 +There is one exception to this rule, being "tcp/udp". If given in a ruleset,
 +it will match either of the two protocols. This is useful when setting up
 +port restrictions. Eg:
 +
 +# prevent any packets destined for NFS from coming in
 +block in on le0 proto tcp/udp from any to any port = 2049
 +
 +  ------------------------------------------------------------------------
 +
 +Filtering IP fragments
 +
 +IP fragments are bad news, in general. Recent study has shown that IP
 +fragments can pose a large threat to IP packet filtering, IF there are rules
 +used which rely on data which may be distributed across fragments. To this
 +package, the threat is that the TCP flags field of the TCP packet may be in
 +the 2nd or 3rd fragment or possibly be believed to be in the first when
 +actually in the 2nd or 3rd.
 +
 +To filter out these nasties, it is possible to select fragmented packets out
 +as follows:
 +
 +#
 +# get rid of all IP fragments
 +#
 +block in all with frag
 +
 +The problem arises that fragments can actually be a non-malicious. The
 +really malicious ones can be grouped under the term "short fragments" and
 +can be filtered out as follows:
 +
 +#
 +# get rid of all short IP fragments (too small for valid comparison)
 +#
 +block in proto tcp all with short
 +
 +  ------------------------------------------------------------------------
 +
 +IP Options
 +
 +IP options have a bad name for being a general security threat. They can be
 +of some use, however, to programs such as traceroute but many find this
 +usefulness not worth the risk.
 +
 +Filtering on IP options can be achieved two ways. The first is by naming
 +them collectively and is done as follows:
 +
 +#
 +# drop and log any IP packets with options set in them.
 +#
 +block in log all with ipopts
 +#
 +
 +The second way is to actually list the names of the options you wish to
 +filter.
 +
 +#
 +# drop any source routing options
 +#
 +block in quick all with opt lsrr
 +block in quick all with opt ssrr
 +
 +[Image] NOTE that options are matched explicitly, so if I had lsrr,ssrr it
 +would only match packets with both options set.
 +
 +It is also possible to select packets which DON'T have various options
 +present in the packet header. For example, to allow telnet connections
 +without any IP options present, the following would be done:
 +
 +#
 +# Allow anyone to telnet in so long as they don't use IP options.
 +#
 +pass in proto tcp from any to any port = 23 with no ipopts
 +#
 +# Allow packets with strict source routing and no loose source routing
 +#
 +pass in from any to any with opt ssrr not opt lsrr
 +
 +  ------------------------------------------------------------------------
 +
 +Filtering by ports
 +
 +Filtering by port number only works with the TCP and UDP IP protocols. When
 +specifying port numbers, either the number or the service name from
 +/etc/services may be used. If the proto field is used in a filter rule, it
 +will be used in conjunction with the port name in determining the port
 +number.
 +
 +The possible operands available for use with port numbers are:
 +
 +Operand Alias   Parameters      Result
 +<       lt      port#           true if port is less than given value
 +>       gt      port#           true if port is greater than given value
 +=       eq      port#           true if port is equal to than given value
 +!=      ne      port#           true if port is not equal to than given value
 +<=      le      port#           true if port is less than or equal to given value
 +=>      ge      port#           true if port is greater than or equal to given value
 +
 +Eg:
 +
 +#
 +# allow any TCP packets from the same subnet as foo is on through to host
 +# 10.1.1.2 if they are destined for port 6667.
 +#
 +pass in proto tcp from fubar/24 to 10.1.1.2/32 port = 6667
 +#
 +# allow in UDP packets which are NOT from port 53 and are destined for
 +# localhost
 +#
 +pass in proto udp from fubar port != 53 to localhost
 +
 +Two range comparisons are also possible:
 +
 +Expression Syntax:
 +port1#  <>      port2#          true if port is less than port1 or greater than port2
 +port1#  ><      port2#          true if port is greater than port1 and less than port2
 +
 +[Image] NOTE that in neither case, when the port number is equal to one of
 +those given, does it match. Eg:
 +
 +#
 +# block anything trying to get to X terminal ports, X:0 to X:9
 +#
 +block in proto tcp from any to any port 5999 >< 6010
 +#
 +# allow any connections to be made, except to BSD print/r-services
 +# this will also protect syslog.
 +#
 +block in proto tcp/udp all
 +pass in proto tcp/udp from any to any port 512 <> 515
 +
 +Note that the last one above could just as easily be done in the reverse
 +fashion: allowing everything through and blocking only a small range. Note
 +that the port numbers are different, however, due to the difference in the
 +way they are compared.
 +
 +#
 +# allow any connections to be made, except to BSD print/r-services
 +# this will also protect syslog.
 +#
 +pass in proto tcp/udp all
 +block in proto tcp/udp from any to any port 511 >< 516
 +
 +  ------------------------------------------------------------------------
 +
 +TCP Flags (established)
 +
 +Filtering on TCP flags is useful, but fraught with danger. I'd recommend
 +that before using TCP flags in your IP filtering, you become at least a
 +little bit acquainted with what the role of each of them is and when they're
 +used. This package will compare the flags present in each TCP packet, if
 +asked, and match if those present in the TCP packet are the same as in the
 +IP filter rule.
 +
 +Some IP filtering/firewall packages allow you to filter out TCP packets
 +which belong to an "established" connection. This is, simply put, filtering
 +on packets which have the ACK bit set. The ACK bit is only set in packets
 +transmitted during the lifecycle of a TCP connection. It is necessary for
 +this flag to be present from either end for data to be transferred. If you
 +were using a rule which as worded something like:
 +
 +allow proto tcp 10.1.0.0 255.255.0.0 port = 23 10.2.0.0 255.255.0.0 established
 +
 +It could be rewritten as:
 +
 +pass in proto tcp 10.1.0.0/16 port = 23 10.2.0.0/16 flags A/A
 +pass out proto tcp 10.1.0.0/16 port = 23 10.2.0.0/16 flags A/A
 +
 +A more useful flag to filter on, for TCP connections, I find, is the SYN
 +flag. This is only set during the initial stages of connection negotiation,
 +and for the very first packet of a new TCP connection, it is the only flag
 +set. At all other times, an ACK or maybe even an URG/PUSH flag may be set.
 +So, if I want to stop connections being made to my internal network
 +(10.1.0.0) from the outside network, I might do something like:
 +
 +#
 +# block incoming connection requests to my internal network from the big bad
 +# internet.
 +#
 +block in on le0 proto tcp from any to 10.1.0.0/16 flags S/SA
 +
 +If you wanted to block the replies to this (the SYN-ACK's), then you might
 +do:
 +
 +block out on le0 proto tcp from 10.1.0.0 to any flags SA/SA
 +
 +where SA represents the SYN-ACK flags both being set.
 +
 +The flags after the / represent the TCP flag mask, indicating which bits of
 +the TCP flags you are interested in checking. When using the SYN bit in a
 +check, you SHOULD specify a mask to ensure that your filter CANNOT be
 +defeated by a packet with SYN and URG flags, for example, set (to Unix, this
 +is the same as a plain SYN).
 +  ------------------------------------------------------------------------
 +
 +ICMP Type/Code
 +
 +ICMP can be a source of a lot of trouble for Internet Connected networks.
 +Blocking out all ICMP packets can be useful, but it will disable some
 +otherwise useful programs, such as "ping". Filtering on ICMP type allows for
 +pings (for example) to work. Eg:
 +
 +# block all ICMP packets.
 +#
 +block in proto icmp all
 +#
 +# allow in ICMP echos and echo-replies.
 +#
 +pass in on le1 proto icmp from any to any icmp-type echo
 +pass in on le1 proto icmp from any to any icmp-type echorep
 +
 +To specify an ICMP code, the numeric value must be used. So, if we wanted to
 +block all port-unreachables, we would do:
 +
 +#
 +# block all ICMP destination unreachable packets which are port-unreachables
 +#
 +block in on le1 proto icmp from any to any icmp-type unreach code 3
 +
 +  ------------------------------------------------------------------------
 +
 +Responding to a BAD packet
 +
 +To provide feedback to people trying to send packets through your filter
 +which you wish to disallow, you can send back either an ICMP error
 +(Destination Unreachable) or, if they're sending a TCP packet, a TCP RST
 +(Reset).
 +
 +What's the difference ? TCP/IP stacks take longer to pass the ICMP errors
 +back, through to the application, as they can often be due to temporary
 +problems (network was unplugged for a second) and it is `incorrect' to shut
 +down a connection for this reason. Others go to the other extreme and will
 +shut down all connections between the two hosts for which the ICMP error is
 +received. The TCP RST, however, is for only *one* connection (cannot be used
 +for more than one) and will cause the connection to immediately shut down.
 +So, for example, if you're blocking port 113, and setup a rule to return a
 +TCP RST rather than nothing or an ICMP packet, you won't experience any
 +delay if the other end was attempting to make a connection to an identd
 +service.
 +
 +Some examples are as follows:
 +
 +#
 +# block all incoming TCP connections but send back a TCP-RST for ones to
 +# the ident port
 +#
 +block in proto tcp from any to any flags S/SA
 +block return-rst in quick proto tcp from any to any port = 113 flags S/SA
 +#
 +# block all inbound UDP packets and send back an ICMP error.
 +#
 +block return-icmp in proto udp from any to any
 +
 +When returning ICMP packets, it is also possible to specify the type of ICMP
 +error return. This was requested so that traceroute traces could be forced
 +to end elegantly. To do this, the requested ICMP Unreachable code is placed
 +in brackets following the "return-icmp" directive:
 +
 +#
 +# block all inbound UDP packets and send back an ICMP error.
 +#
 +block return-icmp (3) in proto udp from any to any port > 30000
 +block return-icmp (port-unr) in proto udp from any to any port > 30000
 +
 +Those two examples are equivalent, and return a ICMP port unreachable error
 +packet to in response to any UDP packet received destined for a port greater
 +than 30,000.
 +  ------------------------------------------------------------------------
 +
 +Filtering IP Security Classes
 +
 +For users who have packets which contain IP security bits, filtering on the
 +defined classes and authority levels is supported. Currently, filtering on
 +16bit authority flags is not supported.
 +
 +As with ipopts and other IP options, it is possible to say that the packet
 +only matches if a certain class isn't present.
 +
 +Some examples of filtering on IP security options:
 +
 +#
 +# drop all packets without IP security options
 +#
 +block in all with no opt sec
 +#
 +# only allow packets in and out on le0 which are top secret
 +#
 +block out on le1 all
 +pass out on le1 all with opt sec-class topsecret
 +block in on le1 all
 +pass in on le1 all with opt sec-class topsecret
 +
 +  ------------------------------------------------------------------------
 +
 +Packet state filtering
 +
 +Packet state filtering can be used for any TCP flow to short-cut later
 +filtering. The "short-cuts" are kept in a table, with no alterations to the
 +packet filter list made. Subsequent packets, if a matching packet is found
 +in the table, are not passed through the list. For TCP flows, the filter
 +will follow the ack/sequence numbers of packets and only allow packets
 +through which fall inside the correct window.
 +
 +#
 +# Keep state for all outgoing telnet connections
 +# and disallow all other TCP traffic.
 +#
 +pass out on le1 proto tcp from any to any port = telnet keep state
 +block out on le1 all
 +
 +For UDP packets, packet exchanges are effectively stateless. However, if a
 +packet is first sent out from a given port, a reply is usually expected in
 +answer, in the `reverse' direction.
 +
 +#
 +# allow UDP replies back from name servers
 +#
 +pass out on le1 proto udp from any to any port = domain keep state
 +
 +Held UDP state is timed out, as is TCP state for entries added which do not
 +have the SYN flag set. If an entry is created with the SYN flag set, any
 +subsequent matching packet which doesn't have this flag set (ie a SYN-ACK)
 +will cause it to be "timeless" (actually, the timeout defaults to 5 days),
 +until either a FIN or RST is seen.
 +
 +  ------------------------------------------------------------------------
 +
 +Network Address Translation (NAT)
 +
 +Network address translation is used to remap IP #'s from one address range
 +to another range of network addresses. For TCP and UDP, this also can
 +include the port numbers. The IP#'s/port #'s are changed when a packet is
 +going out through an interface and IP Filter matches it against a NAT rules.
 +
 +Packets coming back in the same interface are remapped, as a matter of
 +course, to their original address information.
 +
 +# map all tcp connections from 10.1.0.0/16 to 240.1.0.1, changing the source
 +# port number to something between 10,000 and 20,000 inclusive.  For all other
 +# IP packets, allocate an IP # between 240.1.0.0 and 240.1.0.255, temporarily
 +# for each new user.  In this example, ed1 is the external interface.
 +# Use ipnat, not ipf to load these rules.
 +#
 +map ed1 10.1.0.0/16 -> 240.1.0.1/32 portmap tcp 10000:20000
 +map ed1 10.1.0.0/16 -> 240.1.0.0/24
 +
 +  ------------------------------------------------------------------------
 +
 +Transparent Proxy Suppoer
 +
 +Transparent proxies are supported through redirection, which works in a
 +similar way to NAT, except that rules are triggered by input packets. To
 +effect redirection rules, ipnat must be used (same as for NAT) rather than
 +ipf.
 +
 +# Redirection is triggered for input packets.
 +# For example, to redirect FTP connections through this box (in this case ed0
 +# is the interface on the "inside" where default routes point), to the local
 +# ftp port, forcing them to connect through a proxy, you would use:
 +#
 +rdr ed0 0.0.0.0/0 port ftp -> 127.0.0.1 port ftp
 +
 +  ------------------------------------------------------------------------
 +
 +Transparent routing
 +
 +Transparent routing can be performed in two ways using IP Filter. The first
 +is to use the keyword "fastroute" in a rule, using the normal route lookup
 +to occur or using a fixed route with "to". Both effect transparent routing
 +by not causing any decrement in the TTL to occur as it passes through the
 +kernel.
 +
 +# Route all UDP packets through transparently.
 +#
 +pass in quick fastroute proto udp all
 +#
 +# Route all ICMP packets to network 10 (on le0) out through le1, to "router"
 +#
 +pass in quick on le0 to le1:router proto icmp all
 +
 +  ------------------------------------------------------------------------
 +
 +Logging packets to the network
 +
 +Logging packets to the network devices is supported for both packets being
 +passed through the filter and those being blocked. For packets being passed
 +on, the "dup-to" keyword must be used, but for packets being blocked, either
 +"to" (more efficient) or "dup-to" can be used.
 +
 +To log packets to the interface without requiring ARP to work, create a
 +static arp cache for a meaningless IP# (say 10.0.0.1) and log packets to
 +this IP#.
 +
 +# Log all short TCP packets to qe3, with "packetlog" as the intended
 +# destination for the packet.
 +#
 +block in quick to qe3:packetlog proto tcp all with short
 +#
 +# Log all connection attempts for TCP
 +#
 +pass in quick on ppp0 dup-to le1:packetlog proto tcp all flags S/SA
 +
 +  ------------------------------------------------------------------------
 +
 +Rule groups
 +
 +To aide in making rule processing more efficient, it is possible to setup
 +rule `groups'. By default, all rules are in group 0 and all other groups
 +have it as their ultimate parent. To start a new group, a rule includes a
 +`head' statement, such as this:
 +
 +# Process all incoming ppp packets on ppp0 with group 100, with the default for
 +# this interface to block all incoming.
 +#
 +block in quick on ppp0 all head 100
 +
 +If we then wanted to allow people to connect to our WWW server, via ppp0, we
 +could then just add a rule about WWW. NOTE: only packets which match the
 +above rule are processed by any group 100 rules.
 +
 +# Allow connections to the WWW server via ppp0.
 +#
 +pass in quick proto tcp from any to any port = WWW keep state group 100
 +
 +  ------------------------------------------------------------------------
 +Return to the IP Filter home page
 diff -urN share/examples/ipfilter.orig/firewall.1 share/examples/ipfilter/firewall.1
 --- share/examples/ipfilter.orig/firewall.1	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/firewall.1	Sun Apr 22 09:41:54 2001
 @@ -0,0 +1,35 @@
 +#
 +#  This is an example of a very light firewall used to guard against
 +#  some of the most easily exploited common security holes.
 +#
 +#  The example assumes it is running on a gateway with interface ppp0
 +#  attached to the outside world, and interface ed0 attached to
 +#  network 192.168.4.0 which needs to be protected.
 +#
 +#
 +#  Pass any packets not explicitly mentioned by subsequent rules
 +#
 +pass out from any to any
 +pass in from any to any
 +#
 +#  Block any inherently bad packets coming in from the outside world.
 +#  These include ICMP redirect packets and IP fragments so short the
 +#  filtering rules won't be able to examine the whole UDP/TCP header.
 +#
 +block in log quick on ppp0 proto icmp from any to any icmp-type redir
 +block in log quick on ppp0 proto tcp/udp all with short
 +#
 +#  Block any IP spoofing atempts.  (Packets "from" our network
 +#  shouldn't be coming in from outside).
 +#
 +block in log quick on ppp0 from 192.168.4.0/24 to any
 +block in log quick on ppp0 from localhost to any
 +block in log quick on ppp0 from 0.0.0.0/32 to any
 +block in log quick on ppp0 from 255.255.255.255/32 to any
 +#
 +#  Block any incoming traffic to NFS ports, to the RPC portmapper, and
 +#  to X servers.
 +#
 +block in log on ppp0 proto tcp/udp from any to any port = sunrpc
 +block in log on ppp0 proto tcp/udp from any to any port = 2049
 +block in log on ppp0 proto tcp from any to any port = 6000
 diff -urN share/examples/ipfilter.orig/firewall.2 share/examples/ipfilter/firewall.2
 --- share/examples/ipfilter.orig/firewall.2	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/firewall.2	Sun Apr 22 09:41:54 2001
 @@ -0,0 +1,69 @@
 +#
 +#  This is an example of a fairly heavy firewall used to keep everyone
 +#  out of a particular network while still allowing people within that
 +#  network to get outside.
 +#
 +#  The example assumes it is running on a gateway with interface ppp0
 +#  attached to the outside world, and interface ed0 attached to
 +#  network 192.168.4.0 which needs to be protected.
 +#
 +#
 +#  Pass any packets not explicitly mentioned by subsequent rules
 +#
 +pass out from any to any
 +pass in from any to any
 +#
 +#  Block any inherently bad packets coming in from the outside world.
 +#  These include ICMP redirect packets, IP fragments so short the
 +#  filtering rules won't be able to examine the whole UDP/TCP header,
 +#  and anything with IP options.
 +#
 +block in log quick on ppp0 proto icmp from any to any icmp-type redir
 +block in log quick on ppp0 proto tcp/udp all with short
 +block in log quick on ppp0 from any to any with ipopts
 +#
 +#  Block any IP spoofing atempts.  (Packets "from" our network
 +#  shouldn't be coming in from outside).
 +#
 +block in log quick on ppp0 from 192.168.4.0/24 to any
 +block in log quick on ppp0 from localhost to any
 +block in log quick on ppp0 from 0.0.0.0/32 to any
 +block in log quick on ppp0 from 255.255.255.255/32 to any
 +#
 +#  Block all incoming UDP traffic except talk and DNS traffic.  NFS
 +#  and portmap are special-cased and logged.
 +#
 +block in on ppp0 proto udp from any to any
 +block in log on ppp0 proto udp from any to any port = sunrpc
 +block in log on ppp0 proto udp from any to any port = 2049
 +pass in on ppp0 proto udp from any to any port = domain
 +pass in on ppp0 proto udp from any to any port = talk
 +pass in on ppp0 proto udp from any to any port = ntalk
 +#
 +#  Block all incoming TCP traffic connections to known services,
 +#  returning a connection reset so things like ident don't take
 +#  forever timing out.  Don't log ident (auth port) as it's so common.
 +#
 +block return-rst in log on ppp0 proto tcp from any to any flags S/SA
 +block return-rst in on ppp0 proto tcp from any to any port = auth flags S/SA
 +#
 +#  Allow incoming TCP connections to ports between 1024 and 5000, as
 +#  these don't have daemons listening but are used by outgoing
 +#  services like ftp and talk.  For slightly more obscurity (though
 +#  not much more security), the second commented out rule can chosen
 +#  instead.
 +#
 +pass in on ppp0 proto tcp from any to any port 1024 >< 5000
 +#pass in on ppp0 proto tcp from any port = ftp-data to any port 1024 >< 5000
 +#
 +#  Now allow various incoming TCP connections to particular hosts, TCP
 +#  to the main nameserver so secondaries can do zone transfers, SMTP
 +#  to the mail host, www to the web server (which really should be
 +#  outside the firewall if you care about security), and ssh to a
 +#  hypothetical machine caled 'gatekeeper' that can be used to gain
 +#  access to the protected network from the outside world.
 +#
 +pass in on ppp0 proto tcp from any to ns1 port = domain
 +pass in on ppp0 proto tcp from any to mail port = smtp
 +pass in on ppp0 proto tcp from any to www port = www
 +pass in on ppp0 proto tcp from any to gatekeeper port = ssh
 diff -urN share/examples/ipfilter.orig/ipf-howto.txt share/examples/ipfilter/ipf-howto.txt
 --- share/examples/ipfilter.orig/ipf-howto.txt	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/ipf-howto.txt	Sun Apr 22 10:21:43 2001
 @@ -0,0 +1,3168 @@
 +
 +
 +
 +
 +
 +
 +              IP Filter Based Firewalls HOWTO
 +
 +              Brendan Conoboy <synk@swcp.com>
 +            Erik Fichtner <emf@obfuscation.org>
 +
 +
 +                Fri Apr 20 09:31:14 EDT 2001
 +
 +
 +
 +
 +
 +
 +     Abstract:  This document is intended to introduce a new
 +     user to the IP Filter firewalling package and,  at  the
 +     same  time,  teach  the user some basic fundamentals of
 +     good firewall design.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +1.  Introduction
 +
 +     IP Filter is a great little firewall package.  It  does
 +just   about   everything  other  free  firewalls  (ipfwadm,
 +ipchains, ipfw) do, but it's also  portable  and  does  neat
 +stuff  the  others don't.  This document is intended to make
 +some cohesive sense of the  sparse  documentation  presently
 +available  for ipfilter.  Some prior familiarity with packet
 +filtering will be useful, however too much  familiarity  may
 +make this document a waste of your time.  For greater under-
 +standing of firewalls, the authors recommend reading  Build-
 +ing Internet Firewalls, Chapman & Zwicky, O'Reilly and Asso-
 +ciates; and TCP/IP Illustrated, Volume 1, Stevens,  Addison-
 +Wesley.
 +
 +
 +
 +
 +
 +1.1.  Disclaimer
 +
 +     The  authors  of  this document are not responsible for
 +any damages incurred due to actions taken based on this doc-
 +ument. This document is meant as an introduction to building
 +a  firewall  based  on  IP-Filter.   If  you  do  not   feel
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                             -2-
 +
 +
 +comfortable  taking responsibility for your own actions, you
 +should stop reading this document and hire a qualified secu-
 +rity professional to install your firewall for you.
 +
 +
 +1.2.  Copyright
 +
 +     Unless  otherwise  stated,  HOWTO  documents  are copy-
 +righted by their respective authors. HOWTO documents may  be
 +reproduced  and  distributed  in  whole  or  in part, in any
 +medium physical or electronic, as  long  as  this  copyright
 +notice  is retained on all copies. Commercial redistribution
 +is allowed and encouraged; however, the authors  would  like
 +to be notified of any such distributions.
 +
 +     All  translations, derivative works, or aggregate works
 +incorporating any HOWTO documents must be covered under this
 +copyright notice.  That is, you may not produce a derivative
 +work from a HOWTO and impose additional restrictions on  its
 +distribution. Exceptions to these rules may be granted under
 +certain conditions; please contact the HOWTO coordinator.
 +
 +     In short, we wish  to  promote  dissemination  of  this
 +information  through  as many channels as possible. However,
 +we do wish to retain copyright on the HOWTO  documents,  and
 +would  like  to be notified of any plans to redistribute the
 +HOWTOs.
 +
 +
 +1.3.  Where to obtain the important pieces
 +
 +     The     official     IPF      homepage      is      at:
 +<http://coombs.anu.edu.au/~avalon/ip-filter.html>;
 +
 +     The  most  up-to-date  version  of this document can be
 +found at: <http://www.obfuscation.org/ipf/>;
 +
 +
 +
 +
 +2.  Basic Firewalling
 +
 +     This section is designed to familiarize you with ipfil-
 +ter's  syntax, and firewall theory in general.  The features
 +discussed here are features you'll find in any good firewall
 +package.   This  section  will give you a good foundation to
 +make reading and understanding  the  advanced  section  very
 +easy.   It must be emphasized that this section alone is not
 +enough to build a good firewall, and that the advanced  sec-
 +tion  really  is  required  reading for anybody who wants to
 +build an effective security system.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                             -3-
 +
 +
 +2.1.  Config File Dynamics, Order and Precedence
 +
 +     IPF (IP Filter) has a config file (as opposed  to  say,
 +running  some  command  again  and again for each new rule).
 +The config file drips with Unix:  There's one rule per line,
 +the  "#" mark denotes a comment, and you can have a rule and
 +a comment  on  the  same  line.   Extraneous  whitespace  is
 +allowed, and is encouraged to keep the rules readable.
 +
 +
 +2.2.  Basic Rule Processing
 +
 +     The  rules  are  processed from top to bottom, each one
 +appended after another.  This quite simply means that if the
 +entirety of your config file is:
 +
 +    block in all
 +    pass  in all
 +
 +The computer sees it as:
 +
 +    block in all
 +    pass  in all
 +
 +Which is to say that when a packet comes in, the first thing
 +IPF applies is:
 +
 +    block in all
 +
 +Should IPF deem it necessary to move on to the next rule, it
 +would then apply the second rule:
 +
 +    pass  in all
 +
 +     At  this  point,  you might want to ask yourself "would
 +IPF move on to the second rule?"  If  you're  familiar  with
 +ipfwadm  or  ipfw,  you  probably  won't  ask yourself this.
 +Shortly after, you will become bewildered at the  weird  way
 +packets  are  always  getting  denied  or  passed  when they
 +shouldn't.  Many packet filters stop  comparing  packets  to
 +rulesets  the moment the first match is made; IPF is not one
 +of them.
 +
 +     Unlike the other packet filters, IPF keeps  a  flag  on
 +whether  or  not  it's going to pass the packet.  Unless you
 +interrupt the flow, IPF will go through the entire  ruleset,
 +making  its  decision  on whether or not to pass or drop the
 +packet based on the last matching rule.  The scene: IP  Fil-
 +ter's  on  duty.   It's  been  been scheduled a slice of CPU
 +time.  It has a checkpoint clipboard that reads:
 +
 +    block in all
 +    pass  in all
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                             -4-
 +
 +
 +A packet comes in the interface and it's time to go to work.
 +It  takes a look at the packet, it takes a look at the first
 +rule:
 +
 +    block in all
 +
 +"So far I think I will block  this  packet"  says  IPF.   It
 +takes a look at the second rule:
 +
 +    pass  in all
 +
 +"So far I think I will pass this packet" says IPF.  It takes
 +a look at a third rule.  There is no third rule, so it  goes
 +with  what  its  last  motivation  was,  to  pass the packet
 +onward.
 +
 +It's a good time to point out that even if the  ruleset  had
 +been
 +
 +    block in all
 +    block in all
 +    block in all
 +    block in all
 +    pass  in all
 +
 +that  the packet would still have gone through.  There is no
 +cumulative effect.  The  last  matching  rule  always  takes
 +precedence.
 +
 +2.3.  Controlling Rule Processing
 +
 +     If  you  have experience with other packet filters, you
 +may find this layout to be confusing, and you may be  specu-
 +lating  that  there are problems with portability with other
 +filters and speed of rule matching.  Imagine if you had  100
 +rules  and  most  of  the applicable ones were the first 10.
 +There would be a terrible overhead for every  packet  coming
 +in  to  go through 100 rules every time.  Fortunately, there
 +is a simple keyword you can add to any rule  that  makes  it
 +take action at that match.  That keyword is quick.
 +
 +Here's  a  modified  copy  of the original ruleset using the
 +quick keyword:
 +
 +    block in quick all
 +    pass  in       all
 +
 +In this case, IPF looks at the first rule:
 +
 +    block in quick all
 +
 +The packet matches and the search is over.   The  packet  is
 +expunged  without a peep.  There are no notices, no logs, no
 +memorial service.  Cake will not be served.  So  what  about
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                             -5-
 +
 +
 +the next rule?
 +
 +    pass  in       all
 +
 +     This  rule is never encountered.  It could just as eas-
 +ily not be in the config file at all.  The sweeping match of
 +all  and  the  terminal keyword quick from the previous rule
 +make certain that no rules are followed afterward.
 +
 +     Having half a config file laid to  waste  is  rarely  a
 +desirable  state.   On  the other hand, IPF is here to block
 +packets and as configured,  it's  doing  a  very  good  job.
 +Nonetheless,  IPF  is also here to let some packets through,
 +so a change to the ruleset to make this possible  is  called
 +for.
 +
 +2.4.  Basic filtering by IP address
 +
 +     IPF  will match packets on many criteria.  The one that
 +we most commonly think of is the IP address.  There are some
 +blocks of address space from which we should never get traf-
 +fic.  One such  block  is  from   the  unroutable  networks,
 +192.168.0.0/16 (/16 is the CIDR notation for a netmask.  You
 +may  be  more  familiar  with  the  dotted  decimal  format,
 +255.255.0.0.   IPF  accepts  both).   If you wanted to block
 +192.168.0.0/16, this is one way to do it:
 +
 +    block in quick from 192.168.0.0/16 to any
 +    pass  in       all
 +
 +Now we have a less  stringent  ruleset  that  actually  does
 +something  for  us.   Let's  imagine  a packet comes in from
 +1.2.3.4.  The first rule is applied:
 +
 +    block in quick from 192.168.0.0/16 to any
 +
 +The packet is from 1.2.3.4, not 192.168.*.*, so there is  no
 +match.  The second rule is applied:
 +
 +    pass  in       all
 +
 +The  packet from 1.2.3.4 is definitely a part of all, so the
 +packet is sent to whatever it's destination happened to  be.
 +
 +     On  the other hand, suppose we have a packet that comes
 +in from 192.168.1.2.  The first rule is applied:
 +
 +    block in quick from 192.168.0.0/16 to any
 +
 +There's a match, the packet is dropped, and that's the  end.
 +Again,  it doesn't move to the second rule because the first
 +rule matches and contains the quick keyword.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                             -6-
 +
 +
 +     At this point you can build a fairly extensive  set  of
 +definitive  addresses  which  are  passed or blocked.  Since
 +we've already started blocking private  address  space  from
 +entering our firewall, let's take care of the rest of it:
 +
 +    block in quick from 192.168.0.0/16 to any
 +    block in quick from 172.16.0.0/12 to any
 +    block in quick from 10.0.0.0/8 to any
 +    pass  in       all
 +
 +The  first  three  address blocks are some of the private IP
 +space.
 +
 +2.5.  Controlling Your Interfaces
 +
 +     It  seems  very  frequent  that companies have internal
 +networks before they want a link to the outside  world.   In
 +fact, it's probably reasonable to say that's the main reason
 +people consider firewalls in the first place.   The  machine
 +that  bridges the outside world to the inside world and vice
 +versa is the router.  What separates  the  router  from  any
 +other machine is simple: It has more than one interface.
 +
 +     Every  packet  you  receive comes from a network inter-
 +face; every packet you transmit goes out  a  network  inter-
 +face.   Say  your  machine has 3 interfaces, lo0 (loopback),
 +xl0 (3com ethernet),  and  tun0  (FreeBSD's  generic  tunnel
 +interface  that PPP uses), but you don't want packets coming
 +in on the tun0 interface?
 +
 +    block in quick on tun0 all
 +    pass  in               all
 +
 +In this case, the on keyword means that that data is  coming
 +in  on  the  named interface.  If a packet comes in on tun0,
 +the first rule will block it.  If a packet comes in  on  lo0
 +or in on xl0, the first rule will not match, the second rule
 +will, the packet will be passed.
 +
 +2.6.  Using IP Address and Interface Together
 +
 +     It's an odd state of affairs when one decides  it  best
 +to  have the tun0 interface up, but not allow any data to be
 +received from it.  The more criteria  the  firewall  matches
 +against,  the  tighter  (or looser) the firewall can become.
 +Maybe you want data from tun0, but not from  192.168.0.0/16?
 +This is the start of a powerful firewall.
 +
 +    block in quick on tun0 from 192.168.0.0/16 to any
 +-----------
 +            See             rfc1918             at
 +<http://www.faqs.org/rfcs/rfc1918.html>;        and
 +<http://www.ietf.org/internet-drafts/draft-man-
 +ning-dsua-06.txt>
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                             -7-
 +
 +
 +    pass  in       all
 +
 +Compare this to our previous rule:
 +
 +    block in quick from 192.168.0.0/16 to any
 +    pass  in       all
 +
 +The  old way, all traffic from 192.168.0.0/16, regardless of
 +interface, was completely blocked.  The new  way,  using  on
 +tun0 means that it's only blocked if it comes in on the tun0
 +interface.  If a packet arrived on the  xl0  interface  from
 +192.168.0.0/16, it would be passed.
 +
 +     At  this  point you can build a fairly extensive set of
 +definitive addresses which are  passed  or  blocked.   Since
 +we've  already  started  blocking private address space from
 +entering tun0, let's take care of the rest of it:
 +
 +    block in quick on tun0 from 192.168.0.0/16 to any
 +    block in quick on tun0 from 172.16.0.0/12 to any
 +    block in quick on tun0 from 10.0.0.0/8 to any
 +    block in quick on tun0 from 127.0.0.0/8 to any
 +    block in quick on tun0 from 0.0.0.0/8 to any
 +    block in quick on tun0 from 169.254.0.0/16 to any
 +    block in quick on tun0 from 192.0.2.0/24 to any
 +    block in quick on tun0 from 204.152.64.0/23 to any
 +    block in quick on tun0 from 224.0.0.0/3 to any
 +    pass  in       all
 +
 +You've already seen the first  three  blocks,  but  not  the
 +rest.   The  fourth is a largely wasted class-A network used
 +for loopback.  Much software  communicates  with  itself  on
 +127.0.0.1  so  blocking it from an external source is a good
 +idea.  The fifth, 0.0.0.0/8, should never  be  seen  on  the
 +internet.   Most IP stacks treat "0.0.0.0/32" as the default
 +gateway, and the rest of the 0.*.*.*  network  gets  handled
 +strangely  by  various systems as a byproduct of how routing
 +decisions are made.   You should treat 0.0.0.0/8  just  like
 +127.0.0.0/8.    169.254.0.0/16 has been assigned by the IANA
 +for use in auto-configuration when systems have not yet been
 +able  to  obtain  an  IP address via DHCP or the like.  Most
 +notably, Microsoft Windows will use addresses in this  range
 +if  they  are  set  to  DHCP  and cannot find a DHCP server.
 +192.0.2.0/24 has also been reserved for use as an example IP
 +netblock  for documentation authors.  We specifically do not
 +use this range as it would cause confusion when we tell  you
 +to   block   it,   and  thus  all  our  examples  come  from
 +20.20.20.0/24.  204.152.64.0/23 is an odd netblock  reserved
 +by  Sun  Microsystems for private cluster interconnects, and
 +blocking  this  is  up  to  your  own  judgement.    Lastly,
 +224.0.0.0/3  wipes out the "Class D and E" networks which is
 +used mostly for multicast traffic, although further  defini-
 +tion of "Class E" space can be found in RFC 1166.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                             -8-
 +
 +
 +     There's  a very important principle in packet filtering
 +which has only been alluded  to  with  the  private  network
 +blocking  and  that  is  this: When you know there's certain
 +types of data that only comes from certain places, you setup
 +the  system  to  only  allow  that  kind  of data from those
 +places.  In the case of the unroutable addresses,  you  know
 +that  nothing  from  10.0.0.0/8  should  be arriving on tun0
 +because you have no way to reply to it.  It's  an  illegiti-
 +mate  packet.   The  same  goes for the other unroutables as
 +well as 127.0.0.0/8.
 +
 +     Many pieces of software  do  all  their  authentication
 +based  upon  the  packet's originating IP address.  When you
 +have an internal network, say 20.20.20.0/24, you  know  that
 +the  only traffic for that internal network is going to come
 +off the local ethernet.  Should a packet from  20.20.20.0/24
 +arrive  over a PPP dialup, it's perfectly reasonable to drop
 +it on the floor, or put it in a dark room for interrogation.
 +It  should by no means be allowed to get to its final desti-
 +nation.  You can accomplish this  particularly  easily  with
 +what you already know of IPF.  The new ruleset would be:
 +
 +    block in quick on tun0 from 192.168.0.0/16 to any
 +    block in quick on tun0 from 172.16.0.0/12 to any
 +    block in quick on tun0 from 10.0.0.0/8 to any
 +    block in quick on tun0 from 127.0.0.0/8 to any
 +    block in quick on tun0 from 0.0.0.0/8 to any
 +    block in quick on tun0 from 169.254.0.0/16 to any
 +    block in quick on tun0 from 192.0.2.0/24 to any
 +    block in quick on tun0 from 204.152.64.0/23 to any
 +    block in quick on tun0 from 224.0.0.0/3 to any
 +    block in quick on tun0 from 20.20.20.0/24 to any
 +    pass  in       all
 +
 +2.7.  Bi-Directional Filtering; The "out" Keyword
 +
 +     Up  until  now,  we've been passing or blocking inbound
 +traffic.  To clarify, inbound traffic is  all  traffic  that
 +enters  the firewall on any interface.  Conversely, outbound
 +traffic is all traffic that leaves on any interface (whether
 +locally  generated  or  simply passing through).  This means
 +that all packets coming in are not  only  filtered  as  they
 +enter  the  firewall,  they're  also  filtered as they exit.
 +Thusfar there's been an implied pass out all that may or may
 +not  be  desirable.  Just as you may pass and block incoming
 +traffic, you may do the same with outgoing traffic.
 +
 +     Now that we know there's a way to filter outbound pack-
 +ets  just  like inbound, it's up to us to find a conceivable
 +use for such a thing.  One possible use of this idea  is  to
 +keep spoofed packets from exiting your own network.  Instead
 +of passing any traffic out the  router,  you  could  instead
 +limit   permitted   traffic   to   packets   originating  at
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                             -9-
 +
 +
 +20.20.20.0/24.  You might do it like this:
 +
 +    pass  out quick on tun0 from 20.20.20.0/24 to any
 +    block out quick on tun0 from any to any
 +
 +If a packet comes from 20.20.20.1/32, it gets  sent  out  by
 +the  first  rule.  If a packet comes from 1.2.3.4/32 it gets
 +blocked by the second.
 +
 +     You can also make  similar  rules  for  the  unroutable
 +addresses.   If some machine tries to route a packet through
 +IPF with a destination in 192.168.0.0/16, why not  drop  it?
 +The worst that can happen is that you'll spare yourself some
 +bandwidth:
 +
 +    block out quick on tun0 from any to 192.168.0.0/16
 +    block out quick on tun0 from any to 172.16.0.0/12
 +    block out quick on tun0 from any to 10.0.0.0/8
 +    block out quick on tun0 from any to 0.0.0.0/8
 +    block out quick on tun0 from any to 127.0.0.0/8
 +    block out quick on tun0 from any to 169.254.0.0/16
 +    block out quick on tun0 from any to 192.0.2.0/24
 +    block out quick on tun0 from any to 204.152.64.0/23
 +    block out quick on tun0 from any to 224.0.0.0/3
 +    block out quick on tun0 from !20.20.20.0/24 to any
 +
 +In the narrowest viewpoint, this doesn't enhance your  secu-
 +rity.   It  enhances everybody else's security, and that's a
 +nice thing to do.  As another viewpoint, one  might  suppose
 +that because nobody can send spoofed packets from your site,
 +that your site has less value as a relay for  crackers,  and
 +as such is less of a target.
 +
 +     You'll  likely  find a number of uses for blocking out-
 +bound packets.  One thing to always keep in mind is that  in
 +and  out directions are in reference to your firewall, never
 +any other machine.
 +
 +2.8.  Logging What Happens; The "log" Keyword
 +
 +     Up to this point, all blocked and passed  packets  have
 +been silently blocked and silently passed.  Usually you want
 +to know if you're being attacked rather than wonder if  that
 +firewall  is  really buying you any added benefits.  While I
 +wouldn't want to log every passed packet, and in some  cases
 +every blocked packet, I would want to know about the blocked
 +packets from 20.20.20.0/24.  To do this, we add the log key-
 +word:
 +
 +    block in     quick on tun0 from 192.168.0.0/16 to any
 +-----------
 + This can, of course, be changed by using -DIPFIL-
 +TER_DEFAULT_BLOCK  when compiling ipfilter on your
 +system.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -10-
 +
 +
 +    block in     quick on tun0 from 172.16.0.0/12 to any
 +    block in     quick on tun0 from 10.0.0.0/8 to any
 +    block in     quick on tun0 from 127.0.0.0/8 to any
 +    block in     quick on tun0 from 0.0.0.0/8 to any
 +    block in     quick on tun0 from 169.254.0.0/16 to any
 +    block in     quick on tun0 from 192.0.2.0/24 to any
 +    block in     quick on tun0 from 204.152.64.0/23 to any
 +    block in     quick on tun0 from 224.0.0.0/3 to any
 +    block in log quick on tun0 from 20.20.20.0/24 to any
 +    pass  in       all
 +
 +So far, our firewall is pretty good at blocking packets com-
 +ing to it from suspect places, but there's still more to  be
 +done.   For one thing, we're accepting packets destined any-
 +where.  One thing we ought to do is  make  sure  packets  to
 +20.20.20.0/32  and 20.20.20.255/32 get dropped on the floor.
 +To do otherwise opens  the  internal  network  for  a  smurf
 +attack.  These two lines would prevent our hypothetical net-
 +work from being used as a smurf relay:
 +
 +    block in log quick on tun0 from any to 20.20.20.0/32
 +    block in log quick on tun0 from any to 20.20.20.255/32
 +
 +This brings our total ruleset to look something like this:
 +
 +    block in     quick on tun0 from 192.168.0.0/16 to any
 +    block in     quick on tun0 from 172.16.0.0/12 to any
 +    block in     quick on tun0 from 10.0.0.0/8 to any
 +    block in     quick on tun0 from 127.0.0.0/8 to any
 +    block in     quick on tun0 from 0.0.0.0/8 to any
 +    block in     quick on tun0 from 169.254.0.0/16 to any
 +    block in     quick on tun0 from 192.0.2.0/24 to any
 +    block in     quick on tun0 from 204.152.64.0/23 to any
 +    block in     quick on tun0 from 224.0.0.0/3 to any
 +    block in log quick on tun0 from 20.20.20.0/24 to any
 +    block in log quick on tun0 from any to 20.20.20.0/32
 +    block in log quick on tun0 from any to 20.20.20.255/32
 +    pass  in       all
 +
 +2.9.  Complete Bi-Directional Filtering By Interface
 +
 +     So far we have only presented fragments of  a  complete
 +ruleset.   When  you're  actually creating your ruleset, you
 +should setup rules for every direction and every  interface.
 +The  default state of ipfilter is to pass packets.  It is as
 +though there were an invisible rule at the  beginning  which
 +states  pass  in  all and pass out all.  Rather than rely on
 +some default behaviour, make everything as specific as  pos-
 +sible,  interface by interface, until every base is covered.
 +
 +     First we'll start with the lo0 interface,  which  wants
 +to  run  wild and free.  Since these are programs talking to
 +others on the local system,  go  ahead  and  keep  it  unre-
 +stricted:
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -11-
 +
 +
 +    pass out quick on lo0
 +    pass in  quick on lo0
 +
 +Next, there's the xl0 interface.  Later on we'll begin plac-
 +ing restrictions on the xl0 interface, but  to  start  with,
 +we'll  act  as  though  everything  on  our local network is
 +trustworthy and give it much the same treatment as lo0:
 +
 +    pass out quick on xl0
 +    pass in  quick on xl0
 +
 +Finally, there's the tun0 interface, which we've been  half-
 +filtering with up until now:
 +
 +    block out quick on tun0 from any to 192.168.0.0/16
 +    block out quick on tun0 from any to 172.16.0.0/12
 +    block out quick on tun0 from any to 127.0.0.0/8
 +    block out quick on tun0 from any to 10.0.0.0/8
 +    block out quick on tun0 from any to 0.0.0.0/8
 +    block out quick on tun0 from any to 169.254.0.0/16
 +    block out quick on tun0 from any to 192.0.2.0/24
 +    block out quick on tun0 from any to 204.152.64.0/23
 +    block out quick on tun0 from any to 224.0.0.0/3
 +    pass  out quick on tun0 from 20.20.20.0/24 to any
 +    block out quick on tun0 from any to any
 +
 +    block in     quick on tun0 from 192.168.0.0/16 to any
 +    block in     quick on tun0 from 172.16.0.0/12 to any
 +    block in     quick on tun0 from 10.0.0.0/8 to any
 +    block in     quick on tun0 from 127.0.0.0/8 to any
 +    block in     quick on tun0 from 0.0.0.0/8 to any
 +    block in     quick on tun0 from 169.254.0.0/16 to any
 +    block in     quick on tun0 from 192.0.2.0/24 to any
 +    block in     quick on tun0 from 204.152.64.0/23 to any
 +    block in     quick on tun0 from 224.0.0.0/3 to any
 +    block in log quick on tun0 from 20.20.20.0/24 to any
 +    block in log quick on tun0 from any to 20.20.20.0/32
 +    block in log quick on tun0 from any to 20.20.20.255/32
 +    pass  in     all
 +
 +This  is  a  pretty significant amount of filtering already,
 +protecting 20.20.20.0/24 from being spoofed  or  being  used
 +for  spoofing.   Future  examples will continue to show one-
 +sideness, but keep in mind that it's for brevity's sake, and
 +when  setting  up  your  own ruleset, adding rules for every
 +direction and every interface is necessary.
 +
 +
 +2.10.  Controlling Specific Protocols; The "proto" Keyword
 +
 +     Denial of Service attacks  are  as  rampant  as  buffer
 +overflow  exploits.   Many denial of service attacks rely on
 +glitches in the OS's TCP/IP  stack.   Frequently,  this  has
 +come  in  the  form  of  ICMP  packets.   Why not block them
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -12-
 +
 +
 +entirely?
 +
 +    block in log quick on tun0 proto icmp from any to any
 +
 +Now any ICMP traffic coming in from tun0 will be logged  and
 +discarded.
 +
 +2.11.   Filtering ICMP with the "icmp-type" Keyword; Merging
 +Rulesets
 +
 +     Of course, dropping all ICMP isn't really an ideal sit-
 +uation.   Why  not drop all ICMP?  Well, because it's useful
 +to have partially enabled.  So maybe you want to  keep  some
 +types  of  ICMP  traffic  and drop other kinds.  If you want
 +ping and traceroute to work, you need to let in ICMP types 0
 +and  11.   Strictly speaking, this might not be a good idea,
 +but if you need to weigh security against  convenience,  IPF
 +lets you do it.
 +
 +    pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
 +    pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
 +
 +Remember that ruleset order is important.  Since we're doing
 +everything quick we must have our passes before our  blocks,
 +so we really want the last three rules in this order:
 +
 +    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
 +    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
 +    block in log quick on tun0 proto icmp from any to any
 +
 +Adding  these  3  rules  to the anti-spoofing rules is a bit
 +tricky.  One error might be to put the new ICMP rules at the
 +beginning:
 +
 +    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
 +    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
 +    block in log quick on tun0 proto icmp from any to any
 +    block in     quick on tun0 from 192.168.0.0/16 to any
 +    block in     quick on tun0 from 172.16.0.0/12 to any
 +    block in     quick on tun0 from 10.0.0.0/8 to any
 +    block in     quick on tun0 from 127.0.0.0/8 to any
 +    block in     quick on tun0 from 0.0.0.0/8 to any
 +    block in     quick on tun0 from 169.254.0.0/16 to any
 +    block in     quick on tun0 from 192.0.2.0/24 to any
 +    block in     quick on tun0 from 204.152.64.0/23 to any
 +    block in     quick on tun0 from 224.0.0.0/3 to any
 +    block in log quick on tun0 from 20.20.20.0/24 to any
 +    block in log quick on tun0 from any to 20.20.20.0/32
 +    block in log quick on tun0 from any to 20.20.20.255/32
 +    pass  in       all
 +
 +The  problem  with  this  is that an ICMP type 0 packet from
 +192.168.0.0/16 will get passed by the first rule, and  never
 +blocked  by the fourth rule.  Also, since we quickly pass an
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -13-
 +
 +
 +ICMP ECHO_REPLY (type 0) to 20.20.20.0/24, we've just opened
 +ourselves  back  up  to  a  nasty smurf attack and nullified
 +those last two block rules.  Oops.  To avoid this, we  place
 +the ICMP rules after the anti-spoofing rules:
 +
 +    block in     quick on tun0 from 192.168.0.0/16 to any
 +    block in     quick on tun0 from 172.16.0.0/12 to any
 +    block in     quick on tun0 from 10.0.0.0/8 to any
 +    block in     quick on tun0 from 127.0.0.0/8 to any
 +    block in     quick on tun0 from 0.0.0.0/8 to any
 +    block in     quick on tun0 from 169.254.0.0/16 to any
 +    block in     quick on tun0 from 192.0.2.0/24 to any
 +    block in     quick on tun0 from 204.152.64.0/23 to any
 +    block in     quick on tun0 from 224.0.0.0/3 to any
 +    block in log quick on tun0 from 20.20.20.0/24 to any
 +    block in log quick on tun0 from any to 20.20.20.0/32
 +    block in log quick on tun0 from any to 20.20.20.255/32
 +    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
 +    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
 +    block in log quick on tun0 proto icmp from any to any
 +    pass  in       all
 +
 +Because  we  block spoofed traffic before the ICMP rules are
 +processed, a spoofed packet never makes it to the ICMP rule-
 +set.   It's  very  important to keep such situations in mind
 +when merging rules.
 +
 +2.12.  TCP and UDP Ports; The "port" Keyword
 +
 +     Now that we've started blocking packets based on proto-
 +col, we can start blocking packets based on specific aspects
 +of each protocol.  The most frequently used of these aspects
 +is  the port number.  Services such as rsh, rlogin, and tel-
 +net are all very convenient  to  have,  but  also  hideously
 +insecure  against  network sniffing and spoofing.  One great
 +compromise is to only allow the services to run  internally,
 +then  block  them  externally.   This  is easy to do because
 +rlogin, rsh, and telnet use specific TCP  ports  (513,  514,
 +and 23 respectively).  As such, creating rules to block them
 +is easy:
 +
 +    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
 +    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
 +    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
 +
 +Make sure all 3 are before the pass in all  and  they'll  be
 +closed  off  from  the  outside  (leaving  out  spoofing for
 +brevity's sake):
 +
 +    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
 +    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
 +    block in log quick on tun0 proto icmp from any to any
 +    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
 +    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -14-
 +
 +
 +    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
 +    pass  in     all
 +
 +You might also want to block 514/udp  (syslog),   111/tcp  &
 +111/udp  (portmap),  515/tcp  (lpd),  2049/tcp  and 2049/udp
 +(NFS), 6000/tcp (X11) and so on and so forth.  You can get a
 +complete  listing  of  the  ports being listened to by using
 +netstat -a (or lsof -i, if you have it installed).
 +
 +     Blocking UDP instead of  TCP  only  requires  replacing
 +proto tcp with proto udp.  The rule for syslog would be:
 +
 +    block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 514
 +
 +IPF  also  has  a shorthand way to write rules that apply to
 +both proto tcp and proto udp  at  the  same  time,  such  as
 +portmap or NFS.  The rule for portmap would be:
 +
 +    block in log quick on tun0 proto tcp/udp from any to 20.20.20.0/24 port = 111
 +
 +
 +
 +
 +3.  Advanced Firewalling Introduction
 +
 +     This  section  is  designed as an immediate followup to
 +the basic section.  Contained below are  both  concepts  for
 +advanced  firewall  design,  and advanced features contained
 +only within ipfilter.  Once you are  comfortable  with  this
 +section, you should be able to build a very strong firewall.
 +
 +3.1.  Rampant Paranoia; or The Default-Deny Stance
 +
 +     There's a big problem with  blocking  services  by  the
 +port:  sometimes they move.  RPC based programs are terrible
 +about this, lockd, statd, even  nfsd  listens  places  other
 +than  2049.  It's awfully hard to predict, and even worse to
 +automate adjusting all the time.  What if you  miss  a  ser-
 +vice?   Instead of dealing with all that hassle, let's start
 +over with a clean slate.  The  current  ruleset  looks  like
 +this:
 +
 +
 +
 +
 +     Yes, we really are starting over.  The first rule we're
 +going to use is this:
 +
 +    block in all
 +
 +No network traffic gets through. None. Not a  peep.   You're
 +rather  secure  with  this  setup.  Not terribly useful, but
 +quite secure.  The great thing is that it doesn't take  much
 +more  to make your box rather secure, yet useful too.  Let's
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -15-
 +
 +
 +say the machine this is running on is a web server,  nothing
 +more,  nothing  less.   It  doesn't even do DNS lookups.  It
 +just wants to take connections on 80/tcp and that's it.   We
 +can  do  that.   We  can do that with a second rule, and you
 +already know how:
 +
 +    block in       on tun0 all
 +    pass  in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80
 +
 +This machine will pass in port 80  traffic  for  20.20.20.1,
 +and  deny  everything  else.  For basic firewalling, this is
 +all one needs.
 +
 +3.2.  Implicit Allow; The "keep state" Rule
 +
 +     The job of your firewall is to prevent unwanted traffic
 +getting  to  point  B  from  point A.  We have general rules
 +which say "as long as this packet is to port 23, it's okay."
 +We  have general rules which say "as long as this packet has
 +its FIN flag set, it's okay."  Our firewalls don't know  the
 +beginning, middle, or end of any TCP/UDP/ICMP session.  They
 +merely have vague rules that are  applied  to  all  packets.
 +We're  left  to  hope  that the packet with its FIN flag set
 +isn't really a FIN scan, mapping our services.  We hope that
 +the  packet to port 23 isn't an attempted hijack of our tel-
 +net session.  What if there was a way to identify and autho-
 +rize  individual  TCP/UDP/ICMP sessions and distinguish them
 +from port scanners and DoS attacks?  There is  a  way,  it's
 +called keeping state.
 +
 +     We  want convenience and security in one.  Lots of peo-
 +ple do, that's why Ciscos have an "established" clause  that
 +lets  established  tcp sessions go through.  Ipfw has estab-
 +lished.  Ipfwadm has setup/established.  They all have  this
 +feature, but the name is very misleading.  When we first saw
 +it, we thought it meant our packet filter was keeping  track
 +of  what  was  going  on,  that  it knew if a connection was
 +really established or not.  The fact is, they're all  taking
 +the  packet's  word for it from a part of the packet anybody
 +can lie about.  They read the TCP packet's flags section and
 +there's the reason UDP/ICMP don't work with it, they have no
 +such thing.  Anybody who can  create  a  packet  with  bogus
 +flags can get by a firewall with this setup.
 +
 +     Where  does  IPF  come in to play here, you ask?  Well,
 +unlike the other firewalls, IPF really  can  keep  track  of
 +whether or not a connection is established.  And it'll do it
 +with TCP, UDP and ICMP, not just TCP.  Ipf calls it  keeping
 +state.  The keyword for the ruleset is keep state.
 +
 +     Up until now, we've told you that packets come in, then
 +the ruleset gets checked; packets go out, then  the  ruleset
 +gets  checked.   Actually,  what happens is packets come in,
 +the state table  gets  checked,  then  *maybe*  the  inbound
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -16-
 +
 +
 +ruleset  gets  checked; packets go out, the state table gets
 +checked, then *maybe* the  outbound  ruleset  gets  checked.
 +The  state table is a list of TCP/UDP/ICMP sessions that are
 +unquestionadely passed through the  firewall,  circumventing
 +the  entire  ruleset.   Sound  like a serious security hole?
 +Hang on, it's the best thing  that  ever  happened  to  your
 +firewall.
 +
 +     All  TCP/IP sessions have a start, a middle, and an end
 +(even though they're sometimes all in the same packet).  You
 +can't have an end without a middle and you can't have a mid-
 +dle without a start.  This means that all you really need to
 +filter  on  is  the beginning of a TCP/UDP/ICMP session.  If
 +the beginning of the session is  allowed  by  your  firewall
 +rules,  you really want the middle and end to be allowed too
 +(lest your IP stack should overflow and your machines become
 +useless).  Keeping state allows you to ignore the middle and
 +end and simply focus on blocking/passing new  sessions.   If
 +the  new  session is passed, all its subsequent packets will
 +be allowed through.  If it's blocked, none of its subsequent
 +packets will be allowed through.  Here's an example for run-
 +ning an ssh server (and nothing but an ssh server):
 +
 +    block out quick on tun0 all
 +    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep state
 +
 +The first thing you might notice is that  there's  no  "pass
 +out"  provision.   In  fact,  there's  only an all-inclusive
 +"block out" rule.  Despite this, the  ruleset  is  complete.
 +This is because by keeping state, the entire ruleset is cir-
 +cumvented.  Once the first SYN packet hits the  ssh  server,
 +state  is  created  and  the remainder of the ssh session is
 +allowed to take place without interference  from  the  fire-
 +wall.  Here's another example:
 +
 +    block in  quick on tun0 all
 +    pass  out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
 +
 +In  this  case,  the server is running no services.  Infact,
 +it's not a server, it's a client.  And this  client  doesn't
 +want  unauthorized  packets  entering  its  IP stack at all.
 +However, the client wants full access to  the  internet  and
 +the  reply packets that such privledge entails.  This simple
 +ruleset creates state entries for  every  new  outgoing  TCP
 +session.   Again,  since a state entry is created, these new
 +TCP sessions are free to talk back and forth as they  please
 +without  the  hinderance or inspection of the firewall rule-
 +set.  We mentioned that this also works for UDP and ICMP:
 +
 +    block in  quick on tun0 all
 +    pass  out quick on tun0 proto tcp  from 20.20.20.1/32 to any keep state
 +    pass  out quick on tun0 proto udp  from 20.20.20.1/32 to any keep state
 +    pass  out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -17-
 +
 +
 +Yes Virginia, we can ping.  Now we're keeping state on  TCP,
 +UDP,  ICMP.   Now we can make outgoing connections as though
 +there's no firewall at all, yet would-be attackers can't get
 +back  in.   This  is  very  handy because there's no need to
 +track down what ports we're listening to, only the ports  we
 +want people to be able to get to.
 +
 +     State is pretty handy, but it's also a bit tricky.  You
 +can shoot yourself in the foot  in  strange  and  mysterious
 +ways.  Consider the following ruleset:
 +
 +     pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23
 +     pass  out quick on tun0 proto tcp from any to any keep state
 +     block in  quick all
 +     block out quick all
 +
 +At  first  glance,  this seems to be a good setup.  We allow
 +incoming sessions to port 23,  and  outgoing  sessions  any-
 +where.   Naturally  packets going to port 23 will have reply
 +packets, but the ruleset is setup in such  a  way  that  the
 +pass  out  rule  will  generate a state entry and everything
 +will work perfectly.  At least, you'd think so.
 +
 +     The unfortunate truth is that after 60 seconds of  idle
 +time  the state entry will be closed (as opposed to the nor-
 +mal 5 days).  This is because the state  tracker  never  saw
 +the original SYN packet destined to port 23, it only saw the
 +SYN ACK.  IPF is very good about following TCP sessions from
 +start  to  finish,  but it's not very good about coming into
 +the middle of a connection, so rewrite the rule to look like
 +this:
 +
 +     pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
 +     pass  out quick on tun0 proto tcp from any to any keep state
 +     block in  quick all
 +     block out quick all
 +
 +The additional of this rule will enter the very first packet
 +into the state table and everything will work  as  expected.
 +Once  the  3-way  handshake  has  been  witness by the state
 +engine, it is marked in 4/4 mode, which means it's setup for
 +long-term data exchange until such time as the connection is
 +torn down (wherein the mode changes again.  You can see  the
 +current modes of your state table with ipfstat -s.
 +
 +3.3.  Stateful UDP
 +
 +     UDP is stateless so naturally it's a bit harder to do a
 +reliable job of keeping state on it.  Nonetheless, ipf  does
 +a  pretty  good  job.   When machine A sends a UDP packet to
 +machine B with source port X and  destination  port  Y,  ipf
 +will  allow  a reply from machine B to machine A with source
 +port Y and destination port X.  This is a short  term  state
 +entry, a mere 60 seconds.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -18-
 +
 +
 +     Here's an example of what happens if we use nslookup to
 +get the IP address of www.3com.com:
 +
 +    $ nslookup www.3com.com
 +
 +  A DNS packet is generated:
 +
 +    17:54:25.499852 20.20.20.1.2111 > 198.41.0.5.53: 51979+
 +
 +The packet is  from  20.20.20.1,  port  2111,  destined  for
 +198.41.0.5,  port  53.   A 60 second state entry is created.
 +If a packet comes back from 198.41.0.5 port 53 destined  for
 +20.20.20.1  port  2111 within that period of time, the reply
 +packet will be let through.  As you  can  see,  milliseconds
 +later:
 +
 +    17:54:25.501209 198.41.0.5.53 > 20.20.20.1.2111: 51979 q: www.3com.com
 +
 +The  reply  packet  matches  the  state  criteria and is let
 +through.  At that same moment that packet  is  let  through,
 +the state gateway is closed and no new incoming packets will
 +be allowed in, even if they claim to be from the same place.
 +
 +3.4.  Stateful ICMP
 +
 +     IPFilter  handles  ICMP  states  in the manner that one
 +would expect from understanding how ICMP is  used  with  TCP
 +and  UDP,  and  with  your  understanding  of how keep state
 +works.  There  are  two  general  types  of  ICMP  messages;
 +requests and replies.   When you write a rule such as:
 +
 +    pass out on tun0 proto icmp from any to any icmp-type 8 keep state
 +
 +to allow outbound echo requests (a typical ping), the resul-
 +tant icmp-type 0 packet that comes back will be allowed  in.
 +This  state entry has a default timeout of an incomplete 0/0
 +state of 60 seconds.   Thus, if you are keeping state on any
 +outbound  icmp  message  that will elicit an icmp message in
 +reply, you need a proto icmp [...] keep state rule.
 +
 +     However, the majority of ICMP messages are status  mes-
 +sages  generated by some failure in UDP (and sometimes TCP),
 +and in 3.4.x and greater IPFilters, any  ICMP  error  status
 +message  (say  icmp-type 3 code 3 port unreachable, or icmp-
 +type 11 time exceeded) that matches an  active  state  table
 +entry  that  could  have  generated  that  message, the ICMP
 +packet is let in.  For example, in older IPFilters,  if  you
 +wanted traceroute to work, you needed to use:
 +
 +    pass out on tun0 proto udp from any to any port 33434><33690 keep state
 +    pass in on tun0 proto icmp from any to any icmp-type timex
 +
 +whereas  now  you can do the right thing and just keep state
 +on udp with:
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -19-
 +
 +
 +    pass out on tun0 proto udp from any to any port 33434><33690 keep state
 +
 +To provide some protection against  a  third-party  sneaking
 +ICMP  messages  through your firewall when an active connec-
 +tion is known to be in your state table, the  incoming  ICMP
 +packet  is checked not only for matching source and destina-
 +tion addresses (and ports, when applicable) but a tiny  part
 +of the payload of the packet that the ICMP message is claim-
 +ing it was generated by.
 +
 +3.5.  FIN Scan Detection; "flags" Keyword, "keep frags" Key-
 +word
 +
 +Let's go back to the 4 rule set from the previous section:
 +
 +    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
 +    pass  out quick on tun0 proto tcp from any to any keep state
 +    block in  quick all
 +    block out quick all
 +
 +This is almost, but not quite, satisfactory.  The problem is
 +that it's not just SYN packets that're allowed to go to port
 +23,  any  old packet can get through.  We can change this by
 +using the flags option:
 +
 +    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state
 +    pass  out quick on tun0 proto tcp from any to any flags S keep state
 +    block in  quick all
 +    block out quick all
 +
 +Now only TCP packets, destined for 20.20.20.1, at  port  23,
 +with a lone SYN flag will be allowed in and entered into the
 +state table.  A lone SYN flag is only present  as  the  very
 +first packet in a TCP session (called the TCP handshake) and
 +that's really what we wanted all along.   There's  at  least
 +two  advantages  to  this:  No arbitrary packets can come in
 +and make a mess of your state table.   Also,  FIN  and  XMAS
 +scans  will  fail  since  they  set flags other than the SYN
 +flag.  Now all incoming packets must either be handshakes or
 +have state already.  If anything else comes in, it's  proba-
 +bly  a  port scan or a forged packet.  There's one exception
 +to that, which is when a packet comes in  that's  fragmented
 +from  its journey.  IPF has provisions for this as well, the
 +-----------
 + Some examples use flags S/SA instead of flags  S.
 +flags  S  actually  equates  to flags S/AUPRFS and
 +matches against only the SYN packet out of all six
 +possible  flags, while flags S/SA will allow pack-
 +ets that may or may not have the URG, PSH, FIN, or
 +RST  flags  set.  Some protocols demand the URG or
 +PSH flags, and S/SAFR would be a better choice for
 +these,  however  we feel that it is less secure to
 +blindly use S/SA when it isn't required.  But it's
 +your firewall.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -20-
 +
 +
 +keep frags keyword.  With it, IPF will notice and keep track
 +of  packets that are fragmented, allowing the expected frag-
 +ments to to go through.  Let's rewrite the 3  rules  to  log
 +forgeries and allow fragments:
 +
 +    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state keep frags
 +    pass  out quick on tun0 proto tcp from any to any keep state flags S keep frags
 +    block in  log quick all
 +    block out log quick all
 +
 +This  works  because  every  packet  that  should be allowed
 +through makes it into the state table  before  the  blocking
 +rules  are reached. The only scan this won't detect is a SYN
 +scan itself.  If you're truely worried about that, you might
 +even want to log all initial SYN packets.
 +
 +3.6.  Responding To a Blocked Packet
 +
 +     So  far, all of our blocked packets have been dumped on
 +the floor, logged or not, we've never sent anything back  to
 +the  originating host.  Sometimes this isn't the most desir-
 +able of responses because in doing so, we actually tell  the
 +attacker  that  a  packet filter is present.  It seems a far
 +better thing to misguide the attacker into  believing  that,
 +while  there's no packet filter running, there's likewise no
 +services to break into.   This  is  where  fancier  blocking
 +comes into play.
 +
 +     When  a service isn't running on a Unix system, it nor-
 +mally lets the remote host know with  some  sort  of  return
 +packet.   In  TCP,  this is done with an RST (Reset) packet.
 +When blocking a TCP packet, IPF can actually return  an  RST
 +to the origin by using the return-rst keyword.
 +
 +Where once we did:
 +
 +    block in log on tun0 proto tcp from any to 20.20.20.0/24 port = 23
 +    pass  in     all
 +
 +We might now do:
 +
 +    block return-rst in log proto tcp from any to 20.20.20.0/24 port = 23
 +    block in log quick on tun0
 +    pass  in     all
 +
 +We  need  two  block  statements since return-rst only works
 +with TCP, and we still want to block protocols such as  UDP,
 +ICMP,  and  others.   Now that this is done, the remote side
 +will get "connection refused" instead of  "connection  timed
 +out".
 +
 +     It's  also possible to send an error message when some-
 +body sends a packet to a UDP port on your  system.   Whereas
 +once you might have used:
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -21-
 +
 +
 +    block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
 +
 +You  could  instead  use  the  return-icmp keyword to send a
 +reply:
 +
 +    block return-icmp(port-unr) in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
 +
 +According to TCP/IP  Illustrated,  port-unreachable  is  the
 +correct  ICMP type to return when no service is listening on
 +the port in question.  You can use any ICMP type  you  like,
 +but  port-unreachable  is probably your best bet.  It's also
 +the default ICMP type for return-icmp.
 +
 +     However, when using  return-icmp,  you'll  notice  that
 +it's  not very stealthy, and it returns the ICMP packet with
 +the IP address of the firewall, not the original destination
 +of  the  packet.   This was fixed in ipfilter 3.3, and a new
 +keyword; return-icmp-as-dest, has been added.   The new for-
 +mat is:
 +
 +     block return-icmp-as-dest(port-unr) in log on tun0 proto udp from any to 20.20.20.0/24 port = 111
 +
 +3.7.  Fancy Logging Techniques
 +
 +     It  is  important  to note that the presence of the log
 +keyword only ensures that the packet will  be  available  to
 +the  ipfilter  logging device; /dev/ipl.   In order to actu-
 +ally see this log information, one must be running the ipmon
 +utility  (or  some  other utility that reads from /dev/ipl).
 +The typical usage of log is coupled with ipmon -s to log the
 +information to syslog.  As of ipfilter 3.3, one can now even
 +control the logging behavior of syslog by  using  log  level
 +keywords, as in rules such as this:
 +
 +     block in log level auth.info quick on tun0 from 20.20.20.0/24 to any
 +     block in log level auth.alert quick on tun0 proto tcp from any to 20.20.20.0/24 port = 21
 +
 +In  addition  to  this,  you  can tailor what information is
 +being logged.  For example, you may not be  interested  that
 +someone  attempted  to probe your telnet port 500 times, but
 +you are interested that they probed you once.  You  can  use
 +the  log  first  keyword  to only log the first example of a
 +packet.  Of course, the notion of "first-ness" only  applies
 +to  packets  in  a  specific  session,  and  for the typical
 +blocked packet, you will be hard pressed to encounter situa-
 +tions  where this does what you expect.  However, if used in
 +conjunction with pass and keep state, this can be a valuable
 +keyword for keeping tabs on traffic.
 +
 +     Another  useful  thing  you  can do with the logs is to
 +keep track of interesting pieces of the packet  in  addition
 +to  the  header information normally being logged.  Ipfilter
 +will give you the first 128 bytes of the packet if  you  use
 +the  log  body  keyword.   You  should limit the use of body
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -22-
 +
 +
 +logging, as it makes your logs very verbose, but for certain
 +applications,  it  is  often handy to be able to go back and
 +take a look at the packet, or to send this data  to  another
 +application that can examine it further.
 +
 +3.8.  Putting It All Together
 +
 +     So  now  we  have  a  pretty tight firewall, but it can
 +still be tighter.  Some of the  original  ruleset  we  wiped
 +clean  is  actually  very useful.  I'd suggest bringing back
 +all the anti-spoofing stuff.  This leaves us with:
 +
 +    block in           on tun0
 +    block in     quick on tun0 from 192.168.0.0/16 to any
 +    block in     quick on tun0 from 172.16.0.0/12 to any
 +    block in     quick on tun0 from 10.0.0.0/8 to any
 +    block in     quick on tun0 from 127.0.0.0/8 to any
 +    block in     quick on tun0 from 0.0.0.0/8 to any
 +    block in     quick on tun0 from 169.254.0.0/16 to any
 +    block in     quick on tun0 from 192.0.2.0/24 to any
 +    block in     quick on tun0 from 204.152.64.0/23 to any
 +    block in     quick on tun0 from 224.0.0.0/3 to any
 +    block in log quick on tun0 from 20.20.20.0/24 to any
 +    block in log quick on tun0 from any to 20.20.20.0/32
 +    block in log quick on tun0 from any to 20.20.20.255/32
 +    pass  out quick on tun0 proto tcp/udp from 20.20.20.1/32 to any keep state
 +    pass  out quick on tun0 proto icmp    from 20.20.20.1/32 to any keep state
 +    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 flags S keep state
 +
 +3.9.  Improving Performance With Rule Groups
 +
 +     Let's extend our use of our firewall by creating a much
 +more  complicated,  and  we hope more applicable to the real
 +world, example configuration For this example,  we're  going
 +to  change  the interface names, and network numbers.  Let's
 +assume that we have three interfaces in  our  firewall  with
 +interfaces xl0, xl1, and xl2.
 +
 +xl0 is connected to our external network 20.20.20.0/26
 +xl1 is connected to our "DMZ" network 20.20.20.64/26
 +xl2 is connected to our protected network 20.20.20.128/25
 +
 +We'll  define the entire ruleset in one swoop, since we fig-
 +ure that you can read these rules by now:
 +
 +    block in     quick on xl0 from 192.168.0.0/16 to any
 +    block in     quick on xl0 from 172.16.0.0/12 to any
 +    block in     quick on xl0 from 10.0.0.0/8 to any
 +    block in     quick on xl0 from 127.0.0.0/8 to any
 +    block in     quick on xl0 from 0.0.0.0/8 to any
 +    block in     quick on xl0 from 169.254.0.0/16 to any
 +    block in     quick on xl0 from 192.0.2.0/24 to any
 +    block in     quick on xl0 from 204.152.64.0/23 to any
 +    block in     quick on xl0 from 224.0.0.0/3 to any
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -23-
 +
 +
 +    block in log quick on xl0 from 20.20.20.0/24 to any
 +    block in log quick on xl0 from any to 20.20.20.0/32
 +    block in log quick on xl0 from any to 20.20.20.63/32
 +    block in log quick on xl0 from any to 20.20.20.64/32
 +    block in log quick on xl0 from any to 20.20.20.127/32
 +    block in log quick on xl0 from any to 20.20.20.128/32
 +    block in log quick on xl0 from any to 20.20.20.255/32
 +    pass out on xl0 all
 +
 +    pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state
 +    pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state
 +    pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state
 +    pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state
 +    pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state
 +    pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
 +    pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state
 +    block out on xl1 all
 +    pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
 +
 +    block out on xl2 all
 +    pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
 +
 +From this arbitarary example, we can already  see  that  our
 +ruleset is becoming unwieldy.   To make matters worse, as we
 +add more specific rules to our DMZ  network,  we  add  addi-
 +tional  tests  that  must  be parsed for every packet, which
 +affects the performance of the xl0 <-> xl2 connections.   If
 +you set up a firewall with a ruleset like this, and you have
 +lots of bandwidth and a moderate  amount  of  cpu,  everyone
 +that  has  a workstation on the xl2 network is going to come
 +looking for your head to place on a platter.   So,  to  keep
 +your  head  <->  torso  network intact, you can speed things
 +along by creating rule groups.   Rule groups  allow  you  to
 +write your ruleset in a tree fashion, instead of as a linear
 +list, so that if your packet has nothing to do with the  set
 +of  tests  (say, all those xl1 rules) those rules will never
 +be consulted.  It's somewhat like having multiple  firewalls
 +all on the same machine.
 +
 +Here's a simple example to get us started:
 +
 +    block out quick on xl1 all head 10
 +    pass out quick proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
 +    block out on xl2 all
 +
 +In  this  simplistic example, we can see a small hint of the
 +power of the rule group.  If the packet is not destined  for
 +xl1,  the  head of rule group 10 will not match, and we will
 +go on with our tests.  If the packet does match for xl1, the
 +quick  keyword  will short-circuit all further processing at
 +the root level (rule group 0),  and  focus  the  testing  on
 +rules  which  belong  to group 10; namely, the SYN check for
 +80/tcp.  In this way, we can re-write  the  above  rules  so
 +that we can maximize performance of our firewall.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -24-
 +
 +
 +    block in quick on xl0 all head 1
 +      block in     quick on xl0 from 192.168.0.0/16 to any  group 1
 +      block in     quick on xl0 from 172.16.0.0/12 to any   group 1
 +      block in     quick on xl0 from 10.0.0.0/8 to any      group 1
 +      block in     quick on xl0 from 127.0.0.0/8 to any     group 1
 +      block in     quick on xl0 from 0.0.0.0/8 to any       group 1
 +      block in     quick on xl0 from 169.254.0.0/16 to any  group 1
 +      block in     quick on xl0 from 192.0.2.0/24 to any    group 1
 +      block in     quick on xl0 from 204.152.64.0/23 to any group 1
 +      block in     quick on xl0 from 224.0.0.0/3 to any     group 1
 +      block in log quick on xl0 from 20.20.20.0/24 to any   group 1
 +      block in log quick on xl0 from any to 20.20.20.0/32   group 1
 +      block in log quick on xl0 from any to 20.20.20.63/32  group 1
 +      block in log quick on xl0 from any to 20.20.20.64/32  group 1
 +      block in log quick on xl0 from any to 20.20.20.127/32 group 1
 +      block in log quick on xl0 from any to 20.20.20.128/32 group 1
 +      block in log quick on xl0 from any to 20.20.20.255/32 group 1
 +      pass  in           on xl0 all group 1
 +
 +    pass out on xl0 all
 +
 +    block out quick on xl1 all head 10
 +      pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
 +      pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state group 10
 +      pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state group 10
 +      pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state group 10
 +      pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53         keep state group 10
 +      pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
 +      pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53         keep state group 10
 +
 +    pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
 +
 +    block out on xl2 all
 +
 +    pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
 +
 +Now  you  can  see the rule groups in action.  For a host on
 +the xl2 network, we can completely bypass all the checks  in
 +group  10  when  we're  not communicating with hosts on that
 +network.
 +
 +     Depending on your situation, it may be prudent to group
 +your  rules  by protocol, or various machines, or netblocks,
 +or whatever makes it flow smoothly.
 +
 +3.10.  "Fastroute"; The Keyword of Stealthiness
 +
 +     Even though we're forwarding some packets, and blocking
 +other  packets, we're typically behaving like a well behaved
 +router should by decrementing the  TTL  on  the  packet  and
 +acknowledging  to  the entire world that yes, there is a hop
 +here.  But we can hide our presence from inquisitive  appli-
 +cations  like  unix  traceroute  which uses UDP packets with
 +various TTL values to map the hops between two sites.  If we
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -25-
 +
 +
 +want  incoming  traceroutes  to  work, but we do not want to
 +announce the presence of our firewall as a hop, we can do so
 +with a rule like this:
 +
 +    block in quick on xl0 fastroute proto udp from any to any port 33434 >< 33465
 +
 +The  presence  of the fastroute keyword will signal ipfilter
 +to not pass the packet into the Unix IP  stack  for  routing
 +which results in a TTL decrement.  The packet will be placed
 +gently on the output interface by  ipfilter  itself  and  no
 +such decrement will happen.  Ipfilter will of course use the
 +system's routing table to figure out  what  the  appropriate
 +output  interface  really  is,  but it will take care of the
 +actual task of routing itself.
 +
 +     There's a reason we used block quick  in  our  example,
 +too.   If  we  had  used  pass,  and if we had IP Forwarding
 +enabled in our kernel, we would end up having two paths  for
 +a  packet  to  come  out of, and we would probably panic our
 +kernel.
 +
 +     It should be noted, however,  that  most  Unix  kernels
 +(and certainly the ones underlying the systems that ipfilter
 +usually runs on) have far more efficient routing  code  than
 +what  exists  in  ipfilter,  and  this keyword should not be
 +thought of as a way to improve the operating speed  of  your
 +firewall, and should only be used in places where stealth is
 +an issue.
 +
 +
 +
 +
 +4.  NAT and Proxies
 +
 +     Outside  of  the  corporate  environment,  one  of  the
 +biggest  enticements  of firewall technology to the end user
 +is the ability to connect several computers through a common
 +external  interface,  often without the approval, knowledge,
 +or even consent of their service provider.  To those  famil-
 +iar  with Linux, this concept is called IP Masquerading, but
 +to the rest of the world it is known  by  the  more  obscure
 +name of Network Address Translation, or NAT for short.
 +
 +4.1.  Mapping Many Addresses Into One Address
 +
 +     The basic use of NAT accomplishes much the  same  thing
 +that  Linux's  IP Masquerading function does, and it does it
 +-----------
 +  To be pedantic, what IPFilter provides is really
 +called NPAT, for Network and Port Address Transla-
 +tion,  which means we can change any of the source
 +and destination IP Addresses and their source  and
 +destination  ports.   True  NAT only allows one to
 +change the addresses.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -26-
 +
 +
 +with one simple rule:
 +
 +    map tun0 192.168.1.0/24 -> 20.20.20.1/32
 +
 +Very simple.  Whenever a packet goes out the tun0  interface
 +with  a  source  address  matching  the CIDR network mask of
 +192.168.1.0/24 this packet will be rewritten within  the  IP
 +stack  such  that  its  source address is 20.20.20.1, and it
 +will be sent on to its original  destination.    The  system
 +also  keeps  a  list  of  what translated connections are in
 +progress so that it can perform the reverse  and  remap  the
 +response  (which  will  be  directed  to  20.20.20.1) to the
 +internal host that really generated the packet.
 +
 +     There is a drawback to the rule we have  just  written,
 +though.   In  a  large  number of cases, we do not happen to
 +know what the IP address of our outside link  is  (if  we're
 +using tun0 or ppp0 and a typical ISP) so it makes setting up
 +our NAT tables a chore.   Luckily, NAT is  smart  enough  to
 +accept  an  address  of 0/32 as a signal that it needs to go
 +look at what the address of that interface really is and  we
 +can rewrite our rule as follows:
 +
 +    map tun0 192.168.1.0/24 -> 0/32
 +
 +Now we can load our ipnat rules with impunity and connect to
 +the outside world without having to edit  anything.  You  do
 +have to run ipf -y to refresh the address if you get discon-
 +nected and redial or if your DHCP lease changes, though.
 +
 +     Some of you may be wondering what happens to the source
 +port  when  the mapping happens.  With our current rule, the
 +packet's source port is unchanged from the  original  source
 +port.   There  can  be instances where we do not desire this
 +behavior; maybe we have another firewall further upstream we
 +have  to  pass  through, or perhaps many hosts are trying to
 +use the same source port, causing a collision where the rule
 +doesn't  match and the packet is passed untranslated.  ipnat
 +helps us here with the portmap keyword:
 +
 +    map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000
 +
 +Our rule now shoehorns all the translated connections (which
 +can be tcp, udp, or tcp/udp) into the port range of 20000 to
 +30000.
 +
 +
 +
 +-----------
 + This is a typical internal address  space,  since
 +it's non-routable on the Real Internet it is often
 +used for internal  networks.    You  should  still
 +block  these  packets  coming  in from the outside
 +world as discussed earlier.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -27-
 +
 +
 +4.2.  Mapping Many Addresses Into a Pool of Addresses
 +
 +     Another use common use of NAT is to take a small stati-
 +cally  allocated  block  of addresses and map many computers
 +into this smaller address space.   This is  easy  to  accom-
 +plish  using what you already know about the map and portmap
 +keywords by writing a rule like so:
 +
 +    map tun0 192.168.0.0/16 -> 20.20.20.0/24 portmap tcp/udp 20000:60000
 +
 +Also, there may be  instances  where  a  remote  application
 +requires that multiple connections all come from the same IP
 +address.  We can help with these situations by  telling  NAT
 +to  statically  map  sessions  from  a host into the pool of
 +addresses and work some magic to choose a port. This uses  a
 +the keyword map-block as follows:
 +
 +    map-block tun0 192.168.1.0/24 -> 20.20.20.0/24
 +
 +4.3.  One to One Mappings
 +
 +     Occasionally  it is desirable to have a system with one
 +IP address behind the firewall to  appear  to  have  a  com-
 +pletely different IP address.  One example of how this would
 +work would be a lab of computers which are then attached  to
 +various networks that are to be put under some kind of test.
 +In this example, you would not want to have  to  reconfigure
 +the  entire  lab  when you could place a NAT system in front
 +and change the addresses in one simple place.    We  can  do
 +that  with  the  bimap  keyword,  for bidirectional mapping.
 +Bimap has some additional protections  on  it  to  ensure  a
 +known  state  for the connection, whereas the map keyword is
 +designed to allocate  an  address  and  a  source  port  and
 +rewrite the packet and go on with life.
 +
 +      bimap tun0 192.168.1.1/32 -> 20.20.20.1/32
 +
 +will accomplish the mapping for one host.
 +
 +4.4.  Spoofing Services
 +
 +     Spoofing services?  What does that have to do with any-
 +thing?   Plenty.  Let's pretend that we have  a  web  server
 +running  on  20.20.20.5, and since we've gotten increasingly
 +suspicious of our network security, we  desire  to  not  run
 +this  server on port 80 since that requires a brief lifespan
 +as the root  user.    But  how  do  we  run  it  on  a  less
 +privledged port of 8000 in this world of "anything dot com"?
 +How will anyone find our server?  We can use the redirection
 +facilities of NAT to solve this problem by instructing it to
 +remap any connections destined for 20.20.20.5:80  to  really
 +point to 20.20.20.5:8000.   This uses the rdr keyword:
 +
 +      rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -28-
 +
 +
 +We can also specify the protocol here, if we wanted to redi-
 +rect a UDP service, instead of a TCP service (which  is  the
 +default).  For example, if we had a honeypot on our firewall
 +to impersonate the popular  Back  Orifice  for  Windows,  we
 +could  shovel  our entire network into this one place with a
 +simple rule:
 +
 +        rdr tun0 20.20.20.0/24 port 31337 -> 127.0.0.1 port 31337 udp
 +
 +An extremely important point must be made  about  rdr:   You
 +cannot easily use this feature as a "reflector".  E.g:
 +
 +     rdr tun0 20.20.20.5/32 port 80 -> 20.20.20.6 port 80 tcp
 +
 +will  not  work  in the situation where .5 and .6 are on the
 +same  LAN  segment.   The rdr function is applied to packets
 +that enter the firewall on the specified interface.  When  a
 +packet  comes  in  that  matches a rdr rule, its destination
 +address is then rewritten, it is pushed into ipf for filter-
 +ing,  and  should it successfully run the gauntlet of filter
 +rules, it is then sent to the unix routing code.  Since this
 +packet  is  still inbound on the same interface that it will
 +need to leave the system on to reach a host, the system gets
 +confused.   Reflectors  don't work.  Neither does specifying
 +the address of the interface the packet  just  came  in  on.
 +Always  remember  that rdr destinations must exit out of the
 +firewall host on a different interface.
 +
 +4.5.  Transparent Proxy Support; Redirection Made Useful
 +
 +     Since  you're  installing  a  firewall,  you  may  have
 +decided that it is prudent to use a proxy for many  of  your
 +outgoing  connections  so  that you can further tighten your
 +filter rules protecting your internal network,  or  you  may
 +have  run into a situation that the NAT mapping process does
 +not currently handle properly.   This  can  also  be  accom-
 +plished with a redirection statement:
 +
 +        rdr xl0 0.0.0.0/0 port 21 -> 127.0.0.1 port 21
 +
 +This  statement  says  that  any packet coming in on the xl0
 +interface destined for any address (0.0.0.0/0)  on  the  ftp
 +port  should be rewritten to connect it with a proxy that is
 +running on the NAT system on port 21.
 +
 +-----------
 + Yes. There is a way to do this.  It's  so  convo-
 +luted that I refuse to use it, though.  Smart peo-
 +ple who require this functionality will  transpar-
 +ently  redirect into something like TIS plug-gw on
 +127.0.0.1.  Stupid people will set up a dummy loop
 +interface pair and double rewrite.
 + This includes 127.0.0.1, by the way.   That's  on
 +lo0.  Neat, huh?
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -29-
 +
 +
 +     This specific example of FTP proxying does lead to some
 +complications  when  used  with  web browsers or other auto-
 +matic-login type clients that are unaware  of  the  require-
 +ments  of  communicating  with the proxy.  There are patches
 +for TIS Firewall Toolkit'sftp-gw to mate  it  with  the  nat
 +process so that it can determine where you were trying to go
 +and automatically send you there.  Many proxy  packages  now
 +work  in a transparent proxy environment (Squid for example,
 +located at http://squid.nlanr.net, works fine.)
 +
 +     This application of the rdr keyword is often more  use-
 +ful  when you wish to force users to authenticate themselves
 +with the proxy. (For example, you desire your  engineers  to
 +be  able to surf the web, but you would rather not have your
 +call-center staff doing so.)
 +
 +4.6.  Magic Hidden Within NAT; Application Proxies
 +
 +     Since ipnat provides a method  to  rewrite  packets  as
 +they traverse the firewall, it becomes a convenient place to
 +build in some application level proxies to make up for  well
 +known  deficiencies  of  that  application and typical fire-
 +walls.  For example; FTP.   We can  make  our  firewall  pay
 +attention to the packets going across it and when it notices
 +that it's dealing with an Active FTP session, it  can  write
 +itself  some  temporary  rules,  much like what happens with
 +keep state, so that the FTP data connection works.    To  do
 +this, we use a rule like so:
 +
 +   map tun0 192.168.1.0/24 -> 20.20.20.1/32 proxy port ftp ftp/tcp
 +
 +You must always remember to place this proxy rule before any
 +portmap  rules,  otherwise  when  portmap  comes  along  and
 +matches  the  packet and rewrites it before the proxy gets a
 +chance to work on it.  Remember that ipnat rules are  first-
 +match.
 +
 +     There  also  exist proxies for "rcmd" (which we suspect
 +is berkeley r-* commands which should be  forbidden  anyway,
 +thus we haven't looked at what this proxy does) and "raudio"
 +for Real Audio PNM streams.  Likewise, both of  these  rules
 +should be put before any portmap rules, if you're doing NAT.
 +
 +
 +
 +5.  Loading and Manipulating Filter Rules; The ipf Utility
 +
 +     IP Filter rules are loaded by using  the  ipf  utility.
 +The  filter  rules  can be stored in any file on the system,
 +but typically these  rules  are  stored  in  /etc/ipf.rules,
 +/usr/local/etc/ipf.rules, or /etc/opt/ipf/ipf.rules.
 +
 +     IP Filter has two sets of rules, the active set and the
 +inactive set.  By default, all operations are  performed  on
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -30-
 +
 +
 +the  active  set.   You  can  manipulate the inactive set by
 +adding -I to the ipf command line.   The  two  sets  can  be
 +toggled  by  using the -s command line option.  This is very
 +useful for testing new rule sets without wiping out the  old
 +rule set.
 +
 +     Rules  can  also  be  removed  from the list instead of
 +added by using the -r command line option, but it is  gener-
 +ally  a safer idea to flush the rule set that you're working
 +on with -F and completely reload it when making changes.
 +
 +     In summary, the easiest way to load a rule set  is  ipf
 +-Fa  -f  /etc/ipf.rules.  For more complicated manipulations
 +of the rule set, please see the ipf(1) man page.
 +
 +6.  Loading and Manipulating NAT Rules; The ipnat Utility
 +
 +     NAT rules are loaded by using the ipnat  utility.   The
 +NAT rules can be stored in any file on the system, but typi-
 +cally  these   rules   are   stored   in   /etc/ipnat.rules,
 +/usr/local/etc/ipnat.rules, or /etc/opt/ipf/ipnat.rules.
 +
 +     Rules  can  also  be  removed  from the list instead of
 +added by using the -r command line option, but it is  gener-
 +ally  a safer idea to flush the rule set that you're working
 +on with -C and completely reload  it  when  making  changes.
 +Any  active  mappings  are  not  affected  by -C, and can be
 +removed with -F.
 +
 +     NAT rules and active mappings can be examined with  the
 +-l command line option.
 +
 +     In  summary,  the easiest way to load a NAT rule set is
 +ipnat -CF -f /etc/ipnat.rules.
 +
 +7.  Monitoring and Debugging
 +
 +     There will come a time when you are interested in  what
 +your  firewall  is  actually  doing,  and  ipfilter would be
 +incomplete if it didn't have a full suite of status monitor-
 +ing tools.
 +
 +7.1.  The ipfstat utility
 +
 +     In  its  simplest  form,  ipfstat  displays  a table of
 +interesting data about how your firewall is performing, such
 +as  how  many  packets  have been passed or blocked, if they
 +were logged or not, how many state entries have  been  made,
 +and  so  on.   Here's  an example of something you might see
 +from running the tool:
 +
 +    # ipfstat
 +     input packets:         blocked 99286 passed 1255609 nomatch 14686 counted 0
 +    output packets:         blocked 4200 passed 1284345 nomatch 14687 counted 0
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -31-
 +
 +
 +     input packets logged:  blocked 99286 passed 0
 +    output packets logged:  blocked 0 passed 0
 +     packets logged:        input 0 output 0
 +     log failures:          input 3898 output 0
 +    fragment state(in):     kept 0  lost 0
 +    fragment state(out):    kept 0  lost 0
 +    packet state(in):       kept 169364     lost 0
 +    packet state(out):      kept 431395     lost 0
 +    ICMP replies:   0       TCP RSTs sent:  0
 +    Result cache hits(in):  1215208 (out):  1098963
 +    IN Pullups succeeded:   2       failed: 0
 +    OUT Pullups succeeded:  0       failed: 0
 +    Fastroute successes:    0       failures:       0
 +    TCP cksum fails(in):    0       (out):  0
 +    Packet log flags set: (0)
 +            none
 +
 +ipfstat is also capable of showing  you  your  current  rule
 +list.   Using  the -i or the -o flag will show the currently
 +loaded rules for in or out, respectively.  Adding  a  -h  to
 +this  will  provide more useful information at the same time
 +by showing you a "hit count" on each rule.  For example:
 +
 +    # ipfstat -ho
 +    2451423 pass out on xl0 from any to any
 +    354727 block out on ppp0 from any to any
 +    430918 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
 +
 +From this, we can see that perhaps there's something  abnor-
 +mal  going on, since we've got a lot of blocked packets out-
 +bound, even with a very permissive pass out rule.  Something
 +here  may warrant further investigation,  or it may be func-
 +tioning perfectly by design.  ipfstat can't tell you if your
 +rules  are right or wrong, it can only tell you what is hap-
 +pening because of your rules.
 +
 +To further debug your rules, you may  want  to  use  the  -n
 +flag, which will show the rule number next to each rule.
 +
 +    # ipfstat -on
 +    @1 pass out on xl0 from any to any
 +    @2 block out on ppp0 from any to any
 +    @3 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
 +
 +The final piece of really interesting information that ipfs-
 +tat can provide us is a dump of the state  table.   This  is
 +done with the -s flag:
 +
 +    # ipfstat -s
 +            281458 TCP
 +            319349 UDP
 +            0 ICMP
 +            19780145 hits
 +            5723648 misses
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -32-
 +
 +
 +            0 maximum
 +            0 no memory
 +            1 active
 +            319349 expired
 +            281419 closed
 +    100.100.100.1 -> 20.20.20.1 ttl 864000 pass 20490 pr 6 state 4/4
 +            pkts 196 bytes 17394    987 -> 22 585538471:2213225493 16592:16500
 +            pass in log quick keep state
 +            pkt_flags & b = 2,              pkt_options & ffffffff = 0
 +            pkt_security & ffff = 0, pkt_auth & ffff = 0
 +
 +Here  we  see that we have one state entry for a TCP connec-
 +tion.  The output will vary slightly from  version  to  ver-
 +sion,  but the basic information is the same.  We can see in
 +this connection that we have a fully established  connection
 +(represented  by the 4/4 state.  Other states are incomplete
 +and will be documented fully later.)  We can  see  that  the
 +state  entry  has  a  time to live of 240 hours, which is an
 +absurdly long time, but is the default  for  an  established
 +TCP connection.   This TTL counter is decremented every sec-
 +ond that the state entry  is  not  used,  and  will  finally
 +result  in  the  connection being purged if it has been left
 +idle.   The TTL is also reset to 864000 whenever  the  state
 +IS  used, ensuring that the entry will not time out while it
 +is being actively used.  We can also see that we have passed
 +196 packets consisting of about 17kB worth of data over this
 +connection.  We can see the ports  for  both  endpoints,  in
 +this case 987 and 22; which means that this state entry rep-
 +resents  a  connection  from  100.100.100.1  port   987   to
 +20.20.20.1  port  22.   The really big numbers in the second
 +line are the TCP sequence numbers for this connection, which
 +helps  to  ensure that someone isn't easily able to inject a
 +forged packet into your session.  The  TCP  window  is  also
 +shown.    The  third line is a synopsis of the implicit rule
 +that was generated by the keep state code, showing that this
 +connection is an inbound connection.
 +
 +7.2.  The ipmon utility
 +
 +     ipfstat  is  great  for  collecting snapshots of what's
 +going on on the system, but it's often handy  to  have  some
 +kind  of  log  to look at and watch events as they happen in
 +time.   ipmon is this tool.  ipmon is  capable  of  watching
 +the  packet  log  (as  created  with the log keyword in your
 +rules), the state log, or the nat log, or any combination of
 +the  three.   This tool can either be run in the foreground,
 +or as a daemon which logs to syslog or a file.  If we wanted
 +to  watch  the  state table in action, ipmon -o S would show
 +this:
 +
 +    # ipmon -o S
 +    01/08/1999 15:58:57.836053 STATE:NEW 100.100.100.1,53 -> 20.20.20.15,53 PR udp
 +    01/08/1999 15:58:58.030815 STATE:NEW 20.20.20.15,123 -> 128.167.1.69,123 PR udp
 +    01/08/1999 15:59:18.032174 STATE:NEW 20.20.20.15,123 -> 128.173.14.71,123 PR udp
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -33-
 +
 +
 +    01/08/1999 15:59:24.570107 STATE:EXPIRE 100.100.100.1,53 -> 20.20.20.15,53 PR udp Pkts 4 Bytes 356
 +    01/08/1999 16:03:51.754867 STATE:NEW 20.20.20.13,1019 -> 100.100.100.10,22 PR tcp
 +    01/08/1999 16:04:03.070127 STATE:EXPIRE 20.20.20.13,1019 -> 100.100.100.10,22 PR tcp Pkts 63 Bytes 4604
 +
 +Here we see a state entry for an external  dns  request  off
 +our  nameserver,  two xntp pings to well-known time servers,
 +and a very short lived outbound ssh connection.
 +
 +     ipmon is also capable of showing us what  packets  have
 +been  logged.   For  example, when using state, you'll often
 +run into packets like this:
 +
 +    # ipmon -o I
 +    15:57:33.803147 ppp0 @0:2 b 100.100.100.103,443 -> 20.20.20.10,4923 PR tcp len 20 1488 -A
 +
 +What does this mean?   The first field is  obvious,  it's  a
 +timestamp.   The  second  field is also pretty obvious, it's
 +the interface that this event happened on.  The third  field
 +@0:2  is  something  most people miss. This is the rule that
 +caused the event to happen.  Remember ipfstat -in?   If  you
 +wanted  to  know  where this came from, you could look there
 +for rule 2 in rule group 0.  The fourth  field,  the  little
 +"b"  says that this packet was blocked, and you'll generally
 +ignore this unless you're logging passed  packets  as  well,
 +which  would  be  a  little "p" instead. The fifth and sixth
 +fields are pretty  self-explanatory,  they  say  where  this
 +packet  came from and where it was going. The seventh ("PR")
 +and eighth fields tell you the protocol and the ninth  field
 +tells  you  the size of the packet.  The last part, the "-A"
 +in this case, tells you the flags that were on  the  packet;
 +This  one  was  an ACK packet.  Why did I mention state ear-
 +lier?   Due to the often laggy nature of the Internet, some-
 +times  packets  will  be regenerated.  Sometimes, you'll get
 +two copies of the same packet, and  your  state  rule  which
 +keeps  track of sequence numbers will have already seen this
 +packet, so it will assume that the packet is part of a  dif-
 +ferent  connection.   Eventually this packet will run into a
 +real rule and have to be dealt with.   You'll often see  the
 +last packet of a session being closed get logged because the
 +keep state code has already torn down the connection  before
 +the  last  packet  has had a chance to make it to your fire-
 +wall.  This is normal, do not be alarmed.   Another  example
 +packet that might be logged:
 +
 +    12:46:12.470951 xl0 @0:1 S 20.20.20.254 -> 255.255.255.255 PR icmp len 20 9216 icmp 9/0
 +
 +-----------
 + For a technical presentation  of  the  IP  Filter
 +stateful  inspection  engine, please see the white
 +paper Real Stateful TCP  Packet  Filtering  in  IP
 +Filter,  by  Guido  van  Rooij.  This paper may be
 +found                                           at
 +<http://www.iae.nl/users/guido/papers/tcp_filter-
 +ing.ps.gz>
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -34-
 +
 +
 +This  is  a ICMP router discovery broadcast.  We can tell by
 +the ICMP type 9/0.
 +
 +Finally, ipmon also lets us look at the NAT table in action.
 +
 +    # ipmon -o N
 +    01/08/1999 05:30:02.466114 @2 NAT:RDR 20.20.20.253,113 <- -> 20.20.20.253,113 [100.100.100.13,45816]
 +    01/08/1999 05:30:31.990037 @2 NAT:EXPIRE 20.20.20.253,113 <- -> 20.20.20.253,113 [100.100.100.13,45816] Pkts 10 Bytes 455
 +
 +This  would  be a redirection to an identd that lies to pro-
 +vide ident service for the hosts behind our NAT, since  they
 +are  typically unable to provide this service for themselves
 +with ordinary natting.
 +
 +
 +
 +
 +8.  Specific Applications of IP Filter - Things  that  don't
 +fit, but should be mentioned anyway.
 +
 +8.1.  Keep State With Servers and Flags.
 +
 +     Keeping  state  is a good thing, but it's quite easy to
 +make a mistake in the direction that you want to keep  state
 +in.    Generally,  you  want to have a keep state keyword on
 +the first rule that interacts with a packet for the  connec-
 +tion.  One  common  mistake  that  is made when mixing state
 +tracking with filtering on flags is this:
 +
 +     block in all
 +     pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S
 +     pass out all keep state
 +
 +That certainly appears to allow a connection to  be  created
 +to  the  telnet server on 20.20.20.20, and the replies to go
 +back.  If you try using this rule, you'll see that  it  does
 +work--Momentarily.   Since we're filtering for the SYN flag,
 +the state entry never fully gets completed, and the  default
 +time to live for an incomplete state is 60 seconds.
 +
 +We can solve this by rewriting the rules in one of two ways:
 +
 +1)
 +
 +          block in all
 +          pass in quick proto tcp from any to 20.20.20.20/32 port = 23 keep state
 +          block out all
 +
 +or:
 +
 +2)
 +
 +          block in all
 +          pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S keep state
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -35-
 +
 +
 +          pass out all keep state
 +
 +Either of these sets of rules will result in a fully  estab-
 +lished state entry for a connection to your server.
 +
 +8.2.  Coping With FTP
 +
 +     FTP is one of those protocols that you just have to sit
 +back and ask "What the heck were they  thinking?"   FTP  has
 +many  problems that the firewall administrator needs to deal
 +with.  What's worse, the  problems  the  administrator  must
 +face  are different between making ftp clients work and mak-
 +ing ftp servers work.
 +
 +     Within the FTP protocol, there are two  forms  of  data
 +transfer,  called  active and passive.  Active transfers are
 +those where the server connects  to  an  open  port  on  the
 +client  to  send  data.   Conversely,  passive transfers are
 +those where the client connects to  the  server  to  receive
 +data.
 +
 +8.2.1.  Running an FTP Server
 +
 +     In  running an FTP server, handling Active FTP sessions
 +is easy to setup.  At the same time,  handling  Passive  FTP
 +sessions  is a big problem.  First we'll cover how to handle
 +Active FTP, then move on to Passive.  Generally, we can han-
 +dle  Active  FTP  sessions like we would an incoming HTTP or
 +SMTP connection; just open the ftp port and let  keep  state
 +do the rest:
 +
 +     pass in quick proto tcp from any to 20.20.20.20/32 port = 21 flags S keep state
 +     pass out proto tcp all keep state
 +
 +These  rules will allow Active FTP sessions, the most common
 +type, to your ftp server on 20.20.20.20.
 +
 +     The next challenge becomes handling Passive FTP connec-
 +tions.   Web browsers default to this mode, so it's becoming
 +quite popular and as such it should be supported.  The prob-
 +lem with passive connections are that for every passive con-
 +nection, the server starts listening on a new port  (usually
 +above  1023).   This  is  essentially  like  creating  a new
 +unknown service on the server.   Assuming  we  have  a  good
 +firewall  with  a default-deny policy, that new service will
 +be blocked, and thus Active FTP sessions are broken.   Don't
 +despair!  There's hope yet to be had.
 +
 +     A  person's  first  inclination to solving this problem
 +might be to just open up all ports above  1023.   In  truth,
 +this will work:
 +
 +     pass in quick proto tcp from any to 20.20.20.20/32 port > 1023 flags S keep state
 +     pass out proto tcp all keep state
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -36-
 +
 +
 +This  is somewhat unsatisfactory, though.  By letting every-
 +thing above 1023 in, we actually open  ourselves  up  for  a
 +number  of  potential  problems.  While 1-1023 is the desig-
 +nated area for server services  to  run,  numerous  programs
 +decided to use numbers higher than 1023, such as nfsd and X.
 +
 +     The good news is that your FTP server  gets  to  decide
 +which  ports  get  assigned to passive sessions.  This means
 +that instead of opening all ports above 1023, you can  allo-
 +cate ports 15001-19999 as ftp ports and only open that range
 +of your firewall up.  In wu-ftpd, this is done with the pas-
 +sive  ports option in ftpaccess.  Please see the man page on
 +ftpaccess for details  in  wu-ftpd  configuration.   On  the
 +ipfilter side, all we need do is setup corresponding rules:
 +
 +     pass in quick proto tcp from any to 20.20.20.20/32 port 15000 >< 20000 flags S keep state
 +     pass out proto tcp all keep state
 +
 +If  even  this  solution doesn't satisfy you, you can always
 +hack IPF support into your FTP server, or FTP server support
 +into IPF.
 +
 +8.2.2.  Running an FTP Client
 +
 +     While  FTP server support is still less than perfect in
 +IPF, FTP client support has been working well  since  3.3.3.
 +As  with  FTP  servers,  there  are  two types of ftp client
 +transfers: passive and active.
 +
 +     The simplest type of client  transfer  from  the  fire-
 +wall's  standpoint is the passive transfer.  Assuming you're
 +keeping state on all outbound tcp sessions,  passive  trans-
 +fers  will  work already.  If you're not doing this already,
 +please consider the following:
 +
 +    pass out proto tcp all keep state
 +
 +The second type of client transfer, active, is  a  bit  more
 +troublesome,  but  nonetheless  a  solved  problem.   Active
 +transfers cause the server to open up  a  second  connection
 +back  to  the client for data to flow through.  This is nor-
 +mally a problem when there's a firewall in the middle, stop-
 +ping  outside  connections  from  coming  back in.  To solve
 +this, ipfilter includes an  ipnat  proxy  which  temporarily
 +opens  up  a hole in the firewall just for the FTP server to
 +get back to the client.  Even if you're not using  ipnat  to
 +do  nat,  the proxy is still effective.  The following rules
 +is the bare minimum to add to the ipnat  configuration  file
 +(ep0  should  be  the interface name of the outbound network
 +connection):
 +
 +     map ep0 0/0 -> 0/32 proxy port 21 ftp/tcp
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -37-
 +
 +
 +For more details on ipfilter's internal proxies, see section
 +3.6
 +
 +8.3.  Assorted Kernel Variables
 +
 +     There  are some useful kernel tunes that either need to
 +be set for ipf to function, or are just generally  handy  to
 +know  about for building firewalls.  The first major one you
 +must set is to enable IP Forwarding, otherwise ipf  will  do
 +very little, as the underlying ip stack won't actually route
 +packets.
 +
 +IP Forwarding:
 +
 +openbsd:
 +     net.inet.ip.forwarding=1
 +
 +
 +freebsd:
 +     net.inet.ip.forwarding=1
 +
 +
 +netbsd:
 +     net.inet.ip.forwarding=1
 +
 +
 +solaris:
 +     ndd -set /dev/ip ip_forwarding 1
 +
 +Ephemeral Port Adjustment:
 +
 +openbsd:
 +     net.inet.ip.portfirst = 25000
 +
 +
 +freebsd:
 +     net.inet.ip.portrange.first  =  25000  net.inet.ip.por-
 +     trange.last = 49151
 +
 +
 +netbsd:
 +     net.inet.ip.anonportmin = 25000 net.inet.ip.anonportmax
 +     = 49151
 +
 +
 +solaris:
 +     ndd -set /dev/tcp tcp_smallest_anon_port 25000
 +     ndd -set /dev/tcp tcp_largest_anon_port 65535
 +
 +Other Useful Values:
 +
 +openbsd:
 +     net.inet.ip.sourceroute = 0
 +     net.inet.ip.directed-broadcast = 0
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -38-
 +
 +
 +freebsd:
 +     net.inet.ip.sourceroute=0
 +     net.ip.accept_sourceroute=0
 +
 +
 +netbsd:
 +     net.inet.ip.allowsrcrt=0
 +     net.inet.ip.forwsrcrt=0
 +     net.inet.ip.directed-broadcast=0
 +     net.inet.ip.redirect=0
 +
 +
 +solaris:
 +     ndd -set /dev/ip ip_forward_directed_broadcasts 0
 +     ndd -set /dev/ip ip_forward_src_routed 0
 +     ndd -set /dev/ip ip_respond_to_echo_broadcast 0
 +
 +In addition, freebsd has some ipf specific sysctl variables.
 +
 +     net.inet.ipf.fr_flags: 0
 +     net.inet.ipf.fr_pass: 514
 +     net.inet.ipf.fr_active: 0
 +     net.inet.ipf.fr_tcpidletimeout: 864000
 +     net.inet.ipf.fr_tcpclosewait: 60
 +     net.inet.ipf.fr_tcplastack: 20
 +     net.inet.ipf.fr_tcptimeout: 120
 +     net.inet.ipf.fr_tcpclosed: 1
 +     net.inet.ipf.fr_udptimeout: 120
 +     net.inet.ipf.fr_icmptimeout: 120
 +     net.inet.ipf.fr_defnatage: 1200
 +     net.inet.ipf.fr_ipfrttl: 120
 +     net.inet.ipf.ipl_unreach: 13
 +     net.inet.ipf.ipl_inited: 1
 +     net.inet.ipf.fr_authsize: 32
 +     net.inet.ipf.fr_authused: 0
 +     net.inet.ipf.fr_defaultauthage: 600
 +
 +
 +
 +
 +9.  Fun with ipf!
 +
 +     This section doesn't necessarily teach you anything new
 +about ipf, but it may raise an issue or two that you haven't
 +yet  thought  up  on your own, or tickle your brain in a way
 +that  you  invent  something  interesting  that  we  haven't
 +thought of.
 +
 +9.1.  Localhost Filtering
 +
 +     A  long  time ago at a university far, far away, Wietse
 +Venema created the tcp-wrapper package, and ever since, it's
 +been  used  to add a layer of protection to network services
 +all over the world.  This is good.  But,  tcp-wrappers  have
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -39-
 +
 +
 +flaws.  For starters, they only protect TCP services, as the
 +name suggests.   Also, unless  you  run  your  service  from
 +inetd, or you have specifically compiled it with libwrap and
 +the appropriate hooks, your service isn't protected.    This
 +leaves  gigantic  holes in your host security.   We can plug
 +these up by using ipf on the local host.   For  example,  my
 +laptop  often gets plugged into or dialed into networks that
 +I don't specifically trust, and so, I use the following rule
 +set:
 +
 +     pass in quick on lo0 all
 +     pass out quick on lo0 all
 +
 +     block in log all
 +     block out all
 +
 +     pass in quick proto tcp from any to any port = 113 flags S keep state
 +     pass in quick proto tcp from any to any port = 22 flags S keep state
 +     pass in quick proto tcp from any port = 20 to any port 39999 >< 45000 flags S keep state
 +
 +     pass out quick proto icmp from any to any keep state
 +     pass out quick proto tcp/udp from any to any keep state keep frags
 +
 +It's  been  like  that for quite a while, and I haven't suf-
 +fered any pain or anguish as a result of having  ipf  loaded
 +up all the time.  If I wanted to tighten it up more, I could
 +switch to using the NAT ftp proxy and I could  add  in  some
 +rules to prevent spoofing.   But even as it stands now, this
 +box is far more restrictive about what it  presents  to  the
 +local  network and beyond than the typical host does.   This
 +is a good thing if you happen to run a machine that allows a
 +lot  of  users on it, and you want to make sure  one of them
 +doesn't happen to start up a service  they  wern't  supposed
 +to.   It won't stop a malicious hacker with root access from
 +adjusting your ipf rules and starting a service anyway,  but
 +it  will keep the "honest" folks honest, and your weird ser-
 +vices safe, cozy and warm even on a malicious  LAN.   A  big
 +win, in my opinion.   Using local host filtering in addition
 +to a somewhat less-restrictive "main firewall"  machine  can
 +solve  many  performance  issues as well as political night-
 +mares like "Why doesn't ICQ work?" and "Why can't  I  put  a
 +web  server  on  my  own workstation! It's MY WORKSTATION!!"
 +Another very big win.  Who says you can't have security  and
 +convienence at the same time?
 +
 +9.2.  What Firewall?  Transparent filtering.
 +
 +     One  major  concern  in  setting  up  a firewall is the
 +integrity of the firewall itself.  Can somebody  break  into
 +your  firewall,  thereby  subverting its ruleset?  This is a
 +common problem administrators must face,  particularly  when
 +they're  using  firewall  solutions  on top of their Unix/NT
 +machines.  Some use it as an arguement for blackbox hardware
 +solutions,  under  the flawed notion that inherent obscurity
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -40-
 +
 +
 +of their closed system increases their security.  We have  a
 +better way.
 +
 +     Many network admins are familiar with the common ether-
 +net bridge.  This is a device  that  connects  two  separate
 +ethernet  segments  to make them one.  An ethernet bridge is
 +typically used to connect separate buildings, switch network
 +speeds,  and extend maximum wire lengths.  Hubs and switches
 +are common bridges, sometimes they're just 2 ported  devices
 +called   repeaters.   Recent  versions  of  Linux,  OpenBSD,
 +NetBSD, and FreeBSD include code to convert $1000  PCs  into
 +$10  bridges,  too!  What all bridges tend to have in common
 +is that though they  sit  in  the  middle  of  a  connection
 +between two machines, the two machines don't know the bridge
 +is there.  Enter ipfilter and OpenBSD.
 +
 +     Ethernet bridging takes place  at  Layer2  on  the  ISO
 +stack.   IP  takes  place on Layer3.  IP Filter in primarily
 +concerned with Layer3, but dabbles in Layer2 by working with
 +interfaces.   By  mixing  IP  filter  with  OpenBSD's bridge
 +device, we can create a firewall that is both invisible  and
 +unreachable.   The  system  needs  no IP address, it doesn't
 +even need to reveal its ethernet address.  The only telltale
 +sign that the filter might be there is that latency is some-
 +what higher than a piece of cat5 would normally make it, and
 +that  packets  don't seem to make it to their final destina-
 +tion.
 +
 +     The setup for this sort of ruleset is surprisingly sim-
 +ple,  too.   In  OpenBSD,  the  first bridge device is named
 +bridge0.  Say we have two ethernet cards in our  machine  as
 +well,  xl0 and xl1.  To turn this machine into a bridge, all
 +one need do is enter the following three commands:
 +
 +    brconfig bridge0 add xl0 add xl1 up
 +    ifconfig xl0 up
 +    ifconfig xl1 up
 +
 +At ths point, all traffic ariving on xl0 is sent out xl1 and
 +all  traffic  on xl1 is sent out xl0.  You'll note that nei-
 +ther interface has been assigned an IP address,  nor  do  we
 +need assign one.  All things considered, it's likely best we
 +not add one at all.
 +
 +     Rulesets behave essentially the  as  the  always  have.
 +Though  there  is a bridge0 interface, we don't filter based
 +on it.  Rules continue  to  be  based  upon  the  particular
 +interface  we're  using,  making  it important which network
 +cable is plugged into which network card in the back of  the
 +machine.   Let's  start  with some basic filtering to illis-
 +trate what's happened.  Assume the network used to look like
 +this:
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -41-
 +
 +
 +  20.20.20.1 <---------------------------------> 20.20.20.0/24 network hub
 +
 +That  is,  we  have  a router at 20.20.20.1 connected to the
 +20.20.20.0/24 network.  All packets from  the  20.20.20.0/24
 +network  go  through  20.20.20.1 to get to the outside world
 +and vice versa.  Now we add the Ipf Bridge:
 +
 +  20.20.20.1 <-------/xl0 IpfBridge xl1/-------> 20.20.20.0/24 network hub
 +
 +We also have the following ruleset loaded on  the  IpfBridge
 +host:
 +
 +    pass in  quick  all
 +    pass out quick  all
 +
 +With  this ruleset loaded, the network is functionally iden-
 +tical.  As far as the 20.20.20.1 router is concerned, and as
 +far  as  the 20.20.20.0/24 hosts are concerned, the two net-
 +work diagrams are identical.  Now let's change  the  ruleset
 +some:
 +
 +    block in quick on xl0 proto icmp
 +    pass  in  quick all
 +    pass  out quick all
 +
 +Still,  20.20.20.1  and  20.20.20.0/24  think the network is
 +identical, but if 20.20.20.1 attempts to ping 20.20.20.2, it
 +will  never get a reply.  What's more, 20.20.20.2 won't even
 +get the packet in the first place.  IPfilter will  intercept
 +the  packet before it even gets to the other end of the vir-
 +tual wire.  We can put a  bridged  filter  anywhere.   Using
 +this  method  we can shrink the network trust circle down an
 +individual host level (given enough ethernet cards:-)
 +
 +     Blocking icmp from the world seems kind of silly, espe-
 +cially  if  you're a sysadmin and like pinging the world, to
 +traceroute, or to resize your MTU.  Let's construct a better
 +ruleset  and  take  advantage of the original key feature of
 +ipf: stateful inspection.
 +
 +    pass  in quick on xl1 proto tcp  keep state
 +    pass  in quick on xl1 proto udp  keep state
 +    pass  in quick on xl1 proto icmp keep state
 +    block in quick on xl0
 +
 +In this situation, the 20.20.20.0/24 network  (perhaps  more
 +aptly  called  the  xl1  network)  can now reach the outside
 +world, but the outside world can't reach it,  and  it  can't
 +figure out why, either.  The router is accessible, the hosts
 +are active, but the outside world just can't get  in.   Even
 +if  the  router  itself were compromised, the firewall would
 +still be active and successful.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -42-
 +
 +
 +     So far, we've been filtering by interface and  protocol
 +only.   Even  though  bridging  is  concerned layer2, we can
 +still discriminate based on IP address.  Normally we have  a
 +few services running, so our ruleset may look like this:
 +
 +    pass  in quick on xl1 proto tcp  keep state
 +    pass  in quick on xl1 proto udp  keep state
 +    pass  in quick on xl1 proto icmp keep state
 +    block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.
 +    pass  in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
 +    pass  in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
 +    pass  in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
 +    pass  in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
 +    block in quick on xl0
 +
 +Now  we  have  a  network where 20.20.20.2 is a zone serving
 +name server, 20.20.20.3 is  an  incoming  mail  server,  and
 +20.20.20.7 is a web server.
 +
 +     Bridged  IP Filter is not yet perfect, we must confess.
 +
 +     First,  You'll note that all the rules are setup  using
 +the  in  direction  instead  of a combination of in and out.
 +This is because the out direction is presently unimplemented
 +with  bridging in OpenBSD.  This was originally done to pre-
 +vent vast performance drops using multiple interfaces.  Work
 +has  been  done  in  speeding it up, but it remains unimple-
 +mented.  If you really want this feature, you might try your
 +hand at working on the code or asking the OpenBSD people how
 +you can help.
 +
 +     Second, using IP Filter with bridging makes the use  of
 +IPF's  NAT features inadvisable, if not downright dangerous.
 +The first problem is that it would give away that there's  a
 +filtering  bridge.   The  second  problem  would be that the
 +bridge has no IP address to masquerade with, which will most
 +assuredly  lead  to  confusion and perhaps a kernel panic to
 +boot.  You can, of course, put an IP address on the outbound
 +interface to make NAT work, but part of the glee of bridging
 +is thus diminished.
 +
 +9.2.1.  Using Transparent Filtering to  Fix  Network  Design
 +Mistakes
 +
 +     Many  organizations  started  using IP well before they
 +thought a firewall or a subnet would be a  good  idea.   Now
 +they  have class-C sized networks or larger that include all
 +their servers, their  workstations,  their  routers,  coffee
 +makers,  everything.   The  horror!  Renumbering with proper
 +subnets, trust levels, filters, and so are in both time con-
 +suming and expensive.  The expense in hardware and man hours
 +alone is enough to  make  most  organizations  unwilling  to
 +really  solve  the  problem,  not  to  mention  the downtime
 +involved.  The typical problem network looks like this:
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -43-
 +
 +
 +    20.20.20.1   router               20.20.20.6   unix server
 +    20.20.20.2   unix server          20.20.20.7   nt workstation
 +    20.20.20.3   unix server          20.20.20.8   nt server
 +    20.20.20.4   win98 workstation    20.20.20.9   unix workstation
 +    20.20.20.5   intelligent switch   20.20.20.10  win95 workstation
 +
 +Only it's about 20 times larger and messier  and  frequently
 +undocumented.   Ideally, you'd have all the trusting servers
 +in one subnet, all the work- stations in  another,  and  the
 +network  switches  in a third.  Then the router would filter
 +packets between the subnets, giving the workstations limited
 +access  to  the servers, nothing access to the switches, and
 +only the sysadmin's workstation access to  the  coffee  pot.
 +I've never seen a class-C sized network with such coherence.
 +IP Filter can help.
 +
 +     To start with, we're going to separate the router,  the
 +workstations,  and  the  servers.  To do this we're going to
 +need 2 hubs (or switches) which we  probably  already  have,
 +and  an  IPF  machine with 3 ethernet cards.  We're going to
 +put all the servers on one hub and all the  workstations  on
 +the  other.   Normally  we'd  then  connect the hubs to each
 +other, then to the router.  Instead, we're going to plug the
 +router  into IPF's xl0 interface, the servers into IPF's xl1
 +interface, and the workstations into  IPF's  xl2  interface.
 +Our network diagram looks something like this:
 +
 +                                                 | 20.20.20.2  unix server
 +    router (20.20.20.1)              ____________| 20.20.20.3  unix server
 +     |                              /            | 20.20.20.6  unix server
 +     |                             /xl1          | 20.20.20.7  nt server
 +     ------------/xl0 IPF Bridge <
 +                                    xl2         | 20.20.20.4  win98 workstation
 +                                    ____________| 20.20.20.8  nt workstation
 +                                                 | 20.20.20.9  unix workstation
 +                                                 | 20.20.20.10 win95 workstation
 +
 +Where  once there was nothing but interconnecting wires, now
 +there's a filtering bridge that not a single host  needs  to
 +be  modified to take advantage of.  Presumably we've already
 +enabled bridging so the network is behaving  perfectly  nor-
 +mally.  Further, we're starting off with a ruleset much like
 +our last ruleset:
 +
 +    pass  in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
 +    pass  in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
 +    pass  in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
 +    pass  in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
 +    block in quick on xl0
 +    pass  in quick on xl1 proto tcp  keep state
 +    pass  in quick on xl1 proto udp  keep state
 +    pass  in quick on xl1 proto icmp keep state
 +    block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.
 +    pass  in quick on xl2 proto tcp  keep state
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -44-
 +
 +
 +    pass  in quick on xl2 proto udp  keep state
 +    pass  in quick on xl2 proto icmp keep state
 +    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
 +
 +Once again, traffic coming from the router is restricted  to
 +DNS,  SMTP,  and  HTTP.   At the moment, the servers and the
 +workstations can exchange traffic freely.  Depending on what
 +kind of organization you are, there might be something about
 +this network dynamic you don't like.  Perhaps you don't want
 +your  workstations  getting  access  to your servers at all?
 +Take the xl2 ruleset of:
 +
 +    pass  in quick on xl2 proto tcp  keep state
 +    pass  in quick on xl2 proto udp  keep state
 +    pass  in quick on xl2 proto icmp keep state
 +    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
 +
 +And change it to:
 +
 +    block in quick on xl2 from any to 20.20.20.0/24
 +    pass  in quick on xl2 proto tcp  keep state
 +    pass  in quick on xl2 proto udp  keep state
 +    pass  in quick on xl2 proto icmp keep state
 +    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
 +
 +Perhaps you want them to just get to the servers to get  and
 +send their mail with IMAP?  Easily done:
 +
 +    pass  in quick on xl2 proto tcp from any to 20.20.20.3/32 port=25
 +    pass  in quick on xl2 proto tcp from any to 20.20.20.3/32 port=143
 +    block in quick on xl2 from any to 20.20.20.0/24
 +    pass  in quick on xl2 proto tcp  keep state
 +    pass  in quick on xl2 proto udp  keep state
 +    pass  in quick on xl2 proto icmp keep state
 +    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
 +
 +Now  your  workstations  and  servers are protected from the
 +outside world, and the servers are protected from your work-
 +stations.
 +
 +     Perhaps the opposite is true, maybe you want your work-
 +stations to be able to get to the servers, but not the  out-
 +side  world.   After all, the next generation of exploits is
 +breaking the clients, not the servers.  In this case,  you'd
 +change the xl2 rules to look more like this:
 +
 +    pass  in quick on xl2 from any to 20.20.20.0/24
 +    block in quick on xl2
 +
 +Now  the  servers  have free reign, but the clients can only
 +connect to the servers.  We might want to  batten  down  the
 +hatches on the servers, too:
 +
 +    pass  in quick on xl1 from any to 20.20.20.0/24
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -45-
 +
 +
 +    block in quick on xl1
 +
 +With  the  combination of these two, the clients and servers
 +can talk to each other, but neither can access  the  outside
 +world  (though the outside world can get to the few services
 +from earlier).  The whole ruleset would look something  like
 +this:
 +
 +    pass  in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
 +    pass  in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53                                                              flags S keep state
 +    pass  in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25                                                              flags S keep state
 +    pass  in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80                                                              flags S keep state
 +    block in quick on xl0
 +    pass  in quick on xl1 from any to 20.20.20.0/24
 +    block in quick on xl1
 +    pass  in quick on xl2 from any to 20.20.20.0/24
 +    block in quick on xl2
 +
 +So  remember,  when  your  network  is  a  mess of twisty IP
 +addresses and machine classes, transparent filtered  bridges
 +can  solve  a problem that would otherwise be lived with and
 +perhaps someday exploited.
 +
 +9.3.  Drop-Safe Logging With dup-to and to.
 +
 +     Until now, we've been using the filter to drop packets.
 +Instead  of dropping them, let's consider passing them on to
 +another system that can do something useful with this infor-
 +mation  beyond  the logging we can perform with ipmon.   Our
 +firewall system, be it a bridge or a  router,  can  have  as
 +many  interfaces as we can cram into the system.  We can use
 +this information to create a "drop-safe" for our packets.  A
 +good  example  of  a  use  for this would be to implement an
 +intrusion detection network.   For  starters,  it  might  be
 +desirable  to  hide  the presence of our intrusion detection
 +systems from our real network so that we can keep them  from
 +being detected.
 +
 +     Before we get started, there are some operational char-
 +acteristics that we need to make note of.  If  we  are  only
 +going to deal with blocked packets, we can use either the to
 +keyword or the fastroute keyword. (We'll cover  the  differ-
 +ences  between  these two later)  If we're going to pass the
 +packets like we normally would, we need to make  a  copy  of
 +the packet for our drop-safe log with the dup-to keyword.
 +
 +9.3.1.  The dup-to Method
 +
 +     If, for example, we wanted to send a copy of everything
 +going out the xl3 interface off to our drop-safe network  on
 +ed0, we would use this rule in our filter list:
 +
 +     pass out on xl3 dup-to ed0 from any to any
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -46-
 +
 +
 +You  might also have a need to send the packet directly to a
 +specific IP address on your  drop-safe  network  instead  of
 +just  making  a  copy of the packet out there and hoping for
 +the best.  To do this, we modify our rule slightly:
 +
 +     pass out on xl3 dup-to ed0:192.168.254.2 from any to any
 +
 +But be  warned  that  this  method  will  alter  the  copied
 +packet's  destination address, and may thus destroy the use-
 +fulness of the log.  For  this  reason,  we  recommend  only
 +using  the  known  address method of logging when you can be
 +certain that the address that you're logging to  corresponds
 +in  some  way  to  what  you're logging for (e.g.: don't use
 +"192.168.254.2" for logging for both  your  web  server  and
 +your mail server, since you'll have a hard time later trying
 +to figure out which system was the target of a specific  set
 +of packets.)
 +
 +     This  technique  can  be  used quite effectively if you
 +treat an IP Address on your drop-safe network  in  much  the
 +same  way that you would treat a Multicast Group on the real
 +internet. (e.g.: "192.168.254.2" could be  the  channel  for
 +your  http  traffic  analysis system, "23.23.23.23" could be
 +your channel for telnet sessions, and so on.)     You  don't
 +even need to actually have this address set as an address or
 +alias on any  of  your  analysis  systems.   Normally,  your
 +ipfilter  machine  would need to ARP for the new destination
 +address (using dup-to ed0:192.168.254.2  style,  of  course)
 +but  we  can avoid that issue by creating a static arp entry
 +for this "channel" on our ipfilter system.
 +
 +     In general, though, dup-to ed0 is all that is  required
 +to  get  a new copy of the packet over to our drop-safe net-
 +work for logging and examination.
 +
 +9.3.2.  The to Method
 +
 +     The dup-to method  does  have  an  immediate  drawback,
 +though.   Since  it  has  to  make  a copy of the packet and
 +optionally modify it for its new destination, it's going  to
 +take  a while to complete all this work and be ready to deal
 +with the next packet coming in to the ipfilter system.
 +
 +     If we don't care about passing the packet to its normal
 +destination  and  we  were  going to block it anyway, we can
 +just use the to keyword to push this packet past the  normal
 +routing  table  and force it to go out a different interface
 +than it would normally go out.
 +
 +     block in quick on xl0 to ed0 proto tcp from any to any port < 1024
 +
 +we use block quick for to interface  routing,  because  like
 +fastroute,  the  to  interface code will generate two packet
 +paths through ipfilter when used with pass, and likely cause
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -47-
 +
 +
 +your system to panic.
 +
 +
 +
 +10.   Bogus Network Filtering, the ultimate in current anti-
 +spoofing technology.
 +
 +     We've spent a little bit of time tracking down the cur-
 +rent vast tracts of IP address space that have been reserved
 +by the IANA for various reasons, or are otherwise  not  cur-
 +rently in use at the time this document was written.   Since
 +none of these address ranges should  be  in  use  currently,
 +there  should  be no legitimate reason to ever see them as a
 +source address, or to send them  traffic  as  a  destination
 +address, right?   Right!
 +
 +     So without further ado, the complete list of bogus net-
 +works:
 +
 +     #
 +     # s/OUTSIDE/outside-interface (eg: fxp0)
 +     # s/MYNET/network-cidr-address (eg: 1.2.3.0/24)
 +     #
 +     block in on OUTSIDE all
 +     block in quick on OUTSIDE from 0.0.0.0/7 to any
 +     block in quick on OUTSIDE from 2.0.0.0/8 to any
 +     block in quick on OUTSIDE from 5.0.0.0/8 to any
 +     block in quick on OUTSIDE from 10.0.0.0/8 to any
 +     block in quick on OUTSIDE from 23.0.0.0/8 to any
 +     block in quick on OUTSIDE from 27.0.0.0/8 to any
 +     block in quick on OUTSIDE from 31.0.0.0/8 to any
 +     block in quick on OUTSIDE from 67.0.0.0/8 to any
 +     block in quick on OUTSIDE from 68.0.0.0/6 to any
 +     block in quick on OUTSIDE from 72.0.0.0/5 to any
 +     block in quick on OUTSIDE from 80.0.0.0/4 to any
 +     block in quick on OUTSIDE from 96.0.0.0/3 to any
 +     block in quick on OUTSIDE from 127.0.0.0/8 to any
 +     block in quick on OUTSIDE from 128.0.0.0/16 to any
 +     block in quick on OUTSIDE from 128.66.0.0/16 to any
 +     block in quick on OUTSIDE from 169.254.0.0/16 to any
 +     block in quick on OUTSIDE from 172.16.0.0/12 to any
 +     block in quick on OUTSIDE from 191.255.0.0/16 to any
 +     block in quick on OUTSIDE from 192.0.0.0/16 to any
 +     block in quick on OUTSIDE from 192.168.0.0/16 to any
 +     block in quick on OUTSIDE from 197.0.0.0/8 to any
 +     block in quick on OUTSIDE from 201.0.0.0/8 to any
 +     block in quick on OUTSIDE from 204.152.64.0/23 to any
 +     block in quick on OUTSIDE from 224.0.0.0/3 to any
 +     block in quick on OUTSIDE from MYNET to any
 +     # Your pass rules come here...
 +
 +     block out on OUTSIDE all
 +     block out quick on OUTSIDE from !MYNET to any
 +     block out quick on OUTSIDE from MYNET to 0.0.0.0/7
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +                            -48-
 +
 +
 +     block out quick on OUTSIDE from MYNET to 2.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 5.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 10.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 23.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 27.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 31.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 67.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 68.0.0.0/6
 +     block out quick on OUTSIDE from MYNET to 72.0.0.0/5
 +     block out quick on OUTSIDE from MYNET to 80.0.0.0/4
 +     block out quick on OUTSIDE from MYNET to 96.0.0.0/3
 +     block out quick on OUTSIDE from MYNET to 127.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 128.0.0.0/16
 +     block out quick on OUTSIDE from MYNET to 128.66.0.0/16
 +     block out quick on OUTSIDE from MYNET to 169.254.0.0/16
 +     block out quick on OUTSIDE from MYNET to 172.16.0.0/12
 +     block out quick on OUTSIDE from MYNET to 191.255.0.0/16
 +     block out quick on OUTSIDE from MYNET to 192.0.0.0/16
 +     block out quick on OUTSIDE from MYNET to 192.168.0.0/16
 +     block out quick on OUTSIDE from MYNET to 197.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 201.0.0.0/8
 +     block out quick on OUTSIDE from MYNET to 204.152.64.0/23
 +     block out quick on OUTSIDE from MYNET to 224.0.0.0/3
 +     # Your pass rules come here...
 +
 +If you're going to use these, we  suggest  that  you  become
 +familiar  with  whois.arin.net and keep an occasional eye on
 +these, as the IANA isn't going to notify you when they allo-
 +cate  one  of  these to a new corporation or something.  You
 +have been warned.
 +
 +     We'd also like to thank  Frank  DiGennaro  <fsd@server-
 +vault.com> for greatly contributing to this filter list.
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 diff -urN share/examples/ipfilter.orig/ipf.conf.permissive share/examples/ipfilter/ipf.conf.permissive
 --- share/examples/ipfilter.orig/ipf.conf.permissive	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/ipf.conf.permissive	Sun Apr 22 09:41:54 2001
 @@ -0,0 +1,29 @@
 +# augmented rules generated by mkfilters
 +block in log quick from any with ipopts
 +block in log quick proto tcp from any to any with short
 +block in log quick all with opt lsrr
 +block in log quick all with opt ssrr
 +#-------------------------------------------------------
 +# loopback pakets left unmolested
 +pass in quick on lo0 all
 +pass out quick on lo0 all
 +#-------------------------------------------------------
 +pass out on ed1 all head 150
 +block out from 127.0.0.0/8 to any group 150
 +block out from any to 127.0.0.0/8 group 150
 +block out from any to 192.168.1.110/32 group 150
 +#-------------------------------------------------------
 +pass in on ed1 all head 100
 +block in from 127.0.0.0/8 to any group 100
 +block in from 192.168.1.110/32 to any group 100
 +block in from 192.168.0.1/24 to any group 100
 +#-------------------------------------------------------
 +pass  out on fxp0 all head 250
 +block out from 127.0.0.0/8 to any group 250
 +block out from any to 127.0.0.0/8 group 250
 +block out from any to 192.168.0.1/32 group 250
 +#-------------------------------------------------------
 +pass in on fxp0 all head 200
 +block in from 127.0.0.0/8 to any group 200
 +block in from 192.168.0.1/32 to any group 200
 +block in from 192.168.1.110/24 to any group 200
 diff -urN share/examples/ipfilter.orig/ipf.conf.restrictive share/examples/ipfilter/ipf.conf.restrictive
 --- share/examples/ipfilter.orig/ipf.conf.restrictive	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/ipf.conf.restrictive	Sun Apr 22 09:41:54 2001
 @@ -0,0 +1,76 @@
 +#--------------------------------------------------------------------------
 +# ed1 - external interface
 +# fxp0 - internal interface
 +#--------------------------------------------------------------------------
 +# First, nasty packets which we don't want near us at all
 +# packets which are too short to be real except echo replies on lo0
 +pass in log quick on lo0 proto icmp from 127.0.0.1/8 to 127.0.0.1/8 with short
 +block in log quick all with short
 +block in log quick all with opt lsrr
 +block in log quick all with opt ssrr
 +#--------------------------------------------------------------------------
 +# loopback packets left unmolested
 +pass in log quick on lo0 all
 +pass out log quick on lo0 all
 +#--------------------------------------------------------------------------
 +# Group setup:
 +# 100 incoming ed1
 +# 150 outgoing ed1
 +# 200 incoming fxp0
 +# 250 outgoing fxp0
 +#--------------------------------------------------------------------------
 +block in log body on ed1 all head 100
 +block out log body on ed1 all head 150
 +#--------------------------------------------------------------------------
 +block in log on fxp0 all head 200
 +block out log on fxp0 all head 250
 +#--------------------------------------------------------------------------
 +# incoming ed1 traffic - group 100
 +# 1) prevent localhost spoofing
 +block in log quick from 127.0.0.1/32 to 192.168.0.0/24 group 100
 +block in log quick from 127.0.0.1/32 to 192.168.1.0/24 group 100
 +block in log quick from any to 127.0.0.1/8 group 100
 +#--------------------------------------------------------------------------
 +# 2) deny pakets which should not be seen on th internet (paranoid)
 +block in log quick from 10.0.0.0/8 to any group 100
 +block in log quick from any to 10.0.0.0/8 group 100
 +block in log quick from 172.16.0.0/16 to any group 100
 +block in log quick from any to 172.16.0.0/16 group 100
 +block in log quick from 192.168.0.0/16 to any group 100
 +block in log from any to 192.168.0.0/16 group 100
 +# 3) implement policy
 +# allow incoming ftp-data
 +pass in log quick proto tcp/udp from any to 192.168.1.1/24 keep state group 100
 +# if nothing applies, block and return icmp-replies (unreachable and rst)
 +block return-icmp(net-unr) in proto udp from any to any group 100
 +block return-rst in log proto tcp from any to any group 100
 +#--------------------------------------------------------------------------
 +# outgoing ed1 traffic - group 150
 +# Setup outgoing DNS
 +pass out log quick proto tcp/udp from any to 212.40.0.10 port = 53 keep state group 150
 +pass out log quick proto tcp/udp from any to 212.40.5.50 port = 53 keep state group 150
 +# allow outgoing http-service
 +pass out log quick proto tcp from any to any port = 80 flags S/SA keep state keep frags group 150
 +# allow outgoing smtp traffic
 +pass out log quick proto tcp from 192.168.1.1/24 to any port = 25 flags S/SA keep state group 150
 +# allow outgoing pop3 traffic
 +pass out log quick proto tcp from 192.168.1.1/24 to any port = 110 flags S/SA keep state group 150
 +# allow outgoing ftp traffic
 +pass out log quick proto tcp/udp from 192.168.1.1/24 to any port = ftp keep state group 150
 +pass out log quick proto icmp from any to any keep state keep frags group 150
 +#--------------------------------------------------------------------------
 +# incoming traffic on fxp0 - group 200
 +#--------------------------------------------------------------------------
 +# 1) prevent localhost spoofing
 +block in log quick from 127.0.0.0/8 to any group 200
 +block in log quick from 192.168.0.1/32 to any group 200
 +block in log quick from 192.168.1.110/24 to any group 200
 +pass in log quick from any to any group 200
 +#--------------------------------------------------------------------------
 +# outgoing traffic on fxp0 - group 250
 +#--------------------------------------------------------------------------
 +block out log quick from 127.0.0.0/8 to any group 250
 +block out quick from any to 127.0.0.0/8 group 250
 +block out log quick from any to 192.168.0.1/32 group 250
 +pass out log quick from any to nay group 250
 +#--------------------------------------------------------------------------
 diff -urN share/examples/ipfilter.orig/ipf.conf.sample share/examples/ipfilter/ipf.conf.sample
 --- share/examples/ipfilter.orig/ipf.conf.sample	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/ipf.conf.sample	Sun Apr 22 09:41:54 2001
 @@ -0,0 +1,18 @@
 +block in log quick from any with ipopts
 +block in log quick proto tcp from any to any with short
 +pass out on ed1 all head 150
 +block out from 127.0.0.0/8 to any group 150
 +block out from any to 127.0.0.0/8 group 150
 +block out from any to 192.168.1.110/32 group 150
 +pass in on ed1 all head 100
 +block in from 127.0.0.0/8 to any group 100
 +block in from 192.168.1.110/32 to any group 100
 +block in from 192.168.0.1/0xffffff00 to any group 100
 +pass out on fxp0 all head 250
 +block out from 127.0.0.0/8 to any group 250
 +block out from any to 127.0.0.0/8 group 250
 +block out from any to 192.168.0.1/32 group 250
 +pass in on fxp0 all head 200
 +block in from 127.0.0.0/8 to any group 200
 +block in from 192.168.0.1 to any group 200
 +block in from 192.168.1.110/0xffffff00 to any group 200
 diff -urN share/examples/ipfilter.orig/ipnat.conf.sample share/examples/ipfilter/ipnat.conf.sample
 --- share/examples/ipfilter.orig/ipnat.conf.sample	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/ipnat.conf.sample	Sun Apr 22 09:41:54 2001
 @@ -0,0 +1,2 @@
 +map ed1 192.168.0.0/24 -> 192.168.1.110/32 portmap tcp/udp 40000:65000
 +map ed1 192.168.0.0/24 -> 192.168.1.110/32
 diff -urN share/examples/ipfilter.orig/rules.txt share/examples/ipfilter/rules.txt
 --- share/examples/ipfilter.orig/rules.txt	Thu Jan  1 01:00:00 1970
 +++ share/examples/ipfilter/rules.txt	Sun Apr 22 10:06:43 2001
 @@ -0,0 +1,181 @@
 +#
 +# block all incoming TCP packets on le0 from host "foo" to any destination.
 +#
 +block in on le0 proto tcp from foo/32 to any
 +
 +  ------------------------------------------------------------------------
 +
 +#
 +# block all outgoing TCP packets on le0 from any host to port 23 of host bar.
 +#
 +block out on le0 proto tcp from any to bar/32 port != 23
 +
 +  ------------------------------------------------------------------------
 +
 +#
 +# block all inbound packets.
 +#
 +block in from any to any
 +#
 +# pass through packets to and from localhost.
 +#
 +pass in from 127.0.0.1/32 to 127.0.0.1/32
 +#
 +# allow a variety of individual hosts to send any type of IP packet to any
 +# other host.
 +#
 +pass in from 10.1.3.1 to any
 +pass in from 10.1.3.2 to any
 +pass in from 10.1.3.3 to any
 +pass in from 10.1.3.4 to any
 +pass in from 10.1.3.5 to any
 +pass in from 10.1.0.13/32 to any
 +pass in from 10.1.1.1/32 to any
 +pass in from 10.1.2.1/32 to any
 +#
 +#
 +# block all outbound packets.
 +#
 +block out from any to any
 +#
 +# allow any packets destined for localhost out.
 +#
 +pass out from any to 127.0.0.1/32
 +#
 +# allow any host to send any IP packet out to a limited number of hosts.
 +#
 +pass out from any to 10.1.3.1/32
 +pass out from any to 10.1.3.2/32
 +pass out from any to 10.1.3.3/32
 +pass out from any to 10.1.3.4/32
 +pass out from any to 10.1.3.5/32
 +pass out from any to 10.1.0.13/32
 +pass out from any to 10.1.1.1/32
 +pass out from any to 10.1.2.1/32
 +
 +  ------------------------------------------------------------------------
 +
 +#
 +# block all ICMP packets.
 +#
 +block in proto icmp from any to any
 +
 +  ------------------------------------------------------------------------
 +
 +#
 +# test ruleset
 +#
 +# allow packets coming from foo to bar through.
 +#
 +pass from foo to bar
 +#
 +# allow any TCP packets from the same subnet as foo is on through to host
 +# 10.1.1.2 if they are destined for port 6667.
 +#
 +pass proto tcp from fubar/24 to 10.1.1.2/32 port = 6667
 +#
 +# allow in UDP packets which are NOT from port 53 and are destined for
 +# localhost
 +#
 +pass proto udp from fubar port != 53 to localhost
 +#
 +# block all ICMP unreachables.
 +#
 +block from any to any icmp unreach
 +#
 +# allow packets through which have a non-standard IP header length (ie there
 +# are IP options such as source-routing present).
 +#
 +pass from any to any with ipopts
 +
 +  ------------------------------------------------------------------------
 +
 +#
 +# block all TCP packets with only the SYN flag set (this is the first
 +# packet sent to establish a connection).
 +#
 +block in proto tcp from any to any flags S/SA
 +
 +  ------------------------------------------------------------------------
 +
 +#
 +# log all inbound packet on le0 which has IP options present
 +#
 +log in on le0 from any to any with ipopts
 +#
 +# block any inbound packets on le0 which are fragmented and "too short" to
 +# do any meaningful comparison on.  This actually only applies to TCP
 +# packets which can be missing the flags/ports (depending on which part
 +# of the fragment you see).
 +#
 +block in log quick on le0 from any to any with short frag
 +#
 +# log all inbound TCP packets with the SYN flag (only) set
 +#  (NOTE: if it were an inbound TCP packet with the SYN flag set and it
 +#         had IP options present, this rule and the above would cause it
 +#         to be logged twice).
 +#
 +log in on le0 proto tcp from any to any flags S/SA
 +#
 +# block and log any inbound ICMP unreachables
 +#
 +block in log on le0 proto icmp from any to any icmp-type unreach
 +#
 +# block and log any inbound UDP packets on le0 which are going to port 2049
 +# (the NFS port).
 +#
 +block in log on le0 proto udp from any to any port = 2049
 +#
 +# quickly allow any packets to/from a particular pair of hosts
 +#
 +pass in quick from any to 10.1.3.2/32
 +pass in quick from any to 10.1.0.13/32
 +pass in quick from 10.1.3.2/32 to any
 +pass in quick from 10.1.0.13/32 to any
 +#
 +# block (and stop matching) any packet with IP options present.
 +#
 +block in quick on le0 from any to any with ipopts
 +#
 +# allow any packet through
 +#
 +pass in from any to any
 +#
 +# block any inbound UDP packets destined for these subnets.
 +#
 +block in on le0 proto udp from any to 10.1.3.0/24
 +block in on le0 proto udp from any to 10.1.1.0/24
 +block in on le0 proto udp from any to 10.1.2.0/24
 +#
 +# block any inbound TCP packets with only the SYN flag set that are
 +# destined for these subnets.
 +#
 +block in on le0 proto tcp from any to 10.1.3.0/24 flags S/SA
 +block in on le0 proto tcp from any to 10.1.2.0/24 flags S/SA
 +block in on le0 proto tcp from any to 10.1.1.0/24 flags S/SA
 +#
 +# block any inbound ICMP packets destined for these subnets.
 +#
 +block in on le0 proto icmp from any to 10.1.3.0/24
 +block in on le0 proto icmp from any to 10.1.1.0/24
 +block in on le0 proto icmp from any to 10.1.2.0/24
 +#
 +# Log all short TCP packets to qe3, with "packetlog" as the intended
 +# destination for the packet.
 +#
 +block in to qe3:packetlog proto tcp all with short
 +#
 +# Log all connection attempts for TCP
 +#
 +pass in dup-to le0:packetlog proto tcp all flags S/SA
 +#
 +# Route all UDP packets through transparently.
 +#
 +pass in fastroute proto udp all
 +#
 +# Route all ICMP packets to network 10 out through le1, to "router"
 +#
 +pass in to le1:router proto icmp all
 +
 +  ------------------------------------------------------------------------
 +Return to the IP Filter home page
 
 Cyrille.
 --
 home: mailto:clefevre@poboxes.com   UNIX is user-friendly; it's just particular
 work: mailto:Cyrille.Lefevre@edf.fr   about who it chooses to be friends with. 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200104220900.f3M902J83661>