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