1
2
3
4
5
6
7              IP Filter Based Firewalls HOWTO
8
9              Brendan Conoboy <synk@swcp.com>
10            Erik Fichtner <emf@obfuscation.org>
11
12                Fri Apr 20 09:31:14 EDT 2001
13
14
15
16
17
18
19     Abstract:  This document is intended to introduce a new
20     user to the IP Filter firewalling package and,  at  the
21     same  time,  teach  the user some basic fundamentals of
22     good firewall design.
23
24
25
26
27
28
29
30
31
32
33
34
351.  Introduction
36
37     IP Filter is a great little firewall package.  It  does
38just   about   everything  other  free  firewalls  (ipfwadm,
39ipchains, ipfw) do, but it's also  portable  and  does  neat
40stuff  the  others don't.  This document is intended to make
41some cohesive sense of the  sparse  documentation  presently
42available  for ipfilter.  Some prior familiarity with packet
43filtering will be useful, however too much  familiarity  may
44make this document a waste of your time.  For greater under-
45standing of firewalls, the authors recommend reading  Build-
46ing Internet Firewalls, Chapman & Zwicky, O'Reilly and Asso-
47ciates; and TCP/IP Illustrated, Volume 1, Stevens,  Addison-
48Wesley.
49
50
51
52
53
541.1.  Disclaimer
55
56     The  authors  of  this document are not responsible for
57any damages incurred due to actions taken based on this doc-
58ument. This document is meant as an introduction to building
59a  firewall  based  on  IP-Filter.   If  you  do  not   feel
60
61
62
63
64
65
66
67
68
69                             -2-
70
71
72comfortable  taking responsibility for your own actions, you
73should stop reading this document and hire a qualified secu-
74rity professional to install your firewall for you.
75
76
771.2.  Copyright
78
79     Unless  otherwise  stated,  HOWTO  documents  are copy-
80righted by their respective authors. HOWTO documents may  be
81reproduced  and  distributed  in  whole  or  in part, in any
82medium physical or electronic, as  long  as  this  copyright
83notice  is retained on all copies. Commercial redistribution
84is allowed and encouraged; however, the authors  would  like
85to be notified of any such distributions.
86
87     All  translations, derivative works, or aggregate works
88incorporating any HOWTO documents must be covered under this
89copyright notice.  That is, you may not produce a derivative
90work from a HOWTO and impose additional restrictions on  its
91distribution. Exceptions to these rules may be granted under
92certain conditions; please contact the HOWTO coordinator.
93
94     In short, we wish  to  promote  dissemination  of  this
95information  through  as many channels as possible. However,
96we do wish to retain copyright on the HOWTO  documents,  and
97would  like  to be notified of any plans to redistribute the
98HOWTOs.
99
100
1011.3.  Where to obtain the important pieces
102
103     The     official     IPF      homepage      is      at:
104<http://coombs.anu.edu.au/~avalon/ip-filter.html>
105
106     The  most  up-to-date  version  of this document can be
107found at: <http://www.obfuscation.org/ipf/>
108
109
110
111
1122.  Basic Firewalling
113
114     This section is designed to familiarize you with ipfil-
115ter's  syntax, and firewall theory in general.  The features
116discussed here are features you'll find in any good firewall
117package.   This  section  will give you a good foundation to
118make reading and understanding  the  advanced  section  very
119easy.   It must be emphasized that this section alone is not
120enough to build a good firewall, and that the advanced  sec-
121tion  really  is  required  reading for anybody who wants to
122build an effective security system.
123
124
125
126
127
128
129
130
131
132
133
134
135                             -3-
136
137
1382.1.  Config File Dynamics, Order and Precedence
139
140     IPF (IP Filter) has a config file (as opposed  to  say,
141running  some  command  again  and again for each new rule).
142The config file drips with Unix:  There's one rule per line,
143the  "#" mark denotes a comment, and you can have a rule and
144a comment  on  the  same  line.   Extraneous  whitespace  is
145allowed, and is encouraged to keep the rules readable.
146
147
1482.2.  Basic Rule Processing
149
150     The  rules  are  processed from top to bottom, each one
151appended after another.  This quite simply means that if the
152entirety of your config file is:
153
154    block in all
155    pass  in all
156
157The computer sees it as:
158
159    block in all
160    pass  in all
161
162Which is to say that when a packet comes in, the first thing
163IPF applies is:
164
165    block in all
166
167Should IPF deem it necessary to move on to the next rule, it
168would then apply the second rule:
169
170    pass  in all
171
172     At  this  point,  you might want to ask yourself "would
173IPF move on to the second rule?"  If  you're  familiar  with
174ipfwadm  or  ipfw,  you  probably  won't  ask yourself this.
175Shortly after, you will become bewildered at the  weird  way
176packets  are  always  getting  denied  or  passed  when they
177shouldn't.  Many packet filters stop  comparing  packets  to
178rulesets  the moment the first match is made; IPF is not one
179of them.
180
181     Unlike the other packet filters, IPF keeps  a  flag  on
182whether  or  not  it's going to pass the packet.  Unless you
183interrupt the flow, IPF will go through the entire  ruleset,
184making  its  decision  on whether or not to pass or drop the
185packet based on the last matching rule.  The scene: IP  Fil-
186ter's  on  duty.   It's  been  been scheduled a slice of CPU
187time.  It has a checkpoint clipboard that reads:
188
189    block in all
190    pass  in all
191
192
193
194
195
196
197
198
199
200
201                             -4-
202
203
204A packet comes in the interface and it's time to go to work.
205It  takes a look at the packet, it takes a look at the first
206rule:
207
208    block in all
209
210"So far I think I will block  this  packet"  says  IPF.   It
211takes a look at the second rule:
212
213    pass  in all
214
215"So far I think I will pass this packet" says IPF.  It takes
216a look at a third rule.  There is no third rule, so it  goes
217with  what  its  last  motivation  was,  to  pass the packet
218onward.
219
220It's a good time to point out that even if the  ruleset  had
221been
222
223    block in all
224    block in all
225    block in all
226    block in all
227    pass  in all
228
229that  the packet would still have gone through.  There is no
230cumulative effect.  The  last  matching  rule  always  takes
231precedence.
232
2332.3.  Controlling Rule Processing
234
235     If  you  have experience with other packet filters, you
236may find this layout to be confusing, and you may be  specu-
237lating  that  there are problems with portability with other
238filters and speed of rule matching.  Imagine if you had  100
239rules  and  most  of  the applicable ones were the first 10.
240There would be a terrible overhead for every  packet  coming
241in  to  go through 100 rules every time.  Fortunately, there
242is a simple keyword you can add to any rule  that  makes  it
243take action at that match.  That keyword is quick.
244
245Here's  a  modified  copy  of the original ruleset using the
246quick keyword:
247
248    block in quick all
249    pass  in       all
250
251In this case, IPF looks at the first rule:
252
253    block in quick all
254
255The packet matches and the search is over.   The  packet  is
256expunged  without a peep.  There are no notices, no logs, no
257memorial service.  Cake will not be served.  So  what  about
258
259
260
261
262
263
264
265
266
267                             -5-
268
269
270the next rule?
271
272    pass  in       all
273
274     This  rule is never encountered.  It could just as eas-
275ily not be in the config file at all.  The sweeping match of
276all  and  the  terminal keyword quick from the previous rule
277make certain that no rules are followed afterward.
278
279     Having half a config file laid to  waste  is  rarely  a
280desirable  state.   On  the other hand, IPF is here to block
281packets and as configured,  it's  doing  a  very  good  job.
282Nonetheless,  IPF  is also here to let some packets through,
283so a change to the ruleset to make this possible  is  called
284for.
285
2862.4.  Basic filtering by IP address
287
288     IPF  will match packets on many criteria.  The one that
289we most commonly think of is the IP address.  There are some
290blocks of address space from which we should never get traf-
291fic.  One such  block  is  from   the  unroutable  networks,
292192.168.0.0/16 (/16 is the CIDR notation for a netmask.  You
293may  be  more  familiar  with  the  dotted  decimal  format,
294255.255.0.0.   IPF  accepts  both).   If you wanted to block
295192.168.0.0/16, this is one way to do it:
296
297    block in quick from 192.168.0.0/16 to any
298    pass  in       all
299
300Now we have a less  stringent  ruleset  that  actually  does
301something  for  us.   Let's  imagine  a packet comes in from
3021.2.3.4.  The first rule is applied:
303
304    block in quick from 192.168.0.0/16 to any
305
306The packet is from 1.2.3.4, not 192.168.*.*, so there is  no
307match.  The second rule is applied:
308
309    pass  in       all
310
311The  packet from 1.2.3.4 is definitely a part of all, so the
312packet is sent to whatever it's destination happened to  be.
313
314     On  the other hand, suppose we have a packet that comes
315in from 192.168.1.2.  The first rule is applied:
316
317    block in quick from 192.168.0.0/16 to any
318
319There's a match, the packet is dropped, and that's the  end.
320Again,  it doesn't move to the second rule because the first
321rule matches and contains the quick keyword.
322
323
324
325
326
327
328
329
330
331
332
333                             -6-
334
335
336     At this point you can build a fairly extensive  set  of
337definitive  addresses  which  are  passed or blocked.  Since
338we've already started blocking private  address  space  from
339entering our firewall, let's take care of the rest of it:
340
341    block in quick from 192.168.0.0/16 to any
342    block in quick from 172.16.0.0/12 to any
343    block in quick from 10.0.0.0/8 to any
344    pass  in       all
345
346The  first  three  address blocks are some of the private IP
347space.
348
3492.5.  Controlling Your Interfaces
350
351     It  seems  very  frequent  that companies have internal
352networks before they want a link to the outside  world.   In
353fact, it's probably reasonable to say that's the main reason
354people consider firewalls in the first place.   The  machine
355that  bridges the outside world to the inside world and vice
356versa is the router.  What separates  the  router  from  any
357other machine is simple: It has more than one interface.
358
359     Every  packet  you  receive comes from a network inter-
360face; every packet you transmit goes out  a  network  inter-
361face.   Say  your  machine has 3 interfaces, lo0 (loopback),
362xl0 (3com ethernet),  and  tun0  (FreeBSD's  generic  tunnel
363interface  that PPP uses), but you don't want packets coming
364in on the tun0 interface?
365
366    block in quick on tun0 all
367    pass  in               all
368
369In this case, the on keyword means that the data is  coming
370in  on  the  named interface.  If a packet comes in on tun0,
371the first rule will block it.  If a packet comes in  on  lo0
372or in on xl0, the first rule will not match, the second rule
373will, the packet will be passed.
374
3752.6.  Using IP Address and Interface Together
376
377     It's an odd state of affairs when one decides  it  best
378to  have the tun0 interface up, but not allow any data to be
379received from it.  The more criteria  the  firewall  matches
380against,  the  tighter  (or looser) the firewall can become.
381Maybe you want data from tun0, but not from  192.168.0.0/16?
382This is the start of a powerful firewall.
383
384    block in quick on tun0 from 192.168.0.0/16 to any
385-----------
386            See             rfc1918             at
387<http://www.faqs.org/rfcs/rfc1918.html>        and
388<http://www.ietf.org/internet-drafts/draft-man-
389ning-dsua-06.txt>
390
391
392
393
394
395
396
397
398
399                             -7-
400
401
402    pass  in       all
403
404Compare this to our previous rule:
405
406    block in quick from 192.168.0.0/16 to any
407    pass  in       all
408
409The  old way, all traffic from 192.168.0.0/16, regardless of
410interface, was completely blocked.  The new  way,  using  on
411tun0 means that it's only blocked if it comes in on the tun0
412interface.  If a packet arrived on the  xl0  interface  from
413192.168.0.0/16, it would be passed.
414
415     At  this  point you can build a fairly extensive set of
416definitive addresses which are  passed  or  blocked.   Since
417we've  already  started  blocking private address space from
418entering tun0, let's take care of the rest of it:
419
420    block in quick on tun0 from 192.168.0.0/16 to any
421    block in quick on tun0 from 172.16.0.0/12 to any
422    block in quick on tun0 from 10.0.0.0/8 to any
423    block in quick on tun0 from 127.0.0.0/8 to any
424    block in quick on tun0 from 0.0.0.0/8 to any
425    block in quick on tun0 from 169.254.0.0/16 to any
426    block in quick on tun0 from 192.0.2.0/24 to any
427    block in quick on tun0 from 204.152.64.0/23 to any
428    block in quick on tun0 from 224.0.0.0/3 to any
429    pass  in       all
430
431You've already seen the first  three  blocks,  but  not  the
432rest.   The  fourth is a largely wasted class-A network used
433for loopback.  Much software  communicates  with  itself  on
434127.0.0.1  so  blocking it from an external source is a good
435idea.  The fifth, 0.0.0.0/8, should never  be  seen  on  the
436internet.   Most IP stacks treat "0.0.0.0/32" as the default
437gateway, and the rest of the 0.*.*.*  network  gets  handled
438strangely  by  various systems as a byproduct of how routing
439decisions are made.   You should treat 0.0.0.0/8  just  like
440127.0.0.0/8.    169.254.0.0/16 has been assigned by the IANA
441for use in auto-configuration when systems have not yet been
442able  to  obtain  an  IP address via DHCP or the like.  Most
443notably, Microsoft Windows will use addresses in this  range
444if  they  are  set  to  DHCP  and cannot find a DHCP server.
445192.0.2.0/24 has also been reserved for use as an example IP
446netblock  for documentation authors.  We specifically do not
447use this range as it would cause confusion when we tell  you
448to   block   it,   and  thus  all  our  examples  come  from
44920.20.20.0/24.  204.152.64.0/23 is an odd netblock  reserved
450by  Sun  Microsystems for private cluster interconnects, and
451blocking  this  is  up  to  your  own  judgement.    Lastly,
452224.0.0.0/3  wipes out the "Class D and E" networks which is
453used mostly for multicast traffic, although further  defini-
454tion of "Class E" space can be found in RFC 1166.
455
456
457
458
459
460
461
462
463
464
465                             -8-
466
467
468     There's  a very important principle in packet filtering
469which has only been alluded  to  with  the  private  network
470blocking  and  that  is  this: When you know there's certain
471types of data that only comes from certain places, you setup
472the  system  to  only  allow  that  kind  of data from those
473places.  In the case of the unroutable addresses,  you  know
474that  nothing  from  10.0.0.0/8  should  be arriving on tun0
475because you have no way to reply to it.  It's  an  illegiti-
476mate  packet.   The  same  goes for the other unroutables as
477well as 127.0.0.0/8.
478
479     Many pieces of software  do  all  their  authentication
480based  upon  the  packet's originating IP address.  When you
481have an internal network, say 20.20.20.0/24, you  know  that
482the  only traffic for that internal network is going to come
483off the local ethernet.  Should a packet from  20.20.20.0/24
484arrive  over a PPP dialup, it's perfectly reasonable to drop
485it on the floor, or put it in a dark room for interrogation.
486It  should by no means be allowed to get to its final desti-
487nation.  You can accomplish this  particularly  easily  with
488what you already know of IPF.  The new ruleset would be:
489
490    block in quick on tun0 from 192.168.0.0/16 to any
491    block in quick on tun0 from 172.16.0.0/12 to any
492    block in quick on tun0 from 10.0.0.0/8 to any
493    block in quick on tun0 from 127.0.0.0/8 to any
494    block in quick on tun0 from 0.0.0.0/8 to any
495    block in quick on tun0 from 169.254.0.0/16 to any
496    block in quick on tun0 from 192.0.2.0/24 to any
497    block in quick on tun0 from 204.152.64.0/23 to any
498    block in quick on tun0 from 224.0.0.0/3 to any
499    block in quick on tun0 from 20.20.20.0/24 to any
500    pass  in       all
501
5022.7.  Bi-Directional Filtering; The "out" Keyword
503
504     Up  until  now,  we've been passing or blocking inbound
505traffic.  To clarify, inbound traffic is  all  traffic  that
506enters  the firewall on any interface.  Conversely, outbound
507traffic is all traffic that leaves on any interface (whether
508locally  generated  or  simply passing through).  This means
509that all packets coming in are not  only  filtered  as  they
510enter  the  firewall,  they're  also  filtered as they exit.
511Thusfar there's been an implied pass out all that may or may
512not  be  desirable.  Just as you may pass and block incoming
513traffic, you may do the same with outgoing traffic.
514
515     Now that we know there's a way to filter outbound pack-
516ets  just  like inbound, it's up to us to find a conceivable
517use for such a thing.  One possible use of this idea  is  to
518keep spoofed packets from exiting your own network.  Instead
519of passing any traffic out the  router,  you  could  instead
520limit   permitted   traffic   to   packets   originating  at
521
522
523
524
525
526
527
528
529
530
531                             -9-
532
533
53420.20.20.0/24.  You might do it like this:
535
536    pass  out quick on tun0 from 20.20.20.0/24 to any
537    block out quick on tun0 from any to any
538
539If a packet comes from 20.20.20.1/32, it gets  sent  out  by
540the  first  rule.  If a packet comes from 1.2.3.4/32 it gets
541blocked by the second.
542
543     You can also make  similar  rules  for  the  unroutable
544addresses.   If some machine tries to route a packet through
545IPF with a destination in 192.168.0.0/16, why not  drop  it?
546The worst that can happen is that you'll spare yourself some
547bandwidth:
548
549    block out quick on tun0 from any to 192.168.0.0/16
550    block out quick on tun0 from any to 172.16.0.0/12
551    block out quick on tun0 from any to 10.0.0.0/8
552    block out quick on tun0 from any to 0.0.0.0/8
553    block out quick on tun0 from any to 127.0.0.0/8
554    block out quick on tun0 from any to 169.254.0.0/16
555    block out quick on tun0 from any to 192.0.2.0/24
556    block out quick on tun0 from any to 204.152.64.0/23
557    block out quick on tun0 from any to 224.0.0.0/3
558    block out quick on tun0 from !20.20.20.0/24 to any
559
560In the narrowest viewpoint, this doesn't enhance your  secu-
561rity.   It  enhances everybody else's security, and that's a
562nice thing to do.  As another viewpoint, one  might  suppose
563that because nobody can send spoofed packets from your site,
564that your site has less value as a relay for  crackers,  and
565as such is less of a target.
566
567     You'll  likely  find a number of uses for blocking out-
568bound packets.  One thing to always keep in mind is that  in
569and  out directions are in reference to your firewall, never
570any other machine.
571
5722.8.  Logging What Happens; The "log" Keyword
573
574     Up to this point, all blocked and passed  packets  have
575been silently blocked and silently passed.  Usually you want
576to know if you're being attacked rather than wonder if  that
577firewall  is  really buying you any added benefits.  While I
578wouldn't want to log every passed packet, and in some  cases
579every blocked packet, I would want to know about the blocked
580packets from 20.20.20.0/24.  To do this, we add the log key-
581word:
582
583    block in     quick on tun0 from 192.168.0.0/16 to any
584-----------
585 This can, of course, be changed by using -DIPFIL-
586TER_DEFAULT_BLOCK  when compiling ipfilter on your
587system.
588
589
590
591
592
593
594
595
596
597                            -10-
598
599
600    block in     quick on tun0 from 172.16.0.0/12 to any
601    block in     quick on tun0 from 10.0.0.0/8 to any
602    block in     quick on tun0 from 127.0.0.0/8 to any
603    block in     quick on tun0 from 0.0.0.0/8 to any
604    block in     quick on tun0 from 169.254.0.0/16 to any
605    block in     quick on tun0 from 192.0.2.0/24 to any
606    block in     quick on tun0 from 204.152.64.0/23 to any
607    block in     quick on tun0 from 224.0.0.0/3 to any
608    block in log quick on tun0 from 20.20.20.0/24 to any
609    pass  in       all
610
611So far, our firewall is pretty good at blocking packets com-
612ing to it from suspect places, but there's still more to  be
613done.   For one thing, we're accepting packets destined any-
614where.  One thing we ought to do is  make  sure  packets  to
61520.20.20.0/32  and 20.20.20.255/32 get dropped on the floor.
616To do otherwise opens  the  internal  network  for  a  smurf
617attack.  These two lines would prevent our hypothetical net-
618work from being used as a smurf relay:
619
620    block in log quick on tun0 from any to 20.20.20.0/32
621    block in log quick on tun0 from any to 20.20.20.255/32
622
623This brings our total ruleset to look something like this:
624
625    block in     quick on tun0 from 192.168.0.0/16 to any
626    block in     quick on tun0 from 172.16.0.0/12 to any
627    block in     quick on tun0 from 10.0.0.0/8 to any
628    block in     quick on tun0 from 127.0.0.0/8 to any
629    block in     quick on tun0 from 0.0.0.0/8 to any
630    block in     quick on tun0 from 169.254.0.0/16 to any
631    block in     quick on tun0 from 192.0.2.0/24 to any
632    block in     quick on tun0 from 204.152.64.0/23 to any
633    block in     quick on tun0 from 224.0.0.0/3 to any
634    block in log quick on tun0 from 20.20.20.0/24 to any
635    block in log quick on tun0 from any to 20.20.20.0/32
636    block in log quick on tun0 from any to 20.20.20.255/32
637    pass  in       all
638
6392.9.  Complete Bi-Directional Filtering By Interface
640
641     So far we have only presented fragments of  a  complete
642ruleset.   When  you're  actually creating your ruleset, you
643should setup rules for every direction and every  interface.
644The  default state of ipfilter is to pass packets.  It is as
645though there were an invisible rule at the  beginning  which
646states  pass  in  all and pass out all.  Rather than rely on
647some default behaviour, make everything as specific as  pos-
648sible,  interface by interface, until every base is covered.
649
650     First we'll start with the lo0 interface,  which  wants
651to  run  wild and free.  Since these are programs talking to
652others on the local system,  go  ahead  and  keep  it  unre-
653stricted:
654
655
656
657
658
659
660
661
662
663                            -11-
664
665
666    pass out quick on lo0
667    pass in  quick on lo0
668
669Next, there's the xl0 interface.  Later on we'll begin plac-
670ing restrictions on the xl0 interface, but  to  start  with,
671we'll  act  as  though  everything  on  our local network is
672trustworthy and give it much the same treatment as lo0:
673
674    pass out quick on xl0
675    pass in  quick on xl0
676
677Finally, there's the tun0 interface, which we've been  half-
678filtering with up until now:
679
680    block out quick on tun0 from any to 192.168.0.0/16
681    block out quick on tun0 from any to 172.16.0.0/12
682    block out quick on tun0 from any to 127.0.0.0/8
683    block out quick on tun0 from any to 10.0.0.0/8
684    block out quick on tun0 from any to 0.0.0.0/8
685    block out quick on tun0 from any to 169.254.0.0/16
686    block out quick on tun0 from any to 192.0.2.0/24
687    block out quick on tun0 from any to 204.152.64.0/23
688    block out quick on tun0 from any to 224.0.0.0/3
689    pass  out quick on tun0 from 20.20.20.0/24 to any
690    block out quick on tun0 from any to any
691
692    block in     quick on tun0 from 192.168.0.0/16 to any
693    block in     quick on tun0 from 172.16.0.0/12 to any
694    block in     quick on tun0 from 10.0.0.0/8 to any
695    block in     quick on tun0 from 127.0.0.0/8 to any
696    block in     quick on tun0 from 0.0.0.0/8 to any
697    block in     quick on tun0 from 169.254.0.0/16 to any
698    block in     quick on tun0 from 192.0.2.0/24 to any
699    block in     quick on tun0 from 204.152.64.0/23 to any
700    block in     quick on tun0 from 224.0.0.0/3 to any
701    block in log quick on tun0 from 20.20.20.0/24 to any
702    block in log quick on tun0 from any to 20.20.20.0/32
703    block in log quick on tun0 from any to 20.20.20.255/32
704    pass  in     all
705
706This  is  a  pretty significant amount of filtering already,
707protecting 20.20.20.0/24 from being spoofed  or  being  used
708for  spoofing.   Future  examples will continue to show one-
709sideness, but keep in mind that it's for brevity's sake, and
710when  setting  up  your  own ruleset, adding rules for every
711direction and every interface is necessary.
712
713
7142.10.  Controlling Specific Protocols; The "proto" Keyword
715
716     Denial of Service attacks  are  as  rampant  as  buffer
717overflow  exploits.   Many denial of service attacks rely on
718glitches in the OS's TCP/IP  stack.   Frequently,  this  has
719come  in  the  form  of  ICMP  packets.   Why not block them
720
721
722
723
724
725
726
727
728
729                            -12-
730
731
732entirely?
733
734    block in log quick on tun0 proto icmp from any to any
735
736Now any ICMP traffic coming in from tun0 will be logged  and
737discarded.
738
7392.11.   Filtering ICMP with the "icmp-type" Keyword; Merging
740Rulesets
741
742     Of course, dropping all ICMP isn't really an ideal sit-
743uation.   Why  not drop all ICMP?  Well, because it's useful
744to have partially enabled.  So maybe you want to  keep  some
745types  of  ICMP  traffic  and drop other kinds.  If you want
746ping and traceroute to work, you need to let in ICMP types 0
747and  11.   Strictly speaking, this might not be a good idea,
748but if you need to weigh security against  convenience,  IPF
749lets you do it.
750
751    pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
752    pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
753
754Remember that ruleset order is important.  Since we're doing
755everything quick we must have our passes before our  blocks,
756so we really want the last three rules in this order:
757
758    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
759    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
760    block in log quick on tun0 proto icmp from any to any
761
762Adding  these  3  rules  to the anti-spoofing rules is a bit
763tricky.  One error might be to put the new ICMP rules at the
764beginning:
765
766    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
767    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
768    block in log quick on tun0 proto icmp from any to any
769    block in     quick on tun0 from 192.168.0.0/16 to any
770    block in     quick on tun0 from 172.16.0.0/12 to any
771    block in     quick on tun0 from 10.0.0.0/8 to any
772    block in     quick on tun0 from 127.0.0.0/8 to any
773    block in     quick on tun0 from 0.0.0.0/8 to any
774    block in     quick on tun0 from 169.254.0.0/16 to any
775    block in     quick on tun0 from 192.0.2.0/24 to any
776    block in     quick on tun0 from 204.152.64.0/23 to any
777    block in     quick on tun0 from 224.0.0.0/3 to any
778    block in log quick on tun0 from 20.20.20.0/24 to any
779    block in log quick on tun0 from any to 20.20.20.0/32
780    block in log quick on tun0 from any to 20.20.20.255/32
781    pass  in       all
782
783The  problem  with  this  is that an ICMP type 0 packet from
784192.168.0.0/16 will get passed by the first rule, and  never
785blocked  by the fourth rule.  Also, since we quickly pass an
786
787
788
789
790
791
792
793
794
795                            -13-
796
797
798ICMP ECHO_REPLY (type 0) to 20.20.20.0/24, we've just opened
799ourselves  back  up  to  a  nasty smurf attack and nullified
800those last two block rules.  Oops.  To avoid this, we  place
801the ICMP rules after the anti-spoofing rules:
802
803    block in     quick on tun0 from 192.168.0.0/16 to any
804    block in     quick on tun0 from 172.16.0.0/12 to any
805    block in     quick on tun0 from 10.0.0.0/8 to any
806    block in     quick on tun0 from 127.0.0.0/8 to any
807    block in     quick on tun0 from 0.0.0.0/8 to any
808    block in     quick on tun0 from 169.254.0.0/16 to any
809    block in     quick on tun0 from 192.0.2.0/24 to any
810    block in     quick on tun0 from 204.152.64.0/23 to any
811    block in     quick on tun0 from 224.0.0.0/3 to any
812    block in log quick on tun0 from 20.20.20.0/24 to any
813    block in log quick on tun0 from any to 20.20.20.0/32
814    block in log quick on tun0 from any to 20.20.20.255/32
815    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
816    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
817    block in log quick on tun0 proto icmp from any to any
818    pass  in       all
819
820Because  we  block spoofed traffic before the ICMP rules are
821processed, a spoofed packet never makes it to the ICMP rule-
822set.   It's  very  important to keep such situations in mind
823when merging rules.
824
8252.12.  TCP and UDP Ports; The "port" Keyword
826
827     Now that we've started blocking packets based on proto-
828col, we can start blocking packets based on specific aspects
829of each protocol.  The most frequently used of these aspects
830is  the port number.  Services such as rsh, rlogin, and tel-
831net are all very convenient  to  have,  but  also  hideously
832insecure  against  network sniffing and spoofing.  One great
833compromise is to only allow the services to run  internally,
834then  block  them  externally.   This  is easy to do because
835rlogin, rsh, and telnet use specific TCP  ports  (513,  514,
836and 23 respectively).  As such, creating rules to block them
837is easy:
838
839    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
840    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
841    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
842
843Make sure all 3 are before the pass in all  and  they'll  be
844closed  off  from  the  outside  (leaving  out  spoofing for
845brevity's sake):
846
847    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
848    pass  in     quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
849    block in log quick on tun0 proto icmp from any to any
850    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
851    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
852
853
854
855
856
857
858
859
860
861                            -14-
862
863
864    block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
865    pass  in     all
866
867You might also want to block 514/udp  (syslog),   111/tcp  &
868111/udp  (portmap),  515/tcp  (lpd),  2049/tcp  and 2049/udp
869(NFS), 6000/tcp (X11) and so on and so forth.  You can get a
870complete  listing  of  the  ports being listened to by using
871netstat -a (or lsof -i, if you have it installed).
872
873     Blocking UDP instead of  TCP  only  requires  replacing
874proto tcp with proto udp.  The rule for syslog would be:
875
876    block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 514
877
878IPF  also  has  a shorthand way to write rules that apply to
879both proto tcp and proto udp  at  the  same  time,  such  as
880portmap or NFS.  The rule for portmap would be:
881
882    block in log quick on tun0 proto tcp/udp from any to 20.20.20.0/24 port = 111
883
884
885
886
8873.  Advanced Firewalling Introduction
888
889     This  section  is  designed as an immediate followup to
890the basic section.  Contained below are  both  concepts  for
891advanced  firewall  design,  and advanced features contained
892only within ipfilter.  Once you are  comfortable  with  this
893section, you should be able to build a very strong firewall.
894
8953.1.  Rampant Paranoia; or The Default-Deny Stance
896
897     There's a big problem with  blocking  services  by  the
898port:  sometimes they move.  RPC based programs are terrible
899about this, lockd, statd, even  nfsd  listens  places  other
900than  2049.  It's awfully hard to predict, and even worse to
901automate adjusting all the time.  What if you  miss  a  ser-
902vice?   Instead of dealing with all that hassle, let's start
903over with a clean slate.  The  current  ruleset  looks  like
904this:
905
906
907
908
909     Yes, we really are starting over.  The first rule we're
910going to use is this:
911
912    block in all
913
914No network traffic gets through. None. Not a  peep.   You're
915rather  secure  with  this  setup.  Not terribly useful, but
916quite secure.  The great thing is that it doesn't take  much
917more  to make your box rather secure, yet useful too.  Let's
918
919
920
921
922
923
924
925
926
927                            -15-
928
929
930say the machine this is running on is a web server,  nothing
931more,  nothing  less.   It  doesn't even do DNS lookups.  It
932just wants to take connections on 80/tcp and that's it.   We
933can  do  that.   We  can do that with a second rule, and you
934already know how:
935
936    block in       on tun0 all
937    pass  in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80
938
939This machine will pass in port 80  traffic  for  20.20.20.1,
940and  deny  everything  else.  For basic firewalling, this is
941all one needs.
942
9433.2.  Implicit Allow; The "keep state" Rule
944
945     The job of your firewall is to prevent unwanted traffic
946getting  to  point  B  from  point A.  We have general rules
947which say "as long as this packet is to port 23, it's okay."
948We  have general rules which say "as long as this packet has
949its FIN flag set, it's okay."  Our firewalls don't know  the
950beginning, middle, or end of any TCP/UDP/ICMP session.  They
951merely have vague rules that are  applied  to  all  packets.
952We're  left  to  hope  that the packet with its FIN flag set
953isn't really a FIN scan, mapping our services.  We hope that
954the  packet to port 23 isn't an attempted hijack of our tel-
955net session.  What if there was a way to identify and autho-
956rize  individual  TCP/UDP/ICMP sessions and distinguish them
957from port scanners and DoS attacks?  There is  a  way,  it's
958called keeping state.
959
960     We  want convenience and security in one.  Lots of peo-
961ple do, that's why Ciscos have an "established" clause  that
962lets  established  tcp sessions go through.  Ipfw has estab-
963lished.  Ipfwadm has setup/established.  They all have  this
964feature, but the name is very misleading.  When we first saw
965it, we thought it meant our packet filter was keeping  track
966of  what  was  going  on,  that  it knew if a connection was
967really established or not.  The fact is, they're all  taking
968the  packet's  word for it from a part of the packet anybody
969can lie about.  They read the TCP packet's flags section and
970there's the reason UDP/ICMP don't work with it, they have no
971such thing.  Anybody who can  create  a  packet  with  bogus
972flags can get by a firewall with this setup.
973
974     Where  does  IPF  come in to play here, you ask?  Well,
975unlike the other firewalls, IPF really  can  keep  track  of
976whether or not a connection is established.  And it'll do it
977with TCP, UDP and ICMP, not just TCP.  Ipf calls it  keeping
978state.  The keyword for the ruleset is keep state.
979
980     Up until now, we've told you that packets come in, then
981the ruleset gets checked; packets go out, then  the  ruleset
982gets  checked.   Actually,  what happens is packets come in,
983the state table  gets  checked,  then  *maybe*  the  inbound
984
985
986
987
988
989
990
991
992
993                            -16-
994
995
996ruleset  gets  checked; packets go out, the state table gets
997checked, then *maybe* the  outbound  ruleset  gets  checked.
998The  state table is a list of TCP/UDP/ICMP sessions that are
999unquestionadely passed through the  firewall,  circumventing
1000the  entire  ruleset.   Sound  like a serious security hole?
1001Hang on, it's the best thing  that  ever  happened  to  your
1002firewall.
1003
1004     All  TCP/IP sessions have a start, a middle, and an end
1005(even though they're sometimes all in the same packet).  You
1006can't have an end without a middle and you can't have a mid-
1007dle without a start.  This means that all you really need to
1008filter  on  is  the beginning of a TCP/UDP/ICMP session.  If
1009the beginning of the session is  allowed  by  your  firewall
1010rules,  you really want the middle and end to be allowed too
1011(lest your IP stack should overflow and your machines become
1012useless).  Keeping state allows you to ignore the middle and
1013end and simply focus on blocking/passing new  sessions.   If
1014the  new  session is passed, all its subsequent packets will
1015be allowed through.  If it's blocked, none of its subsequent
1016packets will be allowed through.  Here's an example for run-
1017ning an ssh server (and nothing but an ssh server):
1018
1019    block out quick on tun0 all
1020    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep state
1021
1022The first thing you might notice is that  there's  no  "pass
1023out"  provision.   In  fact,  there's  only an all-inclusive
1024"block out" rule.  Despite this, the  ruleset  is  complete.
1025This is because by keeping state, the entire ruleset is cir-
1026cumvented.  Once the first SYN packet hits the  ssh  server,
1027state  is  created  and  the remainder of the ssh session is
1028allowed to take place without interference  from  the  fire-
1029wall.  Here's another example:
1030
1031    block in  quick on tun0 all
1032    pass  out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
1033
1034In  this  case,  the server is running no services.  Infact,
1035it's not a server, it's a client.  And this  client  doesn't
1036want  unauthorized  packets  entering  its  IP stack at all.
1037However, the client wants full access to  the  internet  and
1038the reply packets that such privilege entails.  This simple
1039ruleset creates state entries for  every  new  outgoing  TCP
1040session.   Again,  since a state entry is created, these new
1041TCP sessions are free to talk back and forth as they  please
1042without the hindrance or inspection of the firewall rule-
1043set.  We mentioned that this also works for UDP and ICMP:
1044
1045    block in  quick on tun0 all
1046    pass  out quick on tun0 proto tcp  from 20.20.20.1/32 to any keep state
1047    pass  out quick on tun0 proto udp  from 20.20.20.1/32 to any keep state
1048    pass  out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059                            -17-
1060
1061
1062Yes Virginia, we can ping.  Now we're keeping state on  TCP,
1063UDP,  ICMP.   Now we can make outgoing connections as though
1064there's no firewall at all, yet would-be attackers can't get
1065back  in.   This  is  very  handy because there's no need to
1066track down what ports we're listening to, only the ports  we
1067want people to be able to get to.
1068
1069     State is pretty handy, but it's also a bit tricky.  You
1070can shoot yourself in the foot  in  strange  and  mysterious
1071ways.  Consider the following ruleset:
1072
1073     pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23
1074     pass  out quick on tun0 proto tcp from any to any keep state
1075     block in  quick all
1076     block out quick all
1077
1078At  first  glance,  this seems to be a good setup.  We allow
1079incoming sessions to port 23,  and  outgoing  sessions  any-
1080where.   Naturally  packets going to port 23 will have reply
1081packets, but the ruleset is setup in such  a  way  that  the
1082pass  out  rule  will  generate a state entry and everything
1083will work perfectly.  At least, you'd think so.
1084
1085     The unfortunate truth is that after 60 seconds of  idle
1086time  the state entry will be closed (as opposed to the nor-
1087mal 5 days).  This is because the state  tracker  never  saw
1088the original SYN packet destined to port 23, it only saw the
1089SYN ACK.  IPF is very good about following TCP sessions from
1090start  to  finish,  but it's not very good about coming into
1091the middle of a connection, so rewrite the rule to look like
1092this:
1093
1094     pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
1095     pass  out quick on tun0 proto tcp from any to any keep state
1096     block in  quick all
1097     block out quick all
1098
1099The additional of this rule will enter the very first packet
1100into the state table and everything will work  as  expected.
1101Once  the  3-way  handshake  has  been  witness by the state
1102engine, it is marked in 4/4 mode, which means it's setup for
1103long-term data exchange until such time as the connection is
1104torn down (wherein the mode changes again.  You can see  the
1105current modes of your state table with ipfstat -s.
1106
11073.3.  Stateful UDP
1108
1109     UDP is stateless so naturally it's a bit harder to do a
1110reliable job of keeping state on it.  Nonetheless, ipf  does
1111a  pretty  good  job.   When machine A sends a UDP packet to
1112machine B with source port X and  destination  port  Y,  ipf
1113will  allow  a reply from machine B to machine A with source
1114port Y and destination port X.  This is a short  term  state
1115entry, a mere 60 seconds.
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125                            -18-
1126
1127
1128     Here's an example of what happens if we use nslookup to
1129get the IP address of www.3com.com:
1130
1131    $ nslookup www.3com.com
1132
1133  A DNS packet is generated:
1134
1135    17:54:25.499852 20.20.20.1.2111 > 198.41.0.5.53: 51979+
1136
1137The packet is  from  20.20.20.1,  port  2111,  destined  for
1138198.41.0.5,  port  53.   A 60 second state entry is created.
1139If a packet comes back from 198.41.0.5 port 53 destined  for
114020.20.20.1  port  2111 within that period of time, the reply
1141packet will be let through.  As you  can  see,  milliseconds
1142later:
1143
1144    17:54:25.501209 198.41.0.5.53 > 20.20.20.1.2111: 51979 q: www.3com.com
1145
1146The  reply  packet  matches  the  state  criteria and is let
1147through.  At that same moment that packet  is  let  through,
1148the state gateway is closed and no new incoming packets will
1149be allowed in, even if they claim to be from the same place.
1150
11513.4.  Stateful ICMP
1152
1153     IPFilter  handles  ICMP  states  in the manner that one
1154would expect from understanding how ICMP is  used  with  TCP
1155and  UDP,  and  with  your  understanding  of how keep state
1156works.  There  are  two  general  types  of  ICMP  messages;
1157requests and replies.   When you write a rule such as:
1158
1159    pass out on tun0 proto icmp from any to any icmp-type 8 keep state
1160
1161to allow outbound echo requests (a typical ping), the resul-
1162tant icmp-type 0 packet that comes back will be allowed  in.
1163This  state entry has a default timeout of an incomplete 0/0
1164state of 60 seconds.   Thus, if you are keeping state on any
1165outbound  icmp  message  that will elicit an icmp message in
1166reply, you need a proto icmp [...] keep state rule.
1167
1168     However, the majority of ICMP messages are status  mes-
1169sages  generated by some failure in UDP (and sometimes TCP),
1170and in 3.4.x and greater IPFilters, any  ICMP  error  status
1171message  (say  icmp-type 3 code 3 port unreachable, or icmp-
1172type 11 time exceeded) that matches an  active  state  table
1173entry  that  could  have  generated  that  message, the ICMP
1174packet is let in.  For example, in older IPFilters,  if  you
1175wanted traceroute to work, you needed to use:
1176
1177    pass out on tun0 proto udp from any to any port 33434><33690 keep state
1178    pass in on tun0 proto icmp from any to any icmp-type timex
1179
1180whereas  now  you can do the right thing and just keep state
1181on udp with:
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191                            -19-
1192
1193
1194    pass out on tun0 proto udp from any to any port 33434><33690 keep state
1195
1196To provide some protection against  a  third-party  sneaking
1197ICMP  messages  through your firewall when an active connec-
1198tion is known to be in your state table, the  incoming  ICMP
1199packet  is checked not only for matching source and destina-
1200tion addresses (and ports, when applicable) but a tiny  part
1201of the payload of the packet that the ICMP message is claim-
1202ing it was generated by.
1203
12043.5.  FIN Scan Detection; "flags" Keyword, "keep frags" Key-
1205word
1206
1207Let's go back to the 4 rule set from the previous section:
1208
1209    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
1210    pass  out quick on tun0 proto tcp from any to any keep state
1211    block in  quick all
1212    block out quick all
1213
1214This is almost, but not quite, satisfactory.  The problem is
1215that it's not just SYN packets that're allowed to go to port
121623,  any  old packet can get through.  We can change this by
1217using the flags option:
1218
1219    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state
1220    pass  out quick on tun0 proto tcp from any to any flags S keep state
1221    block in  quick all
1222    block out quick all
1223
1224Now only TCP packets, destined for 20.20.20.1, at  port  23,
1225with a lone SYN flag will be allowed in and entered into the
1226state table.  A lone SYN flag is only present  as  the  very
1227first packet in a TCP session (called the TCP handshake) and
1228that's really what we wanted all along.   There's  at  least
1229two  advantages  to  this:  No arbitrary packets can come in
1230and make a mess of your state table.   Also,  FIN  and  XMAS
1231scans  will  fail  since  they  set flags other than the SYN
1232flag.  Now all incoming packets must either be handshakes or
1233have state already.  If anything else comes in, it's  proba-
1234bly  a  port scan or a forged packet.  There's one exception
1235to that, which is when a packet comes in  that's  fragmented
1236from  its journey.  IPF has provisions for this as well, the
1237-----------
1238 Some examples use flags S/SA instead of flags  S.
1239flags  S  actually  equates  to flags S/AUPRFS and
1240matches against only the SYN packet out of all six
1241possible  flags, while flags S/SA will allow pack-
1242ets that may or may not have the URG, PSH, FIN, or
1243RST  flags  set.  Some protocols demand the URG or
1244PSH flags, and S/SAFR would be a better choice for
1245these,  however  we feel that it is less secure to
1246blindly use S/SA when it isn't required.  But it's
1247your firewall.
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257                            -20-
1258
1259
1260keep frags keyword.  With it, IPF will notice and keep track
1261of  packets that are fragmented, allowing the expected frag-
1262ments to go through.  Let's rewrite the 3  rules  to  log
1263forgeries and allow fragments:
1264
1265    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state keep frags
1266    pass  out quick on tun0 proto tcp from any to any keep state flags S keep frags
1267    block in  log quick all
1268    block out log quick all
1269
1270This  works  because  every  packet  that  should be allowed
1271through makes it into the state table  before  the  blocking
1272rules  are reached. The only scan this won't detect is a SYN
1273scan itself.  If you're truly worried about that, you might
1274even want to log all initial SYN packets.
1275
12763.6.  Responding To a Blocked Packet
1277
1278     So  far, all of our blocked packets have been dumped on
1279the floor, logged or not, we've never sent anything back  to
1280the  originating host.  Sometimes this isn't the most desir-
1281able of responses because in doing so, we actually tell  the
1282attacker  that  a  packet filter is present.  It seems a far
1283better thing to misguide the attacker into  believing  that,
1284while  there's no packet filter running, there's likewise no
1285services to break into.   This  is  where  fancier  blocking
1286comes into play.
1287
1288     When  a service isn't running on a Unix system, it nor-
1289mally lets the remote host know with  some  sort  of  return
1290packet.   In  TCP,  this is done with an RST (Reset) packet.
1291When blocking a TCP packet, IPF can actually return  an  RST
1292to the origin by using the return-rst keyword.
1293
1294Where once we did:
1295
1296    block in log on tun0 proto tcp from any to 20.20.20.0/24 port = 23
1297    pass  in     all
1298
1299We might now do:
1300
1301    block return-rst in log proto tcp from any to 20.20.20.0/24 port = 23
1302    block in log quick on tun0
1303    pass  in     all
1304
1305We  need  two  block  statements since return-rst only works
1306with TCP, and we still want to block protocols such as  UDP,
1307ICMP,  and  others.   Now that this is done, the remote side
1308will get "connection refused" instead of  "connection  timed
1309out".
1310
1311     It's  also possible to send an error message when some-
1312body sends a packet to a UDP port on your  system.   Whereas
1313once you might have used:
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323                            -21-
1324
1325
1326    block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
1327
1328You  could  instead  use  the  return-icmp keyword to send a
1329reply:
1330
1331    block return-icmp(port-unr) in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
1332
1333According to TCP/IP  Illustrated,  port-unreachable  is  the
1334correct  ICMP type to return when no service is listening on
1335the port in question.  You can use any ICMP type  you  like,
1336but  port-unreachable  is probably your best bet.  It's also
1337the default ICMP type for return-icmp.
1338
1339     However, when using  return-icmp,  you'll  notice  that
1340it's  not very stealthy, and it returns the ICMP packet with
1341the IP address of the firewall, not the original destination
1342of  the  packet.   This was fixed in ipfilter 3.3, and a new
1343keyword; return-icmp-as-dest, has been added.   The new for-
1344mat is:
1345
1346     block return-icmp-as-dest(port-unr) in log on tun0 proto udp from any to 20.20.20.0/24 port = 111
1347
13483.7.  Fancy Logging Techniques
1349
1350     It  is  important  to note that the presence of the log
1351keyword only ensures that the packet will  be  available  to
1352the  ipfilter  logging device; /dev/ipl.   In order to actu-
1353ally see this log information, one must be running the ipmon
1354utility  (or  some  other utility that reads from /dev/ipl).
1355The typical usage of log is coupled with ipmon -s to log the
1356information to syslog.  As of ipfilter 3.3, one can now even
1357control the logging behavior of syslog by  using  log  level
1358keywords, as in rules such as this:
1359
1360     block in log level auth.info quick on tun0 from 20.20.20.0/24 to any
1361     block in log level auth.alert quick on tun0 proto tcp from any to 20.20.20.0/24 port = 21
1362
1363In  addition  to  this,  you  can tailor what information is
1364being logged.  For example, you may not be  interested  that
1365someone  attempted  to probe your telnet port 500 times, but
1366you are interested that they probed you once.  You  can  use
1367the  log  first  keyword  to only log the first example of a
1368packet.  Of course, the notion of "first-ness" only  applies
1369to  packets  in  a  specific  session,  and  for the typical
1370blocked packet, you will be hard pressed to encounter situa-
1371tions  where this does what you expect.  However, if used in
1372conjunction with pass and keep state, this can be a valuable
1373keyword for keeping tabs on traffic.
1374
1375     Another  useful  thing  you  can do with the logs is to
1376keep track of interesting pieces of the packet  in  addition
1377to  the  header information normally being logged.  Ipfilter
1378will give you the first 128 bytes of the packet if  you  use
1379the  log  body  keyword.   You  should limit the use of body
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389                            -22-
1390
1391
1392logging, as it makes your logs very verbose, but for certain
1393applications,  it  is  often handy to be able to go back and
1394take a look at the packet, or to send this data  to  another
1395application that can examine it further.
1396
13973.8.  Putting It All Together
1398
1399     So  now  we  have  a  pretty tight firewall, but it can
1400still be tighter.  Some of the  original  ruleset  we  wiped
1401clean  is  actually  very useful.  I'd suggest bringing back
1402all the anti-spoofing stuff.  This leaves us with:
1403
1404    block in           on tun0
1405    block in     quick on tun0 from 192.168.0.0/16 to any
1406    block in     quick on tun0 from 172.16.0.0/12 to any
1407    block in     quick on tun0 from 10.0.0.0/8 to any
1408    block in     quick on tun0 from 127.0.0.0/8 to any
1409    block in     quick on tun0 from 0.0.0.0/8 to any
1410    block in     quick on tun0 from 169.254.0.0/16 to any
1411    block in     quick on tun0 from 192.0.2.0/24 to any
1412    block in     quick on tun0 from 204.152.64.0/23 to any
1413    block in     quick on tun0 from 224.0.0.0/3 to any
1414    block in log quick on tun0 from 20.20.20.0/24 to any
1415    block in log quick on tun0 from any to 20.20.20.0/32
1416    block in log quick on tun0 from any to 20.20.20.255/32
1417    pass  out quick on tun0 proto tcp/udp from 20.20.20.1/32 to any keep state
1418    pass  out quick on tun0 proto icmp    from 20.20.20.1/32 to any keep state
1419    pass  in  quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 flags S keep state
1420
14213.9.  Improving Performance With Rule Groups
1422
1423     Let's extend our use of our firewall by creating a much
1424more  complicated,  and  we hope more applicable to the real
1425world, example configuration For this example,  we're  going
1426to  change  the interface names, and network numbers.  Let's
1427assume that we have three interfaces in  our  firewall  with
1428interfaces xl0, xl1, and xl2.
1429
1430xl0 is connected to our external network 20.20.20.0/26
1431xl1 is connected to our "DMZ" network 20.20.20.64/26
1432xl2 is connected to our protected network 20.20.20.128/25
1433
1434We'll  define the entire ruleset in one swoop, since we fig-
1435ure that you can read these rules by now:
1436
1437    block in     quick on xl0 from 192.168.0.0/16 to any
1438    block in     quick on xl0 from 172.16.0.0/12 to any
1439    block in     quick on xl0 from 10.0.0.0/8 to any
1440    block in     quick on xl0 from 127.0.0.0/8 to any
1441    block in     quick on xl0 from 0.0.0.0/8 to any
1442    block in     quick on xl0 from 169.254.0.0/16 to any
1443    block in     quick on xl0 from 192.0.2.0/24 to any
1444    block in     quick on xl0 from 204.152.64.0/23 to any
1445    block in     quick on xl0 from 224.0.0.0/3 to any
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455                            -23-
1456
1457
1458    block in log quick on xl0 from 20.20.20.0/24 to any
1459    block in log quick on xl0 from any to 20.20.20.0/32
1460    block in log quick on xl0 from any to 20.20.20.63/32
1461    block in log quick on xl0 from any to 20.20.20.64/32
1462    block in log quick on xl0 from any to 20.20.20.127/32
1463    block in log quick on xl0 from any to 20.20.20.128/32
1464    block in log quick on xl0 from any to 20.20.20.255/32
1465    pass out on xl0 all
1466
1467    pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state
1468    pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state
1469    pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state
1470    pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state
1471    pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state
1472    pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
1473    pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state
1474    block out on xl1 all
1475    pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
1476
1477    block out on xl2 all
1478    pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
1479
1480From this arbitarary example, we can already  see  that  our
1481ruleset is becoming unwieldy.   To make matters worse, as we
1482add more specific rules to our DMZ  network,  we  add  addi-
1483tional  tests  that  must  be parsed for every packet, which
1484affects the performance of the xl0 <-> xl2 connections.   If
1485you set up a firewall with a ruleset like this, and you have
1486lots of bandwidth and a moderate  amount  of  cpu,  everyone
1487that  has  a workstation on the xl2 network is going to come
1488looking for your head to place on a platter.   So,  to  keep
1489your  head  <->  torso  network intact, you can speed things
1490along by creating rule groups.   Rule groups  allow  you  to
1491write your ruleset in a tree fashion, instead of as a linear
1492list, so that if your packet has nothing to do with the  set
1493of  tests  (say, all those xl1 rules) those rules will never
1494be consulted.  It's somewhat like having multiple  firewalls
1495all on the same machine.
1496
1497Here's a simple example to get us started:
1498
1499    block out quick on xl1 all head 10
1500    pass out quick proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
1501    block out on xl2 all
1502
1503In  this  simplistic example, we can see a small hint of the
1504power of the rule group.  If the packet is not destined  for
1505xl1,  the  head of rule group 10 will not match, and we will
1506go on with our tests.  If the packet does match for xl1, the
1507quick  keyword  will short-circuit all further processing at
1508the root level (rule group 0),  and  focus  the  testing  on
1509rules  which  belong  to group 10; namely, the SYN check for
151080/tcp.  In this way, we can re-write  the  above  rules  so
1511that we can maximize performance of our firewall.
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521                            -24-
1522
1523
1524    block in quick on xl0 all head 1
1525      block in     quick on xl0 from 192.168.0.0/16 to any  group 1
1526      block in     quick on xl0 from 172.16.0.0/12 to any   group 1
1527      block in     quick on xl0 from 10.0.0.0/8 to any      group 1
1528      block in     quick on xl0 from 127.0.0.0/8 to any     group 1
1529      block in     quick on xl0 from 0.0.0.0/8 to any       group 1
1530      block in     quick on xl0 from 169.254.0.0/16 to any  group 1
1531      block in     quick on xl0 from 192.0.2.0/24 to any    group 1
1532      block in     quick on xl0 from 204.152.64.0/23 to any group 1
1533      block in     quick on xl0 from 224.0.0.0/3 to any     group 1
1534      block in log quick on xl0 from 20.20.20.0/24 to any   group 1
1535      block in log quick on xl0 from any to 20.20.20.0/32   group 1
1536      block in log quick on xl0 from any to 20.20.20.63/32  group 1
1537      block in log quick on xl0 from any to 20.20.20.64/32  group 1
1538      block in log quick on xl0 from any to 20.20.20.127/32 group 1
1539      block in log quick on xl0 from any to 20.20.20.128/32 group 1
1540      block in log quick on xl0 from any to 20.20.20.255/32 group 1
1541      pass  in           on xl0 all group 1
1542
1543    pass out on xl0 all
1544
1545    block out quick on xl1 all head 10
1546      pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
1547      pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state group 10
1548      pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state group 10
1549      pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state group 10
1550      pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53         keep state group 10
1551      pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
1552      pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53         keep state group 10
1553
1554    pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
1555
1556    block out on xl2 all
1557
1558    pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
1559
1560Now  you  can  see the rule groups in action.  For a host on
1561the xl2 network, we can completely bypass all the checks  in
1562group  10  when  we're  not communicating with hosts on that
1563network.
1564
1565     Depending on your situation, it may be prudent to group
1566your  rules  by protocol, or various machines, or netblocks,
1567or whatever makes it flow smoothly.
1568
15693.10.  "Fastroute"; The Keyword of Stealthiness
1570
1571     Even though we're forwarding some packets, and blocking
1572other  packets, we're typically behaving like a well behaved
1573router should by decrementing the  TTL  on  the  packet  and
1574acknowledging  to  the entire world that yes, there is a hop
1575here.  But we can hide our presence from inquisitive  appli-
1576cations  like  unix  traceroute  which uses UDP packets with
1577various TTL values to map the hops between two sites.  If we
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587                            -25-
1588
1589
1590want  incoming  traceroutes  to  work, but we do not want to
1591announce the presence of our firewall as a hop, we can do so
1592with a rule like this:
1593
1594    block in quick on xl0 fastroute proto udp from any to any port 33434 >< 33465
1595
1596The  presence  of the fastroute keyword will signal ipfilter
1597to not pass the packet into the Unix IP  stack  for  routing
1598which results in a TTL decrement.  The packet will be placed
1599gently on the output interface by  ipfilter  itself  and  no
1600such decrement will happen.  Ipfilter will of course use the
1601system's routing table to figure out  what  the  appropriate
1602output  interface  really  is,  but it will take care of the
1603actual task of routing itself.
1604
1605     There's a reason we used block quick  in  our  example,
1606too.   If  we  had  used  pass,  and if we had IP Forwarding
1607enabled in our kernel, we would end up having two paths  for
1608a  packet  to  come  out of, and we would probably panic our
1609kernel.
1610
1611     It should be noted, however,  that  most  Unix  kernels
1612(and certainly the ones underlying the systems that ipfilter
1613usually runs on) have far more efficient routing  code  than
1614what  exists  in  ipfilter,  and  this keyword should not be
1615thought of as a way to improve the operating speed  of  your
1616firewall, and should only be used in places where stealth is
1617an issue.
1618
1619
1620
1621
16224.  NAT and Proxies
1623
1624     Outside  of  the  corporate  environment,  one  of  the
1625biggest  enticements  of firewall technology to the end user
1626is the ability to connect several computers through a common
1627external  interface,  often without the approval, knowledge,
1628or even consent of their service provider.  To those  famil-
1629iar  with Linux, this concept is called IP Masquerading, but
1630to the rest of the world it is known  by  the  more  obscure
1631name of Network Address Translation, or NAT for short.
1632
16334.1.  Mapping Many Addresses Into One Address
1634
1635     The basic use of NAT accomplishes much the  same  thing
1636that  Linux's  IP Masquerading function does, and it does it
1637-----------
1638  To be pedantic, what IPFilter provides is really
1639called NPAT, for Network and Port Address Transla-
1640tion,  which means we can change any of the source
1641and destination IP Addresses and their source  and
1642destination  ports.   True  NAT only allows one to
1643change the addresses.
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653                            -26-
1654
1655
1656with one simple rule:
1657
1658    map tun0 192.168.1.0/24 -> 20.20.20.1/32
1659
1660Very simple.  Whenever a packet goes out the tun0  interface
1661with  a  source  address  matching  the CIDR network mask of
1662192.168.1.0/24 this packet will be rewritten within  the  IP
1663stack  such  that  its  source address is 20.20.20.1, and it
1664will be sent on to its original  destination.    The  system
1665also  keeps  a  list  of  what translated connections are in
1666progress so that it can perform the reverse  and  remap  the
1667response  (which  will  be  directed  to  20.20.20.1) to the
1668internal host that really generated the packet.
1669
1670     There is a drawback to the rule we have  just  written,
1671though.   In  a  large  number of cases, we do not happen to
1672know what the IP address of our outside link  is  (if  we're
1673using tun0 or ppp0 and a typical ISP) so it makes setting up
1674our NAT tables a chore.   Luckily, NAT is  smart  enough  to
1675accept  an  address  of 0/32 as a signal that it needs to go
1676look at what the address of that interface really is and  we
1677can rewrite our rule as follows:
1678
1679    map tun0 192.168.1.0/24 -> 0/32
1680
1681Now we can load our ipnat rules with impunity and connect to
1682the outside world without having to edit  anything.  You  do
1683have to run ipf -y to refresh the address if you get discon-
1684nected and redial or if your DHCP lease changes, though.
1685
1686     Some of you may be wondering what happens to the source
1687port  when  the mapping happens.  With our current rule, the
1688packet's source port is unchanged from the  original  source
1689port.   There  can  be instances where we do not desire this
1690behavior; maybe we have another firewall further upstream we
1691have  to  pass  through, or perhaps many hosts are trying to
1692use the same source port, causing a collision where the rule
1693doesn't  match and the packet is passed untranslated.  ipnat
1694helps us here with the portmap keyword:
1695
1696    map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000
1697
1698Our rule now shoehorns all the translated connections (which
1699can be tcp, udp, or tcp/udp) into the port range of 20000 to
170030000.
1701
1702
1703
1704-----------
1705 This is a typical internal address  space,  since
1706it's non-routable on the Real Internet it is often
1707used for internal  networks.    You  should  still
1708block  these  packets  coming  in from the outside
1709world as discussed earlier.
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719                            -27-
1720
1721
17224.2.  Mapping Many Addresses Into a Pool of Addresses
1723
1724     Another use common use of NAT is to take a small stati-
1725cally  allocated  block  of addresses and map many computers
1726into this smaller address space.   This is  easy  to  accom-
1727plish  using what you already know about the map and portmap
1728keywords by writing a rule like so:
1729
1730    map tun0 192.168.0.0/16 -> 20.20.20.0/24 portmap tcp/udp 20000:60000
1731
1732Also, there may be  instances  where  a  remote  application
1733requires that multiple connections all come from the same IP
1734address.  We can help with these situations by  telling  NAT
1735to  statically  map  sessions  from  a host into the pool of
1736addresses and work some magic to choose a port. This uses  a
1737the keyword map-block as follows:
1738
1739    map-block tun0 192.168.1.0/24 -> 20.20.20.0/24
1740
17414.3.  One to One Mappings
1742
1743     Occasionally  it is desirable to have a system with one
1744IP address behind the firewall to  appear  to  have  a  com-
1745pletely different IP address.  One example of how this would
1746work would be a lab of computers which are then attached  to
1747various networks that are to be put under some kind of test.
1748In this example, you would not want to have  to  reconfigure
1749the  entire  lab  when you could place a NAT system in front
1750and change the addresses in one simple place.    We  can  do
1751that  with  the  bimap  keyword,  for bidirectional mapping.
1752Bimap has some additional protections  on  it  to  ensure  a
1753known  state  for the connection, whereas the map keyword is
1754designed to allocate  an  address  and  a  source  port  and
1755rewrite the packet and go on with life.
1756
1757      bimap tun0 192.168.1.1/32 -> 20.20.20.1/32
1758
1759will accomplish the mapping for one host.
1760
17614.4.  Spoofing Services
1762
1763     Spoofing services?  What does that have to do with any-
1764thing?   Plenty.  Let's pretend that we have  a  web  server
1765running  on  20.20.20.5, and since we've gotten increasingly
1766suspicious of our network security, we  desire  to  not  run
1767this  server on port 80 since that requires a brief lifespan
1768as the root  user.    But  how  do  we  run  it  on  a  less
1769privledged port of 8000 in this world of "anything dot com"?
1770How will anyone find our server?  We can use the redirection
1771facilities of NAT to solve this problem by instructing it to
1772remap any connections destined for 20.20.20.5:80  to  really
1773point to 20.20.20.5:8000.   This uses the rdr keyword:
1774
1775      rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785                            -28-
1786
1787
1788We can also specify the protocol here, if we wanted to redi-
1789rect a UDP service, instead of a TCP service (which  is  the
1790default).  For example, if we had a honeypot on our firewall
1791to impersonate the popular  Back  Orifice  for  Windows,  we
1792could  shovel  our entire network into this one place with a
1793simple rule:
1794
1795        rdr tun0 20.20.20.0/24 port 31337 -> 127.0.0.1 port 31337 udp
1796
1797An extremely important point must be made  about  rdr:   You
1798cannot easily use this feature as a "reflector".  E.g:
1799
1800     rdr tun0 20.20.20.5/32 port 80 -> 20.20.20.6 port 80 tcp
1801
1802will  not  work  in the situation where .5 and .6 are on the
1803same  LAN  segment.   The rdr function is applied to packets
1804that enter the firewall on the specified interface.  When  a
1805packet  comes  in  that  matches a rdr rule, its destination
1806address is then rewritten, it is pushed into ipf for filter-
1807ing,  and  should it successfully run the gauntlet of filter
1808rules, it is then sent to the unix routing code.  Since this
1809packet  is  still inbound on the same interface that it will
1810need to leave the system on to reach a host, the system gets
1811confused.   Reflectors  don't work.  Neither does specifying
1812the address of the interface the packet  just  came  in  on.
1813Always  remember  that rdr destinations must exit out of the
1814firewall host on a different interface.
1815
18164.5.  Transparent Proxy Support; Redirection Made Useful
1817
1818     Since  you're  installing  a  firewall,  you  may  have
1819decided that it is prudent to use a proxy for many  of  your
1820outgoing  connections  so  that you can further tighten your
1821filter rules protecting your internal network,  or  you  may
1822have  run into a situation that the NAT mapping process does
1823not currently handle properly.   This  can  also  be  accom-
1824plished with a redirection statement:
1825
1826        rdr xl0 0.0.0.0/0 port 21 -> 127.0.0.1 port 21
1827
1828This  statement  says  that  any packet coming in on the xl0
1829interface destined for any address (0.0.0.0/0)  on  the  ftp
1830port  should be rewritten to connect it with a proxy that is
1831running on the NAT system on port 21.
1832
1833-----------
1834 Yes. There is a way to do this.  It's  so  convo-
1835luted that I refuse to use it, though.  Smart peo-
1836ple who require this functionality will  transpar-
1837ently  redirect into something like TIS plug-gw on
1838127.0.0.1.  Stupid people will set up a dummy loop
1839interface pair and double rewrite.
1840 This includes 127.0.0.1, by the way.   That's  on
1841lo0.  Neat, huh?
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851                            -29-
1852
1853
1854     This specific example of FTP proxying does lead to some
1855complications  when  used  with  web browsers or other auto-
1856matic-login type clients that are unaware  of  the  require-
1857ments  of  communicating  with the proxy.  There are patches
1858for TIS Firewall Toolkit'sftp-gw to mate  it  with  the  nat
1859process so that it can determine where you were trying to go
1860and automatically send you there.  Many proxy  packages  now
1861work  in a transparent proxy environment (Squid for example,
1862located at http://squid.nlanr.net, works fine.)
1863
1864     This application of the rdr keyword is often more  use-
1865ful  when you wish to force users to authenticate themselves
1866with the proxy. (For example, you desire your  engineers  to
1867be  able to surf the web, but you would rather not have your
1868call-center staff doing so.)
1869
18704.6.  Magic Hidden Within NAT; Application Proxies
1871
1872     Since ipnat provides a method  to  rewrite  packets  as
1873they traverse the firewall, it becomes a convenient place to
1874build in some application level proxies to make up for  well
1875known  deficiencies  of  that  application and typical fire-
1876walls.  For example; FTP.   We can  make  our  firewall  pay
1877attention to the packets going across it and when it notices
1878that it's dealing with an Active FTP session, it  can  write
1879itself  some  temporary  rules,  much like what happens with
1880keep state, so that the FTP data connection works.    To  do
1881this, we use a rule like so:
1882
1883   map tun0 192.168.1.0/24 -> 20.20.20.1/32 proxy port ftp ftp/tcp
1884
1885You must always remember to place this proxy rule before any
1886portmap  rules,  otherwise  when  portmap  comes  along  and
1887matches  the  packet and rewrites it before the proxy gets a
1888chance to work on it.  Remember that ipnat rules are  first-
1889match.
1890
1891     There  also  exist proxies for "rcmd" (which we suspect
1892is berkeley r-* commands which should be  forbidden  anyway,
1893thus we haven't looked at what this proxy does) and "raudio"
1894for Real Audio PNM streams.  Likewise, both of  these  rules
1895should be put before any portmap rules, if you're doing NAT.
1896
1897
1898
18995.  Loading and Manipulating Filter Rules; The ipf Utility
1900
1901     IP Filter rules are loaded by using  the  ipf  utility.
1902The  filter  rules  can be stored in any file on the system,
1903but typically these  rules  are  stored  in  /etc/ipf.rules,
1904/usr/local/etc/ipf.rules, or /etc/opt/ipf/ipf.rules.
1905
1906     IP Filter has two sets of rules, the active set and the
1907inactive set.  By default, all operations are  performed  on
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917                            -30-
1918
1919
1920the  active  set.   You  can  manipulate the inactive set by
1921adding -I to the ipf command line.   The  two  sets  can  be
1922toggled  by  using the -s command line option.  This is very
1923useful for testing new rule sets without wiping out the  old
1924rule set.
1925
1926     Rules  can  also  be  removed  from the list instead of
1927added by using the -r command line option, but it is  gener-
1928ally  a safer idea to flush the rule set that you're working
1929on with -F and completely reload it when making changes.
1930
1931     In summary, the easiest way to load a rule set  is  ipf
1932-Fa  -f  /etc/ipf.rules.  For more complicated manipulations
1933of the rule set, please see the ipf(1) man page.
1934
19356.  Loading and Manipulating NAT Rules; The ipnat Utility
1936
1937     NAT rules are loaded by using the ipnat  utility.   The
1938NAT rules can be stored in any file on the system, but typi-
1939cally  these   rules   are   stored   in   /etc/ipnat.rules,
1940/usr/local/etc/ipnat.rules, or /etc/opt/ipf/ipnat.rules.
1941
1942     Rules  can  also  be  removed  from the list instead of
1943added by using the -r command line option, but it is  gener-
1944ally  a safer idea to flush the rule set that you're working
1945on with -C and completely reload  it  when  making  changes.
1946Any  active  mappings  are  not  affected  by -C, and can be
1947removed with -F.
1948
1949     NAT rules and active mappings can be examined with  the
1950-l command line option.
1951
1952     In  summary,  the easiest way to load a NAT rule set is
1953ipnat -CF -f /etc/ipnat.rules.
1954
19557.  Monitoring and Debugging
1956
1957     There will come a time when you are interested in  what
1958your  firewall  is  actually  doing,  and  ipfilter would be
1959incomplete if it didn't have a full suite of status monitor-
1960ing tools.
1961
19627.1.  The ipfstat utility
1963
1964     In  its  simplest  form,  ipfstat  displays  a table of
1965interesting data about how your firewall is performing, such
1966as  how  many  packets  have been passed or blocked, if they
1967were logged or not, how many state entries have  been  made,
1968and  so  on.   Here's  an example of something you might see
1969from running the tool:
1970
1971    # ipfstat
1972     input packets:         blocked 99286 passed 1255609 nomatch 14686 counted 0
1973    output packets:         blocked 4200 passed 1284345 nomatch 14687 counted 0
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983                            -31-
1984
1985
1986     input packets logged:  blocked 99286 passed 0
1987    output packets logged:  blocked 0 passed 0
1988     packets logged:        input 0 output 0
1989     log failures:          input 3898 output 0
1990    fragment state(in):     kept 0  lost 0
1991    fragment state(out):    kept 0  lost 0
1992    packet state(in):       kept 169364     lost 0
1993    packet state(out):      kept 431395     lost 0
1994    ICMP replies:   0       TCP RSTs sent:  0
1995    Result cache hits(in):  1215208 (out):  1098963
1996    IN Pullups succeeded:   2       failed: 0
1997    OUT Pullups succeeded:  0       failed: 0
1998    Fastroute successes:    0       failures:       0
1999    TCP cksum fails(in):    0       (out):  0
2000    Packet log flags set: (0)
2001            none
2002
2003ipfstat is also capable of showing  you  your  current  rule
2004list.   Using  the -i or the -o flag will show the currently
2005loaded rules for in or out, respectively.  Adding  a  -h  to
2006this  will  provide more useful information at the same time
2007by showing you a "hit count" on each rule.  For example:
2008
2009    # ipfstat -ho
2010    2451423 pass out on xl0 from any to any
2011    354727 block out on ppp0 from any to any
2012    430918 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
2013
2014From this, we can see that perhaps there's something  abnor-
2015mal  going on, since we've got a lot of blocked packets out-
2016bound, even with a very permissive pass out rule.  Something
2017here  may warrant further investigation,  or it may be func-
2018tioning perfectly by design.  ipfstat can't tell you if your
2019rules  are right or wrong, it can only tell you what is hap-
2020pening because of your rules.
2021
2022To further debug your rules, you may  want  to  use  the  -n
2023flag, which will show the rule number next to each rule.
2024
2025    # ipfstat -on
2026    @1 pass out on xl0 from any to any
2027    @2 block out on ppp0 from any to any
2028    @3 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
2029
2030The final piece of really interesting information that ipfs-
2031tat can provide us is a dump of the state  table.   This  is
2032done with the -s flag:
2033
2034    # ipfstat -s
2035            281458 TCP
2036            319349 UDP
2037            0 ICMP
2038            19780145 hits
2039            5723648 misses
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049                            -32-
2050
2051
2052            0 maximum
2053            0 no memory
2054            1 active
2055            319349 expired
2056            281419 closed
2057    100.100.100.1 -> 20.20.20.1 ttl 864000 pass 20490 pr 6 state 4/4
2058            pkts 196 bytes 17394    987 -> 22 585538471:2213225493 16592:16500
2059            pass in log quick keep state
2060            pkt_flags & b = 2,              pkt_options & ffffffff = 0
2061            pkt_security & ffff = 0, pkt_auth & ffff = 0
2062
2063Here  we  see that we have one state entry for a TCP connec-
2064tion.  The output will vary slightly from  version  to  ver-
2065sion,  but the basic information is the same.  We can see in
2066this connection that we have a fully established  connection
2067(represented  by the 4/4 state.  Other states are incomplete
2068and will be documented fully later.)  We can  see  that  the
2069state  entry  has  a  time to live of 240 hours, which is an
2070absurdly long time, but is the default  for  an  established
2071TCP connection.   This TTL counter is decremented every sec-
2072ond that the state entry  is  not  used,  and  will  finally
2073result  in  the  connection being purged if it has been left
2074idle.   The TTL is also reset to 864000 whenever  the  state
2075IS  used, ensuring that the entry will not time out while it
2076is being actively used.  We can also see that we have passed
2077196 packets consisting of about 17kB worth of data over this
2078connection.  We can see the ports  for  both  endpoints,  in
2079this case 987 and 22; which means that this state entry rep-
2080resents  a  connection  from  100.100.100.1  port   987   to
208120.20.20.1  port  22.   The really big numbers in the second
2082line are the TCP sequence numbers for this connection, which
2083helps  to  ensure that someone isn't easily able to inject a
2084forged packet into your session.  The  TCP  window  is  also
2085shown.    The  third line is a synopsis of the implicit rule
2086that was generated by the keep state code, showing that this
2087connection is an inbound connection.
2088
20897.2.  The ipmon utility
2090
2091     ipfstat  is  great  for  collecting snapshots of what's
2092going on on the system, but it's often handy  to  have  some
2093kind  of  log  to look at and watch events as they happen in
2094time.   ipmon is this tool.  ipmon is  capable  of  watching
2095the  packet  log  (as  created  with the log keyword in your
2096rules), the state log, or the nat log, or any combination of
2097the  three.   This tool can either be run in the foreground,
2098or as a daemon which logs to syslog or a file.  If we wanted
2099to  watch  the  state table in action, ipmon -o S would show
2100this:
2101
2102    # ipmon -o S
2103    01/08/1999 15:58:57.836053 STATE:NEW 100.100.100.1,53 -> 20.20.20.15,53 PR udp
2104    01/08/1999 15:58:58.030815 STATE:NEW 20.20.20.15,123 -> 128.167.1.69,123 PR udp
2105    01/08/1999 15:59:18.032174 STATE:NEW 20.20.20.15,123 -> 128.173.14.71,123 PR udp
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115                            -33-
2116
2117
2118    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
2119    01/08/1999 16:03:51.754867 STATE:NEW 20.20.20.13,1019 -> 100.100.100.10,22 PR tcp
2120    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
2121
2122Here we see a state entry for an external  dns  request  off
2123our  nameserver,  two xntp pings to well-known time servers,
2124and a very short lived outbound ssh connection.
2125
2126     ipmon is also capable of showing us what  packets  have
2127been  logged.   For  example, when using state, you'll often
2128run into packets like this:
2129
2130    # ipmon -o I
2131    15:57:33.803147 ppp0 @0:2 b 100.100.100.103,443 -> 20.20.20.10,4923 PR tcp len 20 1488 -A
2132
2133What does this mean?   The first field is  obvious,  it's  a
2134timestamp.   The  second  field is also pretty obvious, it's
2135the interface that this event happened on.  The third  field
2136@0:2  is  something  most people miss. This is the rule that
2137caused the event to happen.  Remember ipfstat -in?   If  you
2138wanted  to  know  where this came from, you could look there
2139for rule 2 in rule group 0.  The fourth  field,  the  little
2140"b"  says that this packet was blocked, and you'll generally
2141ignore this unless you're logging passed  packets  as  well,
2142which  would  be  a  little "p" instead. The fifth and sixth
2143fields are pretty  self-explanatory,  they  say  where  this
2144packet  came from and where it was going. The seventh ("PR")
2145and eighth fields tell you the protocol and the ninth  field
2146tells  you  the size of the packet.  The last part, the "-A"
2147in this case, tells you the flags that were on  the  packet;
2148This  one  was  an ACK packet.  Why did I mention state ear-
2149lier?   Due to the often laggy nature of the Internet, some-
2150times  packets  will  be regenerated.  Sometimes, you'll get
2151two copies of the same packet, and  your  state  rule  which
2152keeps  track of sequence numbers will have already seen this
2153packet, so it will assume that the packet is part of a  dif-
2154ferent  connection.   Eventually this packet will run into a
2155real rule and have to be dealt with.   You'll often see  the
2156last packet of a session being closed get logged because the
2157keep state code has already torn down the connection  before
2158the  last  packet  has had a chance to make it to your fire-
2159wall.  This is normal, do not be alarmed.   Another  example
2160packet that might be logged:
2161
2162    12:46:12.470951 xl0 @0:1 S 20.20.20.254 -> 255.255.255.255 PR icmp len 20 9216 icmp 9/0
2163
2164-----------
2165 For a technical presentation  of  the  IP  Filter
2166stateful  inspection  engine, please see the white
2167paper Real Stateful TCP  Packet  Filtering  in  IP
2168Filter,  by  Guido  van  Rooij.  This paper may be
2169found                                           at
2170<http://www.iae.nl/users/guido/papers/tcp_filter-
2171ing.ps.gz>
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181                            -34-
2182
2183
2184This  is an ICMP router discovery broadcast.  We can tell by
2185the ICMP type 9/0.
2186
2187Finally, ipmon also lets us look at the NAT table in action.
2188
2189    # ipmon -o N
2190    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]
2191    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
2192
2193This  would  be a redirection to an identd that lies to pro-
2194vide ident service for the hosts behind our NAT, since  they
2195are  typically unable to provide this service for themselves
2196with ordinary natting.
2197
2198
2199
2200
22018.  Specific Applications of IP Filter - Things  that  don't
2202fit, but should be mentioned anyway.
2203
22048.1.  Keep State With Servers and Flags.
2205
2206     Keeping  state  is a good thing, but it's quite easy to
2207make a mistake in the direction that you want to keep  state
2208in.    Generally,  you  want to have a keep state keyword on
2209the first rule that interacts with a packet for the  connec-
2210tion.  One  common  mistake  that  is made when mixing state
2211tracking with filtering on flags is this:
2212
2213     block in all
2214     pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S
2215     pass out all keep state
2216
2217That certainly appears to allow a connection to  be  created
2218to  the  telnet server on 20.20.20.20, and the replies to go
2219back.  If you try using this rule, you'll see that  it  does
2220work--Momentarily.   Since we're filtering for the SYN flag,
2221the state entry never fully gets completed, and the  default
2222time to live for an incomplete state is 60 seconds.
2223
2224We can solve this by rewriting the rules in one of two ways:
2225
22261)
2227
2228          block in all
2229          pass in quick proto tcp from any to 20.20.20.20/32 port = 23 keep state
2230          block out all
2231
2232or:
2233
22342)
2235
2236          block in all
2237          pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S keep state
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247                            -35-
2248
2249
2250          pass out all keep state
2251
2252Either of these sets of rules will result in a fully  estab-
2253lished state entry for a connection to your server.
2254
22558.2.  Coping With FTP
2256
2257     FTP is one of those protocols that you just have to sit
2258back and ask "What the heck were they  thinking?"   FTP  has
2259many  problems that the firewall administrator needs to deal
2260with.  What's worse, the  problems  the  administrator  must
2261face  are different between making ftp clients work and mak-
2262ing ftp servers work.
2263
2264     Within the FTP protocol, there are two  forms  of  data
2265transfer,  called  active and passive.  Active transfers are
2266those where the server connects  to  an  open  port  on  the
2267client  to  send  data.   Conversely,  passive transfers are
2268those where the client connects to  the  server  to  receive
2269data.
2270
22718.2.1.  Running an FTP Server
2272
2273     In  running an FTP server, handling Active FTP sessions
2274is easy to setup.  At the same time,  handling  Passive  FTP
2275sessions  is a big problem.  First we'll cover how to handle
2276Active FTP, then move on to Passive.  Generally, we can han-
2277dle  Active  FTP  sessions like we would an incoming HTTP or
2278SMTP connection; just open the ftp port and let  keep  state
2279do the rest:
2280
2281     pass in quick proto tcp from any to 20.20.20.20/32 port = 21 flags S keep state
2282     pass out proto tcp all keep state
2283
2284These  rules will allow Active FTP sessions, the most common
2285type, to your ftp server on 20.20.20.20.
2286
2287     The next challenge becomes handling Passive FTP connec-
2288tions.   Web browsers default to this mode, so it's becoming
2289quite popular and as such it should be supported.  The prob-
2290lem with passive connections are that for every passive con-
2291nection, the server starts listening on a new port  (usually
2292above  1023).   This  is  essentially  like  creating  a new
2293unknown service on the server.   Assuming  we  have  a  good
2294firewall  with  a default-deny policy, that new service will
2295be blocked, and thus Active FTP sessions are broken.   Don't
2296despair!  There's hope yet to be had.
2297
2298     A  person's  first  inclination to solving this problem
2299might be to just open up all ports above  1023.   In  truth,
2300this will work:
2301
2302     pass in quick proto tcp from any to 20.20.20.20/32 port > 1023 flags S keep state
2303     pass out proto tcp all keep state
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313                            -36-
2314
2315
2316This  is somewhat unsatisfactory, though.  By letting every-
2317thing above 1023 in, we actually open  ourselves  up  for  a
2318number  of  potential  problems.  While 1-1023 is the desig-
2319nated area for server services  to  run,  numerous  programs
2320decided to use numbers higher than 1023, such as nfsd and X.
2321
2322     The good news is that your FTP server  gets  to  decide
2323which  ports  get  assigned to passive sessions.  This means
2324that instead of opening all ports above 1023, you can  allo-
2325cate ports 15001-19999 as ftp ports and only open that range
2326of your firewall up.  In wu-ftpd, this is done with the pas-
2327sive  ports option in ftpaccess.  Please see the man page on
2328ftpaccess for details  in  wu-ftpd  configuration.   On  the
2329ipfilter side, all we need do is setup corresponding rules:
2330
2331     pass in quick proto tcp from any to 20.20.20.20/32 port 15000 >< 20000 flags S keep state
2332     pass out proto tcp all keep state
2333
2334If  even  this  solution doesn't satisfy you, you can always
2335hack IPF support into your FTP server, or FTP server support
2336into IPF.
2337
23388.2.2.  Running an FTP Client
2339
2340     While  FTP server support is still less than perfect in
2341IPF, FTP client support has been working well  since  3.3.3.
2342As  with  FTP  servers,  there  are  two types of ftp client
2343transfers: passive and active.
2344
2345     The simplest type of client  transfer  from  the  fire-
2346wall's  standpoint is the passive transfer.  Assuming you're
2347keeping state on all outbound tcp sessions,  passive  trans-
2348fers  will  work already.  If you're not doing this already,
2349please consider the following:
2350
2351    pass out proto tcp all keep state
2352
2353The second type of client transfer, active, is  a  bit  more
2354troublesome,  but  nonetheless  a  solved  problem.   Active
2355transfers cause the server to open up  a  second  connection
2356back  to  the client for data to flow through.  This is nor-
2357mally a problem when there's a firewall in the middle, stop-
2358ping  outside  connections  from  coming  back in.  To solve
2359this, ipfilter includes an  ipnat  proxy  which  temporarily
2360opens  up  a hole in the firewall just for the FTP server to
2361get back to the client.  Even if you're not using  ipnat  to
2362do  nat,  the proxy is still effective.  The following rules
2363is the bare minimum to add to the ipnat  configuration  file
2364(ep0  should  be  the interface name of the outbound network
2365connection):
2366
2367     map ep0 0/0 -> 0/32 proxy port 21 ftp/tcp
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379                            -37-
2380
2381
2382For more details on ipfilter's internal proxies, see section
23833.6
2384
23858.3.  Assorted Kernel Variables
2386
2387     There  are some useful kernel tunes that either need to
2388be set for ipf to function, or are just generally  handy  to
2389know  about for building firewalls.  The first major one you
2390must set is to enable IP Forwarding, otherwise ipf  will  do
2391very little, as the underlying ip stack won't actually route
2392packets.
2393
2394IP Forwarding:
2395
2396openbsd:
2397     net.inet.ip.forwarding=1
2398
2399
2400freebsd:
2401     net.inet.ip.forwarding=1
2402
2403
2404netbsd:
2405     net.inet.ip.forwarding=1
2406
2407
2408solaris:
2409     ndd -set /dev/ip ip_forwarding 1
2410
2411Ephemeral Port Adjustment:
2412
2413openbsd:
2414     net.inet.ip.portfirst = 25000
2415
2416
2417freebsd:
2418     net.inet.ip.portrange.first  =  25000  net.inet.ip.por-
2419     trange.last = 49151
2420
2421
2422netbsd:
2423     net.inet.ip.anonportmin = 25000 net.inet.ip.anonportmax
2424     = 49151
2425
2426
2427solaris:
2428     ndd -set /dev/tcp tcp_smallest_anon_port 25000
2429     ndd -set /dev/tcp tcp_largest_anon_port 65535
2430
2431Other Useful Values:
2432
2433openbsd:
2434     net.inet.ip.sourceroute = 0
2435     net.inet.ip.directed-broadcast = 0
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445                            -38-
2446
2447
2448freebsd:
2449     net.inet.ip.sourceroute=0
2450     net.ip.accept_sourceroute=0
2451
2452
2453netbsd:
2454     net.inet.ip.allowsrcrt=0
2455     net.inet.ip.forwsrcrt=0
2456     net.inet.ip.directed-broadcast=0
2457     net.inet.ip.redirect=0
2458
2459
2460solaris:
2461     ndd -set /dev/ip ip_forward_directed_broadcasts 0
2462     ndd -set /dev/ip ip_forward_src_routed 0
2463     ndd -set /dev/ip ip_respond_to_echo_broadcast 0
2464
2465In addition, freebsd has some ipf specific sysctl variables.
2466
2467     net.inet.ipf.fr_flags: 0
2468     net.inet.ipf.fr_pass: 514
2469     net.inet.ipf.fr_active: 0
2470     net.inet.ipf.fr_tcpidletimeout: 864000
2471     net.inet.ipf.fr_tcpclosewait: 60
2472     net.inet.ipf.fr_tcplastack: 20
2473     net.inet.ipf.fr_tcptimeout: 120
2474     net.inet.ipf.fr_tcpclosed: 1
2475     net.inet.ipf.fr_udptimeout: 120
2476     net.inet.ipf.fr_icmptimeout: 120
2477     net.inet.ipf.fr_defnatage: 1200
2478     net.inet.ipf.fr_ipfrttl: 120
2479     net.inet.ipf.ipl_unreach: 13
2480     net.inet.ipf.ipl_inited: 1
2481     net.inet.ipf.fr_authsize: 32
2482     net.inet.ipf.fr_authused: 0
2483     net.inet.ipf.fr_defaultauthage: 600
2484
2485
2486
2487
24889.  Fun with ipf!
2489
2490     This section doesn't necessarily teach you anything new
2491about ipf, but it may raise an issue or two that you haven't
2492yet  thought  up  on your own, or tickle your brain in a way
2493that  you  invent  something  interesting  that  we  haven't
2494thought of.
2495
24969.1.  Localhost Filtering
2497
2498     A  long  time ago at a university far, far away, Wietse
2499Venema created the tcp-wrapper package, and ever since, it's
2500been  used  to add a layer of protection to network services
2501all over the world.  This is good.  But,  tcp-wrappers  have
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511                            -39-
2512
2513
2514flaws.  For starters, they only protect TCP services, as the
2515name suggests.   Also, unless  you  run  your  service  from
2516inetd, or you have specifically compiled it with libwrap and
2517the appropriate hooks, your service isn't protected.    This
2518leaves  gigantic  holes in your host security.   We can plug
2519these up by using ipf on the local host.   For  example,  my
2520laptop  often gets plugged into or dialed into networks that
2521I don't specifically trust, and so, I use the following rule
2522set:
2523
2524     pass in quick on lo0 all
2525     pass out quick on lo0 all
2526
2527     block in log all
2528     block out all
2529
2530     pass in quick proto tcp from any to any port = 113 flags S keep state
2531     pass in quick proto tcp from any to any port = 22 flags S keep state
2532     pass in quick proto tcp from any port = 20 to any port 39999 >< 45000 flags S keep state
2533
2534     pass out quick proto icmp from any to any keep state
2535     pass out quick proto tcp/udp from any to any keep state keep frags
2536
2537It's  been  like  that for quite a while, and I haven't suf-
2538fered any pain or anguish as a result of having  ipf  loaded
2539up all the time.  If I wanted to tighten it up more, I could
2540switch to using the NAT ftp proxy and I could  add  in  some
2541rules to prevent spoofing.   But even as it stands now, this
2542box is far more restrictive about what it  presents  to  the
2543local  network and beyond than the typical host does.   This
2544is a good thing if you happen to run a machine that allows a
2545lot  of  users on it, and you want to make sure  one of them
2546doesn't happen to start up a service  they  wern't  supposed
2547to.   It won't stop a malicious hacker with root access from
2548adjusting your ipf rules and starting a service anyway,  but
2549it  will keep the "honest" folks honest, and your weird ser-
2550vices safe, cozy and warm even on a malicious  LAN.   A  big
2551win, in my opinion.   Using local host filtering in addition
2552to a somewhat less-restrictive "main firewall"  machine  can
2553solve  many  performance  issues as well as political night-
2554mares like "Why doesn't ICQ work?" and "Why can't  I  put  a
2555web  server  on  my  own workstation! It's MY WORKSTATION!!"
2556Another very big win.  Who says you can't have security  and
2557convienence at the same time?
2558
25599.2.  What Firewall?  Transparent filtering.
2560
2561     One  major  concern  in  setting  up  a firewall is the
2562integrity of the firewall itself.  Can somebody  break  into
2563your  firewall,  thereby  subverting its ruleset?  This is a
2564common problem administrators must face,  particularly  when
2565they're  using  firewall  solutions  on top of their Unix/NT
2566machines.  Some use it as an argument for blackbox hardware
2567solutions,  under  the flawed notion that inherent obscurity
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577                            -40-
2578
2579
2580of their closed system increases their security.  We have  a
2581better way.
2582
2583     Many network admins are familiar with the common ether-
2584net bridge.  This is a device  that  connects  two  separate
2585ethernet  segments  to make them one.  An ethernet bridge is
2586typically used to connect separate buildings, switch network
2587speeds,  and extend maximum wire lengths.  Hubs and switches
2588are common bridges, sometimes they're just 2 ported  devices
2589called   repeaters.   Recent  versions  of  Linux,  OpenBSD,
2590NetBSD, and FreeBSD include code to convert $1000  PCs  into
2591$10  bridges,  too!  What all bridges tend to have in common
2592is that though they  sit  in  the  middle  of  a  connection
2593between two machines, the two machines don't know the bridge
2594is there.  Enter ipfilter and OpenBSD.
2595
2596     Ethernet bridging takes place  at  Layer2  on  the  ISO
2597stack.   IP  takes  place on Layer3.  IP Filter in primarily
2598concerned with Layer3, but dabbles in Layer2 by working with
2599interfaces.   By  mixing  IP  filter  with  OpenBSD's bridge
2600device, we can create a firewall that is both invisible  and
2601unreachable.   The  system  needs  no IP address, it doesn't
2602even need to reveal its ethernet address.  The only telltale
2603sign that the filter might be there is that latency is some-
2604what higher than a piece of cat5 would normally make it, and
2605that  packets  don't seem to make it to their final destina-
2606tion.
2607
2608     The setup for this sort of ruleset is surprisingly sim-
2609ple,  too.   In  OpenBSD,  the  first bridge device is named
2610bridge0.  Say we have two ethernet cards in our  machine  as
2611well,  xl0 and xl1.  To turn this machine into a bridge, all
2612one need do is enter the following three commands:
2613
2614    brconfig bridge0 add xl0 add xl1 up
2615    ifconfig xl0 up
2616    ifconfig xl1 up
2617
2618At ths point, all traffic ariving on xl0 is sent out xl1 and
2619all  traffic  on xl1 is sent out xl0.  You'll note that nei-
2620ther interface has been assigned an IP address,  nor  do  we
2621need assign one.  All things considered, it's likely best we
2622not add one at all.
2623
2624     Rulesets behave essentially the  as  the  always  have.
2625Though  there  is a bridge0 interface, we don't filter based
2626on it.  Rules continue  to  be  based  upon  the  particular
2627interface  we're  using,  making  it important which network
2628cable is plugged into which network card in the back of  the
2629machine.   Let's  start  with some basic filtering to illis-
2630trate what's happened.  Assume the network used to look like
2631this:
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643                            -41-
2644
2645
2646  20.20.20.1 <---------------------------------> 20.20.20.0/24 network hub
2647
2648That  is,  we  have  a router at 20.20.20.1 connected to the
264920.20.20.0/24 network.  All packets from  the  20.20.20.0/24
2650network  go  through  20.20.20.1 to get to the outside world
2651and vice versa.  Now we add the Ipf Bridge:
2652
2653  20.20.20.1 <-------/xl0 IpfBridge xl1/-------> 20.20.20.0/24 network hub
2654
2655We also have the following ruleset loaded on  the  IpfBridge
2656host:
2657
2658    pass in  quick  all
2659    pass out quick  all
2660
2661With  this ruleset loaded, the network is functionally iden-
2662tical.  As far as the 20.20.20.1 router is concerned, and as
2663far  as  the 20.20.20.0/24 hosts are concerned, the two net-
2664work diagrams are identical.  Now let's change  the  ruleset
2665some:
2666
2667    block in quick on xl0 proto icmp
2668    pass  in  quick all
2669    pass  out quick all
2670
2671Still,  20.20.20.1  and  20.20.20.0/24  think the network is
2672identical, but if 20.20.20.1 attempts to ping 20.20.20.2, it
2673will  never get a reply.  What's more, 20.20.20.2 won't even
2674get the packet in the first place.  IPfilter will  intercept
2675the  packet before it even gets to the other end of the vir-
2676tual wire.  We can put a  bridged  filter  anywhere.   Using
2677this  method  we can shrink the network trust circle down an
2678individual host level (given enough ethernet cards:-)
2679
2680     Blocking icmp from the world seems kind of silly, espe-
2681cially  if  you're a sysadmin and like pinging the world, to
2682traceroute, or to resize your MTU.  Let's construct a better
2683ruleset  and  take  advantage of the original key feature of
2684ipf: stateful inspection.
2685
2686    pass  in quick on xl1 proto tcp  keep state
2687    pass  in quick on xl1 proto udp  keep state
2688    pass  in quick on xl1 proto icmp keep state
2689    block in quick on xl0
2690
2691In this situation, the 20.20.20.0/24 network  (perhaps  more
2692aptly  called  the  xl1  network)  can now reach the outside
2693world, but the outside world can't reach it,  and  it  can't
2694figure out why, either.  The router is accessible, the hosts
2695are active, but the outside world just can't get  in.   Even
2696if  the  router  itself were compromised, the firewall would
2697still be active and successful.
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709                            -42-
2710
2711
2712     So far, we've been filtering by interface and  protocol
2713only.   Even  though  bridging  is  concerned layer2, we can
2714still discriminate based on IP address.  Normally we have  a
2715few services running, so our ruleset may look like this:
2716
2717    pass  in quick on xl1 proto tcp  keep state
2718    pass  in quick on xl1 proto udp  keep state
2719    pass  in quick on xl1 proto icmp keep state
2720    block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.
2721    pass  in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
2722    pass  in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
2723    pass  in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
2724    pass  in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
2725    block in quick on xl0
2726
2727Now  we  have  a  network where 20.20.20.2 is a zone serving
2728name server, 20.20.20.3 is  an  incoming  mail  server,  and
272920.20.20.7 is a web server.
2730
2731     Bridged  IP Filter is not yet perfect, we must confess.
2732
2733     First,  You'll note that all the rules are setup  using
2734the  in  direction  instead  of a combination of in and out.
2735This is because the out direction is presently unimplemented
2736with  bridging in OpenBSD.  This was originally done to pre-
2737vent vast performance drops using multiple interfaces.  Work
2738has  been  done  in  speeding it up, but it remains unimple-
2739mented.  If you really want this feature, you might try your
2740hand at working on the code or asking the OpenBSD people how
2741you can help.
2742
2743     Second, using IP Filter with bridging makes the use  of
2744IPF's  NAT features inadvisable, if not downright dangerous.
2745The first problem is that it would give away that there's  a
2746filtering  bridge.   The  second  problem  would be that the
2747bridge has no IP address to masquerade with, which will most
2748assuredly  lead  to  confusion and perhaps a kernel panic to
2749boot.  You can, of course, put an IP address on the outbound
2750interface to make NAT work, but part of the glee of bridging
2751is thus diminished.
2752
27539.2.1.  Using Transparent Filtering to  Fix  Network  Design
2754Mistakes
2755
2756     Many  organizations  started  using IP well before they
2757thought a firewall or a subnet would be a  good  idea.   Now
2758they  have class-C sized networks or larger that include all
2759their servers, their  workstations,  their  routers,  coffee
2760makers,  everything.   The  horror!  Renumbering with proper
2761subnets, trust levels, filters, and so are in both time con-
2762suming and expensive.  The expense in hardware and man hours
2763alone is enough to  make  most  organizations  unwilling  to
2764really  solve  the  problem,  not  to  mention  the downtime
2765involved.  The typical problem network looks like this:
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775                            -43-
2776
2777
2778    20.20.20.1   router               20.20.20.6   unix server
2779    20.20.20.2   unix server          20.20.20.7   nt workstation
2780    20.20.20.3   unix server          20.20.20.8   nt server
2781    20.20.20.4   win98 workstation    20.20.20.9   unix workstation
2782    20.20.20.5   intelligent switch   20.20.20.10  win95 workstation
2783
2784Only it's about 20 times larger and messier  and  frequently
2785undocumented.   Ideally, you'd have all the trusting servers
2786in one subnet, all the work- stations in  another,  and  the
2787network  switches  in a third.  Then the router would filter
2788packets between the subnets, giving the workstations limited
2789access  to  the servers, nothing access to the switches, and
2790only the sysadmin's workstation access to  the  coffee  pot.
2791I've never seen a class-C sized network with such coherence.
2792IP Filter can help.
2793
2794     To start with, we're going to separate the router,  the
2795workstations,  and  the  servers.  To do this we're going to
2796need 2 hubs (or switches) which we  probably  already  have,
2797and  an  IPF  machine with 3 ethernet cards.  We're going to
2798put all the servers on one hub and all the  workstations  on
2799the  other.   Normally  we'd  then  connect the hubs to each
2800other, then to the router.  Instead, we're going to plug the
2801router  into IPF's xl0 interface, the servers into IPF's xl1
2802interface, and the workstations into  IPF's  xl2  interface.
2803Our network diagram looks something like this:
2804
2805                                                 | 20.20.20.2  unix server
2806    router (20.20.20.1)              ____________| 20.20.20.3  unix server
2807     |                              /            | 20.20.20.6  unix server
2808     |                             /xl1          | 20.20.20.7  nt server
2809     ------------/xl0 IPF Bridge <
2810                                    xl2         | 20.20.20.4  win98 workstation
2811                                    ____________| 20.20.20.8  nt workstation
2812                                                 | 20.20.20.9  unix workstation
2813                                                 | 20.20.20.10 win95 workstation
2814
2815Where  once there was nothing but interconnecting wires, now
2816there's a filtering bridge that not a single host  needs  to
2817be  modified to take advantage of.  Presumably we've already
2818enabled bridging so the network is behaving  perfectly  nor-
2819mally.  Further, we're starting off with a ruleset much like
2820our last ruleset:
2821
2822    pass  in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
2823    pass  in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
2824    pass  in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
2825    pass  in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
2826    block in quick on xl0
2827    pass  in quick on xl1 proto tcp  keep state
2828    pass  in quick on xl1 proto udp  keep state
2829    pass  in quick on xl1 proto icmp keep state
2830    block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.
2831    pass  in quick on xl2 proto tcp  keep state
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841                            -44-
2842
2843
2844    pass  in quick on xl2 proto udp  keep state
2845    pass  in quick on xl2 proto icmp keep state
2846    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
2847
2848Once again, traffic coming from the router is restricted  to
2849DNS,  SMTP,  and  HTTP.   At the moment, the servers and the
2850workstations can exchange traffic freely.  Depending on what
2851kind of organization you are, there might be something about
2852this network dynamic you don't like.  Perhaps you don't want
2853your  workstations  getting  access  to your servers at all?
2854Take the xl2 ruleset of:
2855
2856    pass  in quick on xl2 proto tcp  keep state
2857    pass  in quick on xl2 proto udp  keep state
2858    pass  in quick on xl2 proto icmp keep state
2859    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
2860
2861And change it to:
2862
2863    block in quick on xl2 from any to 20.20.20.0/24
2864    pass  in quick on xl2 proto tcp  keep state
2865    pass  in quick on xl2 proto udp  keep state
2866    pass  in quick on xl2 proto icmp keep state
2867    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
2868
2869Perhaps you want them to just get to the servers to get  and
2870send their mail with IMAP?  Easily done:
2871
2872    pass  in quick on xl2 proto tcp from any to 20.20.20.3/32 port=25
2873    pass  in quick on xl2 proto tcp from any to 20.20.20.3/32 port=143
2874    block in quick on xl2 from any to 20.20.20.0/24
2875    pass  in quick on xl2 proto tcp  keep state
2876    pass  in quick on xl2 proto udp  keep state
2877    pass  in quick on xl2 proto icmp keep state
2878    block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
2879
2880Now  your  workstations  and  servers are protected from the
2881outside world, and the servers are protected from your work-
2882stations.
2883
2884     Perhaps the opposite is true, maybe you want your work-
2885stations to be able to get to the servers, but not the  out-
2886side  world.   After all, the next generation of exploits is
2887breaking the clients, not the servers.  In this case,  you'd
2888change the xl2 rules to look more like this:
2889
2890    pass  in quick on xl2 from any to 20.20.20.0/24
2891    block in quick on xl2
2892
2893Now  the  servers  have free reign, but the clients can only
2894connect to the servers.  We might want to  batten  down  the
2895hatches on the servers, too:
2896
2897    pass  in quick on xl1 from any to 20.20.20.0/24
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907                            -45-
2908
2909
2910    block in quick on xl1
2911
2912With  the  combination of these two, the clients and servers
2913can talk to each other, but neither can access  the  outside
2914world  (though the outside world can get to the few services
2915from earlier).  The whole ruleset would look something  like
2916this:
2917
2918    pass  in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
2919    pass  in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53                                                              flags S keep state
2920    pass  in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25                                                              flags S keep state
2921    pass  in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80                                                              flags S keep state
2922    block in quick on xl0
2923    pass  in quick on xl1 from any to 20.20.20.0/24
2924    block in quick on xl1
2925    pass  in quick on xl2 from any to 20.20.20.0/24
2926    block in quick on xl2
2927
2928So  remember,  when  your  network  is  a  mess of twisty IP
2929addresses and machine classes, transparent filtered  bridges
2930can  solve  a problem that would otherwise be lived with and
2931perhaps someday exploited.
2932
29339.3.  Drop-Safe Logging With dup-to and to.
2934
2935     Until now, we've been using the filter to drop packets.
2936Instead  of dropping them, let's consider passing them on to
2937another system that can do something useful with this infor-
2938mation  beyond  the logging we can perform with ipmon.   Our
2939firewall system, be it a bridge or a  router,  can  have  as
2940many  interfaces as we can cram into the system.  We can use
2941this information to create a "drop-safe" for our packets.  A
2942good  example  of  a  use  for this would be to implement an
2943intrusion detection network.   For  starters,  it  might  be
2944desirable  to  hide  the presence of our intrusion detection
2945systems from our real network so that we can keep them  from
2946being detected.
2947
2948     Before we get started, there are some operational char-
2949acteristics that we need to make note of.  If  we  are  only
2950going to deal with blocked packets, we can use either the to
2951keyword or the fastroute keyword. (We'll cover  the  differ-
2952ences  between  these two later)  If we're going to pass the
2953packets like we normally would, we need to make  a  copy  of
2954the packet for our drop-safe log with the dup-to keyword.
2955
29569.3.1.  The dup-to Method
2957
2958     If, for example, we wanted to send a copy of everything
2959going out the xl3 interface off to our drop-safe network  on
2960ed0, we would use this rule in our filter list:
2961
2962     pass out on xl3 dup-to ed0 from any to any
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973                            -46-
2974
2975
2976You  might also have a need to send the packet directly to a
2977specific IP address on your  drop-safe  network  instead  of
2978just  making  a  copy of the packet out there and hoping for
2979the best.  To do this, we modify our rule slightly:
2980
2981     pass out on xl3 dup-to ed0:192.168.254.2 from any to any
2982
2983But be  warned  that  this  method  will  alter  the  copied
2984packet's  destination address, and may thus destroy the use-
2985fulness of the log.  For  this  reason,  we  recommend  only
2986using  the  known  address method of logging when you can be
2987certain that the address that you're logging to  corresponds
2988in  some  way  to  what  you're logging for (e.g.: don't use
2989"192.168.254.2" for logging for both  your  web  server  and
2990your mail server, since you'll have a hard time later trying
2991to figure out which system was the target of a specific  set
2992of packets.)
2993
2994     This  technique  can  be  used quite effectively if you
2995treat an IP Address on your drop-safe network  in  much  the
2996same  way that you would treat a Multicast Group on the real
2997internet. (e.g.: "192.168.254.2" could be  the  channel  for
2998your  http  traffic  analysis system, "23.23.23.23" could be
2999your channel for telnet sessions, and so on.)     You  don't
3000even need to actually have this address set as an address or
3001alias on any  of  your  analysis  systems.   Normally,  your
3002ipfilter  machine  would need to ARP for the new destination
3003address (using dup-to ed0:192.168.254.2  style,  of  course)
3004but  we  can avoid that issue by creating a static arp entry
3005for this "channel" on our ipfilter system.
3006
3007     In general, though, dup-to ed0 is all that is  required
3008to  get  a new copy of the packet over to our drop-safe net-
3009work for logging and examination.
3010
30119.3.2.  The to Method
3012
3013     The dup-to method  does  have  an  immediate  drawback,
3014though.   Since  it  has  to  make  a copy of the packet and
3015optionally modify it for its new destination, it's going  to
3016take  a while to complete all this work and be ready to deal
3017with the next packet coming in to the ipfilter system.
3018
3019     If we don't care about passing the packet to its normal
3020destination  and  we  were  going to block it anyway, we can
3021just use the to keyword to push this packet past the  normal
3022routing  table  and force it to go out a different interface
3023than it would normally go out.
3024
3025     block in quick on xl0 to ed0 proto tcp from any to any port < 1024
3026
3027we use block quick for to interface  routing,  because  like
3028fastroute,  the  to  interface code will generate two packet
3029paths through ipfilter when used with pass, and likely cause
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039                            -47-
3040
3041
3042your system to panic.
3043
3044
3045
304610.   Bogus Network Filtering, the ultimate in current anti-
3047spoofing technology.
3048
3049     We've spent a little bit of time tracking down the cur-
3050rent vast tracts of IP address space that have been reserved
3051by the IANA for various reasons, or are otherwise  not  cur-
3052rently in use at the time this document was written.   Since
3053none of these address ranges should  be  in  use  currently,
3054there  should  be no legitimate reason to ever see them as a
3055source address, or to send them  traffic  as  a  destination
3056address, right?   Right!
3057
3058     So without further ado, the complete list of bogus net-
3059works:
3060
3061     #
3062     # s/OUTSIDE/outside-interface (eg: fxp0)
3063     # s/MYNET/network-cidr-address (eg: 1.2.3.0/24)
3064     #
3065     block in on OUTSIDE all
3066     block in quick on OUTSIDE from 0.0.0.0/7 to any
3067     block in quick on OUTSIDE from 2.0.0.0/8 to any
3068     block in quick on OUTSIDE from 5.0.0.0/8 to any
3069     block in quick on OUTSIDE from 10.0.0.0/8 to any
3070     block in quick on OUTSIDE from 23.0.0.0/8 to any
3071     block in quick on OUTSIDE from 27.0.0.0/8 to any
3072     block in quick on OUTSIDE from 31.0.0.0/8 to any
3073     block in quick on OUTSIDE from 67.0.0.0/8 to any
3074     block in quick on OUTSIDE from 68.0.0.0/6 to any
3075     block in quick on OUTSIDE from 72.0.0.0/5 to any
3076     block in quick on OUTSIDE from 80.0.0.0/4 to any
3077     block in quick on OUTSIDE from 96.0.0.0/3 to any
3078     block in quick on OUTSIDE from 127.0.0.0/8 to any
3079     block in quick on OUTSIDE from 128.0.0.0/16 to any
3080     block in quick on OUTSIDE from 128.66.0.0/16 to any
3081     block in quick on OUTSIDE from 169.254.0.0/16 to any
3082     block in quick on OUTSIDE from 172.16.0.0/12 to any
3083     block in quick on OUTSIDE from 191.255.0.0/16 to any
3084     block in quick on OUTSIDE from 192.0.0.0/16 to any
3085     block in quick on OUTSIDE from 192.168.0.0/16 to any
3086     block in quick on OUTSIDE from 197.0.0.0/8 to any
3087     block in quick on OUTSIDE from 201.0.0.0/8 to any
3088     block in quick on OUTSIDE from 204.152.64.0/23 to any
3089     block in quick on OUTSIDE from 224.0.0.0/3 to any
3090     block in quick on OUTSIDE from MYNET to any
3091     # Your pass rules come here...
3092
3093     block out on OUTSIDE all
3094     block out quick on OUTSIDE from !MYNET to any
3095     block out quick on OUTSIDE from MYNET to 0.0.0.0/7
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105                            -48-
3106
3107
3108     block out quick on OUTSIDE from MYNET to 2.0.0.0/8
3109     block out quick on OUTSIDE from MYNET to 5.0.0.0/8
3110     block out quick on OUTSIDE from MYNET to 10.0.0.0/8
3111     block out quick on OUTSIDE from MYNET to 23.0.0.0/8
3112     block out quick on OUTSIDE from MYNET to 27.0.0.0/8
3113     block out quick on OUTSIDE from MYNET to 31.0.0.0/8
3114     block out quick on OUTSIDE from MYNET to 67.0.0.0/8
3115     block out quick on OUTSIDE from MYNET to 68.0.0.0/6
3116     block out quick on OUTSIDE from MYNET to 72.0.0.0/5
3117     block out quick on OUTSIDE from MYNET to 80.0.0.0/4
3118     block out quick on OUTSIDE from MYNET to 96.0.0.0/3
3119     block out quick on OUTSIDE from MYNET to 127.0.0.0/8
3120     block out quick on OUTSIDE from MYNET to 128.0.0.0/16
3121     block out quick on OUTSIDE from MYNET to 128.66.0.0/16
3122     block out quick on OUTSIDE from MYNET to 169.254.0.0/16
3123     block out quick on OUTSIDE from MYNET to 172.16.0.0/12
3124     block out quick on OUTSIDE from MYNET to 191.255.0.0/16
3125     block out quick on OUTSIDE from MYNET to 192.0.0.0/16
3126     block out quick on OUTSIDE from MYNET to 192.168.0.0/16
3127     block out quick on OUTSIDE from MYNET to 197.0.0.0/8
3128     block out quick on OUTSIDE from MYNET to 201.0.0.0/8
3129     block out quick on OUTSIDE from MYNET to 204.152.64.0/23
3130     block out quick on OUTSIDE from MYNET to 224.0.0.0/3
3131     # Your pass rules come here...
3132
3133If you're going to use these, we  suggest  that  you  become
3134familiar  with  whois.arin.net and keep an occasional eye on
3135these, as the IANA isn't going to notify you when they allo-
3136cate  one  of  these to a new corporation or something.  You
3137have been warned.
3138
3139     We'd also like to thank  Frank  DiGennaro  <fsd@server-
3140vault.com> for greatly contributing to this filter list.
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168