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