7 IP Filter Based Firewalls HOWTO
9 Brendan Conoboy <synk@swcp.com>
10 Erik Fichtner <emf@obfuscation.org>
11 $FreeBSD: src/share/examples/ipfilter/ipf-howto.txt,v 1.1.2.1 2002/04/27 20:04:18 darrenr Exp $
12 $DragonFly: src/share/examples/ipfilter/ipf-howto.txt,v 1.3 2007/05/13 22:25:41 swildner Exp $
14 Fri Apr 20 09:31:14 EDT 2001
21 Abstract: This document is intended to introduce a new
22 user to the IP Filter firewalling package and, at the
23 same time, teach the user some basic fundamentals of
39 IP Filter is a great little firewall package. It does
40 just about everything other free firewalls (ipfwadm,
41 ipchains, ipfw) do, but it's also portable and does neat
42 stuff the others don't. This document is intended to make
43 some cohesive sense of the sparse documentation presently
44 available for ipfilter. Some prior familiarity with packet
45 filtering will be useful, however too much familiarity may
46 make this document a waste of your time. For greater under-
47 standing of firewalls, the authors recommend reading Build-
48 ing Internet Firewalls, Chapman & Zwicky, O'Reilly and Asso-
49 ciates; and TCP/IP Illustrated, Volume 1, Stevens, Addison-
58 The authors of this document are not responsible for
59 any damages incurred due to actions taken based on this doc-
60 ument. This document is meant as an introduction to building
61 a firewall based on IP-Filter. If you do not feel
74 comfortable taking responsibility for your own actions, you
75 should stop reading this document and hire a qualified secu-
76 rity professional to install your firewall for you.
81 Unless otherwise stated, HOWTO documents are copy-
82 righted by their respective authors. HOWTO documents may be
83 reproduced and distributed in whole or in part, in any
84 medium physical or electronic, as long as this copyright
85 notice is retained on all copies. Commercial redistribution
86 is allowed and encouraged; however, the authors would like
87 to be notified of any such distributions.
89 All translations, derivative works, or aggregate works
90 incorporating any HOWTO documents must be covered under this
91 copyright notice. That is, you may not produce a derivative
92 work from a HOWTO and impose additional restrictions on its
93 distribution. Exceptions to these rules may be granted under
94 certain conditions; please contact the HOWTO coordinator.
96 In short, we wish to promote dissemination of this
97 information through as many channels as possible. However,
98 we do wish to retain copyright on the HOWTO documents, and
99 would like to be notified of any plans to redistribute the
103 1.3. Where to obtain the important pieces
105 The official IPF homepage is at:
106 <http://coombs.anu.edu.au/~avalon/ip-filter.html>
108 The most up-to-date version of this document can be
109 found at: <http://www.obfuscation.org/ipf/>
116 This section is designed to familiarize you with ipfil-
117 ter's syntax, and firewall theory in general. The features
118 discussed here are features you'll find in any good firewall
119 package. This section will give you a good foundation to
120 make reading and understanding the advanced section very
121 easy. It must be emphasized that this section alone is not
122 enough to build a good firewall, and that the advanced sec-
123 tion really is required reading for anybody who wants to
124 build an effective security system.
140 2.1. Config File Dynamics, Order and Precedence
142 IPF (IP Filter) has a config file (as opposed to say,
143 running some command again and again for each new rule).
144 The config file drips with Unix: There's one rule per line,
145 the "#" mark denotes a comment, and you can have a rule and
146 a comment on the same line. Extraneous whitespace is
147 allowed, and is encouraged to keep the rules readable.
150 2.2. Basic Rule Processing
152 The rules are processed from top to bottom, each one
153 appended after another. This quite simply means that if the
154 entirety of your config file is:
159 The computer sees it as:
164 Which is to say that when a packet comes in, the first thing
169 Should IPF deem it necessary to move on to the next rule, it
170 would then apply the second rule:
174 At this point, you might want to ask yourself "would
175 IPF move on to the second rule?" If you're familiar with
176 ipfwadm or ipfw, you probably won't ask yourself this.
177 Shortly after, you will become bewildered at the weird way
178 packets are always getting denied or passed when they
179 shouldn't. Many packet filters stop comparing packets to
180 rulesets the moment the first match is made; IPF is not one
183 Unlike the other packet filters, IPF keeps a flag on
184 whether or not it's going to pass the packet. Unless you
185 interrupt the flow, IPF will go through the entire ruleset,
186 making its decision on whether or not to pass or drop the
187 packet based on the last matching rule. The scene: IP Fil-
188 ter's on duty. It's been been scheduled a slice of CPU
189 time. It has a checkpoint clipboard that reads:
206 A packet comes in the interface and it's time to go to work.
207 It takes a look at the packet, it takes a look at the first
212 "So far I think I will block this packet" says IPF. It
213 takes a look at the second rule:
217 "So far I think I will pass this packet" says IPF. It takes
218 a look at a third rule. There is no third rule, so it goes
219 with what its last motivation was, to pass the packet
222 It's a good time to point out that even if the ruleset had
231 that the packet would still have gone through. There is no
232 cumulative effect. The last matching rule always takes
235 2.3. Controlling Rule Processing
237 If you have experience with other packet filters, you
238 may find this layout to be confusing, and you may be specu-
239 lating that there are problems with portability with other
240 filters and speed of rule matching. Imagine if you had 100
241 rules and most of the applicable ones were the first 10.
242 There would be a terrible overhead for every packet coming
243 in to go through 100 rules every time. Fortunately, there
244 is a simple keyword you can add to any rule that makes it
245 take action at that match. That keyword is quick.
247 Here's a modified copy of the original ruleset using the
253 In this case, IPF looks at the first rule:
257 The packet matches and the search is over. The packet is
258 expunged without a peep. There are no notices, no logs, no
259 memorial service. Cake will not be served. So what about
276 This rule is never encountered. It could just as eas-
277 ily not be in the config file at all. The sweeping match of
278 all and the terminal keyword quick from the previous rule
279 make certain that no rules are followed afterward.
281 Having half a config file laid to waste is rarely a
282 desirable state. On the other hand, IPF is here to block
283 packets and as configured, it's doing a very good job.
284 Nonetheless, IPF is also here to let some packets through,
285 so a change to the ruleset to make this possible is called
288 2.4. Basic filtering by IP address
290 IPF will match packets on many criteria. The one that
291 we most commonly think of is the IP address. There are some
292 blocks of address space from which we should never get traf-
293 fic. One such block is from the unroutable networks,
294 192.168.0.0/16 (/16 is the CIDR notation for a netmask. You
295 may be more familiar with the dotted decimal format,
296 255.255.0.0. IPF accepts both). If you wanted to block
297 192.168.0.0/16, this is one way to do it:
299 block in quick from 192.168.0.0/16 to any
302 Now we have a less stringent ruleset that actually does
303 something for us. Let's imagine a packet comes in from
304 1.2.3.4. The first rule is applied:
306 block in quick from 192.168.0.0/16 to any
308 The packet is from 1.2.3.4, not 192.168.*.*, so there is no
309 match. The second rule is applied:
313 The packet from 1.2.3.4 is definitely a part of all, so the
314 packet is sent to whatever it's destination happened to be.
316 On the other hand, suppose we have a packet that comes
317 in from 192.168.1.2. The first rule is applied:
319 block in quick from 192.168.0.0/16 to any
321 There's a match, the packet is dropped, and that's the end.
322 Again, it doesn't move to the second rule because the first
323 rule matches and contains the quick keyword.
338 At this point you can build a fairly extensive set of
339 definitive addresses which are passed or blocked. Since
340 we've already started blocking private address space from
341 entering our firewall, let's take care of the rest of it:
343 block in quick from 192.168.0.0/16 to any
344 block in quick from 172.16.0.0/12 to any
345 block in quick from 10.0.0.0/8 to any
348 The first three address blocks are some of the private IP
351 2.5. Controlling Your Interfaces
353 It seems very frequent that companies have internal
354 networks before they want a link to the outside world. In
355 fact, it's probably reasonable to say that's the main reason
356 people consider firewalls in the first place. The machine
357 that bridges the outside world to the inside world and vice
358 versa is the router. What separates the router from any
359 other machine is simple: It has more than one interface.
361 Every packet you receive comes from a network inter-
362 face; every packet you transmit goes out a network inter-
363 face. Say your machine has 3 interfaces, lo0 (loopback),
364 xl0 (3com ethernet), and tun0 (FreeBSD's generic tunnel
365 interface that PPP uses), but you don't want packets coming
366 in on the tun0 interface?
368 block in quick on tun0 all
371 In this case, the on keyword means that that data is coming
372 in on the named interface. If a packet comes in on tun0,
373 the first rule will block it. If a packet comes in on lo0
374 or in on xl0, the first rule will not match, the second rule
375 will, the packet will be passed.
377 2.6. Using IP Address and Interface Together
379 It's an odd state of affairs when one decides it best
380 to have the tun0 interface up, but not allow any data to be
381 received from it. The more criteria the firewall matches
382 against, the tighter (or looser) the firewall can become.
383 Maybe you want data from tun0, but not from 192.168.0.0/16?
384 This is the start of a powerful firewall.
386 block in quick on tun0 from 192.168.0.0/16 to any
389 <http://www.faqs.org/rfcs/rfc1918.html> and
390 <http://www.ietf.org/internet-drafts/draft-man-
406 Compare this to our previous rule:
408 block in quick from 192.168.0.0/16 to any
411 The old way, all traffic from 192.168.0.0/16, regardless of
412 interface, was completely blocked. The new way, using on
413 tun0 means that it's only blocked if it comes in on the tun0
414 interface. If a packet arrived on the xl0 interface from
415 192.168.0.0/16, it would be passed.
417 At this point you can build a fairly extensive set of
418 definitive addresses which are passed or blocked. Since
419 we've already started blocking private address space from
420 entering tun0, let's take care of the rest of it:
422 block in quick on tun0 from 192.168.0.0/16 to any
423 block in quick on tun0 from 172.16.0.0/12 to any
424 block in quick on tun0 from 10.0.0.0/8 to any
425 block in quick on tun0 from 127.0.0.0/8 to any
426 block in quick on tun0 from 0.0.0.0/8 to any
427 block in quick on tun0 from 169.254.0.0/16 to any
428 block in quick on tun0 from 192.0.2.0/24 to any
429 block in quick on tun0 from 204.152.64.0/23 to any
430 block in quick on tun0 from 224.0.0.0/3 to any
433 You've already seen the first three blocks, but not the
434 rest. The fourth is a largely wasted class-A network used
435 for loopback. Much software communicates with itself on
436 127.0.0.1 so blocking it from an external source is a good
437 idea. The fifth, 0.0.0.0/8, should never be seen on the
438 internet. Most IP stacks treat "0.0.0.0/32" as the default
439 gateway, and the rest of the 0.*.*.* network gets handled
440 strangely by various systems as a byproduct of how routing
441 decisions are made. You should treat 0.0.0.0/8 just like
442 127.0.0.0/8. 169.254.0.0/16 has been assigned by the IANA
443 for use in auto-configuration when systems have not yet been
444 able to obtain an IP address via DHCP or the like. Most
445 notably, Microsoft Windows will use addresses in this range
446 if they are set to DHCP and cannot find a DHCP server.
447 192.0.2.0/24 has also been reserved for use as an example IP
448 netblock for documentation authors. We specifically do not
449 use this range as it would cause confusion when we tell you
450 to block it, and thus all our examples come from
451 20.20.20.0/24. 204.152.64.0/23 is an odd netblock reserved
452 by Sun Microsystems for private cluster interconnects, and
453 blocking this is up to your own judgement. Lastly,
454 224.0.0.0/3 wipes out the "Class D and E" networks which is
455 used mostly for multicast traffic, although further defini-
456 tion of "Class E" space can be found in RFC 1166.
470 There's a very important principle in packet filtering
471 which has only been alluded to with the private network
472 blocking and that is this: When you know there's certain
473 types of data that only comes from certain places, you setup
474 the system to only allow that kind of data from those
475 places. In the case of the unroutable addresses, you know
476 that nothing from 10.0.0.0/8 should be arriving on tun0
477 because you have no way to reply to it. It's an illegiti-
478 mate packet. The same goes for the other unroutables as
481 Many pieces of software do all their authentication
482 based upon the packet's originating IP address. When you
483 have an internal network, say 20.20.20.0/24, you know that
484 the only traffic for that internal network is going to come
485 off the local ethernet. Should a packet from 20.20.20.0/24
486 arrive over a PPP dialup, it's perfectly reasonable to drop
487 it on the floor, or put it in a dark room for interrogation.
488 It should by no means be allowed to get to its final desti-
489 nation. You can accomplish this particularly easily with
490 what you already know of IPF. The new ruleset would be:
492 block in quick on tun0 from 192.168.0.0/16 to any
493 block in quick on tun0 from 172.16.0.0/12 to any
494 block in quick on tun0 from 10.0.0.0/8 to any
495 block in quick on tun0 from 127.0.0.0/8 to any
496 block in quick on tun0 from 0.0.0.0/8 to any
497 block in quick on tun0 from 169.254.0.0/16 to any
498 block in quick on tun0 from 192.0.2.0/24 to any
499 block in quick on tun0 from 204.152.64.0/23 to any
500 block in quick on tun0 from 224.0.0.0/3 to any
501 block in quick on tun0 from 20.20.20.0/24 to any
504 2.7. Bi-Directional Filtering; The "out" Keyword
506 Up until now, we've been passing or blocking inbound
507 traffic. To clarify, inbound traffic is all traffic that
508 enters the firewall on any interface. Conversely, outbound
509 traffic is all traffic that leaves on any interface (whether
510 locally generated or simply passing through). This means
511 that all packets coming in are not only filtered as they
512 enter the firewall, they're also filtered as they exit.
513 Thusfar there's been an implied pass out all that may or may
514 not be desirable. Just as you may pass and block incoming
515 traffic, you may do the same with outgoing traffic.
517 Now that we know there's a way to filter outbound pack-
518 ets just like inbound, it's up to us to find a conceivable
519 use for such a thing. One possible use of this idea is to
520 keep spoofed packets from exiting your own network. Instead
521 of passing any traffic out the router, you could instead
522 limit permitted traffic to packets originating at
536 20.20.20.0/24. You might do it like this:
538 pass out quick on tun0 from 20.20.20.0/24 to any
539 block out quick on tun0 from any to any
541 If a packet comes from 20.20.20.1/32, it gets sent out by
542 the first rule. If a packet comes from 1.2.3.4/32 it gets
543 blocked by the second.
545 You can also make similar rules for the unroutable
546 addresses. If some machine tries to route a packet through
547 IPF with a destination in 192.168.0.0/16, why not drop it?
548 The worst that can happen is that you'll spare yourself some
551 block out quick on tun0 from any to 192.168.0.0/16
552 block out quick on tun0 from any to 172.16.0.0/12
553 block out quick on tun0 from any to 10.0.0.0/8
554 block out quick on tun0 from any to 0.0.0.0/8
555 block out quick on tun0 from any to 127.0.0.0/8
556 block out quick on tun0 from any to 169.254.0.0/16
557 block out quick on tun0 from any to 192.0.2.0/24
558 block out quick on tun0 from any to 204.152.64.0/23
559 block out quick on tun0 from any to 224.0.0.0/3
560 block out quick on tun0 from !20.20.20.0/24 to any
562 In the narrowest viewpoint, this doesn't enhance your secu-
563 rity. It enhances everybody else's security, and that's a
564 nice thing to do. As another viewpoint, one might suppose
565 that because nobody can send spoofed packets from your site,
566 that your site has less value as a relay for crackers, and
567 as such is less of a target.
569 You'll likely find a number of uses for blocking out-
570 bound packets. One thing to always keep in mind is that in
571 and out directions are in reference to your firewall, never
574 2.8. Logging What Happens; The "log" Keyword
576 Up to this point, all blocked and passed packets have
577 been silently blocked and silently passed. Usually you want
578 to know if you're being attacked rather than wonder if that
579 firewall is really buying you any added benefits. While I
580 wouldn't want to log every passed packet, and in some cases
581 every blocked packet, I would want to know about the blocked
582 packets from 20.20.20.0/24. To do this, we add the log key-
585 block in quick on tun0 from 192.168.0.0/16 to any
587 This can, of course, be changed by using -DIPFIL-
588 TER_DEFAULT_BLOCK when compiling ipfilter on your
602 block in quick on tun0 from 172.16.0.0/12 to any
603 block in quick on tun0 from 10.0.0.0/8 to any
604 block in quick on tun0 from 127.0.0.0/8 to any
605 block in quick on tun0 from 0.0.0.0/8 to any
606 block in quick on tun0 from 169.254.0.0/16 to any
607 block in quick on tun0 from 192.0.2.0/24 to any
608 block in quick on tun0 from 204.152.64.0/23 to any
609 block in quick on tun0 from 224.0.0.0/3 to any
610 block in log quick on tun0 from 20.20.20.0/24 to any
613 So far, our firewall is pretty good at blocking packets com-
614 ing to it from suspect places, but there's still more to be
615 done. For one thing, we're accepting packets destined any-
616 where. One thing we ought to do is make sure packets to
617 20.20.20.0/32 and 20.20.20.255/32 get dropped on the floor.
618 To do otherwise opens the internal network for a smurf
619 attack. These two lines would prevent our hypothetical net-
620 work from being used as a smurf relay:
622 block in log quick on tun0 from any to 20.20.20.0/32
623 block in log quick on tun0 from any to 20.20.20.255/32
625 This brings our total ruleset to look something like this:
627 block in quick on tun0 from 192.168.0.0/16 to any
628 block in quick on tun0 from 172.16.0.0/12 to any
629 block in quick on tun0 from 10.0.0.0/8 to any
630 block in quick on tun0 from 127.0.0.0/8 to any
631 block in quick on tun0 from 0.0.0.0/8 to any
632 block in quick on tun0 from 169.254.0.0/16 to any
633 block in quick on tun0 from 192.0.2.0/24 to any
634 block in quick on tun0 from 204.152.64.0/23 to any
635 block in quick on tun0 from 224.0.0.0/3 to any
636 block in log quick on tun0 from 20.20.20.0/24 to any
637 block in log quick on tun0 from any to 20.20.20.0/32
638 block in log quick on tun0 from any to 20.20.20.255/32
641 2.9. Complete Bi-Directional Filtering By Interface
643 So far we have only presented fragments of a complete
644 ruleset. When you're actually creating your ruleset, you
645 should setup rules for every direction and every interface.
646 The default state of ipfilter is to pass packets. It is as
647 though there were an invisible rule at the beginning which
648 states pass in all and pass out all. Rather than rely on
649 some default behaviour, make everything as specific as pos-
650 sible, interface by interface, until every base is covered.
652 First we'll start with the lo0 interface, which wants
653 to run wild and free. Since these are programs talking to
654 others on the local system, go ahead and keep it unre-
668 pass out quick on lo0
671 Next, there's the xl0 interface. Later on we'll begin plac-
672 ing restrictions on the xl0 interface, but to start with,
673 we'll act as though everything on our local network is
674 trustworthy and give it much the same treatment as lo0:
676 pass out quick on xl0
679 Finally, there's the tun0 interface, which we've been half-
680 filtering with up until now:
682 block out quick on tun0 from any to 192.168.0.0/16
683 block out quick on tun0 from any to 172.16.0.0/12
684 block out quick on tun0 from any to 127.0.0.0/8
685 block out quick on tun0 from any to 10.0.0.0/8
686 block out quick on tun0 from any to 0.0.0.0/8
687 block out quick on tun0 from any to 169.254.0.0/16
688 block out quick on tun0 from any to 192.0.2.0/24
689 block out quick on tun0 from any to 204.152.64.0/23
690 block out quick on tun0 from any to 224.0.0.0/3
691 pass out quick on tun0 from 20.20.20.0/24 to any
692 block out quick on tun0 from any to any
694 block in quick on tun0 from 192.168.0.0/16 to any
695 block in quick on tun0 from 172.16.0.0/12 to any
696 block in quick on tun0 from 10.0.0.0/8 to any
697 block in quick on tun0 from 127.0.0.0/8 to any
698 block in quick on tun0 from 0.0.0.0/8 to any
699 block in quick on tun0 from 169.254.0.0/16 to any
700 block in quick on tun0 from 192.0.2.0/24 to any
701 block in quick on tun0 from 204.152.64.0/23 to any
702 block in quick on tun0 from 224.0.0.0/3 to any
703 block in log quick on tun0 from 20.20.20.0/24 to any
704 block in log quick on tun0 from any to 20.20.20.0/32
705 block in log quick on tun0 from any to 20.20.20.255/32
708 This is a pretty significant amount of filtering already,
709 protecting 20.20.20.0/24 from being spoofed or being used
710 for spoofing. Future examples will continue to show one-
711 sideness, but keep in mind that it's for brevity's sake, and
712 when setting up your own ruleset, adding rules for every
713 direction and every interface is necessary.
716 2.10. Controlling Specific Protocols; The "proto" Keyword
718 Denial of Service attacks are as rampant as buffer
719 overflow exploits. Many denial of service attacks rely on
720 glitches in the OS's TCP/IP stack. Frequently, this has
721 come in the form of ICMP packets. Why not block them
736 block in log quick on tun0 proto icmp from any to any
738 Now any ICMP traffic coming in from tun0 will be logged and
741 2.11. Filtering ICMP with the "icmp-type" Keyword; Merging
744 Of course, dropping all ICMP isn't really an ideal sit-
745 uation. Why not drop all ICMP? Well, because it's useful
746 to have partially enabled. So maybe you want to keep some
747 types of ICMP traffic and drop other kinds. If you want
748 ping and traceroute to work, you need to let in ICMP types 0
749 and 11. Strictly speaking, this might not be a good idea,
750 but if you need to weigh security against convenience, IPF
753 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
754 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
756 Remember that ruleset order is important. Since we're doing
757 everything quick we must have our passes before our blocks,
758 so we really want the last three rules in this order:
760 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
761 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
762 block in log quick on tun0 proto icmp from any to any
764 Adding these 3 rules to the anti-spoofing rules is a bit
765 tricky. One error might be to put the new ICMP rules at the
768 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
769 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
770 block in log quick on tun0 proto icmp from any to any
771 block in quick on tun0 from 192.168.0.0/16 to any
772 block in quick on tun0 from 172.16.0.0/12 to any
773 block in quick on tun0 from 10.0.0.0/8 to any
774 block in quick on tun0 from 127.0.0.0/8 to any
775 block in quick on tun0 from 0.0.0.0/8 to any
776 block in quick on tun0 from 169.254.0.0/16 to any
777 block in quick on tun0 from 192.0.2.0/24 to any
778 block in quick on tun0 from 204.152.64.0/23 to any
779 block in quick on tun0 from 224.0.0.0/3 to any
780 block in log quick on tun0 from 20.20.20.0/24 to any
781 block in log quick on tun0 from any to 20.20.20.0/32
782 block in log quick on tun0 from any to 20.20.20.255/32
785 The problem with this is that an ICMP type 0 packet from
786 192.168.0.0/16 will get passed by the first rule, and never
787 blocked by the fourth rule. Also, since we quickly pass an
800 ICMP ECHO_REPLY (type 0) to 20.20.20.0/24, we've just opened
801 ourselves back up to a nasty smurf attack and nullified
802 those last two block rules. Oops. To avoid this, we place
803 the ICMP rules after the anti-spoofing rules:
805 block in quick on tun0 from 192.168.0.0/16 to any
806 block in quick on tun0 from 172.16.0.0/12 to any
807 block in quick on tun0 from 10.0.0.0/8 to any
808 block in quick on tun0 from 127.0.0.0/8 to any
809 block in quick on tun0 from 0.0.0.0/8 to any
810 block in quick on tun0 from 169.254.0.0/16 to any
811 block in quick on tun0 from 192.0.2.0/24 to any
812 block in quick on tun0 from 204.152.64.0/23 to any
813 block in quick on tun0 from 224.0.0.0/3 to any
814 block in log quick on tun0 from 20.20.20.0/24 to any
815 block in log quick on tun0 from any to 20.20.20.0/32
816 block in log quick on tun0 from any to 20.20.20.255/32
817 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
818 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
819 block in log quick on tun0 proto icmp from any to any
822 Because we block spoofed traffic before the ICMP rules are
823 processed, a spoofed packet never makes it to the ICMP rule-
824 set. It's very important to keep such situations in mind
827 2.12. TCP and UDP Ports; The "port" Keyword
829 Now that we've started blocking packets based on proto-
830 col, we can start blocking packets based on specific aspects
831 of each protocol. The most frequently used of these aspects
832 is the port number. Services such as rsh, rlogin, and tel-
833 net are all very convenient to have, but also hideously
834 insecure against network sniffing and spoofing. One great
835 compromise is to only allow the services to run internally,
836 then block them externally. This is easy to do because
837 rlogin, rsh, and telnet use specific TCP ports (513, 514,
838 and 23 respectively). As such, creating rules to block them
841 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
842 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
843 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
845 Make sure all 3 are before the pass in all and they'll be
846 closed off from the outside (leaving out spoofing for
849 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
850 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
851 block in log quick on tun0 proto icmp from any to any
852 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
853 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
866 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
869 You might also want to block 514/udp (syslog), 111/tcp &
870 111/udp (portmap), 515/tcp (lpd), 2049/tcp and 2049/udp
871 (NFS), 6000/tcp (X11) and so on and so forth. You can get a
872 complete listing of the ports being listened to by using
873 netstat -a (or lsof -i, if you have it installed).
875 Blocking UDP instead of TCP only requires replacing
876 proto tcp with proto udp. The rule for syslog would be:
878 block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 514
880 IPF also has a shorthand way to write rules that apply to
881 both proto tcp and proto udp at the same time, such as
882 portmap or NFS. The rule for portmap would be:
884 block in log quick on tun0 proto tcp/udp from any to 20.20.20.0/24 port = 111
889 3. Advanced Firewalling Introduction
891 This section is designed as an immediate followup to
892 the basic section. Contained below are both concepts for
893 advanced firewall design, and advanced features contained
894 only within ipfilter. Once you are comfortable with this
895 section, you should be able to build a very strong firewall.
897 3.1. Rampant Paranoia; or The Default-Deny Stance
899 There's a big problem with blocking services by the
900 port: sometimes they move. RPC based programs are terrible
901 about this, lockd, statd, even nfsd listens places other
902 than 2049. It's awfully hard to predict, and even worse to
903 automate adjusting all the time. What if you miss a ser-
904 vice? Instead of dealing with all that hassle, let's start
905 over with a clean slate. The current ruleset looks like
911 Yes, we really are starting over. The first rule we're
912 going to use is this:
916 No network traffic gets through. None. Not a peep. You're
917 rather secure with this setup. Not terribly useful, but
918 quite secure. The great thing is that it doesn't take much
919 more to make your box rather secure, yet useful too. Let's
932 say the machine this is running on is a web server, nothing
933 more, nothing less. It doesn't even do DNS lookups. It
934 just wants to take connections on 80/tcp and that's it. We
935 can do that. We can do that with a second rule, and you
939 pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80
941 This machine will pass in port 80 traffic for 20.20.20.1,
942 and deny everything else. For basic firewalling, this is
945 3.2. Implicit Allow; The "keep state" Rule
947 The job of your firewall is to prevent unwanted traffic
948 getting to point B from point A. We have general rules
949 which say "as long as this packet is to port 23, it's okay."
950 We have general rules which say "as long as this packet has
951 its FIN flag set, it's okay." Our firewalls don't know the
952 beginning, middle, or end of any TCP/UDP/ICMP session. They
953 merely have vague rules that are applied to all packets.
954 We're left to hope that the packet with its FIN flag set
955 isn't really a FIN scan, mapping our services. We hope that
956 the packet to port 23 isn't an attempted hijack of our tel-
957 net session. What if there was a way to identify and autho-
958 rize individual TCP/UDP/ICMP sessions and distinguish them
959 from port scanners and DoS attacks? There is a way, it's
960 called keeping state.
962 We want convenience and security in one. Lots of peo-
963 ple do, that's why Ciscos have an "established" clause that
964 lets established tcp sessions go through. Ipfw has estab-
965 lished. Ipfwadm has setup/established. They all have this
966 feature, but the name is very misleading. When we first saw
967 it, we thought it meant our packet filter was keeping track
968 of what was going on, that it knew if a connection was
969 really established or not. The fact is, they're all taking
970 the packet's word for it from a part of the packet anybody
971 can lie about. They read the TCP packet's flags section and
972 there's the reason UDP/ICMP don't work with it, they have no
973 such thing. Anybody who can create a packet with bogus
974 flags can get by a firewall with this setup.
976 Where does IPF come in to play here, you ask? Well,
977 unlike the other firewalls, IPF really can keep track of
978 whether or not a connection is established. And it'll do it
979 with TCP, UDP and ICMP, not just TCP. Ipf calls it keeping
980 state. The keyword for the ruleset is keep state.
982 Up until now, we've told you that packets come in, then
983 the ruleset gets checked; packets go out, then the ruleset
984 gets checked. Actually, what happens is packets come in,
985 the state table gets checked, then *maybe* the inbound
998 ruleset gets checked; packets go out, the state table gets
999 checked, then *maybe* the outbound ruleset gets checked.
1000 The state table is a list of TCP/UDP/ICMP sessions that are
1001 unquestionadely passed through the firewall, circumventing
1002 the entire ruleset. Sound like a serious security hole?
1003 Hang on, it's the best thing that ever happened to your
1006 All TCP/IP sessions have a start, a middle, and an end
1007 (even though they're sometimes all in the same packet). You
1008 can't have an end without a middle and you can't have a mid-
1009 dle without a start. This means that all you really need to
1010 filter on is the beginning of a TCP/UDP/ICMP session. If
1011 the beginning of the session is allowed by your firewall
1012 rules, you really want the middle and end to be allowed too
1013 (lest your IP stack should overflow and your machines become
1014 useless). Keeping state allows you to ignore the middle and
1015 end and simply focus on blocking/passing new sessions. If
1016 the new session is passed, all its subsequent packets will
1017 be allowed through. If it's blocked, none of its subsequent
1018 packets will be allowed through. Here's an example for run-
1019 ning an ssh server (and nothing but an ssh server):
1021 block out quick on tun0 all
1022 pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep state
1024 The first thing you might notice is that there's no "pass
1025 out" provision. In fact, there's only an all-inclusive
1026 "block out" rule. Despite this, the ruleset is complete.
1027 This is because by keeping state, the entire ruleset is cir-
1028 cumvented. Once the first SYN packet hits the ssh server,
1029 state is created and the remainder of the ssh session is
1030 allowed to take place without interference from the fire-
1031 wall. Here's another example:
1033 block in quick on tun0 all
1034 pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
1036 In this case, the server is running no services. Infact,
1037 it's not a server, it's a client. And this client doesn't
1038 want unauthorized packets entering its IP stack at all.
1039 However, the client wants full access to the internet and
1040 the reply packets that such privledge entails. This simple
1041 ruleset creates state entries for every new outgoing TCP
1042 session. Again, since a state entry is created, these new
1043 TCP sessions are free to talk back and forth as they please
1044 without the hinderance or inspection of the firewall rule-
1045 set. We mentioned that this also works for UDP and ICMP:
1047 block in quick on tun0 all
1048 pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
1049 pass out quick on tun0 proto udp from 20.20.20.1/32 to any keep state
1050 pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state
1064 Yes Virginia, we can ping. Now we're keeping state on TCP,
1065 UDP, ICMP. Now we can make outgoing connections as though
1066 there's no firewall at all, yet would-be attackers can't get
1067 back in. This is very handy because there's no need to
1068 track down what ports we're listening to, only the ports we
1069 want people to be able to get to.
1071 State is pretty handy, but it's also a bit tricky. You
1072 can shoot yourself in the foot in strange and mysterious
1073 ways. Consider the following ruleset:
1075 pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23
1076 pass out quick on tun0 proto tcp from any to any keep state
1080 At first glance, this seems to be a good setup. We allow
1081 incoming sessions to port 23, and outgoing sessions any-
1082 where. Naturally packets going to port 23 will have reply
1083 packets, but the ruleset is setup in such a way that the
1084 pass out rule will generate a state entry and everything
1085 will work perfectly. At least, you'd think so.
1087 The unfortunate truth is that after 60 seconds of idle
1088 time the state entry will be closed (as opposed to the nor-
1089 mal 5 days). This is because the state tracker never saw
1090 the original SYN packet destined to port 23, it only saw the
1091 SYN ACK. IPF is very good about following TCP sessions from
1092 start to finish, but it's not very good about coming into
1093 the middle of a connection, so rewrite the rule to look like
1096 pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
1097 pass out quick on tun0 proto tcp from any to any keep state
1101 The additional of this rule will enter the very first packet
1102 into the state table and everything will work as expected.
1103 Once the 3-way handshake has been witness by the state
1104 engine, it is marked in 4/4 mode, which means it's setup for
1105 long-term data exchange until such time as the connection is
1106 torn down (wherein the mode changes again. You can see the
1107 current modes of your state table with ipfstat -s.
1111 UDP is stateless so naturally it's a bit harder to do a
1112 reliable job of keeping state on it. Nonetheless, ipf does
1113 a pretty good job. When machine A sends a UDP packet to
1114 machine B with source port X and destination port Y, ipf
1115 will allow a reply from machine B to machine A with source
1116 port Y and destination port X. This is a short term state
1117 entry, a mere 60 seconds.
1130 Here's an example of what happens if we use nslookup to
1131 get the IP address of www.3com.com:
1133 $ nslookup www.3com.com
1135 A DNS packet is generated:
1137 17:54:25.499852 20.20.20.1.2111 > 198.41.0.5.53: 51979+
1139 The packet is from 20.20.20.1, port 2111, destined for
1140 198.41.0.5, port 53. A 60 second state entry is created.
1141 If a packet comes back from 198.41.0.5 port 53 destined for
1142 20.20.20.1 port 2111 within that period of time, the reply
1143 packet will be let through. As you can see, milliseconds
1146 17:54:25.501209 198.41.0.5.53 > 20.20.20.1.2111: 51979 q: www.3com.com
1148 The reply packet matches the state criteria and is let
1149 through. At that same moment that packet is let through,
1150 the state gateway is closed and no new incoming packets will
1151 be allowed in, even if they claim to be from the same place.
1155 IPFilter handles ICMP states in the manner that one
1156 would expect from understanding how ICMP is used with TCP
1157 and UDP, and with your understanding of how keep state
1158 works. There are two general types of ICMP messages;
1159 requests and replies. When you write a rule such as:
1161 pass out on tun0 proto icmp from any to any icmp-type 8 keep state
1163 to allow outbound echo requests (a typical ping), the resul-
1164 tant icmp-type 0 packet that comes back will be allowed in.
1165 This state entry has a default timeout of an incomplete 0/0
1166 state of 60 seconds. Thus, if you are keeping state on any
1167 outbound icmp message that will elicit an icmp message in
1168 reply, you need a proto icmp [...] keep state rule.
1170 However, the majority of ICMP messages are status mes-
1171 sages generated by some failure in UDP (and sometimes TCP),
1172 and in 3.4.x and greater IPFilters, any ICMP error status
1173 message (say icmp-type 3 code 3 port unreachable, or icmp-
1174 type 11 time exceeded) that matches an active state table
1175 entry that could have generated that message, the ICMP
1176 packet is let in. For example, in older IPFilters, if you
1177 wanted traceroute to work, you needed to use:
1179 pass out on tun0 proto udp from any to any port 33434><33690 keep state
1180 pass in on tun0 proto icmp from any to any icmp-type timex
1182 whereas now you can do the right thing and just keep state
1196 pass out on tun0 proto udp from any to any port 33434><33690 keep state
1198 To provide some protection against a third-party sneaking
1199 ICMP messages through your firewall when an active connec-
1200 tion is known to be in your state table, the incoming ICMP
1201 packet is checked not only for matching source and destina-
1202 tion addresses (and ports, when applicable) but a tiny part
1203 of the payload of the packet that the ICMP message is claim-
1204 ing it was generated by.
1206 3.5. FIN Scan Detection; "flags" Keyword, "keep frags" Key-
1209 Let's go back to the 4 rule set from the previous section:
1211 pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state
1212 pass out quick on tun0 proto tcp from any to any keep state
1216 This is almost, but not quite, satisfactory. The problem is
1217 that it's not just SYN packets that're allowed to go to port
1218 23, any old packet can get through. We can change this by
1219 using the flags option:
1221 pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state
1222 pass out quick on tun0 proto tcp from any to any flags S keep state
1226 Now only TCP packets, destined for 20.20.20.1, at port 23,
1227 with a lone SYN flag will be allowed in and entered into the
1228 state table. A lone SYN flag is only present as the very
1229 first packet in a TCP session (called the TCP handshake) and
1230 that's really what we wanted all along. There's at least
1231 two advantages to this: No arbitrary packets can come in
1232 and make a mess of your state table. Also, FIN and XMAS
1233 scans will fail since they set flags other than the SYN
1234 flag. Now all incoming packets must either be handshakes or
1235 have state already. If anything else comes in, it's proba-
1236 bly a port scan or a forged packet. There's one exception
1237 to that, which is when a packet comes in that's fragmented
1238 from its journey. IPF has provisions for this as well, the
1240 Some examples use flags S/SA instead of flags S.
1241 flags S actually equates to flags S/AUPRFS and
1242 matches against only the SYN packet out of all six
1243 possible flags, while flags S/SA will allow pack-
1244 ets that may or may not have the URG, PSH, FIN, or
1245 RST flags set. Some protocols demand the URG or
1246 PSH flags, and S/SAFR would be a better choice for
1247 these, however we feel that it is less secure to
1248 blindly use S/SA when it isn't required. But it's
1262 keep frags keyword. With it, IPF will notice and keep track
1263 of packets that are fragmented, allowing the expected frag-
1264 ments to to go through. Let's rewrite the 3 rules to log
1265 forgeries and allow fragments:
1267 pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state keep frags
1268 pass out quick on tun0 proto tcp from any to any keep state flags S keep frags
1269 block in log quick all
1270 block out log quick all
1272 This works because every packet that should be allowed
1273 through makes it into the state table before the blocking
1274 rules are reached. The only scan this won't detect is a SYN
1275 scan itself. If you're truely worried about that, you might
1276 even want to log all initial SYN packets.
1278 3.6. Responding To a Blocked Packet
1280 So far, all of our blocked packets have been dumped on
1281 the floor, logged or not, we've never sent anything back to
1282 the originating host. Sometimes this isn't the most desir-
1283 able of responses because in doing so, we actually tell the
1284 attacker that a packet filter is present. It seems a far
1285 better thing to misguide the attacker into believing that,
1286 while there's no packet filter running, there's likewise no
1287 services to break into. This is where fancier blocking
1290 When a service isn't running on a Unix system, it nor-
1291 mally lets the remote host know with some sort of return
1292 packet. In TCP, this is done with an RST (Reset) packet.
1293 When blocking a TCP packet, IPF can actually return an RST
1294 to the origin by using the return-rst keyword.
1298 block in log on tun0 proto tcp from any to 20.20.20.0/24 port = 23
1303 block return-rst in log proto tcp from any to 20.20.20.0/24 port = 23
1304 block in log quick on tun0
1307 We need two block statements since return-rst only works
1308 with TCP, and we still want to block protocols such as UDP,
1309 ICMP, and others. Now that this is done, the remote side
1310 will get "connection refused" instead of "connection timed
1313 It's also possible to send an error message when some-
1314 body sends a packet to a UDP port on your system. Whereas
1315 once you might have used:
1328 block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
1330 You could instead use the return-icmp keyword to send a
1333 block return-icmp(port-unr) in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111
1335 According to TCP/IP Illustrated, port-unreachable is the
1336 correct ICMP type to return when no service is listening on
1337 the port in question. You can use any ICMP type you like,
1338 but port-unreachable is probably your best bet. It's also
1339 the default ICMP type for return-icmp.
1341 However, when using return-icmp, you'll notice that
1342 it's not very stealthy, and it returns the ICMP packet with
1343 the IP address of the firewall, not the original destination
1344 of the packet. This was fixed in ipfilter 3.3, and a new
1345 keyword; return-icmp-as-dest, has been added. The new for-
1348 block return-icmp-as-dest(port-unr) in log on tun0 proto udp from any to 20.20.20.0/24 port = 111
1350 3.7. Fancy Logging Techniques
1352 It is important to note that the presence of the log
1353 keyword only ensures that the packet will be available to
1354 the ipfilter logging device; /dev/ipl. In order to actu-
1355 ally see this log information, one must be running the ipmon
1356 utility (or some other utility that reads from /dev/ipl).
1357 The typical usage of log is coupled with ipmon -s to log the
1358 information to syslog. As of ipfilter 3.3, one can now even
1359 control the logging behavior of syslog by using log level
1360 keywords, as in rules such as this:
1362 block in log level auth.info quick on tun0 from 20.20.20.0/24 to any
1363 block in log level auth.alert quick on tun0 proto tcp from any to 20.20.20.0/24 port = 21
1365 In addition to this, you can tailor what information is
1366 being logged. For example, you may not be interested that
1367 someone attempted to probe your telnet port 500 times, but
1368 you are interested that they probed you once. You can use
1369 the log first keyword to only log the first example of a
1370 packet. Of course, the notion of "first-ness" only applies
1371 to packets in a specific session, and for the typical
1372 blocked packet, you will be hard pressed to encounter situa-
1373 tions where this does what you expect. However, if used in
1374 conjunction with pass and keep state, this can be a valuable
1375 keyword for keeping tabs on traffic.
1377 Another useful thing you can do with the logs is to
1378 keep track of interesting pieces of the packet in addition
1379 to the header information normally being logged. Ipfilter
1380 will give you the first 128 bytes of the packet if you use
1381 the log body keyword. You should limit the use of body
1394 logging, as it makes your logs very verbose, but for certain
1395 applications, it is often handy to be able to go back and
1396 take a look at the packet, or to send this data to another
1397 application that can examine it further.
1399 3.8. Putting It All Together
1401 So now we have a pretty tight firewall, but it can
1402 still be tighter. Some of the original ruleset we wiped
1403 clean is actually very useful. I'd suggest bringing back
1404 all the anti-spoofing stuff. This leaves us with:
1407 block in quick on tun0 from 192.168.0.0/16 to any
1408 block in quick on tun0 from 172.16.0.0/12 to any
1409 block in quick on tun0 from 10.0.0.0/8 to any
1410 block in quick on tun0 from 127.0.0.0/8 to any
1411 block in quick on tun0 from 0.0.0.0/8 to any
1412 block in quick on tun0 from 169.254.0.0/16 to any
1413 block in quick on tun0 from 192.0.2.0/24 to any
1414 block in quick on tun0 from 204.152.64.0/23 to any
1415 block in quick on tun0 from 224.0.0.0/3 to any
1416 block in log quick on tun0 from 20.20.20.0/24 to any
1417 block in log quick on tun0 from any to 20.20.20.0/32
1418 block in log quick on tun0 from any to 20.20.20.255/32
1419 pass out quick on tun0 proto tcp/udp from 20.20.20.1/32 to any keep state
1420 pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state
1421 pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 flags S keep state
1423 3.9. Improving Performance With Rule Groups
1425 Let's extend our use of our firewall by creating a much
1426 more complicated, and we hope more applicable to the real
1427 world, example configuration For this example, we're going
1428 to change the interface names, and network numbers. Let's
1429 assume that we have three interfaces in our firewall with
1430 interfaces xl0, xl1, and xl2.
1432 xl0 is connected to our external network 20.20.20.0/26
1433 xl1 is connected to our "DMZ" network 20.20.20.64/26
1434 xl2 is connected to our protected network 20.20.20.128/25
1436 We'll define the entire ruleset in one swoop, since we fig-
1437 ure that you can read these rules by now:
1439 block in quick on xl0 from 192.168.0.0/16 to any
1440 block in quick on xl0 from 172.16.0.0/12 to any
1441 block in quick on xl0 from 10.0.0.0/8 to any
1442 block in quick on xl0 from 127.0.0.0/8 to any
1443 block in quick on xl0 from 0.0.0.0/8 to any
1444 block in quick on xl0 from 169.254.0.0/16 to any
1445 block in quick on xl0 from 192.0.2.0/24 to any
1446 block in quick on xl0 from 204.152.64.0/23 to any
1447 block in quick on xl0 from 224.0.0.0/3 to any
1460 block in log quick on xl0 from 20.20.20.0/24 to any
1461 block in log quick on xl0 from any to 20.20.20.0/32
1462 block in log quick on xl0 from any to 20.20.20.63/32
1463 block in log quick on xl0 from any to 20.20.20.64/32
1464 block in log quick on xl0 from any to 20.20.20.127/32
1465 block in log quick on xl0 from any to 20.20.20.128/32
1466 block in log quick on xl0 from any to 20.20.20.255/32
1469 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state
1470 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state
1471 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state
1472 pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state
1473 pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state
1474 pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
1475 pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state
1476 block out on xl1 all
1477 pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
1479 block out on xl2 all
1480 pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
1482 From this arbitrary example, we can already see that our
1483 ruleset is becoming unwieldy. To make matters worse, as we
1484 add more specific rules to our DMZ network, we add addi-
1485 tional tests that must be parsed for every packet, which
1486 affects the performance of the xl0 <-> xl2 connections. If
1487 you set up a firewall with a ruleset like this, and you have
1488 lots of bandwidth and a moderate amount of cpu, everyone
1489 that has a workstation on the xl2 network is going to come
1490 looking for your head to place on a platter. So, to keep
1491 your head <-> torso network intact, you can speed things
1492 along by creating rule groups. Rule groups allow you to
1493 write your ruleset in a tree fashion, instead of as a linear
1494 list, so that if your packet has nothing to do with the set
1495 of tests (say, all those xl1 rules) those rules will never
1496 be consulted. It's somewhat like having multiple firewalls
1497 all on the same machine.
1499 Here's a simple example to get us started:
1501 block out quick on xl1 all head 10
1502 pass out quick proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
1503 block out on xl2 all
1505 In this simplistic example, we can see a small hint of the
1506 power of the rule group. If the packet is not destined for
1507 xl1, the head of rule group 10 will not match, and we will
1508 go on with our tests. If the packet does match for xl1, the
1509 quick keyword will short-circuit all further processing at
1510 the root level (rule group 0), and focus the testing on
1511 rules which belong to group 10; namely, the SYN check for
1512 80/tcp. In this way, we can re-write the above rules so
1513 that we can maximize performance of our firewall.
1526 block in quick on xl0 all head 1
1527 block in quick on xl0 from 192.168.0.0/16 to any group 1
1528 block in quick on xl0 from 172.16.0.0/12 to any group 1
1529 block in quick on xl0 from 10.0.0.0/8 to any group 1
1530 block in quick on xl0 from 127.0.0.0/8 to any group 1
1531 block in quick on xl0 from 0.0.0.0/8 to any group 1
1532 block in quick on xl0 from 169.254.0.0/16 to any group 1
1533 block in quick on xl0 from 192.0.2.0/24 to any group 1
1534 block in quick on xl0 from 204.152.64.0/23 to any group 1
1535 block in quick on xl0 from 224.0.0.0/3 to any group 1
1536 block in log quick on xl0 from 20.20.20.0/24 to any group 1
1537 block in log quick on xl0 from any to 20.20.20.0/32 group 1
1538 block in log quick on xl0 from any to 20.20.20.63/32 group 1
1539 block in log quick on xl0 from any to 20.20.20.64/32 group 1
1540 block in log quick on xl0 from any to 20.20.20.127/32 group 1
1541 block in log quick on xl0 from any to 20.20.20.128/32 group 1
1542 block in log quick on xl0 from any to 20.20.20.255/32 group 1
1543 pass in on xl0 all group 1
1547 block out quick on xl1 all head 10
1548 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10
1549 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state group 10
1550 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state group 10
1551 pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state group 10
1552 pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state group 10
1553 pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state
1554 pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state group 10
1556 pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state
1558 block out on xl2 all
1560 pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state
1562 Now you can see the rule groups in action. For a host on
1563 the xl2 network, we can completely bypass all the checks in
1564 group 10 when we're not communicating with hosts on that
1567 Depending on your situation, it may be prudent to group
1568 your rules by protocol, or various machines, or netblocks,
1569 or whatever makes it flow smoothly.
1571 3.10. "Fastroute"; The Keyword of Stealthiness
1573 Even though we're forwarding some packets, and blocking
1574 other packets, we're typically behaving like a well behaved
1575 router should by decrementing the TTL on the packet and
1576 acknowledging to the entire world that yes, there is a hop
1577 here. But we can hide our presence from inquisitive appli-
1578 cations like unix traceroute which uses UDP packets with
1579 various TTL values to map the hops between two sites. If we
1592 want incoming traceroutes to work, but we do not want to
1593 announce the presence of our firewall as a hop, we can do so
1594 with a rule like this:
1596 block in quick on xl0 fastroute proto udp from any to any port 33434 >< 33465
1598 The presence of the fastroute keyword will signal ipfilter
1599 to not pass the packet into the Unix IP stack for routing
1600 which results in a TTL decrement. The packet will be placed
1601 gently on the output interface by ipfilter itself and no
1602 such decrement will happen. Ipfilter will of course use the
1603 system's routing table to figure out what the appropriate
1604 output interface really is, but it will take care of the
1605 actual task of routing itself.
1607 There's a reason we used block quick in our example,
1608 too. If we had used pass, and if we had IP Forwarding
1609 enabled in our kernel, we would end up having two paths for
1610 a packet to come out of, and we would probably panic our
1613 It should be noted, however, that most Unix kernels
1614 (and certainly the ones underlying the systems that ipfilter
1615 usually runs on) have far more efficient routing code than
1616 what exists in ipfilter, and this keyword should not be
1617 thought of as a way to improve the operating speed of your
1618 firewall, and should only be used in places where stealth is
1626 Outside of the corporate environment, one of the
1627 biggest enticements of firewall technology to the end user
1628 is the ability to connect several computers through a common
1629 external interface, often without the approval, knowledge,
1630 or even consent of their service provider. To those famil-
1631 iar with Linux, this concept is called IP Masquerading, but
1632 to the rest of the world it is known by the more obscure
1633 name of Network Address Translation, or NAT for short.
1635 4.1. Mapping Many Addresses Into One Address
1637 The basic use of NAT accomplishes much the same thing
1638 that Linux's IP Masquerading function does, and it does it
1640 To be pedantic, what IPFilter provides is really
1641 called NPAT, for Network and Port Address Transla-
1642 tion, which means we can change any of the source
1643 and destination IP Addresses and their source and
1644 destination ports. True NAT only allows one to
1645 change the addresses.
1658 with one simple rule:
1660 map tun0 192.168.1.0/24 -> 20.20.20.1/32
1662 Very simple. Whenever a packet goes out the tun0 interface
1663 with a source address matching the CIDR network mask of
1664 192.168.1.0/24 this packet will be rewritten within the IP
1665 stack such that its source address is 20.20.20.1, and it
1666 will be sent on to its original destination. The system
1667 also keeps a list of what translated connections are in
1668 progress so that it can perform the reverse and remap the
1669 response (which will be directed to 20.20.20.1) to the
1670 internal host that really generated the packet.
1672 There is a drawback to the rule we have just written,
1673 though. In a large number of cases, we do not happen to
1674 know what the IP address of our outside link is (if we're
1675 using tun0 or ppp0 and a typical ISP) so it makes setting up
1676 our NAT tables a chore. Luckily, NAT is smart enough to
1677 accept an address of 0/32 as a signal that it needs to go
1678 look at what the address of that interface really is and we
1679 can rewrite our rule as follows:
1681 map tun0 192.168.1.0/24 -> 0/32
1683 Now we can load our ipnat rules with impunity and connect to
1684 the outside world without having to edit anything. You do
1685 have to run ipf -y to refresh the address if you get discon-
1686 nected and redial or if your DHCP lease changes, though.
1688 Some of you may be wondering what happens to the source
1689 port when the mapping happens. With our current rule, the
1690 packet's source port is unchanged from the original source
1691 port. There can be instances where we do not desire this
1692 behavior; maybe we have another firewall further upstream we
1693 have to pass through, or perhaps many hosts are trying to
1694 use the same source port, causing a collision where the rule
1695 doesn't match and the packet is passed untranslated. ipnat
1696 helps us here with the portmap keyword:
1698 map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000
1700 Our rule now shoehorns all the translated connections (which
1701 can be tcp, udp, or tcp/udp) into the port range of 20000 to
1707 This is a typical internal address space, since
1708 it's non-routable on the Real Internet it is often
1709 used for internal networks. You should still
1710 block these packets coming in from the outside
1711 world as discussed earlier.
1724 4.2. Mapping Many Addresses Into a Pool of Addresses
1726 Another use common use of NAT is to take a small stati-
1727 cally allocated block of addresses and map many computers
1728 into this smaller address space. This is easy to accom-
1729 plish using what you already know about the map and portmap
1730 keywords by writing a rule like so:
1732 map tun0 192.168.0.0/16 -> 20.20.20.0/24 portmap tcp/udp 20000:60000
1734 Also, there may be instances where a remote application
1735 requires that multiple connections all come from the same IP
1736 address. We can help with these situations by telling NAT
1737 to statically map sessions from a host into the pool of
1738 addresses and work some magic to choose a port. This uses a
1739 the keyword map-block as follows:
1741 map-block tun0 192.168.1.0/24 -> 20.20.20.0/24
1743 4.3. One to One Mappings
1745 Occasionally it is desirable to have a system with one
1746 IP address behind the firewall to appear to have a com-
1747 pletely different IP address. One example of how this would
1748 work would be a lab of computers which are then attached to
1749 various networks that are to be put under some kind of test.
1750 In this example, you would not want to have to reconfigure
1751 the entire lab when you could place a NAT system in front
1752 and change the addresses in one simple place. We can do
1753 that with the bimap keyword, for bidirectional mapping.
1754 Bimap has some additional protections on it to ensure a
1755 known state for the connection, whereas the map keyword is
1756 designed to allocate an address and a source port and
1757 rewrite the packet and go on with life.
1759 bimap tun0 192.168.1.1/32 -> 20.20.20.1/32
1761 will accomplish the mapping for one host.
1763 4.4. Spoofing Services
1765 Spoofing services? What does that have to do with any-
1766 thing? Plenty. Let's pretend that we have a web server
1767 running on 20.20.20.5, and since we've gotten increasingly
1768 suspicious of our network security, we desire to not run
1769 this server on port 80 since that requires a brief lifespan
1770 as the root user. But how do we run it on a less
1771 privledged port of 8000 in this world of "anything dot com"?
1772 How will anyone find our server? We can use the redirection
1773 facilities of NAT to solve this problem by instructing it to
1774 remap any connections destined for 20.20.20.5:80 to really
1775 point to 20.20.20.5:8000. This uses the rdr keyword:
1777 rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000
1790 We can also specify the protocol here, if we wanted to redi-
1791 rect a UDP service, instead of a TCP service (which is the
1792 default). For example, if we had a honeypot on our firewall
1793 to impersonate the popular Back Orifice for Windows, we
1794 could shovel our entire network into this one place with a
1797 rdr tun0 20.20.20.0/24 port 31337 -> 127.0.0.1 port 31337 udp
1799 An extremely important point must be made about rdr: You
1800 cannot easily use this feature as a "reflector". E.g:
1802 rdr tun0 20.20.20.5/32 port 80 -> 20.20.20.6 port 80 tcp
1804 will not work in the situation where .5 and .6 are on the
1805 same LAN segment. The rdr function is applied to packets
1806 that enter the firewall on the specified interface. When a
1807 packet comes in that matches a rdr rule, its destination
1808 address is then rewritten, it is pushed into ipf for filter-
1809 ing, and should it successfully run the gauntlet of filter
1810 rules, it is then sent to the unix routing code. Since this
1811 packet is still inbound on the same interface that it will
1812 need to leave the system on to reach a host, the system gets
1813 confused. Reflectors don't work. Neither does specifying
1814 the address of the interface the packet just came in on.
1815 Always remember that rdr destinations must exit out of the
1816 firewall host on a different interface.
1818 4.5. Transparent Proxy Support; Redirection Made Useful
1820 Since you're installing a firewall, you may have
1821 decided that it is prudent to use a proxy for many of your
1822 outgoing connections so that you can further tighten your
1823 filter rules protecting your internal network, or you may
1824 have run into a situation that the NAT mapping process does
1825 not currently handle properly. This can also be accom-
1826 plished with a redirection statement:
1828 rdr xl0 0.0.0.0/0 port 21 -> 127.0.0.1 port 21
1830 This statement says that any packet coming in on the xl0
1831 interface destined for any address (0.0.0.0/0) on the ftp
1832 port should be rewritten to connect it with a proxy that is
1833 running on the NAT system on port 21.
1836 Yes. There is a way to do this. It's so convo-
1837 luted that I refuse to use it, though. Smart peo-
1838 ple who require this functionality will transpar-
1839 ently redirect into something like TIS plug-gw on
1840 127.0.0.1. Stupid people will set up a dummy loop
1841 interface pair and double rewrite.
1842 This includes 127.0.0.1, by the way. That's on
1856 This specific example of FTP proxying does lead to some
1857 complications when used with web browsers or other auto-
1858 matic-login type clients that are unaware of the require-
1859 ments of communicating with the proxy. There are patches
1860 for TIS Firewall Toolkit'sftp-gw to mate it with the nat
1861 process so that it can determine where you were trying to go
1862 and automatically send you there. Many proxy packages now
1863 work in a transparent proxy environment (Squid for example,
1864 located at http://squid.nlanr.net, works fine.)
1866 This application of the rdr keyword is often more use-
1867 ful when you wish to force users to authenticate themselves
1868 with the proxy. (For example, you desire your engineers to
1869 be able to surf the web, but you would rather not have your
1870 call-center staff doing so.)
1872 4.6. Magic Hidden Within NAT; Application Proxies
1874 Since ipnat provides a method to rewrite packets as
1875 they traverse the firewall, it becomes a convenient place to
1876 build in some application level proxies to make up for well
1877 known deficiencies of that application and typical fire-
1878 walls. For example; FTP. We can make our firewall pay
1879 attention to the packets going across it and when it notices
1880 that it's dealing with an Active FTP session, it can write
1881 itself some temporary rules, much like what happens with
1882 keep state, so that the FTP data connection works. To do
1883 this, we use a rule like so:
1885 map tun0 192.168.1.0/24 -> 20.20.20.1/32 proxy port ftp ftp/tcp
1887 You must always remember to place this proxy rule before any
1888 portmap rules, otherwise when portmap comes along and
1889 matches the packet and rewrites it before the proxy gets a
1890 chance to work on it. Remember that ipnat rules are first-
1893 There also exist proxies for "rcmd" (which we suspect
1894 is berkeley r-* commands which should be forbidden anyway,
1895 thus we haven't looked at what this proxy does) and "raudio"
1896 for Real Audio PNM streams. Likewise, both of these rules
1897 should be put before any portmap rules, if you're doing NAT.
1901 5. Loading and Manipulating Filter Rules; The ipf Utility
1903 IP Filter rules are loaded by using the ipf utility.
1904 The filter rules can be stored in any file on the system,
1905 but typically these rules are stored in /etc/ipf.rules,
1906 /usr/local/etc/ipf.rules, or /etc/opt/ipf/ipf.rules.
1908 IP Filter has two sets of rules, the active set and the
1909 inactive set. By default, all operations are performed on
1922 the active set. You can manipulate the inactive set by
1923 adding -I to the ipf command line. The two sets can be
1924 toggled by using the -s command line option. This is very
1925 useful for testing new rule sets without wiping out the old
1928 Rules can also be removed from the list instead of
1929 added by using the -r command line option, but it is gener-
1930 ally a safer idea to flush the rule set that you're working
1931 on with -F and completely reload it when making changes.
1933 In summary, the easiest way to load a rule set is ipf
1934 -Fa -f /etc/ipf.rules. For more complicated manipulations
1935 of the rule set, please see the ipf(1) man page.
1937 6. Loading and Manipulating NAT Rules; The ipnat Utility
1939 NAT rules are loaded by using the ipnat utility. The
1940 NAT rules can be stored in any file on the system, but typi-
1941 cally these rules are stored in /etc/ipnat.rules,
1942 /usr/local/etc/ipnat.rules, or /etc/opt/ipf/ipnat.rules.
1944 Rules can also be removed from the list instead of
1945 added by using the -r command line option, but it is gener-
1946 ally a safer idea to flush the rule set that you're working
1947 on with -C and completely reload it when making changes.
1948 Any active mappings are not affected by -C, and can be
1951 NAT rules and active mappings can be examined with the
1952 -l command line option.
1954 In summary, the easiest way to load a NAT rule set is
1955 ipnat -CF -f /etc/ipnat.rules.
1957 7. Monitoring and Debugging
1959 There will come a time when you are interested in what
1960 your firewall is actually doing, and ipfilter would be
1961 incomplete if it didn't have a full suite of status monitor-
1964 7.1. The ipfstat utility
1966 In its simplest form, ipfstat displays a table of
1967 interesting data about how your firewall is performing, such
1968 as how many packets have been passed or blocked, if they
1969 were logged or not, how many state entries have been made,
1970 and so on. Here's an example of something you might see
1971 from running the tool:
1974 input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0
1975 output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0
1988 input packets logged: blocked 99286 passed 0
1989 output packets logged: blocked 0 passed 0
1990 packets logged: input 0 output 0
1991 log failures: input 3898 output 0
1992 fragment state(in): kept 0 lost 0
1993 fragment state(out): kept 0 lost 0
1994 packet state(in): kept 169364 lost 0
1995 packet state(out): kept 431395 lost 0
1996 ICMP replies: 0 TCP RSTs sent: 0
1997 Result cache hits(in): 1215208 (out): 1098963
1998 IN Pullups succeeded: 2 failed: 0
1999 OUT Pullups succeeded: 0 failed: 0
2000 Fastroute successes: 0 failures: 0
2001 TCP cksum fails(in): 0 (out): 0
2002 Packet log flags set: (0)
2005 ipfstat is also capable of showing you your current rule
2006 list. Using the -i or the -o flag will show the currently
2007 loaded rules for in or out, respectively. Adding a -h to
2008 this will provide more useful information at the same time
2009 by showing you a "hit count" on each rule. For example:
2012 2451423 pass out on xl0 from any to any
2013 354727 block out on ppp0 from any to any
2014 430918 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
2016 From this, we can see that perhaps there's something abnor-
2017 mal going on, since we've got a lot of blocked packets out-
2018 bound, even with a very permissive pass out rule. Something
2019 here may warrant further investigation, or it may be func-
2020 tioning perfectly by design. ipfstat can't tell you if your
2021 rules are right or wrong, it can only tell you what is hap-
2022 pening because of your rules.
2024 To further debug your rules, you may want to use the -n
2025 flag, which will show the rule number next to each rule.
2028 @1 pass out on xl0 from any to any
2029 @2 block out on ppp0 from any to any
2030 @3 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags
2032 The final piece of really interesting information that ipfs-
2033 tat can provide us is a dump of the state table. This is
2034 done with the -s flag:
2059 100.100.100.1 -> 20.20.20.1 ttl 864000 pass 20490 pr 6 state 4/4
2060 pkts 196 bytes 17394 987 -> 22 585538471:2213225493 16592:16500
2061 pass in log quick keep state
2062 pkt_flags & b = 2, pkt_options & ffffffff = 0
2063 pkt_security & ffff = 0, pkt_auth & ffff = 0
2065 Here we see that we have one state entry for a TCP connec-
2066 tion. The output will vary slightly from version to ver-
2067 sion, but the basic information is the same. We can see in
2068 this connection that we have a fully established connection
2069 (represented by the 4/4 state. Other states are incomplete
2070 and will be documented fully later.) We can see that the
2071 state entry has a time to live of 240 hours, which is an
2072 absurdly long time, but is the default for an established
2073 TCP connection. This TTL counter is decremented every sec-
2074 ond that the state entry is not used, and will finally
2075 result in the connection being purged if it has been left
2076 idle. The TTL is also reset to 864000 whenever the state
2077 IS used, ensuring that the entry will not time out while it
2078 is being actively used. We can also see that we have passed
2079 196 packets consisting of about 17kB worth of data over this
2080 connection. We can see the ports for both endpoints, in
2081 this case 987 and 22; which means that this state entry rep-
2082 resents a connection from 100.100.100.1 port 987 to
2083 20.20.20.1 port 22. The really big numbers in the second
2084 line are the TCP sequence numbers for this connection, which
2085 helps to ensure that someone isn't easily able to inject a
2086 forged packet into your session. The TCP window is also
2087 shown. The third line is a synopsis of the implicit rule
2088 that was generated by the keep state code, showing that this
2089 connection is an inbound connection.
2091 7.2. The ipmon utility
2093 ipfstat is great for collecting snapshots of what's
2094 going on on the system, but it's often handy to have some
2095 kind of log to look at and watch events as they happen in
2096 time. ipmon is this tool. ipmon is capable of watching
2097 the packet log (as created with the log keyword in your
2098 rules), the state log, or the nat log, or any combination of
2099 the three. This tool can either be run in the foreground,
2100 or as a daemon which logs to syslog or a file. If we wanted
2101 to watch the state table in action, ipmon -o S would show
2105 01/08/1999 15:58:57.836053 STATE:NEW 100.100.100.1,53 -> 20.20.20.15,53 PR udp
2106 01/08/1999 15:58:58.030815 STATE:NEW 20.20.20.15,123 -> 128.167.1.69,123 PR udp
2107 01/08/1999 15:59:18.032174 STATE:NEW 20.20.20.15,123 -> 128.173.14.71,123 PR udp
2120 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
2121 01/08/1999 16:03:51.754867 STATE:NEW 20.20.20.13,1019 -> 100.100.100.10,22 PR tcp
2122 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
2124 Here we see a state entry for an external dns request off
2125 our nameserver, two xntp pings to well-known time servers,
2126 and a very short lived outbound ssh connection.
2128 ipmon is also capable of showing us what packets have
2129 been logged. For example, when using state, you'll often
2130 run into packets like this:
2133 15:57:33.803147 ppp0 @0:2 b 100.100.100.103,443 -> 20.20.20.10,4923 PR tcp len 20 1488 -A
2135 What does this mean? The first field is obvious, it's a
2136 timestamp. The second field is also pretty obvious, it's
2137 the interface that this event happened on. The third field
2138 @0:2 is something most people miss. This is the rule that
2139 caused the event to happen. Remember ipfstat -in? If you
2140 wanted to know where this came from, you could look there
2141 for rule 2 in rule group 0. The fourth field, the little
2142 "b" says that this packet was blocked, and you'll generally
2143 ignore this unless you're logging passed packets as well,
2144 which would be a little "p" instead. The fifth and sixth
2145 fields are pretty self-explanatory, they say where this
2146 packet came from and where it was going. The seventh ("PR")
2147 and eighth fields tell you the protocol and the ninth field
2148 tells you the size of the packet. The last part, the "-A"
2149 in this case, tells you the flags that were on the packet;
2150 This one was an ACK packet. Why did I mention state ear-
2151 lier? Due to the often laggy nature of the Internet, some-
2152 times packets will be regenerated. Sometimes, you'll get
2153 two copies of the same packet, and your state rule which
2154 keeps track of sequence numbers will have already seen this
2155 packet, so it will assume that the packet is part of a dif-
2156 ferent connection. Eventually this packet will run into a
2157 real rule and have to be dealt with. You'll often see the
2158 last packet of a session being closed get logged because the
2159 keep state code has already torn down the connection before
2160 the last packet has had a chance to make it to your fire-
2161 wall. This is normal, do not be alarmed. Another example
2162 packet that might be logged:
2164 12:46:12.470951 xl0 @0:1 S 20.20.20.254 -> 255.255.255.255 PR icmp len 20 9216 icmp 9/0
2167 For a technical presentation of the IP Filter
2168 stateful inspection engine, please see the white
2169 paper Real Stateful TCP Packet Filtering in IP
2170 Filter, by Guido van Rooij. This paper may be
2172 <http://www.iae.nl/users/guido/papers/tcp_filter-
2186 This is a ICMP router discovery broadcast. We can tell by
2189 Finally, ipmon also lets us look at the NAT table in action.
2192 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]
2193 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
2195 This would be a redirection to an identd that lies to pro-
2196 vide ident service for the hosts behind our NAT, since they
2197 are typically unable to provide this service for themselves
2198 with ordinary natting.
2203 8. Specific Applications of IP Filter - Things that don't
2204 fit, but should be mentioned anyway.
2206 8.1. Keep State With Servers and Flags.
2208 Keeping state is a good thing, but it's quite easy to
2209 make a mistake in the direction that you want to keep state
2210 in. Generally, you want to have a keep state keyword on
2211 the first rule that interacts with a packet for the connec-
2212 tion. One common mistake that is made when mixing state
2213 tracking with filtering on flags is this:
2216 pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S
2217 pass out all keep state
2219 That certainly appears to allow a connection to be created
2220 to the telnet server on 20.20.20.20, and the replies to go
2221 back. If you try using this rule, you'll see that it does
2222 work--Momentarily. Since we're filtering for the SYN flag,
2223 the state entry never fully gets completed, and the default
2224 time to live for an incomplete state is 60 seconds.
2226 We can solve this by rewriting the rules in one of two ways:
2231 pass in quick proto tcp from any to 20.20.20.20/32 port = 23 keep state
2239 pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S keep state
2252 pass out all keep state
2254 Either of these sets of rules will result in a fully estab-
2255 lished state entry for a connection to your server.
2257 8.2. Coping With FTP
2259 FTP is one of those protocols that you just have to sit
2260 back and ask "What the heck were they thinking?" FTP has
2261 many problems that the firewall administrator needs to deal
2262 with. What's worse, the problems the administrator must
2263 face are different between making ftp clients work and mak-
2264 ing ftp servers work.
2266 Within the FTP protocol, there are two forms of data
2267 transfer, called active and passive. Active transfers are
2268 those where the server connects to an open port on the
2269 client to send data. Conversely, passive transfers are
2270 those where the client connects to the server to receive
2273 8.2.1. Running an FTP Server
2275 In running an FTP server, handling Active FTP sessions
2276 is easy to setup. At the same time, handling Passive FTP
2277 sessions is a big problem. First we'll cover how to handle
2278 Active FTP, then move on to Passive. Generally, we can han-
2279 dle Active FTP sessions like we would an incoming HTTP or
2280 SMTP connection; just open the ftp port and let keep state
2283 pass in quick proto tcp from any to 20.20.20.20/32 port = 21 flags S keep state
2284 pass out proto tcp all keep state
2286 These rules will allow Active FTP sessions, the most common
2287 type, to your ftp server on 20.20.20.20.
2289 The next challenge becomes handling Passive FTP connec-
2290 tions. Web browsers default to this mode, so it's becoming
2291 quite popular and as such it should be supported. The prob-
2292 lem with passive connections are that for every passive con-
2293 nection, the server starts listening on a new port (usually
2294 above 1023). This is essentially like creating a new
2295 unknown service on the server. Assuming we have a good
2296 firewall with a default-deny policy, that new service will
2297 be blocked, and thus Active FTP sessions are broken. Don't
2298 despair! There's hope yet to be had.
2300 A person's first inclination to solving this problem
2301 might be to just open up all ports above 1023. In truth,
2304 pass in quick proto tcp from any to 20.20.20.20/32 port > 1023 flags S keep state
2305 pass out proto tcp all keep state
2318 This is somewhat unsatisfactory, though. By letting every-
2319 thing above 1023 in, we actually open ourselves up for a
2320 number of potential problems. While 1-1023 is the desig-
2321 nated area for server services to run, numerous programs
2322 decided to use numbers higher than 1023, such as nfsd and X.
2324 The good news is that your FTP server gets to decide
2325 which ports get assigned to passive sessions. This means
2326 that instead of opening all ports above 1023, you can allo-
2327 cate ports 15001-19999 as ftp ports and only open that range
2328 of your firewall up. In wu-ftpd, this is done with the pas-
2329 sive ports option in ftpaccess. Please see the man page on
2330 ftpaccess for details in wu-ftpd configuration. On the
2331 ipfilter side, all we need do is setup corresponding rules:
2333 pass in quick proto tcp from any to 20.20.20.20/32 port 15000 >< 20000 flags S keep state
2334 pass out proto tcp all keep state
2336 If even this solution doesn't satisfy you, you can always
2337 hack IPF support into your FTP server, or FTP server support
2340 8.2.2. Running an FTP Client
2342 While FTP server support is still less than perfect in
2343 IPF, FTP client support has been working well since 3.3.3.
2344 As with FTP servers, there are two types of ftp client
2345 transfers: passive and active.
2347 The simplest type of client transfer from the fire-
2348 wall's standpoint is the passive transfer. Assuming you're
2349 keeping state on all outbound tcp sessions, passive trans-
2350 fers will work already. If you're not doing this already,
2351 please consider the following:
2353 pass out proto tcp all keep state
2355 The second type of client transfer, active, is a bit more
2356 troublesome, but nonetheless a solved problem. Active
2357 transfers cause the server to open up a second connection
2358 back to the client for data to flow through. This is nor-
2359 mally a problem when there's a firewall in the middle, stop-
2360 ping outside connections from coming back in. To solve
2361 this, ipfilter includes an ipnat proxy which temporarily
2362 opens up a hole in the firewall just for the FTP server to
2363 get back to the client. Even if you're not using ipnat to
2364 do nat, the proxy is still effective. The following rules
2365 is the bare minimum to add to the ipnat configuration file
2366 (ep0 should be the interface name of the outbound network
2369 map ep0 0/0 -> 0/32 proxy port 21 ftp/tcp
2384 For more details on ipfilter's internal proxies, see section
2387 8.3. Assorted Kernel Variables
2389 There are some useful kernel tunes that either need to
2390 be set for ipf to function, or are just generally handy to
2391 know about for building firewalls. The first major one you
2392 must set is to enable IP Forwarding, otherwise ipf will do
2393 very little, as the underlying ip stack won't actually route
2399 net.inet.ip.forwarding=1
2403 net.inet.ip.forwarding=1
2407 net.inet.ip.forwarding=1
2411 ndd -set /dev/ip ip_forwarding 1
2413 Ephemeral Port Adjustment:
2416 net.inet.ip.portfirst = 25000
2420 net.inet.ip.portrange.first = 25000 net.inet.ip.por-
2425 net.inet.ip.anonportmin = 25000 net.inet.ip.anonportmax
2430 ndd -set /dev/tcp tcp_smallest_anon_port 25000
2431 ndd -set /dev/tcp tcp_largest_anon_port 65535
2433 Other Useful Values:
2436 net.inet.ip.sourceroute = 0
2437 net.inet.ip.directed-broadcast = 0
2451 net.inet.ip.sourceroute=0
2452 net.ip.accept_sourceroute=0
2456 net.inet.ip.allowsrcrt=0
2457 net.inet.ip.forwsrcrt=0
2458 net.inet.ip.directed-broadcast=0
2459 net.inet.ip.redirect=0
2463 ndd -set /dev/ip ip_forward_directed_broadcasts 0
2464 ndd -set /dev/ip ip_forward_src_routed 0
2465 ndd -set /dev/ip ip_respond_to_echo_broadcast 0
2467 In addition, freebsd has some ipf specific sysctl variables.
2469 net.inet.ipf.fr_flags: 0
2470 net.inet.ipf.fr_pass: 514
2471 net.inet.ipf.fr_active: 0
2472 net.inet.ipf.fr_tcpidletimeout: 864000
2473 net.inet.ipf.fr_tcpclosewait: 60
2474 net.inet.ipf.fr_tcplastack: 20
2475 net.inet.ipf.fr_tcptimeout: 120
2476 net.inet.ipf.fr_tcpclosed: 1
2477 net.inet.ipf.fr_udptimeout: 120
2478 net.inet.ipf.fr_icmptimeout: 120
2479 net.inet.ipf.fr_defnatage: 1200
2480 net.inet.ipf.fr_ipfrttl: 120
2481 net.inet.ipf.ipl_unreach: 13
2482 net.inet.ipf.ipl_inited: 1
2483 net.inet.ipf.fr_authsize: 32
2484 net.inet.ipf.fr_authused: 0
2485 net.inet.ipf.fr_defaultauthage: 600
2492 This section doesn't necessarily teach you anything new
2493 about ipf, but it may raise an issue or two that you haven't
2494 yet thought up on your own, or tickle your brain in a way
2495 that you invent something interesting that we haven't
2498 9.1. Localhost Filtering
2500 A long time ago at a university far, far away, Wietse
2501 Venema created the tcp-wrapper package, and ever since, it's
2502 been used to add a layer of protection to network services
2503 all over the world. This is good. But, tcp-wrappers have
2516 flaws. For starters, they only protect TCP services, as the
2517 name suggests. Also, unless you run your service from
2518 inetd, or you have specifically compiled it with libwrap and
2519 the appropriate hooks, your service isn't protected. This
2520 leaves gigantic holes in your host security. We can plug
2521 these up by using ipf on the local host. For example, my
2522 laptop often gets plugged into or dialed into networks that
2523 I don't specifically trust, and so, I use the following rule
2526 pass in quick on lo0 all
2527 pass out quick on lo0 all
2532 pass in quick proto tcp from any to any port = 113 flags S keep state
2533 pass in quick proto tcp from any to any port = 22 flags S keep state
2534 pass in quick proto tcp from any port = 20 to any port 39999 >< 45000 flags S keep state
2536 pass out quick proto icmp from any to any keep state
2537 pass out quick proto tcp/udp from any to any keep state keep frags
2539 It's been like that for quite a while, and I haven't suf-
2540 fered any pain or anguish as a result of having ipf loaded
2541 up all the time. If I wanted to tighten it up more, I could
2542 switch to using the NAT ftp proxy and I could add in some
2543 rules to prevent spoofing. But even as it stands now, this
2544 box is far more restrictive about what it presents to the
2545 local network and beyond than the typical host does. This
2546 is a good thing if you happen to run a machine that allows a
2547 lot of users on it, and you want to make sure one of them
2548 doesn't happen to start up a service they wern't supposed
2549 to. It won't stop a malicious hacker with root access from
2550 adjusting your ipf rules and starting a service anyway, but
2551 it will keep the "honest" folks honest, and your weird ser-
2552 vices safe, cozy and warm even on a malicious LAN. A big
2553 win, in my opinion. Using local host filtering in addition
2554 to a somewhat less-restrictive "main firewall" machine can
2555 solve many performance issues as well as political night-
2556 mares like "Why doesn't ICQ work?" and "Why can't I put a
2557 web server on my own workstation! It's MY WORKSTATION!!"
2558 Another very big win. Who says you can't have security and
2559 convienence at the same time?
2561 9.2. What Firewall? Transparent filtering.
2563 One major concern in setting up a firewall is the
2564 integrity of the firewall itself. Can somebody break into
2565 your firewall, thereby subverting its ruleset? This is a
2566 common problem administrators must face, particularly when
2567 they're using firewall solutions on top of their Unix/NT
2568 machines. Some use it as an arguement for blackbox hardware
2569 solutions, under the flawed notion that inherent obscurity
2582 of their closed system increases their security. We have a
2585 Many network admins are familiar with the common ether-
2586 net bridge. This is a device that connects two separate
2587 ethernet segments to make them one. An ethernet bridge is
2588 typically used to connect separate buildings, switch network
2589 speeds, and extend maximum wire lengths. Hubs and switches
2590 are common bridges, sometimes they're just 2 ported devices
2591 called repeaters. Recent versions of Linux, OpenBSD,
2592 NetBSD, and FreeBSD include code to convert $1000 PCs into
2593 $10 bridges, too! What all bridges tend to have in common
2594 is that though they sit in the middle of a connection
2595 between two machines, the two machines don't know the bridge
2596 is there. Enter ipfilter and OpenBSD.
2598 Ethernet bridging takes place at Layer2 on the ISO
2599 stack. IP takes place on Layer3. IP Filter in primarily
2600 concerned with Layer3, but dabbles in Layer2 by working with
2601 interfaces. By mixing IP filter with OpenBSD's bridge
2602 device, we can create a firewall that is both invisible and
2603 unreachable. The system needs no IP address, it doesn't
2604 even need to reveal its ethernet address. The only telltale
2605 sign that the filter might be there is that latency is some-
2606 what higher than a piece of cat5 would normally make it, and
2607 that packets don't seem to make it to their final destina-
2610 The setup for this sort of ruleset is surprisingly sim-
2611 ple, too. In OpenBSD, the first bridge device is named
2612 bridge0. Say we have two ethernet cards in our machine as
2613 well, xl0 and xl1. To turn this machine into a bridge, all
2614 one need do is enter the following three commands:
2616 brconfig bridge0 add xl0 add xl1 up
2620 At ths point, all traffic ariving on xl0 is sent out xl1 and
2621 all traffic on xl1 is sent out xl0. You'll note that nei-
2622 ther interface has been assigned an IP address, nor do we
2623 need assign one. All things considered, it's likely best we
2626 Rulesets behave essentially the as the always have.
2627 Though there is a bridge0 interface, we don't filter based
2628 on it. Rules continue to be based upon the particular
2629 interface we're using, making it important which network
2630 cable is plugged into which network card in the back of the
2631 machine. Let's start with some basic filtering to illis-
2632 trate what's happened. Assume the network used to look like
2648 20.20.20.1 <---------------------------------> 20.20.20.0/24 network hub
2650 That is, we have a router at 20.20.20.1 connected to the
2651 20.20.20.0/24 network. All packets from the 20.20.20.0/24
2652 network go through 20.20.20.1 to get to the outside world
2653 and vice versa. Now we add the Ipf Bridge:
2655 20.20.20.1 <-------/xl0 IpfBridge xl1/-------> 20.20.20.0/24 network hub
2657 We also have the following ruleset loaded on the IpfBridge
2663 With this ruleset loaded, the network is functionally iden-
2664 tical. As far as the 20.20.20.1 router is concerned, and as
2665 far as the 20.20.20.0/24 hosts are concerned, the two net-
2666 work diagrams are identical. Now let's change the ruleset
2669 block in quick on xl0 proto icmp
2673 Still, 20.20.20.1 and 20.20.20.0/24 think the network is
2674 identical, but if 20.20.20.1 attempts to ping 20.20.20.2, it
2675 will never get a reply. What's more, 20.20.20.2 won't even
2676 get the packet in the first place. IPfilter will intercept
2677 the packet before it even gets to the other end of the vir-
2678 tual wire. We can put a bridged filter anywhere. Using
2679 this method we can shrink the network trust circle down an
2680 individual host level (given enough ethernet cards:-)
2682 Blocking icmp from the world seems kind of silly, espe-
2683 cially if you're a sysadmin and like pinging the world, to
2684 traceroute, or to resize your MTU. Let's construct a better
2685 ruleset and take advantage of the original key feature of
2686 ipf: stateful inspection.
2688 pass in quick on xl1 proto tcp keep state
2689 pass in quick on xl1 proto udp keep state
2690 pass in quick on xl1 proto icmp keep state
2691 block in quick on xl0
2693 In this situation, the 20.20.20.0/24 network (perhaps more
2694 aptly called the xl1 network) can now reach the outside
2695 world, but the outside world can't reach it, and it can't
2696 figure out why, either. The router is accessible, the hosts
2697 are active, but the outside world just can't get in. Even
2698 if the router itself were compromised, the firewall would
2699 still be active and successful.
2714 So far, we've been filtering by interface and protocol
2715 only. Even though bridging is concerned layer2, we can
2716 still discriminate based on IP address. Normally we have a
2717 few services running, so our ruleset may look like this:
2719 pass in quick on xl1 proto tcp keep state
2720 pass in quick on xl1 proto udp keep state
2721 pass in quick on xl1 proto icmp keep state
2722 block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.
2723 pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
2724 pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
2725 pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
2726 pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
2727 block in quick on xl0
2729 Now we have a network where 20.20.20.2 is a zone serving
2730 name server, 20.20.20.3 is an incoming mail server, and
2731 20.20.20.7 is a web server.
2733 Bridged IP Filter is not yet perfect, we must confess.
2735 First, You'll note that all the rules are setup using
2736 the in direction instead of a combination of in and out.
2737 This is because the out direction is presently unimplemented
2738 with bridging in OpenBSD. This was originally done to pre-
2739 vent vast performance drops using multiple interfaces. Work
2740 has been done in speeding it up, but it remains unimple-
2741 mented. If you really want this feature, you might try your
2742 hand at working on the code or asking the OpenBSD people how
2745 Second, using IP Filter with bridging makes the use of
2746 IPF's NAT features inadvisable, if not downright dangerous.
2747 The first problem is that it would give away that there's a
2748 filtering bridge. The second problem would be that the
2749 bridge has no IP address to masquerade with, which will most
2750 assuredly lead to confusion and perhaps a kernel panic to
2751 boot. You can, of course, put an IP address on the outbound
2752 interface to make NAT work, but part of the glee of bridging
2755 9.2.1. Using Transparent Filtering to Fix Network Design
2758 Many organizations started using IP well before they
2759 thought a firewall or a subnet would be a good idea. Now
2760 they have class-C sized networks or larger that include all
2761 their servers, their workstations, their routers, coffee
2762 makers, everything. The horror! Renumbering with proper
2763 subnets, trust levels, filters, and so are in both time con-
2764 suming and expensive. The expense in hardware and man hours
2765 alone is enough to make most organizations unwilling to
2766 really solve the problem, not to mention the downtime
2767 involved. The typical problem network looks like this:
2780 20.20.20.1 router 20.20.20.6 unix server
2781 20.20.20.2 unix server 20.20.20.7 nt workstation
2782 20.20.20.3 unix server 20.20.20.8 nt server
2783 20.20.20.4 win98 workstation 20.20.20.9 unix workstation
2784 20.20.20.5 intelligent switch 20.20.20.10 win95 workstation
2786 Only it's about 20 times larger and messier and frequently
2787 undocumented. Ideally, you'd have all the trusting servers
2788 in one subnet, all the work- stations in another, and the
2789 network switches in a third. Then the router would filter
2790 packets between the subnets, giving the workstations limited
2791 access to the servers, nothing access to the switches, and
2792 only the sysadmin's workstation access to the coffee pot.
2793 I've never seen a class-C sized network with such coherence.
2796 To start with, we're going to separate the router, the
2797 workstations, and the servers. To do this we're going to
2798 need 2 hubs (or switches) which we probably already have,
2799 and an IPF machine with 3 ethernet cards. We're going to
2800 put all the servers on one hub and all the workstations on
2801 the other. Normally we'd then connect the hubs to each
2802 other, then to the router. Instead, we're going to plug the
2803 router into IPF's xl0 interface, the servers into IPF's xl1
2804 interface, and the workstations into IPF's xl2 interface.
2805 Our network diagram looks something like this:
2807 | 20.20.20.2 unix server
2808 router (20.20.20.1) ____________| 20.20.20.3 unix server
2809 | / | 20.20.20.6 unix server
2810 | /xl1 | 20.20.20.7 nt server
2811 ------------/xl0 IPF Bridge <
2812 xl2 | 20.20.20.4 win98 workstation
2813 ____________| 20.20.20.8 nt workstation
2814 | 20.20.20.9 unix workstation
2815 | 20.20.20.10 win95 workstation
2817 Where once there was nothing but interconnecting wires, now
2818 there's a filtering bridge that not a single host needs to
2819 be modified to take advantage of. Presumably we've already
2820 enabled bridging so the network is behaving perfectly nor-
2821 mally. Further, we're starting off with a ruleset much like
2824 pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
2825 pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
2826 pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
2827 pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
2828 block in quick on xl0
2829 pass in quick on xl1 proto tcp keep state
2830 pass in quick on xl1 proto udp keep state
2831 pass in quick on xl1 proto icmp keep state
2832 block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.
2833 pass in quick on xl2 proto tcp keep state
2846 pass in quick on xl2 proto udp keep state
2847 pass in quick on xl2 proto icmp keep state
2848 block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
2850 Once again, traffic coming from the router is restricted to
2851 DNS, SMTP, and HTTP. At the moment, the servers and the
2852 workstations can exchange traffic freely. Depending on what
2853 kind of organization you are, there might be something about
2854 this network dynamic you don't like. Perhaps you don't want
2855 your workstations getting access to your servers at all?
2856 Take the xl2 ruleset of:
2858 pass in quick on xl2 proto tcp keep state
2859 pass in quick on xl2 proto udp keep state
2860 pass in quick on xl2 proto icmp keep state
2861 block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
2865 block in quick on xl2 from any to 20.20.20.0/24
2866 pass in quick on xl2 proto tcp keep state
2867 pass in quick on xl2 proto udp keep state
2868 pass in quick on xl2 proto icmp keep state
2869 block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
2871 Perhaps you want them to just get to the servers to get and
2872 send their mail with IMAP? Easily done:
2874 pass in quick on xl2 proto tcp from any to 20.20.20.3/32 port=25
2875 pass in quick on xl2 proto tcp from any to 20.20.20.3/32 port=143
2876 block in quick on xl2 from any to 20.20.20.0/24
2877 pass in quick on xl2 proto tcp keep state
2878 pass in quick on xl2 proto udp keep state
2879 pass in quick on xl2 proto icmp keep state
2880 block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.
2882 Now your workstations and servers are protected from the
2883 outside world, and the servers are protected from your work-
2886 Perhaps the opposite is true, maybe you want your work-
2887 stations to be able to get to the servers, but not the out-
2888 side world. After all, the next generation of exploits is
2889 breaking the clients, not the servers. In this case, you'd
2890 change the xl2 rules to look more like this:
2892 pass in quick on xl2 from any to 20.20.20.0/24
2893 block in quick on xl2
2895 Now the servers have free reign, but the clients can only
2896 connect to the servers. We might want to batten down the
2897 hatches on the servers, too:
2899 pass in quick on xl1 from any to 20.20.20.0/24
2912 block in quick on xl1
2914 With the combination of these two, the clients and servers
2915 can talk to each other, but neither can access the outside
2916 world (though the outside world can get to the few services
2917 from earlier). The whole ruleset would look something like
2920 pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
2921 pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
2922 pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
2923 pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
2924 block in quick on xl0
2925 pass in quick on xl1 from any to 20.20.20.0/24
2926 block in quick on xl1
2927 pass in quick on xl2 from any to 20.20.20.0/24
2928 block in quick on xl2
2930 So remember, when your network is a mess of twisty IP
2931 addresses and machine classes, transparent filtered bridges
2932 can solve a problem that would otherwise be lived with and
2933 perhaps someday exploited.
2935 9.3. Drop-Safe Logging With dup-to and to.
2937 Until now, we've been using the filter to drop packets.
2938 Instead of dropping them, let's consider passing them on to
2939 another system that can do something useful with this infor-
2940 mation beyond the logging we can perform with ipmon. Our
2941 firewall system, be it a bridge or a router, can have as
2942 many interfaces as we can cram into the system. We can use
2943 this information to create a "drop-safe" for our packets. A
2944 good example of a use for this would be to implement an
2945 intrusion detection network. For starters, it might be
2946 desirable to hide the presence of our intrusion detection
2947 systems from our real network so that we can keep them from
2950 Before we get started, there are some operational char-
2951 acteristics that we need to make note of. If we are only
2952 going to deal with blocked packets, we can use either the to
2953 keyword or the fastroute keyword. (We'll cover the differ-
2954 ences between these two later) If we're going to pass the
2955 packets like we normally would, we need to make a copy of
2956 the packet for our drop-safe log with the dup-to keyword.
2958 9.3.1. The dup-to Method
2960 If, for example, we wanted to send a copy of everything
2961 going out the xl3 interface off to our drop-safe network on
2962 ed0, we would use this rule in our filter list:
2964 pass out on xl3 dup-to ed0 from any to any
2978 You might also have a need to send the packet directly to a
2979 specific IP address on your drop-safe network instead of
2980 just making a copy of the packet out there and hoping for
2981 the best. To do this, we modify our rule slightly:
2983 pass out on xl3 dup-to ed0:192.168.254.2 from any to any
2985 But be warned that this method will alter the copied
2986 packet's destination address, and may thus destroy the use-
2987 fulness of the log. For this reason, we recommend only
2988 using the known address method of logging when you can be
2989 certain that the address that you're logging to corresponds
2990 in some way to what you're logging for (e.g.: don't use
2991 "192.168.254.2" for logging for both your web server and
2992 your mail server, since you'll have a hard time later trying
2993 to figure out which system was the target of a specific set
2996 This technique can be used quite effectively if you
2997 treat an IP Address on your drop-safe network in much the
2998 same way that you would treat a Multicast Group on the real
2999 internet. (e.g.: "192.168.254.2" could be the channel for
3000 your http traffic analysis system, "23.23.23.23" could be
3001 your channel for telnet sessions, and so on.) You don't
3002 even need to actually have this address set as an address or
3003 alias on any of your analysis systems. Normally, your
3004 ipfilter machine would need to ARP for the new destination
3005 address (using dup-to ed0:192.168.254.2 style, of course)
3006 but we can avoid that issue by creating a static arp entry
3007 for this "channel" on our ipfilter system.
3009 In general, though, dup-to ed0 is all that is required
3010 to get a new copy of the packet over to our drop-safe net-
3011 work for logging and examination.
3013 9.3.2. The to Method
3015 The dup-to method does have an immediate drawback,
3016 though. Since it has to make a copy of the packet and
3017 optionally modify it for its new destination, it's going to
3018 take a while to complete all this work and be ready to deal
3019 with the next packet coming in to the ipfilter system.
3021 If we don't care about passing the packet to its normal
3022 destination and we were going to block it anyway, we can
3023 just use the to keyword to push this packet past the normal
3024 routing table and force it to go out a different interface
3025 than it would normally go out.
3027 block in quick on xl0 to ed0 proto tcp from any to any port < 1024
3029 we use block quick for to interface routing, because like
3030 fastroute, the to interface code will generate two packet
3031 paths through ipfilter when used with pass, and likely cause
3044 your system to panic.
3048 10. Bogus Network Filtering, the ultimate in current anti-
3049 spoofing technology.
3051 We've spent a little bit of time tracking down the cur-
3052 rent vast tracts of IP address space that have been reserved
3053 by the IANA for various reasons, or are otherwise not cur-
3054 rently in use at the time this document was written. Since
3055 none of these address ranges should be in use currently,
3056 there should be no legitimate reason to ever see them as a
3057 source address, or to send them traffic as a destination
3058 address, right? Right!
3060 So without further ado, the complete list of bogus net-
3064 # s/OUTSIDE/outside-interface (eg: fxp0)
3065 # s/MYNET/network-cidr-address (eg: 1.2.3.0/24)
3067 block in on OUTSIDE all
3068 block in quick on OUTSIDE from 0.0.0.0/7 to any
3069 block in quick on OUTSIDE from 2.0.0.0/8 to any
3070 block in quick on OUTSIDE from 5.0.0.0/8 to any
3071 block in quick on OUTSIDE from 10.0.0.0/8 to any
3072 block in quick on OUTSIDE from 23.0.0.0/8 to any
3073 block in quick on OUTSIDE from 27.0.0.0/8 to any
3074 block in quick on OUTSIDE from 31.0.0.0/8 to any
3075 block in quick on OUTSIDE from 67.0.0.0/8 to any
3076 block in quick on OUTSIDE from 68.0.0.0/6 to any
3077 block in quick on OUTSIDE from 72.0.0.0/5 to any
3078 block in quick on OUTSIDE from 80.0.0.0/4 to any
3079 block in quick on OUTSIDE from 96.0.0.0/3 to any
3080 block in quick on OUTSIDE from 127.0.0.0/8 to any
3081 block in quick on OUTSIDE from 128.0.0.0/16 to any
3082 block in quick on OUTSIDE from 128.66.0.0/16 to any
3083 block in quick on OUTSIDE from 169.254.0.0/16 to any
3084 block in quick on OUTSIDE from 172.16.0.0/12 to any
3085 block in quick on OUTSIDE from 191.255.0.0/16 to any
3086 block in quick on OUTSIDE from 192.0.0.0/16 to any
3087 block in quick on OUTSIDE from 192.168.0.0/16 to any
3088 block in quick on OUTSIDE from 197.0.0.0/8 to any
3089 block in quick on OUTSIDE from 201.0.0.0/8 to any
3090 block in quick on OUTSIDE from 204.152.64.0/23 to any
3091 block in quick on OUTSIDE from 224.0.0.0/3 to any
3092 block in quick on OUTSIDE from MYNET to any
3093 # Your pass rules come here...
3095 block out on OUTSIDE all
3096 block out quick on OUTSIDE from !MYNET to any
3097 block out quick on OUTSIDE from MYNET to 0.0.0.0/7
3110 block out quick on OUTSIDE from MYNET to 2.0.0.0/8
3111 block out quick on OUTSIDE from MYNET to 5.0.0.0/8
3112 block out quick on OUTSIDE from MYNET to 10.0.0.0/8
3113 block out quick on OUTSIDE from MYNET to 23.0.0.0/8
3114 block out quick on OUTSIDE from MYNET to 27.0.0.0/8
3115 block out quick on OUTSIDE from MYNET to 31.0.0.0/8
3116 block out quick on OUTSIDE from MYNET to 67.0.0.0/8
3117 block out quick on OUTSIDE from MYNET to 68.0.0.0/6
3118 block out quick on OUTSIDE from MYNET to 72.0.0.0/5
3119 block out quick on OUTSIDE from MYNET to 80.0.0.0/4
3120 block out quick on OUTSIDE from MYNET to 96.0.0.0/3
3121 block out quick on OUTSIDE from MYNET to 127.0.0.0/8
3122 block out quick on OUTSIDE from MYNET to 128.0.0.0/16
3123 block out quick on OUTSIDE from MYNET to 128.66.0.0/16
3124 block out quick on OUTSIDE from MYNET to 169.254.0.0/16
3125 block out quick on OUTSIDE from MYNET to 172.16.0.0/12
3126 block out quick on OUTSIDE from MYNET to 191.255.0.0/16
3127 block out quick on OUTSIDE from MYNET to 192.0.0.0/16
3128 block out quick on OUTSIDE from MYNET to 192.168.0.0/16
3129 block out quick on OUTSIDE from MYNET to 197.0.0.0/8
3130 block out quick on OUTSIDE from MYNET to 201.0.0.0/8
3131 block out quick on OUTSIDE from MYNET to 204.152.64.0/23
3132 block out quick on OUTSIDE from MYNET to 224.0.0.0/3
3133 # Your pass rules come here...
3135 If you're going to use these, we suggest that you become
3136 familiar with whois.arin.net and keep an occasional eye on
3137 these, as the IANA isn't going to notify you when they allo-
3138 cate one of these to a new corporation or something. You
3141 We'd also like to thank Frank DiGennaro <fsd@server-
3142 vault.com> for greatly contributing to this filter list.