185213Sdarrenr
285213Sdarrenr
385213Sdarrenr
485213Sdarrenr
585213Sdarrenr
685213Sdarrenr
785213Sdarrenr              IP Filter Based Firewalls HOWTO
885213Sdarrenr
985213Sdarrenr              Brendan Conoboy <synk@swcp.com>
1085213Sdarrenr            Erik Fichtner <emf@obfuscation.org>
1185213Sdarrenr            $FreeBSD$
1285213Sdarrenr
1385213Sdarrenr                Fri Apr 20 09:31:14 EDT 2001
1485213Sdarrenr
1585213Sdarrenr
1685213Sdarrenr
1785213Sdarrenr
1885213Sdarrenr
1985213Sdarrenr
2085213Sdarrenr     Abstract:  This document is intended to introduce a new
2185213Sdarrenr     user to the IP Filter firewalling package and,  at  the
2285213Sdarrenr     same  time,  teach  the user some basic fundamentals of
2385213Sdarrenr     good firewall design.
2485213Sdarrenr
2585213Sdarrenr
2685213Sdarrenr
2785213Sdarrenr
2885213Sdarrenr
2985213Sdarrenr
3085213Sdarrenr
3185213Sdarrenr
3285213Sdarrenr
3385213Sdarrenr
3485213Sdarrenr
3585213Sdarrenr
3685213Sdarrenr1.  Introduction
3785213Sdarrenr
3885213Sdarrenr     IP Filter is a great little firewall package.  It  does
3985213Sdarrenrjust   about   everything  other  free  firewalls  (ipfwadm,
4085213Sdarrenripchains, ipfw) do, but it's also  portable  and  does  neat
4185213Sdarrenrstuff  the  others don't.  This document is intended to make
4285213Sdarrenrsome cohesive sense of the  sparse  documentation  presently
4385213Sdarrenravailable  for ipfilter.  Some prior familiarity with packet
4485213Sdarrenrfiltering will be useful, however too much  familiarity  may
4585213Sdarrenrmake this document a waste of your time.  For greater under-
4685213Sdarrenrstanding of firewalls, the authors recommend reading  Build-
4785213Sdarrenring Internet Firewalls, Chapman & Zwicky, O'Reilly and Asso-
4885213Sdarrenrciates; and TCP/IP Illustrated, Volume 1, Stevens,  Addison-
4985213SdarrenrWesley.
5085213Sdarrenr
5185213Sdarrenr
5285213Sdarrenr
5385213Sdarrenr
5485213Sdarrenr
5585213Sdarrenr1.1.  Disclaimer
5685213Sdarrenr
5785213Sdarrenr     The  authors  of  this document are not responsible for
5885213Sdarrenrany damages incurred due to actions taken based on this doc-
5985213Sdarrenrument. This document is meant as an introduction to building
6085213Sdarrenra  firewall  based  on  IP-Filter.   If  you  do  not   feel
6185213Sdarrenr
6285213Sdarrenr
6385213Sdarrenr
6485213Sdarrenr
6585213Sdarrenr
6685213Sdarrenr
6785213Sdarrenr
6885213Sdarrenr
6985213Sdarrenr
7085213Sdarrenr                             -2-
7185213Sdarrenr
7285213Sdarrenr
7385213Sdarrenrcomfortable  taking responsibility for your own actions, you
7485213Sdarrenrshould stop reading this document and hire a qualified secu-
7585213Sdarrenrrity professional to install your firewall for you.
7685213Sdarrenr
7785213Sdarrenr
7885213Sdarrenr1.2.  Copyright
7985213Sdarrenr
8085213Sdarrenr     Unless  otherwise  stated,  HOWTO  documents  are copy-
8185213Sdarrenrrighted by their respective authors. HOWTO documents may  be
8285213Sdarrenrreproduced  and  distributed  in  whole  or  in part, in any
8385213Sdarrenrmedium physical or electronic, as  long  as  this  copyright
8485213Sdarrenrnotice  is retained on all copies. Commercial redistribution
8585213Sdarrenris allowed and encouraged; however, the authors  would  like
8685213Sdarrenrto be notified of any such distributions.
8785213Sdarrenr
8885213Sdarrenr     All  translations, derivative works, or aggregate works
8985213Sdarrenrincorporating any HOWTO documents must be covered under this
9085213Sdarrenrcopyright notice.  That is, you may not produce a derivative
9185213Sdarrenrwork from a HOWTO and impose additional restrictions on  its
9285213Sdarrenrdistribution. Exceptions to these rules may be granted under
9385213Sdarrenrcertain conditions; please contact the HOWTO coordinator.
9485213Sdarrenr
9585213Sdarrenr     In short, we wish  to  promote  dissemination  of  this
9685213Sdarrenrinformation  through  as many channels as possible. However,
9785213Sdarrenrwe do wish to retain copyright on the HOWTO  documents,  and
9885213Sdarrenrwould  like  to be notified of any plans to redistribute the
9985213SdarrenrHOWTOs.
10085213Sdarrenr
10185213Sdarrenr
10285213Sdarrenr1.3.  Where to obtain the important pieces
10385213Sdarrenr
10485213Sdarrenr     The     official     IPF      homepage      is      at:
10585213Sdarrenr<http://coombs.anu.edu.au/~avalon/ip-filter.html>
10685213Sdarrenr
10785213Sdarrenr     The  most  up-to-date  version  of this document can be
10885213Sdarrenrfound at: <http://www.obfuscation.org/ipf/>
10985213Sdarrenr
11085213Sdarrenr
11185213Sdarrenr
11285213Sdarrenr
11385213Sdarrenr2.  Basic Firewalling
11485213Sdarrenr
11585213Sdarrenr     This section is designed to familiarize you with ipfil-
11685213Sdarrenrter's  syntax, and firewall theory in general.  The features
11785213Sdarrenrdiscussed here are features you'll find in any good firewall
11885213Sdarrenrpackage.   This  section  will give you a good foundation to
11985213Sdarrenrmake reading and understanding  the  advanced  section  very
12085213Sdarrenreasy.   It must be emphasized that this section alone is not
12185213Sdarrenrenough to build a good firewall, and that the advanced  sec-
12285213Sdarrenrtion  really  is  required  reading for anybody who wants to
12385213Sdarrenrbuild an effective security system.
12485213Sdarrenr
12585213Sdarrenr
12685213Sdarrenr
12785213Sdarrenr
12885213Sdarrenr
12985213Sdarrenr
13085213Sdarrenr
13185213Sdarrenr
13285213Sdarrenr
13385213Sdarrenr
13485213Sdarrenr
13585213Sdarrenr
13685213Sdarrenr                             -3-
13785213Sdarrenr
13885213Sdarrenr
13985213Sdarrenr2.1.  Config File Dynamics, Order and Precedence
14085213Sdarrenr
14185213Sdarrenr     IPF (IP Filter) has a config file (as opposed  to  say,
14285213Sdarrenrrunning  some  command  again  and again for each new rule).
14385213SdarrenrThe config file drips with Unix:  There's one rule per line,
14485213Sdarrenrthe  "#" mark denotes a comment, and you can have a rule and
14585213Sdarrenra comment  on  the  same  line.   Extraneous  whitespace  is
14685213Sdarrenrallowed, and is encouraged to keep the rules readable.
14785213Sdarrenr
14885213Sdarrenr
14985213Sdarrenr2.2.  Basic Rule Processing
15085213Sdarrenr
15185213Sdarrenr     The  rules  are  processed from top to bottom, each one
15285213Sdarrenrappended after another.  This quite simply means that if the
15385213Sdarrenrentirety of your config file is:
15485213Sdarrenr
15585213Sdarrenr    block in all
15685213Sdarrenr    pass  in all
15785213Sdarrenr
15885213SdarrenrThe computer sees it as:
15985213Sdarrenr
16085213Sdarrenr    block in all
16185213Sdarrenr    pass  in all
16285213Sdarrenr
16385213SdarrenrWhich is to say that when a packet comes in, the first thing
16485213SdarrenrIPF applies is:
16585213Sdarrenr
16685213Sdarrenr    block in all
16785213Sdarrenr
16885213SdarrenrShould IPF deem it necessary to move on to the next rule, it
16985213Sdarrenrwould then apply the second rule:
17085213Sdarrenr
17185213Sdarrenr    pass  in all
17285213Sdarrenr
17385213Sdarrenr     At  this  point,  you might want to ask yourself "would
17485213SdarrenrIPF move on to the second rule?"  If  you're  familiar  with
17585213Sdarrenripfwadm  or  ipfw,  you  probably  won't  ask yourself this.
17685213SdarrenrShortly after, you will become bewildered at the  weird  way
17785213Sdarrenrpackets  are  always  getting  denied  or  passed  when they
17885213Sdarrenrshouldn't.  Many packet filters stop  comparing  packets  to
17985213Sdarrenrrulesets  the moment the first match is made; IPF is not one
18085213Sdarrenrof them.
18185213Sdarrenr
18285213Sdarrenr     Unlike the other packet filters, IPF keeps  a  flag  on
18385213Sdarrenrwhether  or  not  it's going to pass the packet.  Unless you
18485213Sdarrenrinterrupt the flow, IPF will go through the entire  ruleset,
18585213Sdarrenrmaking  its  decision  on whether or not to pass or drop the
18685213Sdarrenrpacket based on the last matching rule.  The scene: IP  Fil-
18785213Sdarrenrter's  on  duty.   It's  been  been scheduled a slice of CPU
18885213Sdarrenrtime.  It has a checkpoint clipboard that reads:
18985213Sdarrenr
19085213Sdarrenr    block in all
19185213Sdarrenr    pass  in all
19285213Sdarrenr
19385213Sdarrenr
19485213Sdarrenr
19585213Sdarrenr
19685213Sdarrenr
19785213Sdarrenr
19885213Sdarrenr
19985213Sdarrenr
20085213Sdarrenr
20185213Sdarrenr
20285213Sdarrenr                             -4-
20385213Sdarrenr
20485213Sdarrenr
20585213SdarrenrA packet comes in the interface and it's time to go to work.
20685213SdarrenrIt  takes a look at the packet, it takes a look at the first
20785213Sdarrenrrule:
20885213Sdarrenr
20985213Sdarrenr    block in all
21085213Sdarrenr
21185213Sdarrenr"So far I think I will block  this  packet"  says  IPF.   It
21285213Sdarrenrtakes a look at the second rule:
21385213Sdarrenr
21485213Sdarrenr    pass  in all
21585213Sdarrenr
21685213Sdarrenr"So far I think I will pass this packet" says IPF.  It takes
21785213Sdarrenra look at a third rule.  There is no third rule, so it  goes
21885213Sdarrenrwith  what  its  last  motivation  was,  to  pass the packet
21985213Sdarrenronward.
22085213Sdarrenr
22185213SdarrenrIt's a good time to point out that even if the  ruleset  had
22285213Sdarrenrbeen
22385213Sdarrenr
22485213Sdarrenr    block in all
22585213Sdarrenr    block in all
22685213Sdarrenr    block in all
22785213Sdarrenr    block in all
22885213Sdarrenr    pass  in all
22985213Sdarrenr
23085213Sdarrenrthat  the packet would still have gone through.  There is no
23185213Sdarrenrcumulative effect.  The  last  matching  rule  always  takes
23285213Sdarrenrprecedence.
23385213Sdarrenr
23485213Sdarrenr2.3.  Controlling Rule Processing
23585213Sdarrenr
23685213Sdarrenr     If  you  have experience with other packet filters, you
23785213Sdarrenrmay find this layout to be confusing, and you may be  specu-
23885213Sdarrenrlating  that  there are problems with portability with other
23985213Sdarrenrfilters and speed of rule matching.  Imagine if you had  100
24085213Sdarrenrrules  and  most  of  the applicable ones were the first 10.
24185213SdarrenrThere would be a terrible overhead for every  packet  coming
24285213Sdarrenrin  to  go through 100 rules every time.  Fortunately, there
24385213Sdarrenris a simple keyword you can add to any rule  that  makes  it
24485213Sdarrenrtake action at that match.  That keyword is quick.
24585213Sdarrenr
24685213SdarrenrHere's  a  modified  copy  of the original ruleset using the
24785213Sdarrenrquick keyword:
24885213Sdarrenr
24985213Sdarrenr    block in quick all
25085213Sdarrenr    pass  in       all
25185213Sdarrenr
25285213SdarrenrIn this case, IPF looks at the first rule:
25385213Sdarrenr
25485213Sdarrenr    block in quick all
25585213Sdarrenr
25685213SdarrenrThe packet matches and the search is over.   The  packet  is
25785213Sdarrenrexpunged  without a peep.  There are no notices, no logs, no
25885213Sdarrenrmemorial service.  Cake will not be served.  So  what  about
25985213Sdarrenr
26085213Sdarrenr
26185213Sdarrenr
26285213Sdarrenr
26385213Sdarrenr
26485213Sdarrenr
26585213Sdarrenr
26685213Sdarrenr
26785213Sdarrenr
26885213Sdarrenr                             -5-
26985213Sdarrenr
27085213Sdarrenr
27185213Sdarrenrthe next rule?
27285213Sdarrenr
27385213Sdarrenr    pass  in       all
27485213Sdarrenr
27585213Sdarrenr     This  rule is never encountered.  It could just as eas-
27685213Sdarrenrily not be in the config file at all.  The sweeping match of
27785213Sdarrenrall  and  the  terminal keyword quick from the previous rule
27885213Sdarrenrmake certain that no rules are followed afterward.
27985213Sdarrenr
28085213Sdarrenr     Having half a config file laid to  waste  is  rarely  a
28185213Sdarrenrdesirable  state.   On  the other hand, IPF is here to block
28285213Sdarrenrpackets and as configured,  it's  doing  a  very  good  job.
28385213SdarrenrNonetheless,  IPF  is also here to let some packets through,
28485213Sdarrenrso a change to the ruleset to make this possible  is  called
28585213Sdarrenrfor.
28685213Sdarrenr
28785213Sdarrenr2.4.  Basic filtering by IP address
28885213Sdarrenr
28985213Sdarrenr     IPF  will match packets on many criteria.  The one that
29085213Sdarrenrwe most commonly think of is the IP address.  There are some
29185213Sdarrenrblocks of address space from which we should never get traf-
29285213Sdarrenrfic.  One such  block  is  from   the  unroutable  networks,
29385213Sdarrenr192.168.0.0/16 (/16 is the CIDR notation for a netmask.  You
29485213Sdarrenrmay  be  more  familiar  with  the  dotted  decimal  format,
29585213Sdarrenr255.255.0.0.   IPF  accepts  both).   If you wanted to block
29685213Sdarrenr192.168.0.0/16, this is one way to do it:
29785213Sdarrenr
29885213Sdarrenr    block in quick from 192.168.0.0/16 to any
29985213Sdarrenr    pass  in       all
30085213Sdarrenr
30185213SdarrenrNow we have a less  stringent  ruleset  that  actually  does
30285213Sdarrenrsomething  for  us.   Let's  imagine  a packet comes in from
30385213Sdarrenr1.2.3.4.  The first rule is applied:
30485213Sdarrenr
30585213Sdarrenr    block in quick from 192.168.0.0/16 to any
30685213Sdarrenr
30785213SdarrenrThe packet is from 1.2.3.4, not 192.168.*.*, so there is  no
30885213Sdarrenrmatch.  The second rule is applied:
30985213Sdarrenr
31085213Sdarrenr    pass  in       all
31185213Sdarrenr
31285213SdarrenrThe  packet from 1.2.3.4 is definitely a part of all, so the
31385213Sdarrenrpacket is sent to whatever it's destination happened to  be.
31485213Sdarrenr
31585213Sdarrenr     On  the other hand, suppose we have a packet that comes
31685213Sdarrenrin from 192.168.1.2.  The first rule is applied:
31785213Sdarrenr
31885213Sdarrenr    block in quick from 192.168.0.0/16 to any
31985213Sdarrenr
32085213SdarrenrThere's a match, the packet is dropped, and that's the  end.
32185213SdarrenrAgain,  it doesn't move to the second rule because the first
32285213Sdarrenrrule matches and contains the quick keyword.
32385213Sdarrenr
32485213Sdarrenr
32585213Sdarrenr
32685213Sdarrenr
32785213Sdarrenr
32885213Sdarrenr
32985213Sdarrenr
33085213Sdarrenr
33185213Sdarrenr
33285213Sdarrenr
33385213Sdarrenr
33485213Sdarrenr                             -6-
33585213Sdarrenr
33685213Sdarrenr
33785213Sdarrenr     At this point you can build a fairly extensive  set  of
33885213Sdarrenrdefinitive  addresses  which  are  passed or blocked.  Since
33985213Sdarrenrwe've already started blocking private  address  space  from
34085213Sdarrenrentering our firewall, let's take care of the rest of it:
34185213Sdarrenr
34285213Sdarrenr    block in quick from 192.168.0.0/16 to any
34385213Sdarrenr    block in quick from 172.16.0.0/12 to any
34485213Sdarrenr    block in quick from 10.0.0.0/8 to any
34585213Sdarrenr    pass  in       all
34685213Sdarrenr
34785213SdarrenrThe  first  three  address blocks are some of the private IP
34885213Sdarrenrspace.
34985213Sdarrenr
35085213Sdarrenr2.5.  Controlling Your Interfaces
35185213Sdarrenr
35285213Sdarrenr     It  seems  very  frequent  that companies have internal
35385213Sdarrenrnetworks before they want a link to the outside  world.   In
35485213Sdarrenrfact, it's probably reasonable to say that's the main reason
35585213Sdarrenrpeople consider firewalls in the first place.   The  machine
35685213Sdarrenrthat  bridges the outside world to the inside world and vice
35785213Sdarrenrversa is the router.  What separates  the  router  from  any
35885213Sdarrenrother machine is simple: It has more than one interface.
35985213Sdarrenr
36085213Sdarrenr     Every  packet  you  receive comes from a network inter-
36185213Sdarrenrface; every packet you transmit goes out  a  network  inter-
36285213Sdarrenrface.   Say  your  machine has 3 interfaces, lo0 (loopback),
36385213Sdarrenrxl0 (3com ethernet),  and  tun0  (FreeBSD's  generic  tunnel
36485213Sdarrenrinterface  that PPP uses), but you don't want packets coming
36585213Sdarrenrin on the tun0 interface?
36685213Sdarrenr
36785213Sdarrenr    block in quick on tun0 all
36885213Sdarrenr    pass  in               all
36985213Sdarrenr
37085213SdarrenrIn this case, the on keyword means that that data is  coming
37185213Sdarrenrin  on  the  named interface.  If a packet comes in on tun0,
37285213Sdarrenrthe first rule will block it.  If a packet comes in  on  lo0
37385213Sdarrenror in on xl0, the first rule will not match, the second rule
37485213Sdarrenrwill, the packet will be passed.
37585213Sdarrenr
37685213Sdarrenr2.6.  Using IP Address and Interface Together
37785213Sdarrenr
37885213Sdarrenr     It's an odd state of affairs when one decides  it  best
37985213Sdarrenrto  have the tun0 interface up, but not allow any data to be
38085213Sdarrenrreceived from it.  The more criteria  the  firewall  matches
38185213Sdarrenragainst,  the  tighter  (or looser) the firewall can become.
38285213SdarrenrMaybe you want data from tun0, but not from  192.168.0.0/16?
38385213SdarrenrThis is the start of a powerful firewall.
38485213Sdarrenr
38585213Sdarrenr    block in quick on tun0 from 192.168.0.0/16 to any
38685213Sdarrenr-----------
38785213Sdarrenr            See             rfc1918             at
38885213Sdarrenr<http://www.faqs.org/rfcs/rfc1918.html>        and
38985213Sdarrenr<http://www.ietf.org/internet-drafts/draft-man-
39085213Sdarrenrning-dsua-06.txt>
39185213Sdarrenr
39285213Sdarrenr
39385213Sdarrenr
39485213Sdarrenr
39585213Sdarrenr
39685213Sdarrenr
39785213Sdarrenr
39885213Sdarrenr
39985213Sdarrenr
40085213Sdarrenr                             -7-
40185213Sdarrenr
40285213Sdarrenr
40385213Sdarrenr    pass  in       all
40485213Sdarrenr
40585213SdarrenrCompare this to our previous rule:
40685213Sdarrenr
40785213Sdarrenr    block in quick from 192.168.0.0/16 to any
40885213Sdarrenr    pass  in       all
40985213Sdarrenr
41085213SdarrenrThe  old way, all traffic from 192.168.0.0/16, regardless of
41185213Sdarrenrinterface, was completely blocked.  The new  way,  using  on
41285213Sdarrenrtun0 means that it's only blocked if it comes in on the tun0
41385213Sdarrenrinterface.  If a packet arrived on the  xl0  interface  from
41485213Sdarrenr192.168.0.0/16, it would be passed.
41585213Sdarrenr
41685213Sdarrenr     At  this  point you can build a fairly extensive set of
41785213Sdarrenrdefinitive addresses which are  passed  or  blocked.   Since
41885213Sdarrenrwe've  already  started  blocking private address space from
41985213Sdarrenrentering tun0, let's take care of the rest of it:
42085213Sdarrenr
42185213Sdarrenr    block in quick on tun0 from 192.168.0.0/16 to any
42285213Sdarrenr    block in quick on tun0 from 172.16.0.0/12 to any
42385213Sdarrenr    block in quick on tun0 from 10.0.0.0/8 to any
42485213Sdarrenr    block in quick on tun0 from 127.0.0.0/8 to any
42585213Sdarrenr    block in quick on tun0 from 0.0.0.0/8 to any
42685213Sdarrenr    block in quick on tun0 from 169.254.0.0/16 to any
42785213Sdarrenr    block in quick on tun0 from 192.0.2.0/24 to any
42885213Sdarrenr    block in quick on tun0 from 204.152.64.0/23 to any
42985213Sdarrenr    block in quick on tun0 from 224.0.0.0/3 to any
43085213Sdarrenr    pass  in       all
43185213Sdarrenr
43285213SdarrenrYou've already seen the first  three  blocks,  but  not  the
43385213Sdarrenrrest.   The  fourth is a largely wasted class-A network used
43485213Sdarrenrfor loopback.  Much software  communicates  with  itself  on
43585213Sdarrenr127.0.0.1  so  blocking it from an external source is a good
43685213Sdarrenridea.  The fifth, 0.0.0.0/8, should never  be  seen  on  the
43785213Sdarrenrinternet.   Most IP stacks treat "0.0.0.0/32" as the default
43885213Sdarrenrgateway, and the rest of the 0.*.*.*  network  gets  handled
43985213Sdarrenrstrangely  by  various systems as a byproduct of how routing
44085213Sdarrenrdecisions are made.   You should treat 0.0.0.0/8  just  like
44185213Sdarrenr127.0.0.0/8.    169.254.0.0/16 has been assigned by the IANA
44285213Sdarrenrfor use in auto-configuration when systems have not yet been
44385213Sdarrenrable  to  obtain  an  IP address via DHCP or the like.  Most
44485213Sdarrenrnotably, Microsoft Windows will use addresses in this  range
44585213Sdarrenrif  they  are  set  to  DHCP  and cannot find a DHCP server.
44685213Sdarrenr192.0.2.0/24 has also been reserved for use as an example IP
44785213Sdarrenrnetblock  for documentation authors.  We specifically do not
44885213Sdarrenruse this range as it would cause confusion when we tell  you
44985213Sdarrenrto   block   it,   and  thus  all  our  examples  come  from
45085213Sdarrenr20.20.20.0/24.  204.152.64.0/23 is an odd netblock  reserved
45185213Sdarrenrby  Sun  Microsystems for private cluster interconnects, and
45285213Sdarrenrblocking  this  is  up  to  your  own  judgement.    Lastly,
45385213Sdarrenr224.0.0.0/3  wipes out the "Class D and E" networks which is
45485213Sdarrenrused mostly for multicast traffic, although further  defini-
45585213Sdarrenrtion of "Class E" space can be found in RFC 1166.
45685213Sdarrenr
45785213Sdarrenr
45885213Sdarrenr
45985213Sdarrenr
46085213Sdarrenr
46185213Sdarrenr
46285213Sdarrenr
46385213Sdarrenr
46485213Sdarrenr
46585213Sdarrenr
46685213Sdarrenr                             -8-
46785213Sdarrenr
46885213Sdarrenr
46985213Sdarrenr     There's  a very important principle in packet filtering
47085213Sdarrenrwhich has only been alluded  to  with  the  private  network
47185213Sdarrenrblocking  and  that  is  this: When you know there's certain
47285213Sdarrenrtypes of data that only comes from certain places, you setup
47385213Sdarrenrthe  system  to  only  allow  that  kind  of data from those
47485213Sdarrenrplaces.  In the case of the unroutable addresses,  you  know
47585213Sdarrenrthat  nothing  from  10.0.0.0/8  should  be arriving on tun0
47685213Sdarrenrbecause you have no way to reply to it.  It's  an  illegiti-
47785213Sdarrenrmate  packet.   The  same  goes for the other unroutables as
47885213Sdarrenrwell as 127.0.0.0/8.
47985213Sdarrenr
48085213Sdarrenr     Many pieces of software  do  all  their  authentication
48185213Sdarrenrbased  upon  the  packet's originating IP address.  When you
48285213Sdarrenrhave an internal network, say 20.20.20.0/24, you  know  that
48385213Sdarrenrthe  only traffic for that internal network is going to come
48485213Sdarrenroff the local ethernet.  Should a packet from  20.20.20.0/24
48585213Sdarrenrarrive  over a PPP dialup, it's perfectly reasonable to drop
48685213Sdarrenrit on the floor, or put it in a dark room for interrogation.
48785213SdarrenrIt  should by no means be allowed to get to its final desti-
48885213Sdarrenrnation.  You can accomplish this  particularly  easily  with
48985213Sdarrenrwhat you already know of IPF.  The new ruleset would be:
49085213Sdarrenr
49185213Sdarrenr    block in quick on tun0 from 192.168.0.0/16 to any
49285213Sdarrenr    block in quick on tun0 from 172.16.0.0/12 to any
49385213Sdarrenr    block in quick on tun0 from 10.0.0.0/8 to any
49485213Sdarrenr    block in quick on tun0 from 127.0.0.0/8 to any
49585213Sdarrenr    block in quick on tun0 from 0.0.0.0/8 to any
49685213Sdarrenr    block in quick on tun0 from 169.254.0.0/16 to any
49785213Sdarrenr    block in quick on tun0 from 192.0.2.0/24 to any
49885213Sdarrenr    block in quick on tun0 from 204.152.64.0/23 to any
49985213Sdarrenr    block in quick on tun0 from 224.0.0.0/3 to any
50085213Sdarrenr    block in quick on tun0 from 20.20.20.0/24 to any
50185213Sdarrenr    pass  in       all
50285213Sdarrenr
50385213Sdarrenr2.7.  Bi-Directional Filtering; The "out" Keyword
50485213Sdarrenr
50585213Sdarrenr     Up  until  now,  we've been passing or blocking inbound
50685213Sdarrenrtraffic.  To clarify, inbound traffic is  all  traffic  that
50785213Sdarrenrenters  the firewall on any interface.  Conversely, outbound
50885213Sdarrenrtraffic is all traffic that leaves on any interface (whether
50985213Sdarrenrlocally  generated  or  simply passing through).  This means
51085213Sdarrenrthat all packets coming in are not  only  filtered  as  they
51185213Sdarrenrenter  the  firewall,  they're  also  filtered as they exit.
51285213SdarrenrThusfar there's been an implied pass out all that may or may
51385213Sdarrenrnot  be  desirable.  Just as you may pass and block incoming
51485213Sdarrenrtraffic, you may do the same with outgoing traffic.
51585213Sdarrenr
51685213Sdarrenr     Now that we know there's a way to filter outbound pack-
51785213Sdarrenrets  just  like inbound, it's up to us to find a conceivable
51885213Sdarrenruse for such a thing.  One possible use of this idea  is  to
51985213Sdarrenrkeep spoofed packets from exiting your own network.  Instead
52085213Sdarrenrof passing any traffic out the  router,  you  could  instead
52185213Sdarrenrlimit   permitted   traffic   to   packets   originating  at
52285213Sdarrenr
52385213Sdarrenr
52485213Sdarrenr
52585213Sdarrenr
52685213Sdarrenr
52785213Sdarrenr
52885213Sdarrenr
52985213Sdarrenr
53085213Sdarrenr
53185213Sdarrenr
53285213Sdarrenr                             -9-
53385213Sdarrenr
53485213Sdarrenr
53585213Sdarrenr20.20.20.0/24.  You might do it like this:
53685213Sdarrenr
53785213Sdarrenr    pass  out quick on tun0 from 20.20.20.0/24 to any
53885213Sdarrenr    block out quick on tun0 from any to any
53985213Sdarrenr
54085213SdarrenrIf a packet comes from 20.20.20.1/32, it gets  sent  out  by
54185213Sdarrenrthe  first  rule.  If a packet comes from 1.2.3.4/32 it gets
54285213Sdarrenrblocked by the second.
54385213Sdarrenr
54485213Sdarrenr     You can also make  similar  rules  for  the  unroutable
54585213Sdarrenraddresses.   If some machine tries to route a packet through
54685213SdarrenrIPF with a destination in 192.168.0.0/16, why not  drop  it?
54785213SdarrenrThe worst that can happen is that you'll spare yourself some
54885213Sdarrenrbandwidth:
54985213Sdarrenr
55085213Sdarrenr    block out quick on tun0 from any to 192.168.0.0/16
55185213Sdarrenr    block out quick on tun0 from any to 172.16.0.0/12
55285213Sdarrenr    block out quick on tun0 from any to 10.0.0.0/8
55385213Sdarrenr    block out quick on tun0 from any to 0.0.0.0/8
55485213Sdarrenr    block out quick on tun0 from any to 127.0.0.0/8
55585213Sdarrenr    block out quick on tun0 from any to 169.254.0.0/16
55685213Sdarrenr    block out quick on tun0 from any to 192.0.2.0/24
55785213Sdarrenr    block out quick on tun0 from any to 204.152.64.0/23
55885213Sdarrenr    block out quick on tun0 from any to 224.0.0.0/3
55985213Sdarrenr    block out quick on tun0 from !20.20.20.0/24 to any
56085213Sdarrenr
56185213SdarrenrIn the narrowest viewpoint, this doesn't enhance your  secu-
56285213Sdarrenrrity.   It  enhances everybody else's security, and that's a
56385213Sdarrenrnice thing to do.  As another viewpoint, one  might  suppose
56485213Sdarrenrthat because nobody can send spoofed packets from your site,
56585213Sdarrenrthat your site has less value as a relay for  crackers,  and
56685213Sdarrenras such is less of a target.
56785213Sdarrenr
56885213Sdarrenr     You'll  likely  find a number of uses for blocking out-
56985213Sdarrenrbound packets.  One thing to always keep in mind is that  in
57085213Sdarrenrand  out directions are in reference to your firewall, never
57185213Sdarrenrany other machine.
57285213Sdarrenr
57385213Sdarrenr2.8.  Logging What Happens; The "log" Keyword
57485213Sdarrenr
57585213Sdarrenr     Up to this point, all blocked and passed  packets  have
57685213Sdarrenrbeen silently blocked and silently passed.  Usually you want
57785213Sdarrenrto know if you're being attacked rather than wonder if  that
57885213Sdarrenrfirewall  is  really buying you any added benefits.  While I
57985213Sdarrenrwouldn't want to log every passed packet, and in some  cases
58085213Sdarrenrevery blocked packet, I would want to know about the blocked
58185213Sdarrenrpackets from 20.20.20.0/24.  To do this, we add the log key-
58285213Sdarrenrword:
58385213Sdarrenr
58485213Sdarrenr    block in     quick on tun0 from 192.168.0.0/16 to any
58585213Sdarrenr-----------
58685213Sdarrenr This can, of course, be changed by using -DIPFIL-
58785213SdarrenrTER_DEFAULT_BLOCK  when compiling ipfilter on your
58885213Sdarrenrsystem.
58985213Sdarrenr
59085213Sdarrenr
59185213Sdarrenr
59285213Sdarrenr
59385213Sdarrenr
59485213Sdarrenr
59585213Sdarrenr
59685213Sdarrenr
59785213Sdarrenr
59885213Sdarrenr                            -10-
59985213Sdarrenr
60085213Sdarrenr
60185213Sdarrenr    block in     quick on tun0 from 172.16.0.0/12 to any
60285213Sdarrenr    block in     quick on tun0 from 10.0.0.0/8 to any
60385213Sdarrenr    block in     quick on tun0 from 127.0.0.0/8 to any
60485213Sdarrenr    block in     quick on tun0 from 0.0.0.0/8 to any
60585213Sdarrenr    block in     quick on tun0 from 169.254.0.0/16 to any
60685213Sdarrenr    block in     quick on tun0 from 192.0.2.0/24 to any
60785213Sdarrenr    block in     quick on tun0 from 204.152.64.0/23 to any
60885213Sdarrenr    block in     quick on tun0 from 224.0.0.0/3 to any
60985213Sdarrenr    block in log quick on tun0 from 20.20.20.0/24 to any
61085213Sdarrenr    pass  in       all
61185213Sdarrenr
61285213SdarrenrSo far, our firewall is pretty good at blocking packets com-
61385213Sdarrenring to it from suspect places, but there's still more to  be
61485213Sdarrenrdone.   For one thing, we're accepting packets destined any-
61585213Sdarrenrwhere.  One thing we ought to do is  make  sure  packets  to
61685213Sdarrenr20.20.20.0/32  and 20.20.20.255/32 get dropped on the floor.
61785213SdarrenrTo do otherwise opens  the  internal  network  for  a  smurf
61885213Sdarrenrattack.  These two lines would prevent our hypothetical net-
61985213Sdarrenrwork from being used as a smurf relay:
62085213Sdarrenr
62185213Sdarrenr    block in log quick on tun0 from any to 20.20.20.0/32
62285213Sdarrenr    block in log quick on tun0 from any to 20.20.20.255/32
62385213Sdarrenr
62485213SdarrenrThis brings our total ruleset to look something like this:
62585213Sdarrenr
62685213Sdarrenr    block in     quick on tun0 from 192.168.0.0/16 to any
62785213Sdarrenr    block in     quick on tun0 from 172.16.0.0/12 to any
62885213Sdarrenr    block in     quick on tun0 from 10.0.0.0/8 to any
62985213Sdarrenr    block in     quick on tun0 from 127.0.0.0/8 to any
63085213Sdarrenr    block in     quick on tun0 from 0.0.0.0/8 to any
63185213Sdarrenr    block in     quick on tun0 from 169.254.0.0/16 to any
63285213Sdarrenr    block in     quick on tun0 from 192.0.2.0/24 to any
63385213Sdarrenr    block in     quick on tun0 from 204.152.64.0/23 to any
63485213Sdarrenr    block in     quick on tun0 from 224.0.0.0/3 to any
63585213Sdarrenr    block in log quick on tun0 from 20.20.20.0/24 to any
63685213Sdarrenr    block in log quick on tun0 from any to 20.20.20.0/32
63785213Sdarrenr    block in log quick on tun0 from any to 20.20.20.255/32
63885213Sdarrenr    pass  in       all
63985213Sdarrenr
64085213Sdarrenr2.9.  Complete Bi-Directional Filtering By Interface
64185213Sdarrenr
64285213Sdarrenr     So far we have only presented fragments of  a  complete
64385213Sdarrenrruleset.   When  you're  actually creating your ruleset, you
64485213Sdarrenrshould setup rules for every direction and every  interface.
64585213SdarrenrThe  default state of ipfilter is to pass packets.  It is as
64685213Sdarrenrthough there were an invisible rule at the  beginning  which
64785213Sdarrenrstates  pass  in  all and pass out all.  Rather than rely on
64885213Sdarrenrsome default behaviour, make everything as specific as  pos-
64985213Sdarrenrsible,  interface by interface, until every base is covered.
65085213Sdarrenr
65185213Sdarrenr     First we'll start with the lo0 interface,  which  wants
65285213Sdarrenrto  run  wild and free.  Since these are programs talking to
65385213Sdarrenrothers on the local system,  go  ahead  and  keep  it  unre-
65485213Sdarrenrstricted:
65585213Sdarrenr
65685213Sdarrenr
65785213Sdarrenr
65885213Sdarrenr
65985213Sdarrenr
66085213Sdarrenr
66185213Sdarrenr
66285213Sdarrenr
66385213Sdarrenr
66485213Sdarrenr                            -11-
66585213Sdarrenr
66685213Sdarrenr
66785213Sdarrenr    pass out quick on lo0
66885213Sdarrenr    pass in  quick on lo0
66985213Sdarrenr
67085213SdarrenrNext, there's the xl0 interface.  Later on we'll begin plac-
67185213Sdarrenring restrictions on the xl0 interface, but  to  start  with,
67285213Sdarrenrwe'll  act  as  though  everything  on  our local network is
67385213Sdarrenrtrustworthy and give it much the same treatment as lo0:
67485213Sdarrenr
67585213Sdarrenr    pass out quick on xl0
67685213Sdarrenr    pass in  quick on xl0
67785213Sdarrenr
67885213SdarrenrFinally, there's the tun0 interface, which we've been  half-
67985213Sdarrenrfiltering with up until now:
68085213Sdarrenr
68185213Sdarrenr    block out quick on tun0 from any to 192.168.0.0/16
68285213Sdarrenr    block out quick on tun0 from any to 172.16.0.0/12
68385213Sdarrenr    block out quick on tun0 from any to 127.0.0.0/8
68485213Sdarrenr    block out quick on tun0 from any to 10.0.0.0/8
68585213Sdarrenr    block out quick on tun0 from any to 0.0.0.0/8
68685213Sdarrenr    block out quick on tun0 from any to 169.254.0.0/16
68785213Sdarrenr    block out quick on tun0 from any to 192.0.2.0/24
68885213Sdarrenr    block out quick on tun0 from any to 204.152.64.0/23
68985213Sdarrenr    block out quick on tun0 from any to 224.0.0.0/3
69085213Sdarrenr    pass  out quick on tun0 from 20.20.20.0/24 to any
69185213Sdarrenr    block out quick on tun0 from any to any
69285213Sdarrenr
69385213Sdarrenr    block in     quick on tun0 from 192.168.0.0/16 to any
69485213Sdarrenr    block in     quick on tun0 from 172.16.0.0/12 to any
69585213Sdarrenr    block in     quick on tun0 from 10.0.0.0/8 to any
69685213Sdarrenr    block in     quick on tun0 from 127.0.0.0/8 to any
69785213Sdarrenr    block in     quick on tun0 from 0.0.0.0/8 to any
69885213Sdarrenr    block in     quick on tun0 from 169.254.0.0/16 to any
69985213Sdarrenr    block in     quick on tun0 from 192.0.2.0/24 to any
70085213Sdarrenr    block in     quick on tun0 from 204.152.64.0/23 to any
70185213Sdarrenr    block in     quick on tun0 from 224.0.0.0/3 to any
70285213Sdarrenr    block in log quick on tun0 from 20.20.20.0/24 to any
70385213Sdarrenr    block in log quick on tun0 from any to 20.20.20.0/32
70485213Sdarrenr    block in log quick on tun0 from any to 20.20.20.255/32
70585213Sdarrenr    pass  in     all
70685213Sdarrenr
70785213SdarrenrThis  is  a  pretty significant amount of filtering already,
70885213Sdarrenrprotecting 20.20.20.0/24 from being spoofed  or  being  used
70985213Sdarrenrfor  spoofing.   Future  examples will continue to show one-
71085213Sdarrenrsideness, but keep in mind that it's for brevity's sake, and
71185213Sdarrenrwhen  setting  up  your  own ruleset, adding rules for every
71285213Sdarrenrdirection and every interface is necessary.
71385213Sdarrenr
71485213Sdarrenr
71585213Sdarrenr2.10.  Controlling Specific Protocols; The "proto" Keyword
71685213Sdarrenr
71785213Sdarrenr     Denial of Service attacks  are  as  rampant  as  buffer
71885213Sdarrenroverflow  exploits.   Many denial of service attacks rely on
71985213Sdarrenrglitches in the OS's TCP/IP  stack.   Frequently,  this  has
72085213Sdarrenrcome  in  the  form  of  ICMP  packets.   Why not block them
72185213Sdarrenr
72285213Sdarrenr
72385213Sdarrenr
72485213Sdarrenr
72585213Sdarrenr
72685213Sdarrenr
72785213Sdarrenr
72885213Sdarrenr
72985213Sdarrenr
73085213Sdarrenr                            -12-
73185213Sdarrenr
73285213Sdarrenr
73385213Sdarrenrentirely?
73485213Sdarrenr
73585213Sdarrenr    block in log quick on tun0 proto icmp from any to any
73685213Sdarrenr
73785213SdarrenrNow any ICMP traffic coming in from tun0 will be logged  and
73885213Sdarrenrdiscarded.
73985213Sdarrenr
74085213Sdarrenr2.11.   Filtering ICMP with the "icmp-type" Keyword; Merging
74185213SdarrenrRulesets
74285213Sdarrenr
74385213Sdarrenr     Of course, dropping all ICMP isn't really an ideal sit-
74485213Sdarrenruation.   Why  not drop all ICMP?  Well, because it's useful
74585213Sdarrenrto have partially enabled.  So maybe you want to  keep  some
74685213Sdarrenrtypes  of  ICMP  traffic  and drop other kinds.  If you want
74785213Sdarrenrping and traceroute to work, you need to let in ICMP types 0
74885213Sdarrenrand  11.   Strictly speaking, this might not be a good idea,
74985213Sdarrenrbut if you need to weigh security against  convenience,  IPF
75085213Sdarrenrlets you do it.
75185213Sdarrenr
75285213Sdarrenr    pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
75385213Sdarrenr    pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
75485213Sdarrenr
75585213SdarrenrRemember that ruleset order is important.  Since we're doing
75685213Sdarrenreverything quick we must have our passes before our  blocks,
75785213Sdarrenrso we really want the last three rules in this order:
75885213Sdarrenr
75985213Sdarrenr    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
76085213Sdarrenr    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
76185213Sdarrenr    block in log quick on tun0 proto icmp from any to any
76285213Sdarrenr
76385213SdarrenrAdding  these  3  rules  to the anti-spoofing rules is a bit
76485213Sdarrenrtricky.  One error might be to put the new ICMP rules at the
76585213Sdarrenrbeginning:
76685213Sdarrenr
76785213Sdarrenr    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
76885213Sdarrenr    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
76985213Sdarrenr    block in log quick on tun0 proto icmp from any to any
77085213Sdarrenr    block in     quick on tun0 from 192.168.0.0/16 to any
77185213Sdarrenr    block in     quick on tun0 from 172.16.0.0/12 to any
77285213Sdarrenr    block in     quick on tun0 from 10.0.0.0/8 to any
77385213Sdarrenr    block in     quick on tun0 from 127.0.0.0/8 to any
77485213Sdarrenr    block in     quick on tun0 from 0.0.0.0/8 to any
77585213Sdarrenr    block in     quick on tun0 from 169.254.0.0/16 to any
77685213Sdarrenr    block in     quick on tun0 from 192.0.2.0/24 to any
77785213Sdarrenr    block in     quick on tun0 from 204.152.64.0/23 to any
77885213Sdarrenr    block in     quick on tun0 from 224.0.0.0/3 to any
77985213Sdarrenr    block in log quick on tun0 from 20.20.20.0/24 to any
78085213Sdarrenr    block in log quick on tun0 from any to 20.20.20.0/32
78185213Sdarrenr    block in log quick on tun0 from any to 20.20.20.255/32
78285213Sdarrenr    pass  in       all
78385213Sdarrenr
78485213SdarrenrThe  problem  with  this  is that an ICMP type 0 packet from
78585213Sdarrenr192.168.0.0/16 will get passed by the first rule, and  never
78685213Sdarrenrblocked  by the fourth rule.  Also, since we quickly pass an
78785213Sdarrenr
78885213Sdarrenr
78985213Sdarrenr
79085213Sdarrenr
79185213Sdarrenr
79285213Sdarrenr
79385213Sdarrenr
79485213Sdarrenr
79585213Sdarrenr
79685213Sdarrenr                            -13-
79785213Sdarrenr
79885213Sdarrenr
79985213SdarrenrICMP ECHO_REPLY (type 0) to 20.20.20.0/24, we've just opened
80085213Sdarrenrourselves  back  up  to  a  nasty smurf attack and nullified
80185213Sdarrenrthose last two block rules.  Oops.  To avoid this, we  place
80285213Sdarrenrthe ICMP rules after the anti-spoofing rules:
80385213Sdarrenr
80485213Sdarrenr    block in     quick on tun0 from 192.168.0.0/16 to any
80585213Sdarrenr    block in     quick on tun0 from 172.16.0.0/12 to any
80685213Sdarrenr    block in     quick on tun0 from 10.0.0.0/8 to any
80785213Sdarrenr    block in     quick on tun0 from 127.0.0.0/8 to any
80885213Sdarrenr    block in     quick on tun0 from 0.0.0.0/8 to any
80985213Sdarrenr    block in     quick on tun0 from 169.254.0.0/16 to any
81085213Sdarrenr    block in     quick on tun0 from 192.0.2.0/24 to any
81185213Sdarrenr    block in     quick on tun0 from 204.152.64.0/23 to any
81285213Sdarrenr    block in     quick on tun0 from 224.0.0.0/3 to any
81385213Sdarrenr    block in log quick on tun0 from 20.20.20.0/24 to any
81485213Sdarrenr    block in log quick on tun0 from any to 20.20.20.0/32
81585213Sdarrenr    block in log quick on tun0 from any to 20.20.20.255/32
81685213Sdarrenr    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
81785213Sdarrenr    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
81885213Sdarrenr    block in log quick on tun0 proto icmp from any to any
81985213Sdarrenr    pass  in       all
82085213Sdarrenr
82185213SdarrenrBecause  we  block spoofed traffic before the ICMP rules are
82285213Sdarrenrprocessed, a spoofed packet never makes it to the ICMP rule-
82385213Sdarrenrset.   It's  very  important to keep such situations in mind
82485213Sdarrenrwhen merging rules.
82585213Sdarrenr
82685213Sdarrenr2.12.  TCP and UDP Ports; The "port" Keyword
82785213Sdarrenr
82885213Sdarrenr     Now that we've started blocking packets based on proto-
82985213Sdarrenrcol, we can start blocking packets based on specific aspects
83085213Sdarrenrof each protocol.  The most frequently used of these aspects
83185213Sdarrenris  the port number.  Services such as rsh, rlogin, and tel-
83285213Sdarrenrnet are all very convenient  to  have,  but  also  hideously
83385213Sdarrenrinsecure  against  network sniffing and spoofing.  One great
83485213Sdarrenrcompromise is to only allow the services to run  internally,
83585213Sdarrenrthen  block  them  externally.   This  is easy to do because
83685213Sdarrenrrlogin, rsh, and telnet use specific TCP  ports  (513,  514,
83785213Sdarrenrand 23 respectively).  As such, creating rules to block them
83885213Sdarrenris easy:
83985213Sdarrenr
84085213Sdarrenr    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
84185213Sdarrenr    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
84285213Sdarrenr    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
84385213Sdarrenr
84485213SdarrenrMake sure all 3 are before the pass in all  and  they'll  be
84585213Sdarrenrclosed  off  from  the  outside  (leaving  out  spoofing for
84685213Sdarrenrbrevity's sake):
84785213Sdarrenr
84885213Sdarrenr    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
84985213Sdarrenr    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
85085213Sdarrenr    block in log quick on tun0 proto icmp from any to any
85185213Sdarrenr    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
85285213Sdarrenr    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
85385213Sdarrenr
85485213Sdarrenr
85585213Sdarrenr
85685213Sdarrenr
85785213Sdarrenr
85885213Sdarrenr
85985213Sdarrenr
86085213Sdarrenr
86185213Sdarrenr
86285213Sdarrenr                            -14-
86385213Sdarrenr
86485213Sdarrenr
86585213Sdarrenr    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
86685213Sdarrenr    pass  in     all
86785213Sdarrenr
86885213SdarrenrYou might also want to block 514/udp  (syslog),   111/tcp  &
86985213Sdarrenr111/udp  (portmap),  515/tcp  (lpd),  2049/tcp  and 2049/udp
87085213Sdarrenr(NFS), 6000/tcp (X11) and so on and so forth.  You can get a
87185213Sdarrenrcomplete  listing  of  the  ports being listened to by using
87285213Sdarrenrnetstat -a (or lsof -i, if you have it installed).
87385213Sdarrenr
87485213Sdarrenr     Blocking UDP instead of  TCP  only  requires  replacing
87585213Sdarrenrproto tcp with proto udp.  The rule for syslog would be:
87685213Sdarrenr
87785213Sdarrenr    block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 514
87885213Sdarrenr
87985213SdarrenrIPF  also  has  a shorthand way to write rules that apply to
88085213Sdarrenrboth proto tcp and proto udp  at  the  same  time,  such  as
88185213Sdarrenrportmap or NFS.  The rule for portmap would be:
88285213Sdarrenr
88385213Sdarrenr    block in log quick on tun0 proto tcp/udp from any to 20.20.20.0/24 port = 111
88485213Sdarrenr
88585213Sdarrenr
88685213Sdarrenr
88785213Sdarrenr
88885213Sdarrenr3.  Advanced Firewalling Introduction
88985213Sdarrenr
89085213Sdarrenr     This  section  is  designed as an immediate followup to
89185213Sdarrenrthe basic section.  Contained below are  both  concepts  for
89285213Sdarrenradvanced  firewall  design,  and advanced features contained
89385213Sdarrenronly within ipfilter.  Once you are  comfortable  with  this
89485213Sdarrenrsection, you should be able to build a very strong firewall.
89585213Sdarrenr
89685213Sdarrenr3.1.  Rampant Paranoia; or The Default-Deny Stance
89785213Sdarrenr
89885213Sdarrenr     There's a big problem with  blocking  services  by  the
89985213Sdarrenrport:  sometimes they move.  RPC based programs are terrible
90085213Sdarrenrabout this, lockd, statd, even  nfsd  listens  places  other
90185213Sdarrenrthan  2049.  It's awfully hard to predict, and even worse to
90285213Sdarrenrautomate adjusting all the time.  What if you  miss  a  ser-
90385213Sdarrenrvice?   Instead of dealing with all that hassle, let's start
90485213Sdarrenrover with a clean slate.  The  current  ruleset  looks  like
90585213Sdarrenrthis:
90685213Sdarrenr
90785213Sdarrenr
90885213Sdarrenr
90985213Sdarrenr
91085213Sdarrenr     Yes, we really are starting over.  The first rule we're
91185213Sdarrenrgoing to use is this:
91285213Sdarrenr
91385213Sdarrenr    block in all
91485213Sdarrenr
91585213SdarrenrNo network traffic gets through. None. Not a  peep.   You're
91685213Sdarrenrrather  secure  with  this  setup.  Not terribly useful, but
91785213Sdarrenrquite secure.  The great thing is that it doesn't take  much
91885213Sdarrenrmore  to make your box rather secure, yet useful too.  Let's
91985213Sdarrenr
92085213Sdarrenr
92185213Sdarrenr
92285213Sdarrenr
92385213Sdarrenr
92485213Sdarrenr
92585213Sdarrenr
92685213Sdarrenr
92785213Sdarrenr
92885213Sdarrenr                            -15-
92985213Sdarrenr
93085213Sdarrenr
93185213Sdarrenrsay the machine this is running on is a web server,  nothing
93285213Sdarrenrmore,  nothing  less.   It  doesn't even do DNS lookups.  It
93385213Sdarrenrjust wants to take connections on 80/tcp and that's it.   We
93485213Sdarrenrcan  do  that.   We  can do that with a second rule, and you
93585213Sdarrenralready know how:
93685213Sdarrenr
93785213Sdarrenr    block in       on tun0 all
93885213Sdarrenr    pass  in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80
93985213Sdarrenr
94085213SdarrenrThis machine will pass in port 80  traffic  for  20.20.20.1,
94185213Sdarrenrand  deny  everything  else.  For basic firewalling, this is
94285213Sdarrenrall one needs.
94385213Sdarrenr
94485213Sdarrenr3.2.  Implicit Allow; The "keep state" Rule
94585213Sdarrenr
94685213Sdarrenr     The job of your firewall is to prevent unwanted traffic
94785213Sdarrenrgetting  to  point  B  from  point A.  We have general rules
94885213Sdarrenrwhich say "as long as this packet is to port 23, it's okay."
94985213SdarrenrWe  have general rules which say "as long as this packet has
95085213Sdarrenrits FIN flag set, it's okay."  Our firewalls don't know  the
95185213Sdarrenrbeginning, middle, or end of any TCP/UDP/ICMP session.  They
95285213Sdarrenrmerely have vague rules that are  applied  to  all  packets.
95385213SdarrenrWe're  left  to  hope  that the packet with its FIN flag set
95485213Sdarrenrisn't really a FIN scan, mapping our services.  We hope that
95585213Sdarrenrthe  packet to port 23 isn't an attempted hijack of our tel-
95685213Sdarrenrnet session.  What if there was a way to identify and autho-
95785213Sdarrenrrize  individual  TCP/UDP/ICMP sessions and distinguish them
95885213Sdarrenrfrom port scanners and DoS attacks?  There is  a  way,  it's
95985213Sdarrenrcalled keeping state.
96085213Sdarrenr
96185213Sdarrenr     We  want convenience and security in one.  Lots of peo-
96285213Sdarrenrple do, that's why Ciscos have an "established" clause  that
96385213Sdarrenrlets  established  tcp sessions go through.  Ipfw has estab-
96485213Sdarrenrlished.  Ipfwadm has setup/established.  They all have  this
96585213Sdarrenrfeature, but the name is very misleading.  When we first saw
96685213Sdarrenrit, we thought it meant our packet filter was keeping  track
96785213Sdarrenrof  what  was  going  on,  that  it knew if a connection was
96885213Sdarrenrreally established or not.  The fact is, they're all  taking
96985213Sdarrenrthe  packet's  word for it from a part of the packet anybody
97085213Sdarrenrcan lie about.  They read the TCP packet's flags section and
97185213Sdarrenrthere's the reason UDP/ICMP don't work with it, they have no
97285213Sdarrenrsuch thing.  Anybody who can  create  a  packet  with  bogus
97385213Sdarrenrflags can get by a firewall with this setup.
97485213Sdarrenr
97585213Sdarrenr     Where  does  IPF  come in to play here, you ask?  Well,
97685213Sdarrenrunlike the other firewalls, IPF really  can  keep  track  of
97785213Sdarrenrwhether or not a connection is established.  And it'll do it
97885213Sdarrenrwith TCP, UDP and ICMP, not just TCP.  Ipf calls it  keeping
97985213Sdarrenrstate.  The keyword for the ruleset is keep state.
98085213Sdarrenr
98185213Sdarrenr     Up until now, we've told you that packets come in, then
98285213Sdarrenrthe ruleset gets checked; packets go out, then  the  ruleset
98385213Sdarrenrgets  checked.   Actually,  what happens is packets come in,
98485213Sdarrenrthe state table  gets  checked,  then  *maybe*  the  inbound
98585213Sdarrenr
98685213Sdarrenr
98785213Sdarrenr
98885213Sdarrenr
98985213Sdarrenr
99085213Sdarrenr
99185213Sdarrenr
99285213Sdarrenr
99385213Sdarrenr
99485213Sdarrenr                            -16-
99585213Sdarrenr
99685213Sdarrenr
99785213Sdarrenrruleset  gets  checked; packets go out, the state table gets
99885213Sdarrenrchecked, then *maybe* the  outbound  ruleset  gets  checked.
99985213SdarrenrThe  state table is a list of TCP/UDP/ICMP sessions that are
100085213Sdarrenrunquestionadely passed through the  firewall,  circumventing
100185213Sdarrenrthe  entire  ruleset.   Sound  like a serious security hole?
100285213SdarrenrHang on, it's the best thing  that  ever  happened  to  your
100385213Sdarrenrfirewall.
100485213Sdarrenr
100585213Sdarrenr     All  TCP/IP sessions have a start, a middle, and an end
100685213Sdarrenr(even though they're sometimes all in the same packet).  You
100785213Sdarrenrcan't have an end without a middle and you can't have a mid-
100885213Sdarrenrdle without a start.  This means that all you really need to
100985213Sdarrenrfilter  on  is  the beginning of a TCP/UDP/ICMP session.  If
101085213Sdarrenrthe beginning of the session is  allowed  by  your  firewall
101185213Sdarrenrrules,  you really want the middle and end to be allowed too
101285213Sdarrenr(lest your IP stack should overflow and your machines become
101385213Sdarrenruseless).  Keeping state allows you to ignore the middle and
101485213Sdarrenrend and simply focus on blocking/passing new  sessions.   If
101585213Sdarrenrthe  new  session is passed, all its subsequent packets will
101685213Sdarrenrbe allowed through.  If it's blocked, none of its subsequent
101785213Sdarrenrpackets will be allowed through.  Here's an example for run-
101885213Sdarrenrning an ssh server (and nothing but an ssh server):
101985213Sdarrenr
102085213Sdarrenr    block out quick on tun0 all
102185213Sdarrenr    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep state
102285213Sdarrenr
102385213SdarrenrThe first thing you might notice is that  there's  no  "pass
102485213Sdarrenrout"  provision.   In  fact,  there's  only an all-inclusive
102585213Sdarrenr"block out" rule.  Despite this, the  ruleset  is  complete.
102685213SdarrenrThis is because by keeping state, the entire ruleset is cir-
102785213Sdarrenrcumvented.  Once the first SYN packet hits the  ssh  server,
102885213Sdarrenrstate  is  created  and  the remainder of the ssh session is
102985213Sdarrenrallowed to take place without interference  from  the  fire-
103085213Sdarrenrwall.  Here's another example:
103185213Sdarrenr
103285213Sdarrenr    block in  quick on tun0 all
103385213Sdarrenr    pass  out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
103485213Sdarrenr
103585213SdarrenrIn  this  case,  the server is running no services.  Infact,
103685213Sdarrenrit's not a server, it's a client.  And this  client  doesn't
103785213Sdarrenrwant  unauthorized  packets  entering  its  IP stack at all.
103885213SdarrenrHowever, the client wants full access to  the  internet  and
103985213Sdarrenrthe  reply packets that such privledge entails.  This simple
104085213Sdarrenrruleset creates state entries for  every  new  outgoing  TCP
104185213Sdarrenrsession.   Again,  since a state entry is created, these new
104285213SdarrenrTCP sessions are free to talk back and forth as they  please
104385213Sdarrenrwithout  the  hinderance or inspection of the firewall rule-
104485213Sdarrenrset.  We mentioned that this also works for UDP and ICMP:
104585213Sdarrenr
104685213Sdarrenr    block in  quick on tun0 all
104785213Sdarrenr    pass  out quick on tun0 proto tcp  from 20.20.20.1/32 to any keep state
104885213Sdarrenr    pass  out quick on tun0 proto udp  from 20.20.20.1/32 to any keep state
104985213Sdarrenr    pass  out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state
105085213Sdarrenr
105185213Sdarrenr
105285213Sdarrenr
105385213Sdarrenr
105485213Sdarrenr
105585213Sdarrenr
105685213Sdarrenr
105785213Sdarrenr
105885213Sdarrenr
105985213Sdarrenr
106085213Sdarrenr                            -17-
106185213Sdarrenr
106285213Sdarrenr
106385213SdarrenrYes Virginia, we can ping.  Now we're keeping state on  TCP,
106485213SdarrenrUDP,  ICMP.   Now we can make outgoing connections as though
106585213Sdarrenrthere's no firewall at all, yet would-be attackers can't get
106685213Sdarrenrback  in.   This  is  very  handy because there's no need to
106785213Sdarrenrtrack down what ports we're listening to, only the ports  we
106885213Sdarrenrwant people to be able to get to.
106985213Sdarrenr
107085213Sdarrenr     State is pretty handy, but it's also a bit tricky.  You
107185213Sdarrenrcan shoot yourself in the foot  in  strange  and  mysterious
107285213Sdarrenrways.  Consider the following ruleset:
107385213Sdarrenr
107485213Sdarrenr     pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23
107585213Sdarrenr     pass  out quick on tun0 proto tcp from any to any keep state
107685213Sdarrenr     block in  quick all
107785213Sdarrenr     block out quick all
107885213Sdarrenr
107985213SdarrenrAt  first  glance,  this seems to be a good setup.  We allow
108085213Sdarrenrincoming sessions to port 23,  and  outgoing  sessions  any-
108185213Sdarrenrwhere.   Naturally  packets going to port 23 will have reply
108285213Sdarrenrpackets, but the ruleset is setup in such  a  way  that  the
108385213Sdarrenrpass  out  rule  will  generate a state entry and everything
108485213Sdarrenrwill work perfectly.  At least, you'd think so.
108585213Sdarrenr
108685213Sdarrenr     The unfortunate truth is that after 60 seconds of  idle
108785213Sdarrenrtime  the state entry will be closed (as opposed to the nor-
108885213Sdarrenrmal 5 days).  This is because the state  tracker  never  saw
108985213Sdarrenrthe original SYN packet destined to port 23, it only saw the
109085213SdarrenrSYN ACK.  IPF is very good about following TCP sessions from
109185213Sdarrenrstart  to  finish,  but it's not very good about coming into
109285213Sdarrenrthe middle of a connection, so rewrite the rule to look like
109385213Sdarrenrthis:
109485213Sdarrenr
109585213Sdarrenr     pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
109685213Sdarrenr     pass  out quick on tun0 proto tcp from any to any keep state
109785213Sdarrenr     block in  quick all
109885213Sdarrenr     block out quick all
109985213Sdarrenr
110085213SdarrenrThe additional of this rule will enter the very first packet
110185213Sdarrenrinto the state table and everything will work  as  expected.
110285213SdarrenrOnce  the  3-way  handshake  has  been  witness by the state
110385213Sdarrenrengine, it is marked in 4/4 mode, which means it's setup for
110485213Sdarrenrlong-term data exchange until such time as the connection is
110585213Sdarrenrtorn down (wherein the mode changes again.  You can see  the
110685213Sdarrenrcurrent modes of your state table with ipfstat -s.
110785213Sdarrenr
110885213Sdarrenr3.3.  Stateful UDP
110985213Sdarrenr
111085213Sdarrenr     UDP is stateless so naturally it's a bit harder to do a
111185213Sdarrenrreliable job of keeping state on it.  Nonetheless, ipf  does
111285213Sdarrenra  pretty  good  job.   When machine A sends a UDP packet to
111385213Sdarrenrmachine B with source port X and  destination  port  Y,  ipf
111485213Sdarrenrwill  allow  a reply from machine B to machine A with source
111585213Sdarrenrport Y and destination port X.  This is a short  term  state
111685213Sdarrenrentry, a mere 60 seconds.
111785213Sdarrenr
111885213Sdarrenr
111985213Sdarrenr
112085213Sdarrenr
112185213Sdarrenr
112285213Sdarrenr
112385213Sdarrenr
112485213Sdarrenr
112585213Sdarrenr
112685213Sdarrenr                            -18-
112785213Sdarrenr
112885213Sdarrenr
112985213Sdarrenr     Here's an example of what happens if we use nslookup to
113085213Sdarrenrget the IP address of www.3com.com:
113185213Sdarrenr
113285213Sdarrenr    $ nslookup www.3com.com
113385213Sdarrenr
113485213Sdarrenr  A DNS packet is generated:
113585213Sdarrenr
113685213Sdarrenr    17:54:25.499852 20.20.20.1.2111 > 198.41.0.5.53: 51979+
113785213Sdarrenr
113885213SdarrenrThe packet is  from  20.20.20.1,  port  2111,  destined  for
113985213Sdarrenr198.41.0.5,  port  53.   A 60 second state entry is created.
114085213SdarrenrIf a packet comes back from 198.41.0.5 port 53 destined  for
114185213Sdarrenr20.20.20.1  port  2111 within that period of time, the reply
114285213Sdarrenrpacket will be let through.  As you  can  see,  milliseconds
114385213Sdarrenrlater:
114485213Sdarrenr
114585213Sdarrenr    17:54:25.501209 198.41.0.5.53 > 20.20.20.1.2111: 51979 q: www.3com.com
114685213Sdarrenr
114785213SdarrenrThe  reply  packet  matches  the  state  criteria and is let
114885213Sdarrenrthrough.  At that same moment that packet  is  let  through,
114985213Sdarrenrthe state gateway is closed and no new incoming packets will
115085213Sdarrenrbe allowed in, even if they claim to be from the same place.
115185213Sdarrenr
115285213Sdarrenr3.4.  Stateful ICMP
115385213Sdarrenr
115485213Sdarrenr     IPFilter  handles  ICMP  states  in the manner that one
115585213Sdarrenrwould expect from understanding how ICMP is  used  with  TCP
115685213Sdarrenrand  UDP,  and  with  your  understanding  of how keep state
115785213Sdarrenrworks.  There  are  two  general  types  of  ICMP  messages;
115885213Sdarrenrrequests and replies.   When you write a rule such as:
115985213Sdarrenr
116085213Sdarrenr    pass out on tun0 proto icmp from any to any icmp-type 8 keep state
116185213Sdarrenr
116285213Sdarrenrto allow outbound echo requests (a typical ping), the resul-
116385213Sdarrenrtant icmp-type 0 packet that comes back will be allowed  in.
116485213SdarrenrThis  state entry has a default timeout of an incomplete 0/0
116585213Sdarrenrstate of 60 seconds.   Thus, if you are keeping state on any
116685213Sdarrenroutbound  icmp  message  that will elicit an icmp message in
116785213Sdarrenrreply, you need a proto icmp [...] keep state rule.
116885213Sdarrenr
116985213Sdarrenr     However, the majority of ICMP messages are status  mes-
117085213Sdarrenrsages  generated by some failure in UDP (and sometimes TCP),
117185213Sdarrenrand in 3.4.x and greater IPFilters, any  ICMP  error  status
117285213Sdarrenrmessage  (say  icmp-type 3 code 3 port unreachable, or icmp-
117385213Sdarrenrtype 11 time exceeded) that matches an  active  state  table
117485213Sdarrenrentry  that  could  have  generated  that  message, the ICMP
117585213Sdarrenrpacket is let in.  For example, in older IPFilters,  if  you
117685213Sdarrenrwanted traceroute to work, you needed to use:
117785213Sdarrenr
117885213Sdarrenr    pass out on tun0 proto udp from any to any port 33434><33690 keep state
117985213Sdarrenr    pass in on tun0 proto icmp from any to any icmp-type timex
118085213Sdarrenr
118185213Sdarrenrwhereas  now  you can do the right thing and just keep state
118285213Sdarrenron udp with:
118385213Sdarrenr
118485213Sdarrenr
118585213Sdarrenr
118685213Sdarrenr
118785213Sdarrenr
118885213Sdarrenr
118985213Sdarrenr
119085213Sdarrenr
119185213Sdarrenr
119285213Sdarrenr                            -19-
119385213Sdarrenr
119485213Sdarrenr
119585213Sdarrenr    pass out on tun0 proto udp from any to any port 33434><33690 keep state
119685213Sdarrenr
119785213SdarrenrTo provide some protection against  a  third-party  sneaking
119885213SdarrenrICMP  messages  through your firewall when an active connec-
119985213Sdarrenrtion is known to be in your state table, the  incoming  ICMP
120085213Sdarrenrpacket  is checked not only for matching source and destina-
120185213Sdarrenrtion addresses (and ports, when applicable) but a tiny  part
120285213Sdarrenrof the payload of the packet that the ICMP message is claim-
120385213Sdarrenring it was generated by.
120485213Sdarrenr
120585213Sdarrenr3.5.  FIN Scan Detection; "flags" Keyword, "keep frags" Key-
120685213Sdarrenrword
120785213Sdarrenr
120885213SdarrenrLet's go back to the 4 rule set from the previous section:
120985213Sdarrenr
121085213Sdarrenr    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
121185213Sdarrenr    pass  out quick on tun0 proto tcp from any to any keep state
121285213Sdarrenr    block in  quick all
121385213Sdarrenr    block out quick all
121485213Sdarrenr
121585213SdarrenrThis is almost, but not quite, satisfactory.  The problem is
121685213Sdarrenrthat it's not just SYN packets that're allowed to go to port
121785213Sdarrenr23,  any  old packet can get through.  We can change this by
121885213Sdarrenrusing the flags option:
121985213Sdarrenr
122085213Sdarrenr    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state
122185213Sdarrenr    pass  out quick on tun0 proto tcp from any to any flags S keep state
122285213Sdarrenr    block in  quick all
122385213Sdarrenr    block out quick all
122485213Sdarrenr
122585213SdarrenrNow only TCP packets, destined for 20.20.20.1, at  port  23,
122685213Sdarrenrwith a lone SYN flag will be allowed in and entered into the
122785213Sdarrenrstate table.  A lone SYN flag is only present  as  the  very
122885213Sdarrenrfirst packet in a TCP session (called the TCP handshake) and
122985213Sdarrenrthat's really what we wanted all along.   There's  at  least
123085213Sdarrenrtwo  advantages  to  this:  No arbitrary packets can come in
123185213Sdarrenrand make a mess of your state table.   Also,  FIN  and  XMAS
123285213Sdarrenrscans  will  fail  since  they  set flags other than the SYN
123385213Sdarrenrflag.  Now all incoming packets must either be handshakes or
123485213Sdarrenrhave state already.  If anything else comes in, it's  proba-
123585213Sdarrenrbly  a  port scan or a forged packet.  There's one exception
123685213Sdarrenrto that, which is when a packet comes in  that's  fragmented
123785213Sdarrenrfrom  its journey.  IPF has provisions for this as well, the
123885213Sdarrenr-----------
123985213Sdarrenr Some examples use flags S/SA instead of flags  S.
124085213Sdarrenrflags  S  actually  equates  to flags S/AUPRFS and
124185213Sdarrenrmatches against only the SYN packet out of all six
124285213Sdarrenrpossible  flags, while flags S/SA will allow pack-
124385213Sdarrenrets that may or may not have the URG, PSH, FIN, or
124485213SdarrenrRST  flags  set.  Some protocols demand the URG or
124585213SdarrenrPSH flags, and S/SAFR would be a better choice for
124685213Sdarrenrthese,  however  we feel that it is less secure to
124785213Sdarrenrblindly use S/SA when it isn't required.  But it's
124885213Sdarrenryour firewall.
124985213Sdarrenr
125085213Sdarrenr
125185213Sdarrenr
125285213Sdarrenr
125385213Sdarrenr
125485213Sdarrenr
125585213Sdarrenr
125685213Sdarrenr
125785213Sdarrenr
125885213Sdarrenr                            -20-
125985213Sdarrenr
126085213Sdarrenr
126185213Sdarrenrkeep frags keyword.  With it, IPF will notice and keep track
126285213Sdarrenrof  packets that are fragmented, allowing the expected frag-
126385213Sdarrenrments to to go through.  Let's rewrite the 3  rules  to  log
126485213Sdarrenrforgeries and allow fragments:
126585213Sdarrenr
126685213Sdarrenr    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state keep frags
126785213Sdarrenr    pass  out quick on tun0 proto tcp from any to any keep state flags S keep frags
126885213Sdarrenr    block in  log quick all
126985213Sdarrenr    block out log quick all
127085213Sdarrenr
127185213SdarrenrThis  works  because  every  packet  that  should be allowed
127285213Sdarrenrthrough makes it into the state table  before  the  blocking
127385213Sdarrenrrules  are reached. The only scan this won't detect is a SYN
127485213Sdarrenrscan itself.  If you're truely worried about that, you might
127585213Sdarrenreven want to log all initial SYN packets.
127685213Sdarrenr
127785213Sdarrenr3.6.  Responding To a Blocked Packet
127885213Sdarrenr
127985213Sdarrenr     So  far, all of our blocked packets have been dumped on
128085213Sdarrenrthe floor, logged or not, we've never sent anything back  to
128185213Sdarrenrthe  originating host.  Sometimes this isn't the most desir-
128285213Sdarrenrable of responses because in doing so, we actually tell  the
128385213Sdarrenrattacker  that  a  packet filter is present.  It seems a far
128485213Sdarrenrbetter thing to misguide the attacker into  believing  that,
128585213Sdarrenrwhile  there's no packet filter running, there's likewise no
128685213Sdarrenrservices to break into.   This  is  where  fancier  blocking
128785213Sdarrenrcomes into play.
128885213Sdarrenr
128985213Sdarrenr     When  a service isn't running on a Unix system, it nor-
129085213Sdarrenrmally lets the remote host know with  some  sort  of  return
129185213Sdarrenrpacket.   In  TCP,  this is done with an RST (Reset) packet.
129285213SdarrenrWhen blocking a TCP packet, IPF can actually return  an  RST
129385213Sdarrenrto the origin by using the return-rst keyword.
129485213Sdarrenr
129585213SdarrenrWhere once we did:
129685213Sdarrenr
129785213Sdarrenr    block in log on tun0 proto tcp from any to 20.20.20.0/24 port = 23
129885213Sdarrenr    pass  in     all
129985213Sdarrenr
130085213SdarrenrWe might now do:
130185213Sdarrenr
130285213Sdarrenr    block return-rst in log proto tcp from any to 20.20.20.0/24 port = 23
130385213Sdarrenr    block in log quick on tun0
130485213Sdarrenr    pass  in     all
130585213Sdarrenr
130685213SdarrenrWe  need  two  block  statements since return-rst only works
130785213Sdarrenrwith TCP, and we still want to block protocols such as  UDP,
130885213SdarrenrICMP,  and  others.   Now that this is done, the remote side
130985213Sdarrenrwill get "connection refused" instead of  "connection  timed
131085213Sdarrenrout".
131185213Sdarrenr
131285213Sdarrenr     It's  also possible to send an error message when some-
131385213Sdarrenrbody sends a packet to a UDP port on your  system.   Whereas
131485213Sdarrenronce you might have used:
131585213Sdarrenr
131685213Sdarrenr
131785213Sdarrenr
131885213Sdarrenr
131985213Sdarrenr
132085213Sdarrenr
132185213Sdarrenr
132285213Sdarrenr
132385213Sdarrenr
132485213Sdarrenr                            -21-
132585213Sdarrenr
132685213Sdarrenr
132785213Sdarrenr    block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
132885213Sdarrenr
132985213SdarrenrYou  could  instead  use  the  return-icmp keyword to send a
133085213Sdarrenrreply:
133185213Sdarrenr
133285213Sdarrenr    block return-icmp(port-unr) in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
133385213Sdarrenr
133485213SdarrenrAccording to TCP/IP  Illustrated,  port-unreachable  is  the
133585213Sdarrenrcorrect  ICMP type to return when no service is listening on
133685213Sdarrenrthe port in question.  You can use any ICMP type  you  like,
133785213Sdarrenrbut  port-unreachable  is probably your best bet.  It's also
133885213Sdarrenrthe default ICMP type for return-icmp.
133985213Sdarrenr
134085213Sdarrenr     However, when using  return-icmp,  you'll  notice  that
134185213Sdarrenrit's  not very stealthy, and it returns the ICMP packet with
134285213Sdarrenrthe IP address of the firewall, not the original destination
134385213Sdarrenrof  the  packet.   This was fixed in ipfilter 3.3, and a new
134485213Sdarrenrkeyword; return-icmp-as-dest, has been added.   The new for-
134585213Sdarrenrmat is:
134685213Sdarrenr
134785213Sdarrenr     block return-icmp-as-dest(port-unr) in log on tun0 proto udp from any to 20.20.20.0/24 port = 111
134885213Sdarrenr
134985213Sdarrenr3.7.  Fancy Logging Techniques
135085213Sdarrenr
135185213Sdarrenr     It  is  important  to note that the presence of the log
135285213Sdarrenrkeyword only ensures that the packet will  be  available  to
135385213Sdarrenrthe  ipfilter  logging device; /dev/ipl.   In order to actu-
135485213Sdarrenrally see this log information, one must be running the ipmon
135585213Sdarrenrutility  (or  some  other utility that reads from /dev/ipl).
135685213SdarrenrThe typical usage of log is coupled with ipmon -s to log the
135785213Sdarrenrinformation to syslog.  As of ipfilter 3.3, one can now even
135885213Sdarrenrcontrol the logging behavior of syslog by  using  log  level
135985213Sdarrenrkeywords, as in rules such as this:
136085213Sdarrenr
136185213Sdarrenr     block in log level auth.info quick on tun0 from 20.20.20.0/24 to any
136285213Sdarrenr     block in log level auth.alert quick on tun0 proto tcp from any to 20.20.20.0/24 port = 21
136385213Sdarrenr
136485213SdarrenrIn  addition  to  this,  you  can tailor what information is
136585213Sdarrenrbeing logged.  For example, you may not be  interested  that
136685213Sdarrenrsomeone  attempted  to probe your telnet port 500 times, but
136785213Sdarrenryou are interested that they probed you once.  You  can  use
136885213Sdarrenrthe  log  first  keyword  to only log the first example of a
136985213Sdarrenrpacket.  Of course, the notion of "first-ness" only  applies
137085213Sdarrenrto  packets  in  a  specific  session,  and  for the typical
137185213Sdarrenrblocked packet, you will be hard pressed to encounter situa-
137285213Sdarrenrtions  where this does what you expect.  However, if used in
137385213Sdarrenrconjunction with pass and keep state, this can be a valuable
137485213Sdarrenrkeyword for keeping tabs on traffic.
137585213Sdarrenr
137685213Sdarrenr     Another  useful  thing  you  can do with the logs is to
137785213Sdarrenrkeep track of interesting pieces of the packet  in  addition
137885213Sdarrenrto  the  header information normally being logged.  Ipfilter
137985213Sdarrenrwill give you the first 128 bytes of the packet if  you  use
138085213Sdarrenrthe  log  body  keyword.   You  should limit the use of body
138185213Sdarrenr
138285213Sdarrenr
138385213Sdarrenr
138485213Sdarrenr
138585213Sdarrenr
138685213Sdarrenr
138785213Sdarrenr
138885213Sdarrenr
138985213Sdarrenr
139085213Sdarrenr                            -22-
139185213Sdarrenr
139285213Sdarrenr
139385213Sdarrenrlogging, as it makes your logs very verbose, but for certain
139485213Sdarrenrapplications,  it  is  often handy to be able to go back and
139585213Sdarrenrtake a look at the packet, or to send this data  to  another
139685213Sdarrenrapplication that can examine it further.
139785213Sdarrenr
139885213Sdarrenr3.8.  Putting It All Together
139985213Sdarrenr
140085213Sdarrenr     So  now  we  have  a  pretty tight firewall, but it can
140185213Sdarrenrstill be tighter.  Some of the  original  ruleset  we  wiped
140285213Sdarrenrclean  is  actually  very useful.  I'd suggest bringing back
140385213Sdarrenrall the anti-spoofing stuff.  This leaves us with:
140485213Sdarrenr
140585213Sdarrenr    block in           on tun0
140685213Sdarrenr    block in     quick on tun0 from 192.168.0.0/16 to any
140785213Sdarrenr    block in     quick on tun0 from 172.16.0.0/12 to any
140885213Sdarrenr    block in     quick on tun0 from 10.0.0.0/8 to any
140985213Sdarrenr    block in     quick on tun0 from 127.0.0.0/8 to any
141085213Sdarrenr    block in     quick on tun0 from 0.0.0.0/8 to any
141185213Sdarrenr    block in     quick on tun0 from 169.254.0.0/16 to any
141285213Sdarrenr    block in     quick on tun0 from 192.0.2.0/24 to any
141385213Sdarrenr    block in     quick on tun0 from 204.152.64.0/23 to any
141485213Sdarrenr    block in     quick on tun0 from 224.0.0.0/3 to any
141585213Sdarrenr    block in log quick on tun0 from 20.20.20.0/24 to any
141685213Sdarrenr    block in log quick on tun0 from any to 20.20.20.0/32
141785213Sdarrenr    block in log quick on tun0 from any to 20.20.20.255/32
141885213Sdarrenr    pass  out quick on tun0 proto tcp/udp from 20.20.20.1/32 to any keep state
141985213Sdarrenr    pass  out quick on tun0 proto icmp    from 20.20.20.1/32 to any keep state
142085213Sdarrenr    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 flags S keep state
142185213Sdarrenr
142285213Sdarrenr3.9.  Improving Performance With Rule Groups
142385213Sdarrenr
142485213Sdarrenr     Let's extend our use of our firewall by creating a much
142585213Sdarrenrmore  complicated,  and  we hope more applicable to the real
142685213Sdarrenrworld, example configuration For this example,  we're  going
142785213Sdarrenrto  change  the interface names, and network numbers.  Let's
142885213Sdarrenrassume that we have three interfaces in  our  firewall  with
142985213Sdarrenrinterfaces xl0, xl1, and xl2.
143085213Sdarrenr
143185213Sdarrenrxl0 is connected to our external network 20.20.20.0/26
143285213Sdarrenrxl1 is connected to our "DMZ" network 20.20.20.64/26
143385213Sdarrenrxl2 is connected to our protected network 20.20.20.128/25
143485213Sdarrenr
143585213SdarrenrWe'll  define the entire ruleset in one swoop, since we fig-
143685213Sdarrenrure that you can read these rules by now:
143785213Sdarrenr
143885213Sdarrenr    block in     quick on xl0 from 192.168.0.0/16 to any
143985213Sdarrenr    block in     quick on xl0 from 172.16.0.0/12 to any
144085213Sdarrenr    block in     quick on xl0 from 10.0.0.0/8 to any
144185213Sdarrenr    block in     quick on xl0 from 127.0.0.0/8 to any
144285213Sdarrenr    block in     quick on xl0 from 0.0.0.0/8 to any
144385213Sdarrenr    block in     quick on xl0 from 169.254.0.0/16 to any
144485213Sdarrenr    block in     quick on xl0 from 192.0.2.0/24 to any
144585213Sdarrenr    block in     quick on xl0 from 204.152.64.0/23 to any
144685213Sdarrenr    block in     quick on xl0 from 224.0.0.0/3 to any
144785213Sdarrenr
144885213Sdarrenr
144985213Sdarrenr
145085213Sdarrenr
145185213Sdarrenr
145285213Sdarrenr
145385213Sdarrenr
145485213Sdarrenr
145585213Sdarrenr
145685213Sdarrenr                            -23-
145785213Sdarrenr
145885213Sdarrenr
145985213Sdarrenr    block in log quick on xl0 from 20.20.20.0/24 to any
146085213Sdarrenr    block in log quick on xl0 from any to 20.20.20.0/32
146185213Sdarrenr    block in log quick on xl0 from any to 20.20.20.63/32
146285213Sdarrenr    block in log quick on xl0 from any to 20.20.20.64/32
146385213Sdarrenr    block in log quick on xl0 from any to 20.20.20.127/32
146485213Sdarrenr    block in log quick on xl0 from any to 20.20.20.128/32
146585213Sdarrenr    block in log quick on xl0 from any to 20.20.20.255/32
146685213Sdarrenr    pass out on xl0 all
146785213Sdarrenr
146885213Sdarrenr    pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state
146985213Sdarrenr    pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state
147085213Sdarrenr    pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state
147185213Sdarrenr    pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state
147285213Sdarrenr    pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state
147385213Sdarrenr    pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
147485213Sdarrenr    pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state
147585213Sdarrenr    block out on xl1 all
147685213Sdarrenr    pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
147785213Sdarrenr
147885213Sdarrenr    block out on xl2 all
147985213Sdarrenr    pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
148085213Sdarrenr
148185213SdarrenrFrom this arbitarary example, we can already  see  that  our
148285213Sdarrenrruleset is becoming unwieldy.   To make matters worse, as we
148385213Sdarrenradd more specific rules to our DMZ  network,  we  add  addi-
148485213Sdarrenrtional  tests  that  must  be parsed for every packet, which
148585213Sdarrenraffects the performance of the xl0 <-> xl2 connections.   If
148685213Sdarrenryou set up a firewall with a ruleset like this, and you have
148785213Sdarrenrlots of bandwidth and a moderate  amount  of  cpu,  everyone
148885213Sdarrenrthat  has  a workstation on the xl2 network is going to come
148985213Sdarrenrlooking for your head to place on a platter.   So,  to  keep
149085213Sdarrenryour  head  <->  torso  network intact, you can speed things
149185213Sdarrenralong by creating rule groups.   Rule groups  allow  you  to
149285213Sdarrenrwrite your ruleset in a tree fashion, instead of as a linear
149385213Sdarrenrlist, so that if your packet has nothing to do with the  set
149485213Sdarrenrof  tests  (say, all those xl1 rules) those rules will never
149585213Sdarrenrbe consulted.  It's somewhat like having multiple  firewalls
149685213Sdarrenrall on the same machine.
149785213Sdarrenr
149885213SdarrenrHere's a simple example to get us started:
149985213Sdarrenr
150085213Sdarrenr    block out quick on xl1 all head 10
150185213Sdarrenr    pass out quick proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
150285213Sdarrenr    block out on xl2 all
150385213Sdarrenr
150485213SdarrenrIn  this  simplistic example, we can see a small hint of the
150585213Sdarrenrpower of the rule group.  If the packet is not destined  for
150685213Sdarrenrxl1,  the  head of rule group 10 will not match, and we will
150785213Sdarrenrgo on with our tests.  If the packet does match for xl1, the
150885213Sdarrenrquick  keyword  will short-circuit all further processing at
150985213Sdarrenrthe root level (rule group 0),  and  focus  the  testing  on
151085213Sdarrenrrules  which  belong  to group 10; namely, the SYN check for
151185213Sdarrenr80/tcp.  In this way, we can re-write  the  above  rules  so
151285213Sdarrenrthat we can maximize performance of our firewall.
151385213Sdarrenr
151485213Sdarrenr
151585213Sdarrenr
151685213Sdarrenr
151785213Sdarrenr
151885213Sdarrenr
151985213Sdarrenr
152085213Sdarrenr
152185213Sdarrenr
152285213Sdarrenr                            -24-
152385213Sdarrenr
152485213Sdarrenr
152585213Sdarrenr    block in quick on xl0 all head 1
152685213Sdarrenr      block in     quick on xl0 from 192.168.0.0/16 to any  group 1
152785213Sdarrenr      block in     quick on xl0 from 172.16.0.0/12 to any   group 1
152885213Sdarrenr      block in     quick on xl0 from 10.0.0.0/8 to any      group 1
152985213Sdarrenr      block in     quick on xl0 from 127.0.0.0/8 to any     group 1
153085213Sdarrenr      block in     quick on xl0 from 0.0.0.0/8 to any       group 1
153185213Sdarrenr      block in     quick on xl0 from 169.254.0.0/16 to any  group 1
153285213Sdarrenr      block in     quick on xl0 from 192.0.2.0/24 to any    group 1
153385213Sdarrenr      block in     quick on xl0 from 204.152.64.0/23 to any group 1
153485213Sdarrenr      block in     quick on xl0 from 224.0.0.0/3 to any     group 1
153585213Sdarrenr      block in log quick on xl0 from 20.20.20.0/24 to any   group 1
153685213Sdarrenr      block in log quick on xl0 from any to 20.20.20.0/32   group 1
153785213Sdarrenr      block in log quick on xl0 from any to 20.20.20.63/32  group 1
153885213Sdarrenr      block in log quick on xl0 from any to 20.20.20.64/32  group 1
153985213Sdarrenr      block in log quick on xl0 from any to 20.20.20.127/32 group 1
154085213Sdarrenr      block in log quick on xl0 from any to 20.20.20.128/32 group 1
154185213Sdarrenr      block in log quick on xl0 from any to 20.20.20.255/32 group 1
154285213Sdarrenr      pass  in           on xl0 all group 1
154385213Sdarrenr
154485213Sdarrenr    pass out on xl0 all
154585213Sdarrenr
154685213Sdarrenr    block out quick on xl1 all head 10
154785213Sdarrenr      pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
154885213Sdarrenr      pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state group 10
154985213Sdarrenr      pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state group 10
155085213Sdarrenr      pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state group 10
155185213Sdarrenr      pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53         keep state group 10
155285213Sdarrenr      pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
155385213Sdarrenr      pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53         keep state group 10
155485213Sdarrenr
155585213Sdarrenr    pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
155685213Sdarrenr
155785213Sdarrenr    block out on xl2 all
155885213Sdarrenr
155985213Sdarrenr    pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
156085213Sdarrenr
156185213SdarrenrNow  you  can  see the rule groups in action.  For a host on
156285213Sdarrenrthe xl2 network, we can completely bypass all the checks  in
156385213Sdarrenrgroup  10  when  we're  not communicating with hosts on that
156485213Sdarrenrnetwork.
156585213Sdarrenr
156685213Sdarrenr     Depending on your situation, it may be prudent to group
156785213Sdarrenryour  rules  by protocol, or various machines, or netblocks,
156885213Sdarrenror whatever makes it flow smoothly.
156985213Sdarrenr
157085213Sdarrenr3.10.  "Fastroute"; The Keyword of Stealthiness
157185213Sdarrenr
157285213Sdarrenr     Even though we're forwarding some packets, and blocking
157385213Sdarrenrother  packets, we're typically behaving like a well behaved
157485213Sdarrenrrouter should by decrementing the  TTL  on  the  packet  and
157585213Sdarrenracknowledging  to  the entire world that yes, there is a hop
157685213Sdarrenrhere.  But we can hide our presence from inquisitive  appli-
157785213Sdarrenrcations  like  unix  traceroute  which uses UDP packets with
157885213Sdarrenrvarious TTL values to map the hops between two sites.  If we
157985213Sdarrenr
158085213Sdarrenr
158185213Sdarrenr
158285213Sdarrenr
158385213Sdarrenr
158485213Sdarrenr
158585213Sdarrenr
158685213Sdarrenr
158785213Sdarrenr
158885213Sdarrenr                            -25-
158985213Sdarrenr
159085213Sdarrenr
159185213Sdarrenrwant  incoming  traceroutes  to  work, but we do not want to
159285213Sdarrenrannounce the presence of our firewall as a hop, we can do so
159385213Sdarrenrwith a rule like this:
159485213Sdarrenr
159585213Sdarrenr    block in quick on xl0 fastroute proto udp from any to any port 33434 >< 33465
159685213Sdarrenr
159785213SdarrenrThe  presence  of the fastroute keyword will signal ipfilter
159885213Sdarrenrto not pass the packet into the Unix IP  stack  for  routing
159985213Sdarrenrwhich results in a TTL decrement.  The packet will be placed
160085213Sdarrenrgently on the output interface by  ipfilter  itself  and  no
160185213Sdarrenrsuch decrement will happen.  Ipfilter will of course use the
160285213Sdarrenrsystem's routing table to figure out  what  the  appropriate
160385213Sdarrenroutput  interface  really  is,  but it will take care of the
160485213Sdarrenractual task of routing itself.
160585213Sdarrenr
160685213Sdarrenr     There's a reason we used block quick  in  our  example,
160785213Sdarrenrtoo.   If  we  had  used  pass,  and if we had IP Forwarding
160885213Sdarrenrenabled in our kernel, we would end up having two paths  for
160985213Sdarrenra  packet  to  come  out of, and we would probably panic our
161085213Sdarrenrkernel.
161185213Sdarrenr
161285213Sdarrenr     It should be noted, however,  that  most  Unix  kernels
161385213Sdarrenr(and certainly the ones underlying the systems that ipfilter
161485213Sdarrenrusually runs on) have far more efficient routing  code  than
161585213Sdarrenrwhat  exists  in  ipfilter,  and  this keyword should not be
161685213Sdarrenrthought of as a way to improve the operating speed  of  your
161785213Sdarrenrfirewall, and should only be used in places where stealth is
161885213Sdarrenran issue.
161985213Sdarrenr
162085213Sdarrenr
162185213Sdarrenr
162285213Sdarrenr
162385213Sdarrenr4.  NAT and Proxies
162485213Sdarrenr
162585213Sdarrenr     Outside  of  the  corporate  environment,  one  of  the
162685213Sdarrenrbiggest  enticements  of firewall technology to the end user
162785213Sdarrenris the ability to connect several computers through a common
162885213Sdarrenrexternal  interface,  often without the approval, knowledge,
162985213Sdarrenror even consent of their service provider.  To those  famil-
163085213Sdarrenriar  with Linux, this concept is called IP Masquerading, but
163185213Sdarrenrto the rest of the world it is known  by  the  more  obscure
163285213Sdarrenrname of Network Address Translation, or NAT for short.
163385213Sdarrenr
163485213Sdarrenr4.1.  Mapping Many Addresses Into One Address
163585213Sdarrenr
163685213Sdarrenr     The basic use of NAT accomplishes much the  same  thing
163785213Sdarrenrthat  Linux's  IP Masquerading function does, and it does it
163885213Sdarrenr-----------
163985213Sdarrenr  To be pedantic, what IPFilter provides is really
164085213Sdarrenrcalled NPAT, for Network and Port Address Transla-
164185213Sdarrenrtion,  which means we can change any of the source
164285213Sdarrenrand destination IP Addresses and their source  and
164385213Sdarrenrdestination  ports.   True  NAT only allows one to
164485213Sdarrenrchange the addresses.
164585213Sdarrenr
164685213Sdarrenr
164785213Sdarrenr
164885213Sdarrenr
164985213Sdarrenr
165085213Sdarrenr
165185213Sdarrenr
165285213Sdarrenr
165385213Sdarrenr
165485213Sdarrenr                            -26-
165585213Sdarrenr
165685213Sdarrenr
165785213Sdarrenrwith one simple rule:
165885213Sdarrenr
165985213Sdarrenr    map tun0 192.168.1.0/24 -> 20.20.20.1/32
166085213Sdarrenr
166185213SdarrenrVery simple.  Whenever a packet goes out the tun0  interface
166285213Sdarrenrwith  a  source  address  matching  the CIDR network mask of
166385213Sdarrenr192.168.1.0/24 this packet will be rewritten within  the  IP
166485213Sdarrenrstack  such  that  its  source address is 20.20.20.1, and it
166585213Sdarrenrwill be sent on to its original  destination.    The  system
166685213Sdarrenralso  keeps  a  list  of  what translated connections are in
166785213Sdarrenrprogress so that it can perform the reverse  and  remap  the
166885213Sdarrenrresponse  (which  will  be  directed  to  20.20.20.1) to the
166985213Sdarrenrinternal host that really generated the packet.
167085213Sdarrenr
167185213Sdarrenr     There is a drawback to the rule we have  just  written,
167285213Sdarrenrthough.   In  a  large  number of cases, we do not happen to
167385213Sdarrenrknow what the IP address of our outside link  is  (if  we're
167485213Sdarrenrusing tun0 or ppp0 and a typical ISP) so it makes setting up
167585213Sdarrenrour NAT tables a chore.   Luckily, NAT is  smart  enough  to
167685213Sdarrenraccept  an  address  of 0/32 as a signal that it needs to go
167785213Sdarrenrlook at what the address of that interface really is and  we
167885213Sdarrenrcan rewrite our rule as follows:
167985213Sdarrenr
168085213Sdarrenr    map tun0 192.168.1.0/24 -> 0/32
168185213Sdarrenr
168285213SdarrenrNow we can load our ipnat rules with impunity and connect to
168385213Sdarrenrthe outside world without having to edit  anything.  You  do
168485213Sdarrenrhave to run ipf -y to refresh the address if you get discon-
168585213Sdarrenrnected and redial or if your DHCP lease changes, though.
168685213Sdarrenr
168785213Sdarrenr     Some of you may be wondering what happens to the source
168885213Sdarrenrport  when  the mapping happens.  With our current rule, the
168985213Sdarrenrpacket's source port is unchanged from the  original  source
169085213Sdarrenrport.   There  can  be instances where we do not desire this
169185213Sdarrenrbehavior; maybe we have another firewall further upstream we
169285213Sdarrenrhave  to  pass  through, or perhaps many hosts are trying to
169385213Sdarrenruse the same source port, causing a collision where the rule
169485213Sdarrenrdoesn't  match and the packet is passed untranslated.  ipnat
169585213Sdarrenrhelps us here with the portmap keyword:
169685213Sdarrenr
169785213Sdarrenr    map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000
169885213Sdarrenr
169985213SdarrenrOur rule now shoehorns all the translated connections (which
170085213Sdarrenrcan be tcp, udp, or tcp/udp) into the port range of 20000 to
170185213Sdarrenr30000.
170285213Sdarrenr
170385213Sdarrenr
170485213Sdarrenr
170585213Sdarrenr-----------
170685213Sdarrenr This is a typical internal address  space,  since
170785213Sdarrenrit's non-routable on the Real Internet it is often
170885213Sdarrenrused for internal  networks.    You  should  still
170985213Sdarrenrblock  these  packets  coming  in from the outside
171085213Sdarrenrworld as discussed earlier.
171185213Sdarrenr
171285213Sdarrenr
171385213Sdarrenr
171485213Sdarrenr
171585213Sdarrenr
171685213Sdarrenr
171785213Sdarrenr
171885213Sdarrenr
171985213Sdarrenr
172085213Sdarrenr                            -27-
172185213Sdarrenr
172285213Sdarrenr
172385213Sdarrenr4.2.  Mapping Many Addresses Into a Pool of Addresses
172485213Sdarrenr
172585213Sdarrenr     Another use common use of NAT is to take a small stati-
172685213Sdarrenrcally  allocated  block  of addresses and map many computers
172785213Sdarrenrinto this smaller address space.   This is  easy  to  accom-
172885213Sdarrenrplish  using what you already know about the map and portmap
172985213Sdarrenrkeywords by writing a rule like so:
173085213Sdarrenr
173185213Sdarrenr    map tun0 192.168.0.0/16 -> 20.20.20.0/24 portmap tcp/udp 20000:60000
173285213Sdarrenr
173385213SdarrenrAlso, there may be  instances  where  a  remote  application
173485213Sdarrenrrequires that multiple connections all come from the same IP
173585213Sdarrenraddress.  We can help with these situations by  telling  NAT
173685213Sdarrenrto  statically  map  sessions  from  a host into the pool of
173785213Sdarrenraddresses and work some magic to choose a port. This uses  a
173885213Sdarrenrthe keyword map-block as follows:
173985213Sdarrenr
174085213Sdarrenr    map-block tun0 192.168.1.0/24 -> 20.20.20.0/24
174185213Sdarrenr
174285213Sdarrenr4.3.  One to One Mappings
174385213Sdarrenr
174485213Sdarrenr     Occasionally  it is desirable to have a system with one
174585213SdarrenrIP address behind the firewall to  appear  to  have  a  com-
174685213Sdarrenrpletely different IP address.  One example of how this would
174785213Sdarrenrwork would be a lab of computers which are then attached  to
174885213Sdarrenrvarious networks that are to be put under some kind of test.
174985213SdarrenrIn this example, you would not want to have  to  reconfigure
175085213Sdarrenrthe  entire  lab  when you could place a NAT system in front
175185213Sdarrenrand change the addresses in one simple place.    We  can  do
175285213Sdarrenrthat  with  the  bimap  keyword,  for bidirectional mapping.
175385213SdarrenrBimap has some additional protections  on  it  to  ensure  a
175485213Sdarrenrknown  state  for the connection, whereas the map keyword is
175585213Sdarrenrdesigned to allocate  an  address  and  a  source  port  and
175685213Sdarrenrrewrite the packet and go on with life.
175785213Sdarrenr
175885213Sdarrenr      bimap tun0 192.168.1.1/32 -> 20.20.20.1/32
175985213Sdarrenr
176085213Sdarrenrwill accomplish the mapping for one host.
176185213Sdarrenr
176285213Sdarrenr4.4.  Spoofing Services
176385213Sdarrenr
176485213Sdarrenr     Spoofing services?  What does that have to do with any-
176585213Sdarrenrthing?   Plenty.  Let's pretend that we have  a  web  server
176685213Sdarrenrrunning  on  20.20.20.5, and since we've gotten increasingly
176785213Sdarrenrsuspicious of our network security, we  desire  to  not  run
176885213Sdarrenrthis  server on port 80 since that requires a brief lifespan
176985213Sdarrenras the root  user.    But  how  do  we  run  it  on  a  less
177085213Sdarrenrprivledged port of 8000 in this world of "anything dot com"?
177185213SdarrenrHow will anyone find our server?  We can use the redirection
177285213Sdarrenrfacilities of NAT to solve this problem by instructing it to
177385213Sdarrenrremap any connections destined for 20.20.20.5:80  to  really
177485213Sdarrenrpoint to 20.20.20.5:8000.   This uses the rdr keyword:
177585213Sdarrenr
177685213Sdarrenr      rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000
177785213Sdarrenr
177885213Sdarrenr
177985213Sdarrenr
178085213Sdarrenr
178185213Sdarrenr
178285213Sdarrenr
178385213Sdarrenr
178485213Sdarrenr
178585213Sdarrenr
178685213Sdarrenr                            -28-
178785213Sdarrenr
178885213Sdarrenr
178985213SdarrenrWe can also specify the protocol here, if we wanted to redi-
179085213Sdarrenrrect a UDP service, instead of a TCP service (which  is  the
179185213Sdarrenrdefault).  For example, if we had a honeypot on our firewall
179285213Sdarrenrto impersonate the popular  Back  Orifice  for  Windows,  we
179385213Sdarrenrcould  shovel  our entire network into this one place with a
179485213Sdarrenrsimple rule:
179585213Sdarrenr
179685213Sdarrenr        rdr tun0 20.20.20.0/24 port 31337 -> 127.0.0.1 port 31337 udp
179785213Sdarrenr
179885213SdarrenrAn extremely important point must be made  about  rdr:   You
179985213Sdarrenrcannot easily use this feature as a "reflector".  E.g:
180085213Sdarrenr
180185213Sdarrenr     rdr tun0 20.20.20.5/32 port 80 -> 20.20.20.6 port 80 tcp
180285213Sdarrenr
180385213Sdarrenrwill  not  work  in the situation where .5 and .6 are on the
180485213Sdarrenrsame  LAN  segment.   The rdr function is applied to packets
180585213Sdarrenrthat enter the firewall on the specified interface.  When  a
180685213Sdarrenrpacket  comes  in  that  matches a rdr rule, its destination
180785213Sdarrenraddress is then rewritten, it is pushed into ipf for filter-
180885213Sdarrenring,  and  should it successfully run the gauntlet of filter
180985213Sdarrenrrules, it is then sent to the unix routing code.  Since this
181085213Sdarrenrpacket  is  still inbound on the same interface that it will
181185213Sdarrenrneed to leave the system on to reach a host, the system gets
181285213Sdarrenrconfused.   Reflectors  don't work.  Neither does specifying
181385213Sdarrenrthe address of the interface the packet  just  came  in  on.
181485213SdarrenrAlways  remember  that rdr destinations must exit out of the
181585213Sdarrenrfirewall host on a different interface.
181685213Sdarrenr
181785213Sdarrenr4.5.  Transparent Proxy Support; Redirection Made Useful
181885213Sdarrenr
181985213Sdarrenr     Since  you're  installing  a  firewall,  you  may  have
182085213Sdarrenrdecided that it is prudent to use a proxy for many  of  your
182185213Sdarrenroutgoing  connections  so  that you can further tighten your
182285213Sdarrenrfilter rules protecting your internal network,  or  you  may
182385213Sdarrenrhave  run into a situation that the NAT mapping process does
182485213Sdarrenrnot currently handle properly.   This  can  also  be  accom-
182585213Sdarrenrplished with a redirection statement:
182685213Sdarrenr
182785213Sdarrenr        rdr xl0 0.0.0.0/0 port 21 -> 127.0.0.1 port 21
182885213Sdarrenr
182985213SdarrenrThis  statement  says  that  any packet coming in on the xl0
183085213Sdarrenrinterface destined for any address (0.0.0.0/0)  on  the  ftp
183185213Sdarrenrport  should be rewritten to connect it with a proxy that is
183285213Sdarrenrrunning on the NAT system on port 21.
183385213Sdarrenr
183485213Sdarrenr-----------
183585213Sdarrenr Yes. There is a way to do this.  It's  so  convo-
183685213Sdarrenrluted that I refuse to use it, though.  Smart peo-
183785213Sdarrenrple who require this functionality will  transpar-
183885213Sdarrenrently  redirect into something like TIS plug-gw on
183985213Sdarrenr127.0.0.1.  Stupid people will set up a dummy loop
184085213Sdarrenrinterface pair and double rewrite.
184185213Sdarrenr This includes 127.0.0.1, by the way.   That's  on
184285213Sdarrenrlo0.  Neat, huh?
184385213Sdarrenr
184485213Sdarrenr
184585213Sdarrenr
184685213Sdarrenr
184785213Sdarrenr
184885213Sdarrenr
184985213Sdarrenr
185085213Sdarrenr
185185213Sdarrenr
185285213Sdarrenr                            -29-
185385213Sdarrenr
185485213Sdarrenr
185585213Sdarrenr     This specific example of FTP proxying does lead to some
185685213Sdarrenrcomplications  when  used  with  web browsers or other auto-
185785213Sdarrenrmatic-login type clients that are unaware  of  the  require-
185885213Sdarrenrments  of  communicating  with the proxy.  There are patches
185985213Sdarrenrfor TIS Firewall Toolkit'sftp-gw to mate  it  with  the  nat
186085213Sdarrenrprocess so that it can determine where you were trying to go
186185213Sdarrenrand automatically send you there.  Many proxy  packages  now
186285213Sdarrenrwork  in a transparent proxy environment (Squid for example,
186385213Sdarrenrlocated at http://squid.nlanr.net, works fine.)
186485213Sdarrenr
186585213Sdarrenr     This application of the rdr keyword is often more  use-
186685213Sdarrenrful  when you wish to force users to authenticate themselves
186785213Sdarrenrwith the proxy. (For example, you desire your  engineers  to
186885213Sdarrenrbe  able to surf the web, but you would rather not have your
186985213Sdarrenrcall-center staff doing so.)
187085213Sdarrenr
187185213Sdarrenr4.6.  Magic Hidden Within NAT; Application Proxies
187285213Sdarrenr
187385213Sdarrenr     Since ipnat provides a method  to  rewrite  packets  as
187485213Sdarrenrthey traverse the firewall, it becomes a convenient place to
187585213Sdarrenrbuild in some application level proxies to make up for  well
187685213Sdarrenrknown  deficiencies  of  that  application and typical fire-
187785213Sdarrenrwalls.  For example; FTP.   We can  make  our  firewall  pay
187885213Sdarrenrattention to the packets going across it and when it notices
187985213Sdarrenrthat it's dealing with an Active FTP session, it  can  write
188085213Sdarrenritself  some  temporary  rules,  much like what happens with
188185213Sdarrenrkeep state, so that the FTP data connection works.    To  do
188285213Sdarrenrthis, we use a rule like so:
188385213Sdarrenr
188485213Sdarrenr   map tun0 192.168.1.0/24 -> 20.20.20.1/32 proxy port ftp ftp/tcp
188585213Sdarrenr
188685213SdarrenrYou must always remember to place this proxy rule before any
188785213Sdarrenrportmap  rules,  otherwise  when  portmap  comes  along  and
188885213Sdarrenrmatches  the  packet and rewrites it before the proxy gets a
188985213Sdarrenrchance to work on it.  Remember that ipnat rules are  first-
189085213Sdarrenrmatch.
189185213Sdarrenr
189285213Sdarrenr     There  also  exist proxies for "rcmd" (which we suspect
189385213Sdarrenris berkeley r-* commands which should be  forbidden  anyway,
189485213Sdarrenrthus we haven't looked at what this proxy does) and "raudio"
189585213Sdarrenrfor Real Audio PNM streams.  Likewise, both of  these  rules
189685213Sdarrenrshould be put before any portmap rules, if you're doing NAT.
189785213Sdarrenr
189885213Sdarrenr
189985213Sdarrenr
190085213Sdarrenr5.  Loading and Manipulating Filter Rules; The ipf Utility
190185213Sdarrenr
190285213Sdarrenr     IP Filter rules are loaded by using  the  ipf  utility.
190385213SdarrenrThe  filter  rules  can be stored in any file on the system,
190485213Sdarrenrbut typically these  rules  are  stored  in  /etc/ipf.rules,
190585213Sdarrenr/usr/local/etc/ipf.rules, or /etc/opt/ipf/ipf.rules.
190685213Sdarrenr
190785213Sdarrenr     IP Filter has two sets of rules, the active set and the
190885213Sdarrenrinactive set.  By default, all operations are  performed  on
190985213Sdarrenr
191085213Sdarrenr
191185213Sdarrenr
191285213Sdarrenr
191385213Sdarrenr
191485213Sdarrenr
191585213Sdarrenr
191685213Sdarrenr
191785213Sdarrenr
191885213Sdarrenr                            -30-
191985213Sdarrenr
192085213Sdarrenr
192185213Sdarrenrthe  active  set.   You  can  manipulate the inactive set by
192285213Sdarrenradding -I to the ipf command line.   The  two  sets  can  be
192385213Sdarrenrtoggled  by  using the -s command line option.  This is very
192485213Sdarrenruseful for testing new rule sets without wiping out the  old
192585213Sdarrenrrule set.
192685213Sdarrenr
192785213Sdarrenr     Rules  can  also  be  removed  from the list instead of
192885213Sdarrenradded by using the -r command line option, but it is  gener-
192985213Sdarrenrally  a safer idea to flush the rule set that you're working
193085213Sdarrenron with -F and completely reload it when making changes.
193185213Sdarrenr
193285213Sdarrenr     In summary, the easiest way to load a rule set  is  ipf
193385213Sdarrenr-Fa  -f  /etc/ipf.rules.  For more complicated manipulations
193485213Sdarrenrof the rule set, please see the ipf(1) man page.
193585213Sdarrenr
193685213Sdarrenr6.  Loading and Manipulating NAT Rules; The ipnat Utility
193785213Sdarrenr
193885213Sdarrenr     NAT rules are loaded by using the ipnat  utility.   The
193985213SdarrenrNAT rules can be stored in any file on the system, but typi-
194085213Sdarrenrcally  these   rules   are   stored   in   /etc/ipnat.rules,
194185213Sdarrenr/usr/local/etc/ipnat.rules, or /etc/opt/ipf/ipnat.rules.
194285213Sdarrenr
194385213Sdarrenr     Rules  can  also  be  removed  from the list instead of
194485213Sdarrenradded by using the -r command line option, but it is  gener-
194585213Sdarrenrally  a safer idea to flush the rule set that you're working
194685213Sdarrenron with -C and completely reload  it  when  making  changes.
194785213SdarrenrAny  active  mappings  are  not  affected  by -C, and can be
194885213Sdarrenrremoved with -F.
194985213Sdarrenr
195085213Sdarrenr     NAT rules and active mappings can be examined with  the
195185213Sdarrenr-l command line option.
195285213Sdarrenr
195385213Sdarrenr     In  summary,  the easiest way to load a NAT rule set is
195485213Sdarrenripnat -CF -f /etc/ipnat.rules.
195585213Sdarrenr
195685213Sdarrenr7.  Monitoring and Debugging
195785213Sdarrenr
195885213Sdarrenr     There will come a time when you are interested in  what
195985213Sdarrenryour  firewall  is  actually  doing,  and  ipfilter would be
196085213Sdarrenrincomplete if it didn't have a full suite of status monitor-
196185213Sdarrenring tools.
196285213Sdarrenr
196385213Sdarrenr7.1.  The ipfstat utility
196485213Sdarrenr
196585213Sdarrenr     In  its  simplest  form,  ipfstat  displays  a table of
196685213Sdarrenrinteresting data about how your firewall is performing, such
196785213Sdarrenras  how  many  packets  have been passed or blocked, if they
196885213Sdarrenrwere logged or not, how many state entries have  been  made,
196985213Sdarrenrand  so  on.   Here's  an example of something you might see
197085213Sdarrenrfrom running the tool:
197185213Sdarrenr
197285213Sdarrenr    # ipfstat
197385213Sdarrenr     input packets:         blocked 99286 passed 1255609 nomatch 14686 counted 0
197485213Sdarrenr    output packets:         blocked 4200 passed 1284345 nomatch 14687 counted 0
197585213Sdarrenr
197685213Sdarrenr
197785213Sdarrenr
197885213Sdarrenr
197985213Sdarrenr
198085213Sdarrenr
198185213Sdarrenr
198285213Sdarrenr
198385213Sdarrenr
198485213Sdarrenr                            -31-
198585213Sdarrenr
198685213Sdarrenr
198785213Sdarrenr     input packets logged:  blocked 99286 passed 0
198885213Sdarrenr    output packets logged:  blocked 0 passed 0
198985213Sdarrenr     packets logged:        input 0 output 0
199085213Sdarrenr     log failures:          input 3898 output 0
199185213Sdarrenr    fragment state(in):     kept 0  lost 0
199285213Sdarrenr    fragment state(out):    kept 0  lost 0
199385213Sdarrenr    packet state(in):       kept 169364     lost 0
199485213Sdarrenr    packet state(out):      kept 431395     lost 0
199585213Sdarrenr    ICMP replies:   0       TCP RSTs sent:  0
199685213Sdarrenr    Result cache hits(in):  1215208 (out):  1098963
199785213Sdarrenr    IN Pullups succeeded:   2       failed: 0
199885213Sdarrenr    OUT Pullups succeeded:  0       failed: 0
199985213Sdarrenr    Fastroute successes:    0       failures:       0
200085213Sdarrenr    TCP cksum fails(in):    0       (out):  0
200185213Sdarrenr    Packet log flags set: (0)
200285213Sdarrenr            none
200385213Sdarrenr
200485213Sdarrenripfstat is also capable of showing  you  your  current  rule
200585213Sdarrenrlist.   Using  the -i or the -o flag will show the currently
200685213Sdarrenrloaded rules for in or out, respectively.  Adding  a  -h  to
200785213Sdarrenrthis  will  provide more useful information at the same time
200885213Sdarrenrby showing you a "hit count" on each rule.  For example:
200985213Sdarrenr
201085213Sdarrenr    # ipfstat -ho
201185213Sdarrenr    2451423 pass out on xl0 from any to any
201285213Sdarrenr    354727 block out on ppp0 from any to any
201385213Sdarrenr    430918 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
201485213Sdarrenr
201585213SdarrenrFrom this, we can see that perhaps there's something  abnor-
201685213Sdarrenrmal  going on, since we've got a lot of blocked packets out-
201785213Sdarrenrbound, even with a very permissive pass out rule.  Something
201885213Sdarrenrhere  may warrant further investigation,  or it may be func-
201985213Sdarrenrtioning perfectly by design.  ipfstat can't tell you if your
202085213Sdarrenrrules  are right or wrong, it can only tell you what is hap-
202185213Sdarrenrpening because of your rules.
202285213Sdarrenr
202385213SdarrenrTo further debug your rules, you may  want  to  use  the  -n
202485213Sdarrenrflag, which will show the rule number next to each rule.
202585213Sdarrenr
202685213Sdarrenr    # ipfstat -on
202785213Sdarrenr    @1 pass out on xl0 from any to any
202885213Sdarrenr    @2 block out on ppp0 from any to any
202985213Sdarrenr    @3 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
203085213Sdarrenr
203185213SdarrenrThe final piece of really interesting information that ipfs-
203285213Sdarrenrtat can provide us is a dump of the state  table.   This  is
203385213Sdarrenrdone with the -s flag:
203485213Sdarrenr
203585213Sdarrenr    # ipfstat -s
203685213Sdarrenr            281458 TCP
203785213Sdarrenr            319349 UDP
203885213Sdarrenr            0 ICMP
203985213Sdarrenr            19780145 hits
204085213Sdarrenr            5723648 misses
204185213Sdarrenr
204285213Sdarrenr
204385213Sdarrenr
204485213Sdarrenr
204585213Sdarrenr
204685213Sdarrenr
204785213Sdarrenr
204885213Sdarrenr
204985213Sdarrenr
205085213Sdarrenr                            -32-
205185213Sdarrenr
205285213Sdarrenr
205385213Sdarrenr            0 maximum
205485213Sdarrenr            0 no memory
205585213Sdarrenr            1 active
205685213Sdarrenr            319349 expired
205785213Sdarrenr            281419 closed
205885213Sdarrenr    100.100.100.1 -> 20.20.20.1 ttl 864000 pass 20490 pr 6 state 4/4
205985213Sdarrenr            pkts 196 bytes 17394    987 -> 22 585538471:2213225493 16592:16500
206085213Sdarrenr            pass in log quick keep state
206185213Sdarrenr            pkt_flags & b = 2,              pkt_options & ffffffff = 0
206285213Sdarrenr            pkt_security & ffff = 0, pkt_auth & ffff = 0
206385213Sdarrenr
206485213SdarrenrHere  we  see that we have one state entry for a TCP connec-
206585213Sdarrenrtion.  The output will vary slightly from  version  to  ver-
206685213Sdarrenrsion,  but the basic information is the same.  We can see in
206785213Sdarrenrthis connection that we have a fully established  connection
206885213Sdarrenr(represented  by the 4/4 state.  Other states are incomplete
206985213Sdarrenrand will be documented fully later.)  We can  see  that  the
207085213Sdarrenrstate  entry  has  a  time to live of 240 hours, which is an
207185213Sdarrenrabsurdly long time, but is the default  for  an  established
207285213SdarrenrTCP connection.   This TTL counter is decremented every sec-
207385213Sdarrenrond that the state entry  is  not  used,  and  will  finally
207485213Sdarrenrresult  in  the  connection being purged if it has been left
207585213Sdarrenridle.   The TTL is also reset to 864000 whenever  the  state
207685213SdarrenrIS  used, ensuring that the entry will not time out while it
207785213Sdarrenris being actively used.  We can also see that we have passed
207885213Sdarrenr196 packets consisting of about 17kB worth of data over this
207985213Sdarrenrconnection.  We can see the ports  for  both  endpoints,  in
208085213Sdarrenrthis case 987 and 22; which means that this state entry rep-
208185213Sdarrenrresents  a  connection  from  100.100.100.1  port   987   to
208285213Sdarrenr20.20.20.1  port  22.   The really big numbers in the second
208385213Sdarrenrline are the TCP sequence numbers for this connection, which
208485213Sdarrenrhelps  to  ensure that someone isn't easily able to inject a
208585213Sdarrenrforged packet into your session.  The  TCP  window  is  also
208685213Sdarrenrshown.    The  third line is a synopsis of the implicit rule
208785213Sdarrenrthat was generated by the keep state code, showing that this
208885213Sdarrenrconnection is an inbound connection.
208985213Sdarrenr
209085213Sdarrenr7.2.  The ipmon utility
209185213Sdarrenr
209285213Sdarrenr     ipfstat  is  great  for  collecting snapshots of what's
209385213Sdarrenrgoing on on the system, but it's often handy  to  have  some
209485213Sdarrenrkind  of  log  to look at and watch events as they happen in
209585213Sdarrenrtime.   ipmon is this tool.  ipmon is  capable  of  watching
209685213Sdarrenrthe  packet  log  (as  created  with the log keyword in your
209785213Sdarrenrrules), the state log, or the nat log, or any combination of
209885213Sdarrenrthe  three.   This tool can either be run in the foreground,
209985213Sdarrenror as a daemon which logs to syslog or a file.  If we wanted
210085213Sdarrenrto  watch  the  state table in action, ipmon -o S would show
210185213Sdarrenrthis:
210285213Sdarrenr
210385213Sdarrenr    # ipmon -o S
210485213Sdarrenr    01/08/1999 15:58:57.836053 STATE:NEW 100.100.100.1,53 -> 20.20.20.15,53 PR udp
210585213Sdarrenr    01/08/1999 15:58:58.030815 STATE:NEW 20.20.20.15,123 -> 128.167.1.69,123 PR udp
210685213Sdarrenr    01/08/1999 15:59:18.032174 STATE:NEW 20.20.20.15,123 -> 128.173.14.71,123 PR udp
210785213Sdarrenr
210885213Sdarrenr
210985213Sdarrenr
211085213Sdarrenr
211185213Sdarrenr
211285213Sdarrenr
211385213Sdarrenr
211485213Sdarrenr
211585213Sdarrenr
211685213Sdarrenr                            -33-
211785213Sdarrenr
211885213Sdarrenr
211985213Sdarrenr    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
212085213Sdarrenr    01/08/1999 16:03:51.754867 STATE:NEW 20.20.20.13,1019 -> 100.100.100.10,22 PR tcp
212185213Sdarrenr    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
212285213Sdarrenr
212385213SdarrenrHere we see a state entry for an external  dns  request  off
212485213Sdarrenrour  nameserver,  two xntp pings to well-known time servers,
212585213Sdarrenrand a very short lived outbound ssh connection.
212685213Sdarrenr
212785213Sdarrenr     ipmon is also capable of showing us what  packets  have
212885213Sdarrenrbeen  logged.   For  example, when using state, you'll often
212985213Sdarrenrrun into packets like this:
213085213Sdarrenr
213185213Sdarrenr    # ipmon -o I
213285213Sdarrenr    15:57:33.803147 ppp0 @0:2 b 100.100.100.103,443 -> 20.20.20.10,4923 PR tcp len 20 1488 -A
213385213Sdarrenr
213485213SdarrenrWhat does this mean?   The first field is  obvious,  it's  a
213585213Sdarrenrtimestamp.   The  second  field is also pretty obvious, it's
213685213Sdarrenrthe interface that this event happened on.  The third  field
213785213Sdarrenr@0:2  is  something  most people miss. This is the rule that
213885213Sdarrenrcaused the event to happen.  Remember ipfstat -in?   If  you
213985213Sdarrenrwanted  to  know  where this came from, you could look there
214085213Sdarrenrfor rule 2 in rule group 0.  The fourth  field,  the  little
214185213Sdarrenr"b"  says that this packet was blocked, and you'll generally
214285213Sdarrenrignore this unless you're logging passed  packets  as  well,
214385213Sdarrenrwhich  would  be  a  little "p" instead. The fifth and sixth
214485213Sdarrenrfields are pretty  self-explanatory,  they  say  where  this
214585213Sdarrenrpacket  came from and where it was going. The seventh ("PR")
214685213Sdarrenrand eighth fields tell you the protocol and the ninth  field
214785213Sdarrenrtells  you  the size of the packet.  The last part, the "-A"
214885213Sdarrenrin this case, tells you the flags that were on  the  packet;
214985213SdarrenrThis  one  was  an ACK packet.  Why did I mention state ear-
215085213Sdarrenrlier?   Due to the often laggy nature of the Internet, some-
215185213Sdarrenrtimes  packets  will  be regenerated.  Sometimes, you'll get
215285213Sdarrenrtwo copies of the same packet, and  your  state  rule  which
215385213Sdarrenrkeeps  track of sequence numbers will have already seen this
215485213Sdarrenrpacket, so it will assume that the packet is part of a  dif-
215585213Sdarrenrferent  connection.   Eventually this packet will run into a
215685213Sdarrenrreal rule and have to be dealt with.   You'll often see  the
215785213Sdarrenrlast packet of a session being closed get logged because the
215885213Sdarrenrkeep state code has already torn down the connection  before
215985213Sdarrenrthe  last  packet  has had a chance to make it to your fire-
216085213Sdarrenrwall.  This is normal, do not be alarmed.   Another  example
216185213Sdarrenrpacket that might be logged:
216285213Sdarrenr
216385213Sdarrenr    12:46:12.470951 xl0 @0:1 S 20.20.20.254 -> 255.255.255.255 PR icmp len 20 9216 icmp 9/0
216485213Sdarrenr
216585213Sdarrenr-----------
216685213Sdarrenr For a technical presentation  of  the  IP  Filter
216785213Sdarrenrstateful  inspection  engine, please see the white
216885213Sdarrenrpaper Real Stateful TCP  Packet  Filtering  in  IP
216985213SdarrenrFilter,  by  Guido  van  Rooij.  This paper may be
217085213Sdarrenrfound                                           at
217185213Sdarrenr<http://www.iae.nl/users/guido/papers/tcp_filter-
217285213Sdarrenring.ps.gz>
217385213Sdarrenr
217485213Sdarrenr
217585213Sdarrenr
217685213Sdarrenr
217785213Sdarrenr
217885213Sdarrenr
217985213Sdarrenr
218085213Sdarrenr
218185213Sdarrenr
218285213Sdarrenr                            -34-
218385213Sdarrenr
218485213Sdarrenr
2185108533SschweikhThis  is an ICMP router discovery broadcast.  We can tell by
218685213Sdarrenrthe ICMP type 9/0.
218785213Sdarrenr
218885213SdarrenrFinally, ipmon also lets us look at the NAT table in action.
218985213Sdarrenr
219085213Sdarrenr    # ipmon -o N
219185213Sdarrenr    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]
219285213Sdarrenr    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
219385213Sdarrenr
219485213SdarrenrThis  would  be a redirection to an identd that lies to pro-
219585213Sdarrenrvide ident service for the hosts behind our NAT, since  they
219685213Sdarrenrare  typically unable to provide this service for themselves
219785213Sdarrenrwith ordinary natting.
219885213Sdarrenr
219985213Sdarrenr
220085213Sdarrenr
220185213Sdarrenr
220285213Sdarrenr8.  Specific Applications of IP Filter - Things  that  don't
220385213Sdarrenrfit, but should be mentioned anyway.
220485213Sdarrenr
220585213Sdarrenr8.1.  Keep State With Servers and Flags.
220685213Sdarrenr
220785213Sdarrenr     Keeping  state  is a good thing, but it's quite easy to
220885213Sdarrenrmake a mistake in the direction that you want to keep  state
220985213Sdarrenrin.    Generally,  you  want to have a keep state keyword on
221085213Sdarrenrthe first rule that interacts with a packet for the  connec-
221185213Sdarrenrtion.  One  common  mistake  that  is made when mixing state
221285213Sdarrenrtracking with filtering on flags is this:
221385213Sdarrenr
221485213Sdarrenr     block in all
221585213Sdarrenr     pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S
221685213Sdarrenr     pass out all keep state
221785213Sdarrenr
221885213SdarrenrThat certainly appears to allow a connection to  be  created
221985213Sdarrenrto  the  telnet server on 20.20.20.20, and the replies to go
222085213Sdarrenrback.  If you try using this rule, you'll see that  it  does
222185213Sdarrenrwork--Momentarily.   Since we're filtering for the SYN flag,
222285213Sdarrenrthe state entry never fully gets completed, and the  default
222385213Sdarrenrtime to live for an incomplete state is 60 seconds.
222485213Sdarrenr
222585213SdarrenrWe can solve this by rewriting the rules in one of two ways:
222685213Sdarrenr
222785213Sdarrenr1)
222885213Sdarrenr
222985213Sdarrenr          block in all
223085213Sdarrenr          pass in quick proto tcp from any to 20.20.20.20/32 port = 23 keep state
223185213Sdarrenr          block out all
223285213Sdarrenr
223385213Sdarrenror:
223485213Sdarrenr
223585213Sdarrenr2)
223685213Sdarrenr
223785213Sdarrenr          block in all
223885213Sdarrenr          pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S keep state
223985213Sdarrenr
224085213Sdarrenr
224185213Sdarrenr
224285213Sdarrenr
224385213Sdarrenr
224485213Sdarrenr
224585213Sdarrenr
224685213Sdarrenr
224785213Sdarrenr
224885213Sdarrenr                            -35-
224985213Sdarrenr
225085213Sdarrenr
225185213Sdarrenr          pass out all keep state
225285213Sdarrenr
225385213SdarrenrEither of these sets of rules will result in a fully  estab-
225485213Sdarrenrlished state entry for a connection to your server.
225585213Sdarrenr
225685213Sdarrenr8.2.  Coping With FTP
225785213Sdarrenr
225885213Sdarrenr     FTP is one of those protocols that you just have to sit
225985213Sdarrenrback and ask "What the heck were they  thinking?"   FTP  has
226085213Sdarrenrmany  problems that the firewall administrator needs to deal
226185213Sdarrenrwith.  What's worse, the  problems  the  administrator  must
226285213Sdarrenrface  are different between making ftp clients work and mak-
226385213Sdarrenring ftp servers work.
226485213Sdarrenr
226585213Sdarrenr     Within the FTP protocol, there are two  forms  of  data
226685213Sdarrenrtransfer,  called  active and passive.  Active transfers are
226785213Sdarrenrthose where the server connects  to  an  open  port  on  the
226885213Sdarrenrclient  to  send  data.   Conversely,  passive transfers are
226985213Sdarrenrthose where the client connects to  the  server  to  receive
227085213Sdarrenrdata.
227185213Sdarrenr
227285213Sdarrenr8.2.1.  Running an FTP Server
227385213Sdarrenr
227485213Sdarrenr     In  running an FTP server, handling Active FTP sessions
227585213Sdarrenris easy to setup.  At the same time,  handling  Passive  FTP
227685213Sdarrenrsessions  is a big problem.  First we'll cover how to handle
227785213SdarrenrActive FTP, then move on to Passive.  Generally, we can han-
227885213Sdarrenrdle  Active  FTP  sessions like we would an incoming HTTP or
227985213SdarrenrSMTP connection; just open the ftp port and let  keep  state
228085213Sdarrenrdo the rest:
228185213Sdarrenr
228285213Sdarrenr     pass in quick proto tcp from any to 20.20.20.20/32 port = 21 flags S keep state
228385213Sdarrenr     pass out proto tcp all keep state
228485213Sdarrenr
228585213SdarrenrThese  rules will allow Active FTP sessions, the most common
228685213Sdarrenrtype, to your ftp server on 20.20.20.20.
228785213Sdarrenr
228885213Sdarrenr     The next challenge becomes handling Passive FTP connec-
228985213Sdarrenrtions.   Web browsers default to this mode, so it's becoming
229085213Sdarrenrquite popular and as such it should be supported.  The prob-
229185213Sdarrenrlem with passive connections are that for every passive con-
229285213Sdarrenrnection, the server starts listening on a new port  (usually
229385213Sdarrenrabove  1023).   This  is  essentially  like  creating  a new
229485213Sdarrenrunknown service on the server.   Assuming  we  have  a  good
229585213Sdarrenrfirewall  with  a default-deny policy, that new service will
229685213Sdarrenrbe blocked, and thus Active FTP sessions are broken.   Don't
229785213Sdarrenrdespair!  There's hope yet to be had.
229885213Sdarrenr
229985213Sdarrenr     A  person's  first  inclination to solving this problem
230085213Sdarrenrmight be to just open up all ports above  1023.   In  truth,
230185213Sdarrenrthis will work:
230285213Sdarrenr
230385213Sdarrenr     pass in quick proto tcp from any to 20.20.20.20/32 port > 1023 flags S keep state
230485213Sdarrenr     pass out proto tcp all keep state
230585213Sdarrenr
230685213Sdarrenr
230785213Sdarrenr
230885213Sdarrenr
230985213Sdarrenr
231085213Sdarrenr
231185213Sdarrenr
231285213Sdarrenr
231385213Sdarrenr
231485213Sdarrenr                            -36-
231585213Sdarrenr
231685213Sdarrenr
231785213SdarrenrThis  is somewhat unsatisfactory, though.  By letting every-
231885213Sdarrenrthing above 1023 in, we actually open  ourselves  up  for  a
231985213Sdarrenrnumber  of  potential  problems.  While 1-1023 is the desig-
232085213Sdarrenrnated area for server services  to  run,  numerous  programs
232185213Sdarrenrdecided to use numbers higher than 1023, such as nfsd and X.
232285213Sdarrenr
232385213Sdarrenr     The good news is that your FTP server  gets  to  decide
232485213Sdarrenrwhich  ports  get  assigned to passive sessions.  This means
232585213Sdarrenrthat instead of opening all ports above 1023, you can  allo-
232685213Sdarrenrcate ports 15001-19999 as ftp ports and only open that range
232785213Sdarrenrof your firewall up.  In wu-ftpd, this is done with the pas-
232885213Sdarrenrsive  ports option in ftpaccess.  Please see the man page on
232985213Sdarrenrftpaccess for details  in  wu-ftpd  configuration.   On  the
233085213Sdarrenripfilter side, all we need do is setup corresponding rules:
233185213Sdarrenr
233285213Sdarrenr     pass in quick proto tcp from any to 20.20.20.20/32 port 15000 >< 20000 flags S keep state
233385213Sdarrenr     pass out proto tcp all keep state
233485213Sdarrenr
233585213SdarrenrIf  even  this  solution doesn't satisfy you, you can always
233685213Sdarrenrhack IPF support into your FTP server, or FTP server support
233785213Sdarrenrinto IPF.
233885213Sdarrenr
233985213Sdarrenr8.2.2.  Running an FTP Client
234085213Sdarrenr
234185213Sdarrenr     While  FTP server support is still less than perfect in
234285213SdarrenrIPF, FTP client support has been working well  since  3.3.3.
234385213SdarrenrAs  with  FTP  servers,  there  are  two types of ftp client
234485213Sdarrenrtransfers: passive and active.
234585213Sdarrenr
234685213Sdarrenr     The simplest type of client  transfer  from  the  fire-
234785213Sdarrenrwall's  standpoint is the passive transfer.  Assuming you're
234885213Sdarrenrkeeping state on all outbound tcp sessions,  passive  trans-
234985213Sdarrenrfers  will  work already.  If you're not doing this already,
235085213Sdarrenrplease consider the following:
235185213Sdarrenr
235285213Sdarrenr    pass out proto tcp all keep state
235385213Sdarrenr
235485213SdarrenrThe second type of client transfer, active, is  a  bit  more
235585213Sdarrenrtroublesome,  but  nonetheless  a  solved  problem.   Active
235685213Sdarrenrtransfers cause the server to open up  a  second  connection
235785213Sdarrenrback  to  the client for data to flow through.  This is nor-
235885213Sdarrenrmally a problem when there's a firewall in the middle, stop-
235985213Sdarrenrping  outside  connections  from  coming  back in.  To solve
236085213Sdarrenrthis, ipfilter includes an  ipnat  proxy  which  temporarily
236185213Sdarrenropens  up  a hole in the firewall just for the FTP server to
236285213Sdarrenrget back to the client.  Even if you're not using  ipnat  to
236385213Sdarrenrdo  nat,  the proxy is still effective.  The following rules
236485213Sdarrenris the bare minimum to add to the ipnat  configuration  file
236585213Sdarrenr(ep0  should  be  the interface name of the outbound network
236685213Sdarrenrconnection):
236785213Sdarrenr
236885213Sdarrenr     map ep0 0/0 -> 0/32 proxy port 21 ftp/tcp
236985213Sdarrenr
237085213Sdarrenr
237185213Sdarrenr
237285213Sdarrenr
237385213Sdarrenr
237485213Sdarrenr
237585213Sdarrenr
237685213Sdarrenr
237785213Sdarrenr
237885213Sdarrenr
237985213Sdarrenr
238085213Sdarrenr                            -37-
238185213Sdarrenr
238285213Sdarrenr
238385213SdarrenrFor more details on ipfilter's internal proxies, see section
238485213Sdarrenr3.6
238585213Sdarrenr
238685213Sdarrenr8.3.  Assorted Kernel Variables
238785213Sdarrenr
238885213Sdarrenr     There  are some useful kernel tunes that either need to
238985213Sdarrenrbe set for ipf to function, or are just generally  handy  to
239085213Sdarrenrknow  about for building firewalls.  The first major one you
239185213Sdarrenrmust set is to enable IP Forwarding, otherwise ipf  will  do
239285213Sdarrenrvery little, as the underlying ip stack won't actually route
239385213Sdarrenrpackets.
239485213Sdarrenr
239585213SdarrenrIP Forwarding:
239685213Sdarrenr
239785213Sdarrenropenbsd:
239885213Sdarrenr     net.inet.ip.forwarding=1
239985213Sdarrenr
240085213Sdarrenr
240185213Sdarrenrfreebsd:
240285213Sdarrenr     net.inet.ip.forwarding=1
240385213Sdarrenr
240485213Sdarrenr
240585213Sdarrenrnetbsd:
240685213Sdarrenr     net.inet.ip.forwarding=1
240785213Sdarrenr
240885213Sdarrenr
240985213Sdarrenrsolaris:
241085213Sdarrenr     ndd -set /dev/ip ip_forwarding 1
241185213Sdarrenr
241285213SdarrenrEphemeral Port Adjustment:
241385213Sdarrenr
241485213Sdarrenropenbsd:
241585213Sdarrenr     net.inet.ip.portfirst = 25000
241685213Sdarrenr
241785213Sdarrenr
241885213Sdarrenrfreebsd:
241985213Sdarrenr     net.inet.ip.portrange.first  =  25000  net.inet.ip.por-
242085213Sdarrenr     trange.last = 49151
242185213Sdarrenr
242285213Sdarrenr
242385213Sdarrenrnetbsd:
242485213Sdarrenr     net.inet.ip.anonportmin = 25000 net.inet.ip.anonportmax
242585213Sdarrenr     = 49151
242685213Sdarrenr
242785213Sdarrenr
242885213Sdarrenrsolaris:
242985213Sdarrenr     ndd -set /dev/tcp tcp_smallest_anon_port 25000
243085213Sdarrenr     ndd -set /dev/tcp tcp_largest_anon_port 65535
243185213Sdarrenr
243285213SdarrenrOther Useful Values:
243385213Sdarrenr
243485213Sdarrenropenbsd:
243585213Sdarrenr     net.inet.ip.sourceroute = 0
243685213Sdarrenr     net.inet.ip.directed-broadcast = 0
243785213Sdarrenr
243885213Sdarrenr
243985213Sdarrenr
244085213Sdarrenr
244185213Sdarrenr
244285213Sdarrenr
244385213Sdarrenr
244485213Sdarrenr
244585213Sdarrenr
244685213Sdarrenr                            -38-
244785213Sdarrenr
244885213Sdarrenr
244985213Sdarrenrfreebsd:
245085213Sdarrenr     net.inet.ip.sourceroute=0
245185213Sdarrenr     net.ip.accept_sourceroute=0
245285213Sdarrenr
245385213Sdarrenr
245485213Sdarrenrnetbsd:
245585213Sdarrenr     net.inet.ip.allowsrcrt=0
245685213Sdarrenr     net.inet.ip.forwsrcrt=0
245785213Sdarrenr     net.inet.ip.directed-broadcast=0
245885213Sdarrenr     net.inet.ip.redirect=0
245985213Sdarrenr
246085213Sdarrenr
246185213Sdarrenrsolaris:
246285213Sdarrenr     ndd -set /dev/ip ip_forward_directed_broadcasts 0
246385213Sdarrenr     ndd -set /dev/ip ip_forward_src_routed 0
246485213Sdarrenr     ndd -set /dev/ip ip_respond_to_echo_broadcast 0
246585213Sdarrenr
246685213SdarrenrIn addition, freebsd has some ipf specific sysctl variables.
246785213Sdarrenr
246885213Sdarrenr     net.inet.ipf.fr_flags: 0
246985213Sdarrenr     net.inet.ipf.fr_pass: 514
247085213Sdarrenr     net.inet.ipf.fr_active: 0
247185213Sdarrenr     net.inet.ipf.fr_tcpidletimeout: 864000
247285213Sdarrenr     net.inet.ipf.fr_tcpclosewait: 60
247385213Sdarrenr     net.inet.ipf.fr_tcplastack: 20
247485213Sdarrenr     net.inet.ipf.fr_tcptimeout: 120
247585213Sdarrenr     net.inet.ipf.fr_tcpclosed: 1
247685213Sdarrenr     net.inet.ipf.fr_udptimeout: 120
247785213Sdarrenr     net.inet.ipf.fr_icmptimeout: 120
247885213Sdarrenr     net.inet.ipf.fr_defnatage: 1200
247985213Sdarrenr     net.inet.ipf.fr_ipfrttl: 120
248085213Sdarrenr     net.inet.ipf.ipl_unreach: 13
248185213Sdarrenr     net.inet.ipf.ipl_inited: 1
248285213Sdarrenr     net.inet.ipf.fr_authsize: 32
248385213Sdarrenr     net.inet.ipf.fr_authused: 0
248485213Sdarrenr     net.inet.ipf.fr_defaultauthage: 600
248585213Sdarrenr
248685213Sdarrenr
248785213Sdarrenr
248885213Sdarrenr
248985213Sdarrenr9.  Fun with ipf!
249085213Sdarrenr
249185213Sdarrenr     This section doesn't necessarily teach you anything new
249285213Sdarrenrabout ipf, but it may raise an issue or two that you haven't
249385213Sdarrenryet  thought  up  on your own, or tickle your brain in a way
249485213Sdarrenrthat  you  invent  something  interesting  that  we  haven't
249585213Sdarrenrthought of.
249685213Sdarrenr
249785213Sdarrenr9.1.  Localhost Filtering
249885213Sdarrenr
249985213Sdarrenr     A  long  time ago at a university far, far away, Wietse
250085213SdarrenrVenema created the tcp-wrapper package, and ever since, it's
250185213Sdarrenrbeen  used  to add a layer of protection to network services
250285213Sdarrenrall over the world.  This is good.  But,  tcp-wrappers  have
250385213Sdarrenr
250485213Sdarrenr
250585213Sdarrenr
250685213Sdarrenr
250785213Sdarrenr
250885213Sdarrenr
250985213Sdarrenr
251085213Sdarrenr
251185213Sdarrenr
251285213Sdarrenr                            -39-
251385213Sdarrenr
251485213Sdarrenr
251585213Sdarrenrflaws.  For starters, they only protect TCP services, as the
251685213Sdarrenrname suggests.   Also, unless  you  run  your  service  from
251785213Sdarrenrinetd, or you have specifically compiled it with libwrap and
251885213Sdarrenrthe appropriate hooks, your service isn't protected.    This
251985213Sdarrenrleaves  gigantic  holes in your host security.   We can plug
252085213Sdarrenrthese up by using ipf on the local host.   For  example,  my
252185213Sdarrenrlaptop  often gets plugged into or dialed into networks that
252285213SdarrenrI don't specifically trust, and so, I use the following rule
252385213Sdarrenrset:
252485213Sdarrenr
252585213Sdarrenr     pass in quick on lo0 all
252685213Sdarrenr     pass out quick on lo0 all
252785213Sdarrenr
252885213Sdarrenr     block in log all
252985213Sdarrenr     block out all
253085213Sdarrenr
253185213Sdarrenr     pass in quick proto tcp from any to any port = 113 flags S keep state
253285213Sdarrenr     pass in quick proto tcp from any to any port = 22 flags S keep state
253385213Sdarrenr     pass in quick proto tcp from any port = 20 to any port 39999 >< 45000 flags S keep state
253485213Sdarrenr
253585213Sdarrenr     pass out quick proto icmp from any to any keep state
253685213Sdarrenr     pass out quick proto tcp/udp from any to any keep state keep frags
253785213Sdarrenr
253885213SdarrenrIt's  been  like  that for quite a while, and I haven't suf-
253985213Sdarrenrfered any pain or anguish as a result of having  ipf  loaded
254085213Sdarrenrup all the time.  If I wanted to tighten it up more, I could
254185213Sdarrenrswitch to using the NAT ftp proxy and I could  add  in  some
254285213Sdarrenrrules to prevent spoofing.   But even as it stands now, this
254385213Sdarrenrbox is far more restrictive about what it  presents  to  the
254485213Sdarrenrlocal  network and beyond than the typical host does.   This
254585213Sdarrenris a good thing if you happen to run a machine that allows a
254685213Sdarrenrlot  of  users on it, and you want to make sure  one of them
254785213Sdarrenrdoesn't happen to start up a service  they  wern't  supposed
254885213Sdarrenrto.   It won't stop a malicious hacker with root access from
254985213Sdarrenradjusting your ipf rules and starting a service anyway,  but
255085213Sdarrenrit  will keep the "honest" folks honest, and your weird ser-
255185213Sdarrenrvices safe, cozy and warm even on a malicious  LAN.   A  big
255285213Sdarrenrwin, in my opinion.   Using local host filtering in addition
255385213Sdarrenrto a somewhat less-restrictive "main firewall"  machine  can
255485213Sdarrenrsolve  many  performance  issues as well as political night-
255585213Sdarrenrmares like "Why doesn't ICQ work?" and "Why can't  I  put  a
255685213Sdarrenrweb  server  on  my  own workstation! It's MY WORKSTATION!!"
255785213SdarrenrAnother very big win.  Who says you can't have security  and
255885213Sdarrenrconvienence at the same time?
255985213Sdarrenr
256085213Sdarrenr9.2.  What Firewall?  Transparent filtering.
256185213Sdarrenr
256285213Sdarrenr     One  major  concern  in  setting  up  a firewall is the
256385213Sdarrenrintegrity of the firewall itself.  Can somebody  break  into
256485213Sdarrenryour  firewall,  thereby  subverting its ruleset?  This is a
256585213Sdarrenrcommon problem administrators must face,  particularly  when
256685213Sdarrenrthey're  using  firewall  solutions  on top of their Unix/NT
2567151702Sjhbmachines.  Some use it as an argument for blackbox hardware
256885213Sdarrenrsolutions,  under  the flawed notion that inherent obscurity
256985213Sdarrenr
257085213Sdarrenr
257185213Sdarrenr
257285213Sdarrenr
257385213Sdarrenr
257485213Sdarrenr
257585213Sdarrenr
257685213Sdarrenr
257785213Sdarrenr
257885213Sdarrenr                            -40-
257985213Sdarrenr
258085213Sdarrenr
258185213Sdarrenrof their closed system increases their security.  We have  a
258285213Sdarrenrbetter way.
258385213Sdarrenr
258485213Sdarrenr     Many network admins are familiar with the common ether-
258585213Sdarrenrnet bridge.  This is a device  that  connects  two  separate
258685213Sdarrenrethernet  segments  to make them one.  An ethernet bridge is
258785213Sdarrenrtypically used to connect separate buildings, switch network
258885213Sdarrenrspeeds,  and extend maximum wire lengths.  Hubs and switches
258985213Sdarrenrare common bridges, sometimes they're just 2 ported  devices
259085213Sdarrenrcalled   repeaters.   Recent  versions  of  Linux,  OpenBSD,
259185213SdarrenrNetBSD, and FreeBSD include code to convert $1000  PCs  into
259285213Sdarrenr$10  bridges,  too!  What all bridges tend to have in common
259385213Sdarrenris that though they  sit  in  the  middle  of  a  connection
259485213Sdarrenrbetween two machines, the two machines don't know the bridge
259585213Sdarrenris there.  Enter ipfilter and OpenBSD.
259685213Sdarrenr
259785213Sdarrenr     Ethernet bridging takes place  at  Layer2  on  the  ISO
259885213Sdarrenrstack.   IP  takes  place on Layer3.  IP Filter in primarily
259985213Sdarrenrconcerned with Layer3, but dabbles in Layer2 by working with
260085213Sdarrenrinterfaces.   By  mixing  IP  filter  with  OpenBSD's bridge
260185213Sdarrenrdevice, we can create a firewall that is both invisible  and
260285213Sdarrenrunreachable.   The  system  needs  no IP address, it doesn't
260385213Sdarrenreven need to reveal its ethernet address.  The only telltale
260485213Sdarrenrsign that the filter might be there is that latency is some-
260585213Sdarrenrwhat higher than a piece of cat5 would normally make it, and
260685213Sdarrenrthat  packets  don't seem to make it to their final destina-
260785213Sdarrenrtion.
260885213Sdarrenr
260985213Sdarrenr     The setup for this sort of ruleset is surprisingly sim-
261085213Sdarrenrple,  too.   In  OpenBSD,  the  first bridge device is named
261185213Sdarrenrbridge0.  Say we have two ethernet cards in our  machine  as
261285213Sdarrenrwell,  xl0 and xl1.  To turn this machine into a bridge, all
261385213Sdarrenrone need do is enter the following three commands:
261485213Sdarrenr
261585213Sdarrenr    brconfig bridge0 add xl0 add xl1 up
261685213Sdarrenr    ifconfig xl0 up
261785213Sdarrenr    ifconfig xl1 up
261885213Sdarrenr
261985213SdarrenrAt ths point, all traffic ariving on xl0 is sent out xl1 and
262085213Sdarrenrall  traffic  on xl1 is sent out xl0.  You'll note that nei-
262185213Sdarrenrther interface has been assigned an IP address,  nor  do  we
262285213Sdarrenrneed assign one.  All things considered, it's likely best we
262385213Sdarrenrnot add one at all.
262485213Sdarrenr
262585213Sdarrenr     Rulesets behave essentially the  as  the  always  have.
262685213SdarrenrThough  there  is a bridge0 interface, we don't filter based
262785213Sdarrenron it.  Rules continue  to  be  based  upon  the  particular
262885213Sdarrenrinterface  we're  using,  making  it important which network
262985213Sdarrenrcable is plugged into which network card in the back of  the
263085213Sdarrenrmachine.   Let's  start  with some basic filtering to illis-
263185213Sdarrenrtrate what's happened.  Assume the network used to look like
263285213Sdarrenrthis:
263385213Sdarrenr
263485213Sdarrenr
263585213Sdarrenr
263685213Sdarrenr
263785213Sdarrenr
263885213Sdarrenr
263985213Sdarrenr
264085213Sdarrenr
264185213Sdarrenr
264285213Sdarrenr
264385213Sdarrenr
264485213Sdarrenr                            -41-
264585213Sdarrenr
264685213Sdarrenr
264785213Sdarrenr  20.20.20.1 <---------------------------------> 20.20.20.0/24 network hub
264885213Sdarrenr
264985213SdarrenrThat  is,  we  have  a router at 20.20.20.1 connected to the
265085213Sdarrenr20.20.20.0/24 network.  All packets from  the  20.20.20.0/24
265185213Sdarrenrnetwork  go  through  20.20.20.1 to get to the outside world
265285213Sdarrenrand vice versa.  Now we add the Ipf Bridge:
265385213Sdarrenr
265485213Sdarrenr  20.20.20.1 <-------/xl0 IpfBridge xl1/-------> 20.20.20.0/24 network hub
265585213Sdarrenr
265685213SdarrenrWe also have the following ruleset loaded on  the  IpfBridge
265785213Sdarrenrhost:
265885213Sdarrenr
265985213Sdarrenr    pass in  quick  all
266085213Sdarrenr    pass out quick  all
266185213Sdarrenr
266285213SdarrenrWith  this ruleset loaded, the network is functionally iden-
266385213Sdarrenrtical.  As far as the 20.20.20.1 router is concerned, and as
266485213Sdarrenrfar  as  the 20.20.20.0/24 hosts are concerned, the two net-
266585213Sdarrenrwork diagrams are identical.  Now let's change  the  ruleset
266685213Sdarrenrsome:
266785213Sdarrenr
266885213Sdarrenr    block in quick on xl0 proto icmp
266985213Sdarrenr    pass  in  quick all
267085213Sdarrenr    pass  out quick all
267185213Sdarrenr
267285213SdarrenrStill,  20.20.20.1  and  20.20.20.0/24  think the network is
267385213Sdarrenridentical, but if 20.20.20.1 attempts to ping 20.20.20.2, it
267485213Sdarrenrwill  never get a reply.  What's more, 20.20.20.2 won't even
267585213Sdarrenrget the packet in the first place.  IPfilter will  intercept
267685213Sdarrenrthe  packet before it even gets to the other end of the vir-
267785213Sdarrenrtual wire.  We can put a  bridged  filter  anywhere.   Using
267885213Sdarrenrthis  method  we can shrink the network trust circle down an
267985213Sdarrenrindividual host level (given enough ethernet cards:-)
268085213Sdarrenr
268185213Sdarrenr     Blocking icmp from the world seems kind of silly, espe-
268285213Sdarrenrcially  if  you're a sysadmin and like pinging the world, to
268385213Sdarrenrtraceroute, or to resize your MTU.  Let's construct a better
268485213Sdarrenrruleset  and  take  advantage of the original key feature of
268585213Sdarrenripf: stateful inspection.
268685213Sdarrenr
268785213Sdarrenr    pass  in quick on xl1 proto tcp  keep state
268885213Sdarrenr    pass  in quick on xl1 proto udp  keep state
268985213Sdarrenr    pass  in quick on xl1 proto icmp keep state
269085213Sdarrenr    block in quick on xl0
269185213Sdarrenr
269285213SdarrenrIn this situation, the 20.20.20.0/24 network  (perhaps  more
269385213Sdarrenraptly  called  the  xl1  network)  can now reach the outside
269485213Sdarrenrworld, but the outside world can't reach it,  and  it  can't
269585213Sdarrenrfigure out why, either.  The router is accessible, the hosts
269685213Sdarrenrare active, but the outside world just can't get  in.   Even
269785213Sdarrenrif  the  router  itself were compromised, the firewall would
269885213Sdarrenrstill be active and successful.
269985213Sdarrenr
270085213Sdarrenr
270185213Sdarrenr
270285213Sdarrenr
270385213Sdarrenr
270485213Sdarrenr
270585213Sdarrenr
270685213Sdarrenr
270785213Sdarrenr
270885213Sdarrenr
270985213Sdarrenr
271085213Sdarrenr                            -42-
271185213Sdarrenr
271285213Sdarrenr
271385213Sdarrenr     So far, we've been filtering by interface and  protocol
271485213Sdarrenronly.   Even  though  bridging  is  concerned layer2, we can
271585213Sdarrenrstill discriminate based on IP address.  Normally we have  a
271685213Sdarrenrfew services running, so our ruleset may look like this:
271785213Sdarrenr
271885213Sdarrenr    pass  in quick on xl1 proto tcp  keep state
271985213Sdarrenr    pass  in quick on xl1 proto udp  keep state
272085213Sdarrenr    pass  in quick on xl1 proto icmp keep state
272185213Sdarrenr    block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.
272285213Sdarrenr    pass  in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
272385213Sdarrenr    pass  in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
272485213Sdarrenr    pass  in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
272585213Sdarrenr    pass  in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
272685213Sdarrenr    block in quick on xl0
272785213Sdarrenr
272885213SdarrenrNow  we  have  a  network where 20.20.20.2 is a zone serving
272985213Sdarrenrname server, 20.20.20.3 is  an  incoming  mail  server,  and
273085213Sdarrenr20.20.20.7 is a web server.
273185213Sdarrenr
273285213Sdarrenr     Bridged  IP Filter is not yet perfect, we must confess.
273385213Sdarrenr
273485213Sdarrenr     First,  You'll note that all the rules are setup  using
273585213Sdarrenrthe  in  direction  instead  of a combination of in and out.
273685213SdarrenrThis is because the out direction is presently unimplemented
273785213Sdarrenrwith  bridging in OpenBSD.  This was originally done to pre-
273885213Sdarrenrvent vast performance drops using multiple interfaces.  Work
273985213Sdarrenrhas  been  done  in  speeding it up, but it remains unimple-
274085213Sdarrenrmented.  If you really want this feature, you might try your
274185213Sdarrenrhand at working on the code or asking the OpenBSD people how
274285213Sdarrenryou can help.
274385213Sdarrenr
274485213Sdarrenr     Second, using IP Filter with bridging makes the use  of
274585213SdarrenrIPF's  NAT features inadvisable, if not downright dangerous.
274685213SdarrenrThe first problem is that it would give away that there's  a
274785213Sdarrenrfiltering  bridge.   The  second  problem  would be that the
274885213Sdarrenrbridge has no IP address to masquerade with, which will most
274985213Sdarrenrassuredly  lead  to  confusion and perhaps a kernel panic to
275085213Sdarrenrboot.  You can, of course, put an IP address on the outbound
275185213Sdarrenrinterface to make NAT work, but part of the glee of bridging
275285213Sdarrenris thus diminished.
275385213Sdarrenr
275485213Sdarrenr9.2.1.  Using Transparent Filtering to  Fix  Network  Design
275585213SdarrenrMistakes
275685213Sdarrenr
275785213Sdarrenr     Many  organizations  started  using IP well before they
275885213Sdarrenrthought a firewall or a subnet would be a  good  idea.   Now
275985213Sdarrenrthey  have class-C sized networks or larger that include all
276085213Sdarrenrtheir servers, their  workstations,  their  routers,  coffee
276185213Sdarrenrmakers,  everything.   The  horror!  Renumbering with proper
276285213Sdarrenrsubnets, trust levels, filters, and so are in both time con-
276385213Sdarrenrsuming and expensive.  The expense in hardware and man hours
276485213Sdarrenralone is enough to  make  most  organizations  unwilling  to
276585213Sdarrenrreally  solve  the  problem,  not  to  mention  the downtime
276685213Sdarrenrinvolved.  The typical problem network looks like this:
276785213Sdarrenr
276885213Sdarrenr
276985213Sdarrenr
277085213Sdarrenr
277185213Sdarrenr
277285213Sdarrenr
277385213Sdarrenr
277485213Sdarrenr
277585213Sdarrenr
277685213Sdarrenr                            -43-
277785213Sdarrenr
277885213Sdarrenr
277985213Sdarrenr    20.20.20.1   router               20.20.20.6   unix server
278085213Sdarrenr    20.20.20.2   unix server          20.20.20.7   nt workstation
278185213Sdarrenr    20.20.20.3   unix server          20.20.20.8   nt server
278285213Sdarrenr    20.20.20.4   win98 workstation    20.20.20.9   unix workstation
278385213Sdarrenr    20.20.20.5   intelligent switch   20.20.20.10  win95 workstation
278485213Sdarrenr
278585213SdarrenrOnly it's about 20 times larger and messier  and  frequently
278685213Sdarrenrundocumented.   Ideally, you'd have all the trusting servers
278785213Sdarrenrin one subnet, all the work- stations in  another,  and  the
278885213Sdarrenrnetwork  switches  in a third.  Then the router would filter
278985213Sdarrenrpackets between the subnets, giving the workstations limited
279085213Sdarrenraccess  to  the servers, nothing access to the switches, and
279185213Sdarrenronly the sysadmin's workstation access to  the  coffee  pot.
279285213SdarrenrI've never seen a class-C sized network with such coherence.
279385213SdarrenrIP Filter can help.
279485213Sdarrenr
279585213Sdarrenr     To start with, we're going to separate the router,  the
279685213Sdarrenrworkstations,  and  the  servers.  To do this we're going to
279785213Sdarrenrneed 2 hubs (or switches) which we  probably  already  have,
279885213Sdarrenrand  an  IPF  machine with 3 ethernet cards.  We're going to
279985213Sdarrenrput all the servers on one hub and all the  workstations  on
280085213Sdarrenrthe  other.   Normally  we'd  then  connect the hubs to each
280185213Sdarrenrother, then to the router.  Instead, we're going to plug the
280285213Sdarrenrrouter  into IPF's xl0 interface, the servers into IPF's xl1
280385213Sdarrenrinterface, and the workstations into  IPF's  xl2  interface.
280485213SdarrenrOur network diagram looks something like this:
280585213Sdarrenr
280685213Sdarrenr                                                 | 20.20.20.2  unix server
280785213Sdarrenr    router (20.20.20.1)              ____________| 20.20.20.3  unix server
280885213Sdarrenr     |                              /            | 20.20.20.6  unix server
280985213Sdarrenr     |                             /xl1          | 20.20.20.7  nt server
281085213Sdarrenr     ------------/xl0 IPF Bridge <
281185213Sdarrenr                                    xl2         | 20.20.20.4  win98 workstation
281285213Sdarrenr                                    ____________| 20.20.20.8  nt workstation
281385213Sdarrenr                                                 | 20.20.20.9  unix workstation
281485213Sdarrenr                                                 | 20.20.20.10 win95 workstation
281585213Sdarrenr
281685213SdarrenrWhere  once there was nothing but interconnecting wires, now
281785213Sdarrenrthere's a filtering bridge that not a single host  needs  to
281885213Sdarrenrbe  modified to take advantage of.  Presumably we've already
281985213Sdarrenrenabled bridging so the network is behaving  perfectly  nor-
282085213Sdarrenrmally.  Further, we're starting off with a ruleset much like
282185213Sdarrenrour last ruleset:
282285213Sdarrenr
282385213Sdarrenr    pass  in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
282485213Sdarrenr    pass  in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
282585213Sdarrenr    pass  in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
282685213Sdarrenr    pass  in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
282785213Sdarrenr    block in quick on xl0
282885213Sdarrenr    pass  in quick on xl1 proto tcp  keep state
282985213Sdarrenr    pass  in quick on xl1 proto udp  keep state
283085213Sdarrenr    pass  in quick on xl1 proto icmp keep state
283185213Sdarrenr    block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.
283285213Sdarrenr    pass  in quick on xl2 proto tcp  keep state
283385213Sdarrenr
283485213Sdarrenr
283585213Sdarrenr
283685213Sdarrenr
283785213Sdarrenr
283885213Sdarrenr
283985213Sdarrenr
284085213Sdarrenr
284185213Sdarrenr
284285213Sdarrenr                            -44-
284385213Sdarrenr
284485213Sdarrenr
284585213Sdarrenr    pass  in quick on xl2 proto udp  keep state
284685213Sdarrenr    pass  in quick on xl2 proto icmp keep state
284785213Sdarrenr    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
284885213Sdarrenr
284985213SdarrenrOnce again, traffic coming from the router is restricted  to
285085213SdarrenrDNS,  SMTP,  and  HTTP.   At the moment, the servers and the
285185213Sdarrenrworkstations can exchange traffic freely.  Depending on what
285285213Sdarrenrkind of organization you are, there might be something about
285385213Sdarrenrthis network dynamic you don't like.  Perhaps you don't want
285485213Sdarrenryour  workstations  getting  access  to your servers at all?
285585213SdarrenrTake the xl2 ruleset of:
285685213Sdarrenr
285785213Sdarrenr    pass  in quick on xl2 proto tcp  keep state
285885213Sdarrenr    pass  in quick on xl2 proto udp  keep state
285985213Sdarrenr    pass  in quick on xl2 proto icmp keep state
286085213Sdarrenr    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
286185213Sdarrenr
286285213SdarrenrAnd change it to:
286385213Sdarrenr
286485213Sdarrenr    block in quick on xl2 from any to 20.20.20.0/24
286585213Sdarrenr    pass  in quick on xl2 proto tcp  keep state
286685213Sdarrenr    pass  in quick on xl2 proto udp  keep state
286785213Sdarrenr    pass  in quick on xl2 proto icmp keep state
286885213Sdarrenr    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
286985213Sdarrenr
287085213SdarrenrPerhaps you want them to just get to the servers to get  and
287185213Sdarrenrsend their mail with IMAP?  Easily done:
287285213Sdarrenr
287385213Sdarrenr    pass  in quick on xl2 proto tcp from any to 20.20.20.3/32 port=25
287485213Sdarrenr    pass  in quick on xl2 proto tcp from any to 20.20.20.3/32 port=143
287585213Sdarrenr    block in quick on xl2 from any to 20.20.20.0/24
287685213Sdarrenr    pass  in quick on xl2 proto tcp  keep state
287785213Sdarrenr    pass  in quick on xl2 proto udp  keep state
287885213Sdarrenr    pass  in quick on xl2 proto icmp keep state
287985213Sdarrenr    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
288085213Sdarrenr
288185213SdarrenrNow  your  workstations  and  servers are protected from the
288285213Sdarrenroutside world, and the servers are protected from your work-
288385213Sdarrenrstations.
288485213Sdarrenr
288585213Sdarrenr     Perhaps the opposite is true, maybe you want your work-
288685213Sdarrenrstations to be able to get to the servers, but not the  out-
288785213Sdarrenrside  world.   After all, the next generation of exploits is
288885213Sdarrenrbreaking the clients, not the servers.  In this case,  you'd
288985213Sdarrenrchange the xl2 rules to look more like this:
289085213Sdarrenr
289185213Sdarrenr    pass  in quick on xl2 from any to 20.20.20.0/24
289285213Sdarrenr    block in quick on xl2
289385213Sdarrenr
289485213SdarrenrNow  the  servers  have free reign, but the clients can only
289585213Sdarrenrconnect to the servers.  We might want to  batten  down  the
289685213Sdarrenrhatches on the servers, too:
289785213Sdarrenr
289885213Sdarrenr    pass  in quick on xl1 from any to 20.20.20.0/24
289985213Sdarrenr
290085213Sdarrenr
290185213Sdarrenr
290285213Sdarrenr
290385213Sdarrenr
290485213Sdarrenr
290585213Sdarrenr
290685213Sdarrenr
290785213Sdarrenr
290885213Sdarrenr                            -45-
290985213Sdarrenr
291085213Sdarrenr
291185213Sdarrenr    block in quick on xl1
291285213Sdarrenr
291385213SdarrenrWith  the  combination of these two, the clients and servers
291485213Sdarrenrcan talk to each other, but neither can access  the  outside
291585213Sdarrenrworld  (though the outside world can get to the few services
291685213Sdarrenrfrom earlier).  The whole ruleset would look something  like
291785213Sdarrenrthis:
291885213Sdarrenr
291985213Sdarrenr    pass  in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
292085213Sdarrenr    pass  in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53                                                              flags S keep state
292185213Sdarrenr    pass  in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25                                                              flags S keep state
292285213Sdarrenr    pass  in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80                                                              flags S keep state
292385213Sdarrenr    block in quick on xl0
292485213Sdarrenr    pass  in quick on xl1 from any to 20.20.20.0/24
292585213Sdarrenr    block in quick on xl1
292685213Sdarrenr    pass  in quick on xl2 from any to 20.20.20.0/24
292785213Sdarrenr    block in quick on xl2
292885213Sdarrenr
292985213SdarrenrSo  remember,  when  your  network  is  a  mess of twisty IP
293085213Sdarrenraddresses and machine classes, transparent filtered  bridges
293185213Sdarrenrcan  solve  a problem that would otherwise be lived with and
293285213Sdarrenrperhaps someday exploited.
293385213Sdarrenr
293485213Sdarrenr9.3.  Drop-Safe Logging With dup-to and to.
293585213Sdarrenr
293685213Sdarrenr     Until now, we've been using the filter to drop packets.
293785213SdarrenrInstead  of dropping them, let's consider passing them on to
293885213Sdarrenranother system that can do something useful with this infor-
293985213Sdarrenrmation  beyond  the logging we can perform with ipmon.   Our
294085213Sdarrenrfirewall system, be it a bridge or a  router,  can  have  as
294185213Sdarrenrmany  interfaces as we can cram into the system.  We can use
294285213Sdarrenrthis information to create a "drop-safe" for our packets.  A
294385213Sdarrenrgood  example  of  a  use  for this would be to implement an
294485213Sdarrenrintrusion detection network.   For  starters,  it  might  be
294585213Sdarrenrdesirable  to  hide  the presence of our intrusion detection
294685213Sdarrenrsystems from our real network so that we can keep them  from
294785213Sdarrenrbeing detected.
294885213Sdarrenr
294985213Sdarrenr     Before we get started, there are some operational char-
295085213Sdarrenracteristics that we need to make note of.  If  we  are  only
295185213Sdarrenrgoing to deal with blocked packets, we can use either the to
295285213Sdarrenrkeyword or the fastroute keyword. (We'll cover  the  differ-
295385213Sdarrenrences  between  these two later)  If we're going to pass the
295485213Sdarrenrpackets like we normally would, we need to make  a  copy  of
295585213Sdarrenrthe packet for our drop-safe log with the dup-to keyword.
295685213Sdarrenr
295785213Sdarrenr9.3.1.  The dup-to Method
295885213Sdarrenr
295985213Sdarrenr     If, for example, we wanted to send a copy of everything
296085213Sdarrenrgoing out the xl3 interface off to our drop-safe network  on
296185213Sdarrenred0, we would use this rule in our filter list:
296285213Sdarrenr
296385213Sdarrenr     pass out on xl3 dup-to ed0 from any to any
296485213Sdarrenr
296585213Sdarrenr
296685213Sdarrenr
296785213Sdarrenr
296885213Sdarrenr
296985213Sdarrenr
297085213Sdarrenr
297185213Sdarrenr
297285213Sdarrenr
297385213Sdarrenr
297485213Sdarrenr                            -46-
297585213Sdarrenr
297685213Sdarrenr
297785213SdarrenrYou  might also have a need to send the packet directly to a
297885213Sdarrenrspecific IP address on your  drop-safe  network  instead  of
297985213Sdarrenrjust  making  a  copy of the packet out there and hoping for
298085213Sdarrenrthe best.  To do this, we modify our rule slightly:
298185213Sdarrenr
298285213Sdarrenr     pass out on xl3 dup-to ed0:192.168.254.2 from any to any
298385213Sdarrenr
298485213SdarrenrBut be  warned  that  this  method  will  alter  the  copied
298585213Sdarrenrpacket's  destination address, and may thus destroy the use-
298685213Sdarrenrfulness of the log.  For  this  reason,  we  recommend  only
298785213Sdarrenrusing  the  known  address method of logging when you can be
298885213Sdarrenrcertain that the address that you're logging to  corresponds
298985213Sdarrenrin  some  way  to  what  you're logging for (e.g.: don't use
299085213Sdarrenr"192.168.254.2" for logging for both  your  web  server  and
299185213Sdarrenryour mail server, since you'll have a hard time later trying
299285213Sdarrenrto figure out which system was the target of a specific  set
299385213Sdarrenrof packets.)
299485213Sdarrenr
299585213Sdarrenr     This  technique  can  be  used quite effectively if you
299685213Sdarrenrtreat an IP Address on your drop-safe network  in  much  the
299785213Sdarrenrsame  way that you would treat a Multicast Group on the real
299885213Sdarrenrinternet. (e.g.: "192.168.254.2" could be  the  channel  for
299985213Sdarrenryour  http  traffic  analysis system, "23.23.23.23" could be
300085213Sdarrenryour channel for telnet sessions, and so on.)     You  don't
300185213Sdarrenreven need to actually have this address set as an address or
300285213Sdarrenralias on any  of  your  analysis  systems.   Normally,  your
300385213Sdarrenripfilter  machine  would need to ARP for the new destination
300485213Sdarrenraddress (using dup-to ed0:192.168.254.2  style,  of  course)
300585213Sdarrenrbut  we  can avoid that issue by creating a static arp entry
300685213Sdarrenrfor this "channel" on our ipfilter system.
300785213Sdarrenr
300885213Sdarrenr     In general, though, dup-to ed0 is all that is  required
300985213Sdarrenrto  get  a new copy of the packet over to our drop-safe net-
301085213Sdarrenrwork for logging and examination.
301185213Sdarrenr
301285213Sdarrenr9.3.2.  The to Method
301385213Sdarrenr
301485213Sdarrenr     The dup-to method  does  have  an  immediate  drawback,
301585213Sdarrenrthough.   Since  it  has  to  make  a copy of the packet and
301685213Sdarrenroptionally modify it for its new destination, it's going  to
301785213Sdarrenrtake  a while to complete all this work and be ready to deal
301885213Sdarrenrwith the next packet coming in to the ipfilter system.
301985213Sdarrenr
302085213Sdarrenr     If we don't care about passing the packet to its normal
302185213Sdarrenrdestination  and  we  were  going to block it anyway, we can
302285213Sdarrenrjust use the to keyword to push this packet past the  normal
302385213Sdarrenrrouting  table  and force it to go out a different interface
302485213Sdarrenrthan it would normally go out.
302585213Sdarrenr
302685213Sdarrenr     block in quick on xl0 to ed0 proto tcp from any to any port < 1024
302785213Sdarrenr
302885213Sdarrenrwe use block quick for to interface  routing,  because  like
302985213Sdarrenrfastroute,  the  to  interface code will generate two packet
303085213Sdarrenrpaths through ipfilter when used with pass, and likely cause
303185213Sdarrenr
303285213Sdarrenr
303385213Sdarrenr
303485213Sdarrenr
303585213Sdarrenr
303685213Sdarrenr
303785213Sdarrenr
303885213Sdarrenr
303985213Sdarrenr
304085213Sdarrenr                            -47-
304185213Sdarrenr
304285213Sdarrenr
304385213Sdarrenryour system to panic.
304485213Sdarrenr
304585213Sdarrenr
304685213Sdarrenr
304785213Sdarrenr10.   Bogus Network Filtering, the ultimate in current anti-
304885213Sdarrenrspoofing technology.
304985213Sdarrenr
305085213Sdarrenr     We've spent a little bit of time tracking down the cur-
305185213Sdarrenrrent vast tracts of IP address space that have been reserved
305285213Sdarrenrby the IANA for various reasons, or are otherwise  not  cur-
305385213Sdarrenrrently in use at the time this document was written.   Since
305485213Sdarrenrnone of these address ranges should  be  in  use  currently,
305585213Sdarrenrthere  should  be no legitimate reason to ever see them as a
305685213Sdarrenrsource address, or to send them  traffic  as  a  destination
305785213Sdarrenraddress, right?   Right!
305885213Sdarrenr
305985213Sdarrenr     So without further ado, the complete list of bogus net-
306085213Sdarrenrworks:
306185213Sdarrenr
306285213Sdarrenr     #
306385213Sdarrenr     # s/OUTSIDE/outside-interface (eg: fxp0)
306485213Sdarrenr     # s/MYNET/network-cidr-address (eg: 1.2.3.0/24)
306585213Sdarrenr     #
306685213Sdarrenr     block in on OUTSIDE all
306785213Sdarrenr     block in quick on OUTSIDE from 0.0.0.0/7 to any
306885213Sdarrenr     block in quick on OUTSIDE from 2.0.0.0/8 to any
306985213Sdarrenr     block in quick on OUTSIDE from 5.0.0.0/8 to any
307085213Sdarrenr     block in quick on OUTSIDE from 10.0.0.0/8 to any
307185213Sdarrenr     block in quick on OUTSIDE from 23.0.0.0/8 to any
307285213Sdarrenr     block in quick on OUTSIDE from 27.0.0.0/8 to any
307385213Sdarrenr     block in quick on OUTSIDE from 31.0.0.0/8 to any
307485213Sdarrenr     block in quick on OUTSIDE from 67.0.0.0/8 to any
307585213Sdarrenr     block in quick on OUTSIDE from 68.0.0.0/6 to any
307685213Sdarrenr     block in quick on OUTSIDE from 72.0.0.0/5 to any
307785213Sdarrenr     block in quick on OUTSIDE from 80.0.0.0/4 to any
307885213Sdarrenr     block in quick on OUTSIDE from 96.0.0.0/3 to any
307985213Sdarrenr     block in quick on OUTSIDE from 127.0.0.0/8 to any
308085213Sdarrenr     block in quick on OUTSIDE from 128.0.0.0/16 to any
308185213Sdarrenr     block in quick on OUTSIDE from 128.66.0.0/16 to any
308285213Sdarrenr     block in quick on OUTSIDE from 169.254.0.0/16 to any
308385213Sdarrenr     block in quick on OUTSIDE from 172.16.0.0/12 to any
308485213Sdarrenr     block in quick on OUTSIDE from 191.255.0.0/16 to any
308585213Sdarrenr     block in quick on OUTSIDE from 192.0.0.0/16 to any
308685213Sdarrenr     block in quick on OUTSIDE from 192.168.0.0/16 to any
308785213Sdarrenr     block in quick on OUTSIDE from 197.0.0.0/8 to any
308885213Sdarrenr     block in quick on OUTSIDE from 201.0.0.0/8 to any
308985213Sdarrenr     block in quick on OUTSIDE from 204.152.64.0/23 to any
309085213Sdarrenr     block in quick on OUTSIDE from 224.0.0.0/3 to any
309185213Sdarrenr     block in quick on OUTSIDE from MYNET to any
309285213Sdarrenr     # Your pass rules come here...
309385213Sdarrenr
309485213Sdarrenr     block out on OUTSIDE all
309585213Sdarrenr     block out quick on OUTSIDE from !MYNET to any
309685213Sdarrenr     block out quick on OUTSIDE from MYNET to 0.0.0.0/7
309785213Sdarrenr
309885213Sdarrenr
309985213Sdarrenr
310085213Sdarrenr
310185213Sdarrenr
310285213Sdarrenr
310385213Sdarrenr
310485213Sdarrenr
310585213Sdarrenr
310685213Sdarrenr                            -48-
310785213Sdarrenr
310885213Sdarrenr
310985213Sdarrenr     block out quick on OUTSIDE from MYNET to 2.0.0.0/8
311085213Sdarrenr     block out quick on OUTSIDE from MYNET to 5.0.0.0/8
311185213Sdarrenr     block out quick on OUTSIDE from MYNET to 10.0.0.0/8
311285213Sdarrenr     block out quick on OUTSIDE from MYNET to 23.0.0.0/8
311385213Sdarrenr     block out quick on OUTSIDE from MYNET to 27.0.0.0/8
311485213Sdarrenr     block out quick on OUTSIDE from MYNET to 31.0.0.0/8
311585213Sdarrenr     block out quick on OUTSIDE from MYNET to 67.0.0.0/8
311685213Sdarrenr     block out quick on OUTSIDE from MYNET to 68.0.0.0/6
311785213Sdarrenr     block out quick on OUTSIDE from MYNET to 72.0.0.0/5
311885213Sdarrenr     block out quick on OUTSIDE from MYNET to 80.0.0.0/4
311985213Sdarrenr     block out quick on OUTSIDE from MYNET to 96.0.0.0/3
312085213Sdarrenr     block out quick on OUTSIDE from MYNET to 127.0.0.0/8
312185213Sdarrenr     block out quick on OUTSIDE from MYNET to 128.0.0.0/16
312285213Sdarrenr     block out quick on OUTSIDE from MYNET to 128.66.0.0/16
312385213Sdarrenr     block out quick on OUTSIDE from MYNET to 169.254.0.0/16
312485213Sdarrenr     block out quick on OUTSIDE from MYNET to 172.16.0.0/12
312585213Sdarrenr     block out quick on OUTSIDE from MYNET to 191.255.0.0/16
312685213Sdarrenr     block out quick on OUTSIDE from MYNET to 192.0.0.0/16
312785213Sdarrenr     block out quick on OUTSIDE from MYNET to 192.168.0.0/16
312885213Sdarrenr     block out quick on OUTSIDE from MYNET to 197.0.0.0/8
312985213Sdarrenr     block out quick on OUTSIDE from MYNET to 201.0.0.0/8
313085213Sdarrenr     block out quick on OUTSIDE from MYNET to 204.152.64.0/23
313185213Sdarrenr     block out quick on OUTSIDE from MYNET to 224.0.0.0/3
313285213Sdarrenr     # Your pass rules come here...
313385213Sdarrenr
313485213SdarrenrIf you're going to use these, we  suggest  that  you  become
313585213Sdarrenrfamiliar  with  whois.arin.net and keep an occasional eye on
313685213Sdarrenrthese, as the IANA isn't going to notify you when they allo-
313785213Sdarrenrcate  one  of  these to a new corporation or something.  You
313885213Sdarrenrhave been warned.
313985213Sdarrenr
314085213Sdarrenr     We'd also like to thank  Frank  DiGennaro  <fsd@server-
314185213Sdarrenrvault.com> for greatly contributing to this filter list.
314285213Sdarrenr
314385213Sdarrenr
314485213Sdarrenr
314585213Sdarrenr
314685213Sdarrenr
314785213Sdarrenr
314885213Sdarrenr
314985213Sdarrenr
315085213Sdarrenr
315185213Sdarrenr
315285213Sdarrenr
315385213Sdarrenr
315485213Sdarrenr
315585213Sdarrenr
315685213Sdarrenr
315785213Sdarrenr
315885213Sdarrenr
315985213Sdarrenr
316085213Sdarrenr
316185213Sdarrenr
316285213Sdarrenr
316385213Sdarrenr
316485213Sdarrenr
316585213Sdarrenr
316685213Sdarrenr
316785213Sdarrenr
316885213Sdarrenr
3169