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