Date: Fri, 25 Jul 2003 02:42:32 +0200 (CEST) From: Dusan Marjanovic <madafaka@bsd.org.yu> To: FreeBSD-gnats-submit@FreeBSD.org Subject: ports/54832: [NEW PORT] irc/bitlbee: An IRC to other chat networks gateway Message-ID: <20030725004232.AEC89621B@zvezda.fc> Resent-Message-ID: <200307250050.h6P0oM8u042614@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 54832 >Category: ports >Synopsis: [NEW PORT] irc/bitlbee: An IRC to other chat networks gateway >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu Jul 24 17:50:17 PDT 2003 >Closed-Date: >Last-Modified: >Originator: Dusan Marjanovic >Release: FreeBSD 5.1-RELEASE i386 >Organization: >Environment: System: FreeBSD zvezda.fc 5.1-RELEASE FreeBSD 5.1-RELEASE #1: Wed Jun 11 19:41:40 CEST 2003 >Description: This is port of bitlbee, An IRC to other chat networks gateway. Bitlbee supports a wide range of different IM protocols like jabber, icq, msn... WWW: http://www.lintux.cx/bitlbee.html - Dusan Marjanovic dbm@root.co.yu >How-To-Repeat: >Fix: --- bitlbee-0.80.shar begins here --- # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # bitlbee # bitlbee/ipf-howto.html # bitlbee/files # bitlbee/files/patch-ab # bitlbee/files/patch-a # bitlbee/files/patch-ac # bitlbee/files/patch-ad # bitlbee/files/patch-ae # bitlbee/files/patch-af # bitlbee/files/patch-ag # bitlbee/files/patch-ah # bitlbee/tcp_filtering.pdf # bitlbee/Makefile # bitlbee/distinfo # bitlbee/pkg-descr # bitlbee/pkg-plist # echo c - bitlbee mkdir -p bitlbee > /dev/null 2>&1 echo x - bitlbee/ipf-howto.html sed 's/^X//' >bitlbee/ipf-howto.html << 'END-of-bitlbee/ipf-howto.html' X<HTML> X<!-- this file was generated by troffcvt and tc2html --> X<BODY> X<!-- Start Mirror Here --> X<!-- TOC BEGIN --> X<UL> X<LI> X<A HREF=#TOC_1>Introduction</A> X<LI> X<A HREF=#TOC_2>Disclaimer</A> X<LI> X<A HREF=#TOC_3>Copyright</A> X<LI> X<A HREF=#TOC_4>Where to obtain the important pieces</A> X<LI> X<A HREF=#TOC_5>Basic Firewalling</A> X<LI> X<A HREF=#TOC_6>Config File Dynamics, Order and Precedence</A> X<LI> X<A HREF=#TOC_7>Basic Rule Processing</A> X<LI> X<A HREF=#TOC_8>Controlling Rule Processing</A> X<LI> X<A HREF=#TOC_9>Basic filtering by IP address</A> X<LI> X<A HREF=#TOC_10>Controlling Your Interfaces</A> X<LI> X<A HREF=#TOC_11>Using IP Address and Interface Together</A> X<LI> X<A HREF=#TOC_12>Bi-Directional Filtering; The "out" Keyword</A> X<LI> X<A HREF=#TOC_13>Logging What Happens; The "log" Keyword</A> X<LI> X<A HREF=#TOC_14>Complete Bi-Directional Filtering By Interface</A> X<LI> X<A HREF=#TOC_15>Controlling Specific Protocols; The "proto" Keyword</A> X<LI> X<A HREF=#TOC_16>Filtering ICMP with the "icmp-type" Keyword; Merging Rulesets</A> X<LI> X<A HREF=#TOC_17>TCP and UDP Ports; The "port" Keyword</A> X<LI> X<A HREF=#TOC_18>Advanced Firewalling Introduction</A> X<LI> X<A HREF=#TOC_19>Rampant Paranoia; or The Default-Deny Stance</A> X<LI> X<A HREF=#TOC_20>Implicit Allow; The "keep state" Rule</A> X<LI> X<A HREF=#TOC_21>Stateful UDP</A> X<LI> X<A HREF=#TOC_22>Stateful ICMP</A> X<LI> X<A HREF=#TOC_23>FIN Scan Detection; "flags" Keyword, "keep frags" Keyword</A> X<LI> X<A HREF=#TOC_24>Responding To a Blocked Packet</A> X<LI> X<A HREF=#TOC_25>Fancy Logging Techniques</A> X<LI> X<A HREF=#TOC_26>Putting It All Together</A> X<LI> X<A HREF=#TOC_27>Improving Performance With Rule Groups</A> X<LI> X<A HREF=#TOC_28>"Fastroute"; The Keyword of Stealthiness</A> X<LI> X<A HREF=#TOC_29>NAT and Proxies</A> X<LI> X<A HREF=#TOC_30>Mapping Many Addresses Into One Address</A> X<LI> X<A HREF=#TOC_31>Mapping Many Addresses Into a Pool of Addresses</A> X<LI> X<A HREF=#TOC_32>One to One Mappings</A> X<LI> X<A HREF=#TOC_33>Policy NAT</A> X<LI> X<A HREF=#TOC_34>Spoofing Services</A> X<LI> X<A HREF=#TOC_35>Transparent Proxy Support; Redirection Made Useful</A> X<LI> X<A HREF=#TOC_36>Filtering Redirected Services</A> X<LI> X<A HREF=#TOC_37>Magic Hidden Within NAT; Application Proxies</A> X<LI> X<A HREF=#TOC_38>More Magic; Using NAT As a Load Balancer</A> X<LI> X<A HREF=#TOC_39>Loading and Manipulating Filter Rules; The ipf Utility</A> X<LI> X<A HREF=#TOC_40>Loading and Manipulating NAT Rules; The ipnat Utility</A> X<LI> X<A HREF=#TOC_41>Monitoring and Debugging</A> X<LI> X<A HREF=#TOC_42>The ipfstat utility</A> X<LI> X<A HREF=#TOC_43>The ipmon utility</A> X<LI> X<A HREF=#TOC_44>Keep State With Servers and Flags.</A> X<LI> X<A HREF=#TOC_45>Coping With FTP</A> X<LI> X<A HREF=#TOC_46>Running an FTP Server</A> X<LI> X<A HREF=#TOC_47>Running an FTP Client</A> X<LI> X<A HREF=#TOC_48>Assorted Kernel Variables</A> X<LI> X<A HREF=#TOC_49>Fun with ipf!</A> X<LI> X<A HREF=#TOC_50>Localhost Filtering</A> X<LI> X<A HREF=#TOC_51>What Firewall? Transparent filtering.</A> X<LI> X<A HREF=#TOC_52>Using Transparent Filtering to Fix Network Design Mistakes</A> X<LI> X<A HREF=#TOC_53>Drop-Safe Logging With dup-to and to.</A> X<LI> X<A HREF=#TOC_54>The dup-to Method</A> X<LI> X<A HREF=#TOC_55>The to Method</A> X<LI> X<A HREF=#TOC_56>Bogus Network Filtering, the ultimate in current anti-spoofing technology.</A> X</UL> X<!-- TOC END --> X<P> X<CENTER> XIP Filter Based Firewalls HOWTO<BR> X</CENTER> X<CENTER> X<P> X<I>Brendan Conoboy <synk@swcp.com><BR> XErik Fichtner <emf@obfuscation.org><BR> XFri Mar 1 22:29:33 EST 2002<BR> X</I> X</CENTER> X<P> X<B>Abstract:</B> This document is intended to introduce a new Xuser to the IP Filter firewalling package and, at the same time, Xteach the user some basic fundamentals of good firewall design.<BR> X<A NAME=TOC_1> X<H2> XIntroduction X</H2> X</A><BR> X<P> XIP Filter is a great little firewall package. It does just about Xeverything other free firewalls (ipfwadm, ipchains, ipfw) do, Xbut it's also portable and does neat stuff the others don't. XThis document is intended to make some cohesive sense of the sparse Xdocumentation presently available for ipfilter. Futhermore, this Xdocument will also serve as documentation for syntatically compatible Xpacket filters (notably <I>pf</I>) and, wherever applicable, will Xpoint out any important differences; however this document is Xspecifically targeted at the rules language and syntax, and is Xnot intended to be platform specific. Some prior familiarity Xwith packet filtering will be useful, however too much familiarity Xmay make this document a waste of your time. For greater understanding Xof firewalls, the authors recommend reading <I>Building Internet XFirewalls</I>, Chapman & Zwicky, O'Reilly and Associates; Xand <I>TCP/IP Illustrated, Volume 1</I>, Stevens, Addison-Wesley.<BR> X<A NAME=TOC_2> X<H2> XDisclaimer X</H2> X</A><BR> X<P> X<P> XThe authors of this document are not responsible for any damages Xincurred due to actions taken based on this document. This document Xis meant as an introduction to building a firewall based on IP-Filter. XIf you do not feel comfortable taking responsibility for your Xown actions, you should stop reading this document and hire a Xqualified security professional to install your firewall for you.<BR> X<A NAME=TOC_3> X<H2> XCopyright X</H2> X</A><BR> X<P> X<P> XUnless otherwise stated, HOWTO documents are copyrighted by their Xrespective authors. HOWTO documents may be reproduced and distributed Xin whole or in part, in any medium physical or electronic, as Xlong as this copyright notice is retained on all copies. Commercial Xredistribution is allowed and encouraged; however, the authors Xwould like to be notified of any such distributions.<BR> X<P> X<P> XAll translations, derivative works, or aggregate works incorporating Xany HOWTO documents must be covered under this copyright notice. XThat is, you may not produce a derivative work from a HOWTO and Ximpose additional restrictions on its distribution. Exceptions Xto these rules may be granted under certain conditions; please Xcontact the HOWTO coordinator.<BR> X<P> X<P> XIn short, we wish to promote dissemination of this information Xthrough as many channels as possible. However, we do wish to retain Xcopyright on the HOWTO documents, and would like to be notified Xof any plans to redistribute the HOWTOs.<BR> X<A NAME=TOC_4> X<H2> XWhere to obtain the important pieces X</H2> X</A><BR> X<P> X<P> XThe official IPF homepage is at: <I><http://coombs.anu.edu.au/~avalon/ip-filter.html></I><BR> X<P> X<P> XThe BSD licensed compatible packet filter, pf, is at: <I><http://www.benzedrine.cx/pf.html></I><BR> X<P> X<P> XThe most up-to-date version of this document can be found at: X<I><http://www.obfuscation.org/ipf/></I><BR> X<A NAME=TOC_5> X<H2> XBasic Firewalling X</H2> X</A><BR> X<P> X<P> XThis section is designed to familiarize you with ipfilter's syntax, Xand firewall theory in general. The features discussed here are Xfeatures you'll find in any good firewall package. This section Xwill give you a good foundation to make reading and understanding Xthe advanced section very easy. It must be emphasized that this Xsection alone is not enough to build a good firewall, and that Xthe advanced section really is required reading for anybody who Xwants to build an effective security system.<BR> X<A NAME=TOC_6> X<H2> XConfig File Dynamics, Order and Precedence X</H2> X</A><BR> X<P> X<P> XIPF (IP Filter) has a config file (as opposed to say, running Xsome command again and again for each new rule). The config file Xdrips with Unix: There's one rule per line, the "#" Xmark denotes a comment, and you can have a rule and a comment Xon the same line. Extraneous whitespace is allowed, and is encouraged Xto keep the rules readable.<BR> X<A NAME=TOC_7> X<H2> XBasic Rule Processing X</H2> X</A><BR> X<P> X<P> XThe rules are processed from top to bottom, each one appended Xafter another. This quite simply means that if the entirety of Xyour config file is:<BR> X<TT> block in all<BR> X pass in all<BR> X</TT>The computer sees it as:<BR> X<TT> block in all<BR> X pass in all<BR> X</TT>Which is to say that when a packet comes in, the first thing XIPF applies is:<BR> X<TT> block in all<BR> X</TT>Should IPF deem it necessary to move on to the next rule, Xit would then apply the second rule:<BR> X<TT> pass in all<BR> X<P> X<P> X</TT>At this point, you might want to ask yourself "would XIPF move on to the second rule?" If you're familiar with Xipfwadm or ipfw, you probably won't ask yourself this. Shortly Xafter, you will become bewildered at the weird way packets are Xalways getting denied or passed when they shouldn't. Many packet Xfilters stop comparing packets to rulesets the moment the first Xmatch is made; IPF is not one of them.<BR> X<P> X<P> XUnlike the other packet filters, IPF keeps a flag on whether or Xnot it's going to pass the packet. Unless you interrupt the flow, XIPF will go through the entire ruleset, making its decision on Xwhether or not to pass or drop the packet based on the last matching Xrule. The scene: IP Filter's on duty. It's been been scheduled Xa slice of CPU time. It has a checkpoint clipboard that reads:<BR> X<TT> block in all<BR> X pass in all<BR> X</TT>A packet comes in the interface and it's time to go to work. XIt takes a look at the packet, it takes a look at the first rule:<BR> X<TT> block in all<BR> X</TT>"So far I think I will block this packet" says XIPF. It takes a look at the second rule:<BR> X<TT> pass in all<BR> X</TT>"So far I think I will pass this packet" says IPF. XIt takes a look at a third rule. There is no third rule, so it Xgoes with what its last motivation was, to pass the packet onward.<BR> XIt's a good time to point out that even if the ruleset had been<BR> X<TT> block in all<BR> X block in all<BR> X block in all<BR> X block in all<BR> X pass in all<BR> X</TT>that the packet would still have gone through. There is Xno cumulative effect. The last matching rule always takes precedence.<BR> X<A NAME=TOC_8> X<H2> XControlling Rule Processing X</H2> X</A><BR> X<P> X<P> XIf you have experience with other packet filters, you may find Xthis layout to be confusing, and you may be speculating that there Xare problems with portability with other filters and speed of Xrule matching. Imagine if you had 100 rules and most of the applicable Xones were the first 10. There would be a terrible overhead for Xevery packet coming in to go through 100 rules every time. Fortunately, Xthere is a simple keyword you can add to any rule that makes it Xtake action at that match. That keyword is <TT>quick</TT>.<BR> XHere's a modified copy of the original ruleset using the <TT>quick</TT> Xkeyword:<BR> X<TT> block in quick all<BR> X pass in all<BR> X</TT>In this case, IPF looks at the first rule:<BR> X<TT> block in quick all<BR> X</TT>The packet matches and the search is over. The packet is Xexpunged without a peep. There are no notices, no logs, no memorial Xservice. Cake will not be served. So what about the next rule?<BR> X<TT> pass in all<BR> X<P> X<P> X</TT>This rule is never encountered. It could just as easily Xnot be in the config file at all. The sweeping match of <TT>all</TT> Xand the terminal keyword <TT>quick</TT> from the previous rule Xmake certain that no rules are followed afterward.<BR> X<P> X<P> XHaving half a config file laid to waste is rarely a desirable Xstate. On the other hand, IPF is here to block packets and as Xconfigured, it's doing a very good job. Nonetheless, IPF is also Xhere to let some packets through, so a change to the ruleset to Xmake this possible is called for.<BR> X<A NAME=TOC_9> X<H2> XBasic filtering by IP address X</H2> X</A><BR> X<P> X<P> XIPF will match packets on many criteria. The one that we most Xcommonly think of is the IP address. There are some blocks of Xaddress space from which we should never get traffic. One such Xblock is from the unroutable networks, 192.168.0.0/16 (/16 is Xthe CIDR notation for a netmask. You may be more familiar with Xthe dotted decimal format, 255.255.0.0. IPF accepts both). If Xyou wanted to block 192.168.0.0/16, this is one way to do it:<BR> X<TT> block in quick from 192.168.0.0/16 to any<BR> X pass in all<BR> X</TT>Now we have a less stringent ruleset that actually does something Xfor us. Let's imagine a packet comes in from 1.2.3.4. The first Xrule is applied:<BR> X<TT> block in quick from 192.168.0.0/16 to any<BR> X</TT>The packet is from 1.2.3.4, not 192.168.*.*, so there is Xno match. The second rule is applied:<BR> X<TT> pass in all<BR> X</TT>The packet from 1.2.3.4 is definitely a part of <TT>all</TT>, Xso the packet is sent to whatever it's destination happened to Xbe.<BR> X<P> X<P> XOn the other hand, suppose we have a packet that comes in from X192.168.1.2. The first rule is applied:<BR> X<TT> block in quick from 192.168.0.0/16 to any<BR> X</TT>There's a match, the packet is dropped, and that's the end. XAgain, it doesn't move to the second rule because the first rule Xmatches and contains the <TT>quick</TT> keyword.<BR> X<P> X<P> XAt this point you can build a fairly extensive set of definitive Xaddresses which are passed or blocked. Since we've already started Xblocking private address space from entering our firewall, let's Xtake care of the rest of it:<BR> X<TT> block in quick from 192.168.0.0/16 to any<BR> X block in quick from 172.16.0.0/12 to any<BR> X block in quick from 10.0.0.0/8 to any<BR> X pass in all<BR> X</TT>The first three address blocks are some of the private IP Xspace.[[dagger]] [[footnote: [[dagger]] See rfc1918 at <I><http://www.faqs.org/rfcs/rfc1918.html></I> Xand <I><http://www.ietf.org/internet-drafts/draft-manning-dsua-06.txt></I> X]]<BR> X<A NAME=TOC_10> X<H2> XControlling Your Interfaces X</H2> X</A><BR> X<P> X<P> XIt seems very frequent that companies have internal networks before Xthey want a link to the outside world. In fact, it's probably Xreasonable to say that's the main reason people consider firewalls Xin the first place. The machine that bridges the outside world Xto the inside world and vice versa is the router. What separates Xthe router from any other machine is simple: It has more than Xone interface.<BR> X<P> X<P> XEvery packet you receive comes from a network interface; every Xpacket you transmit goes out a network interface. Say your machine Xhas 3 interfaces, <TT>lo0</TT> (loopback), <TT>xl0</TT> (3com Xethernet), and <TT>tun0</TT> (FreeBSD's generic tunnel interface Xthat PPP uses), but you don't want packets coming in on the <TT>tun0</TT> Xinterface?<BR> X<TT> block in quick on tun0 all<BR> X pass in all<BR> X</TT>In this case, the <TT>on</TT> keyword means that that data Xis coming in on the named interface. If a packet comes <TT>in Xon tun0</TT>, the first rule will block it. If a packet comes X<TT>in on lo0</TT> or <TT>in on xl0</TT>, the first rule will Xnot match, the second rule will, the packet will be passed.<BR> X<A NAME=TOC_11> X<H2> XUsing IP Address and Interface Together X</H2> X</A><BR> X<P> X<P> XIt's an odd state of affairs when one decides it best to have Xthe <TT>tun0</TT> interface up, but not allow any data to be received Xfrom it. The more criteria the firewall matches against, the tighter X(or looser) the firewall can become. Maybe you want data from X<TT>tun0</TT>, but not from 192.168.0.0/16? This is the start Xof a powerful firewall.<BR> X<TT> block in quick on tun0 from 192.168.0.0/16 to any<BR> X pass in all<BR> X</TT>Compare this to our previous rule:<BR> X<TT> block in quick from 192.168.0.0/16 to any<BR> X pass in all<BR> X</TT>The old way, all traffic from 192.168.0.0/16, regardless Xof interface, was completely blocked. The new way, using <TT>on Xtun0</TT> means that it's only blocked if it comes in on the <TT>tun0</TT> Xinterface. If a packet arrived on the <TT>xl0</TT> interface Xfrom 192.168.0.0/16, it would be passed.<BR> X<P> X<P> XAt this point you can build a fairly extensive set of definitive Xaddresses which are passed or blocked. Since we've already started Xblocking private address space from entering <TT>tun0</TT>, let's Xtake care of the rest of it:<BR> X<TT> block in quick on tun0 from 192.168.0.0/16 to any<BR> X block in quick on tun0 from 172.16.0.0/12 to any<BR> X block in quick on tun0 from 10.0.0.0/8 to any<BR> X block in quick on tun0 from 127.0.0.0/8 to any<BR> X block in quick on tun0 from 0.0.0.0/8 to any<BR> X block in quick on tun0 from 169.254.0.0/16 to any<BR> X block in quick on tun0 from 192.0.2.0/24 to any<BR> X block in quick on tun0 from 204.152.64.0/23 to any<BR> X block in quick on tun0 from 224.0.0.0/3 to any<BR> X pass in all<BR> X</TT>You've already seen the first three <TT>block</TT>s, but Xnot the rest. The fourth is a largely wasted class-A network used Xfor loopback. Much software communicates with itself on 127.0.0.1 Xso blocking it from an external source is a good idea. The fifth, X0.0.0.0/8, should never be seen on the internet. Most IP stacks Xtreat "0.0.0.0/32" as the default gateway, and the rest Xof the 0.*.*.* network gets handled strangely by various systems Xas a byproduct of how routing decisions are made. You should Xtreat 0.0.0.0/8 just like 127.0.0.0/8. 169.254.0.0/16 has been Xassigned by the IANA for use in auto-configuration when systems Xhave not yet been able to obtain an IP address via DHCP or the Xlike. Most notably, Microsoft Windows will use addresses in this Xrange if they are set to DHCP and cannot find a DHCP server. X192.0.2.0/24 has also been reserved for use as an example IP netblock Xfor documentation authors. We specifically do not use this range Xas it would cause confusion when we tell you to block it, and Xthus all our examples come from 20.20.20.0/24. 204.152.64.0/23 Xis an odd netblock reserved by Sun Microsystems for private cluster Xinterconnects, and blocking this is up to your own judgement. XLastly, 224.0.0.0/3 wipes out the "Class D and E" networks Xwhich is used mostly for multicast traffic, although further definition Xof "Class E" space can be found in RFC 1166.<BR> X<P> X<P> XThere's a very important principle in packet filtering which has Xonly been alluded to with the private network blocking and that Xis this: When you know there's certain types of data that only Xcomes from certain places, you setup the system to only allow Xthat kind of data from those places. In the case of the unroutable Xaddresses, you know that nothing from 10.0.0.0/8 should be arriving Xon <TT>tun0</TT> because you have no way to reply to it. It's Xan illegitimate packet. The same goes for the other unroutables Xas well as 127.0.0.0/8.<BR> X<P> X<P> XMany pieces of software do all their authentication based upon Xthe packet's originating IP address. When you have an internal Xnetwork, say 20.20.20.0/24, you know that the only traffic for Xthat internal network is going to come off the local ethernet. XShould a packet from 20.20.20.0/24 arrive over a PPP dialup, it's Xperfectly reasonable to drop it on the floor, or put it in a dark Xroom for interrogation. It should by no means be allowed to get Xto its final destination. You can accomplish this particularly Xeasily with what you already know of IPF. The new ruleset would Xbe:<BR> X<TT> block in quick on tun0 from 192.168.0.0/16 to any<BR> X block in quick on tun0 from 172.16.0.0/12 to any<BR> X block in quick on tun0 from 10.0.0.0/8 to any<BR> X block in quick on tun0 from 127.0.0.0/8 to any<BR> X block in quick on tun0 from 0.0.0.0/8 to any<BR> X block in quick on tun0 from 169.254.0.0/16 to any<BR> X block in quick on tun0 from 192.0.2.0/24 to any<BR> X block in quick on tun0 from 204.152.64.0/23 to any<BR> X block in quick on tun0 from 224.0.0.0/3 to any<BR> X block in quick on tun0 from 20.20.20.0/24 to any<BR> X pass in all<BR> X</TT> X<A NAME=TOC_12> X<H2> XBi-Directional Filtering; The "out" Keyword X</H2> X</A><BR> X<P> X<P> XUp until now, we've been passing or blocking inbound traffic. XTo clarify, inbound traffic is all traffic that enters the firewall Xon any interface. Conversely, outbound traffic is all traffic Xthat leaves on any interface (whether locally generated or simply Xpassing through). This means that all packets coming in are not Xonly filtered as they enter the firewall, they're also filtered Xas they exit. Thusfar there's been an implied <TT>pass out all</TT> Xthat may or may not be desirable.[[dagger]] Just as you may pass Xand block incoming traffic, you may do the same with outgoing Xtraffic.<BR> X<P> X<P> XNow that we know there's a way to filter outbound packets just Xlike inbound, it's up to us to find a conceivable use for such Xa thing. One possible use of this idea is to keep spoofed packets Xfrom exiting your own network. Instead of passing any traffic Xout the router, you could instead limit permitted traffic to packets Xoriginating at 20.20.20.0/24. You might do it like this: [[footnote: X[[dagger]] This can, of course, be changed by using -DIPFILTER_DEFAULT_BLOCK Xwhen compiling ipfilter on your system. ]]<BR> X<TT> pass out quick on tun0 from 20.20.20.0/24 to any<BR> X block out quick on tun0 from any to any<BR> X</TT>If a packet comes from 20.20.20.1/32, it gets sent out by Xthe first rule. If a packet comes from 1.2.3.4/32 it gets blocked Xby the second.<BR> X<P> X<P> XYou can also make similar rules for the unroutable addresses. XIf some machine tries to route a packet through IPF with a destination Xin 192.168.0.0/16, why not drop it? The worst that can happen Xis that you'll spare yourself some bandwidth:<BR> X<TT> block out quick on tun0 from any to 192.168.0.0/16<BR> X block out quick on tun0 from any to 172.16.0.0/12<BR> X block out quick on tun0 from any to 10.0.0.0/8<BR> X block out quick on tun0 from any to 0.0.0.0/8<BR> X block out quick on tun0 from any to 127.0.0.0/8<BR> X block out quick on tun0 from any to 169.254.0.0/16<BR> X block out quick on tun0 from any to 192.0.2.0/24<BR> X block out quick on tun0 from any to 204.152.64.0/23<BR> X block out quick on tun0 from any to 224.0.0.0/3<BR> X block out quick on tun0 from !20.20.20.0/24 to any<BR> X</TT>In the narrowest viewpoint, this doesn't enhance your security. XIt enhances everybody else's security, and that's a nice thing Xto do. As another viewpoint, one might suppose that because nobody Xcan send spoofed packets from your site, that your site has less Xvalue as a relay for crackers, and as such is less of a target.<BR> X<P> X<P> XYou'll likely find a number of uses for blocking outbound packets. XOne thing to always keep in mind is that in and out directions Xare in reference to your firewall, never any other machine.<BR> X<A NAME=TOC_13> X<H2> XLogging What Happens; The "log" Keyword X</H2> X</A><BR> X<P> X<P> XUp to this point, all blocked and passed packets have been silently Xblocked and silently passed. Usually you want to know if you're Xbeing attacked rather than wonder if that firewall is really buying Xyou any added benefits. While I wouldn't want to log every passed Xpacket, and in some cases every blocked packet, I would want to Xknow about the blocked packets from 20.20.20.0/24. To do this, Xwe add the <TT>log</TT> keyword:<BR> X<TT> block in quick on tun0 from 192.168.0.0/16 to any<BR> X block in quick on tun0 from 172.16.0.0/12 to any<BR> X block in quick on tun0 from 10.0.0.0/8 to any<BR> X block in quick on tun0 from 127.0.0.0/8 to any<BR> X block in quick on tun0 from 0.0.0.0/8 to any<BR> X block in quick on tun0 from 169.254.0.0/16 to any<BR> X block in quick on tun0 from 192.0.2.0/24 to any<BR> X block in quick on tun0 from 204.152.64.0/23 to any<BR> X block in quick on tun0 from 224.0.0.0/3 to any<BR> X block in log quick on tun0 from 20.20.20.0/24 to any<BR> X pass in all<BR> X</TT>So far, our firewall is pretty good at blocking packets coming Xto it from suspect places, but there's still more to be done. XFor one thing, we're accepting packets destined anywhere. One Xthing we ought to do is make sure packets to 20.20.20.0/32 and X20.20.20.255/32 get dropped on the floor. To do otherwise opens Xthe internal network for a smurf attack. These two lines would Xprevent our hypothetical network from being used as a smurf relay:<BR> X<TT> block in log quick on tun0 from any to 20.20.20.0/32<BR> X block in log quick on tun0 from any to 20.20.20.255/32<BR> X</TT>This brings our total ruleset to look something like this:<BR> X<TT> block in quick on tun0 from 192.168.0.0/16 to any<BR> X block in quick on tun0 from 172.16.0.0/12 to any<BR> X block in quick on tun0 from 10.0.0.0/8 to any<BR> X block in quick on tun0 from 127.0.0.0/8 to any<BR> X block in quick on tun0 from 0.0.0.0/8 to any<BR> X block in quick on tun0 from 169.254.0.0/16 to any<BR> X block in quick on tun0 from 192.0.2.0/24 to any<BR> X block in quick on tun0 from 204.152.64.0/23 to any<BR> X block in quick on tun0 from 224.0.0.0/3 to any<BR> X block in log quick on tun0 from 20.20.20.0/24 to any<BR> X block in log quick on tun0 from any to 20.20.20.0/32<BR> X block in log quick on tun0 from any to 20.20.20.255/32<BR> X pass in all<BR> X</TT> X<A NAME=TOC_14> X<H2> XComplete Bi-Directional Filtering By Interface X</H2> X</A><BR> X<P> X<P> XSo far we have only presented fragments of a complete ruleset. XWhen you're actually creating your ruleset, you should setup rules Xfor every direction and every interface. The default state of Xipfilter is to pass packets. It is as though there were an invisible Xrule at the beginning which states <TT>pass in all</TT> and <TT>pass Xout all</TT>. Rather than rely on some default behaviour, make Xeverything as specific as possible, interface by interface, until Xevery base is covered.<BR> X<P> X<P> XFirst we'll start with the <TT>lo0</TT> interface, which wants Xto run wild and free. Since these are programs talking to others Xon the local system, go ahead and keep it unrestricted:<BR> X<TT> pass out quick on lo0<BR> X pass in quick on lo0<BR> X</TT>Next, there's the <TT>xl0</TT> interface. Later on we'll Xbegin placing restrictions on the <TT>xl0</TT> interface, but Xto start with, we'll act as though everything on our local network Xis trustworthy and give it much the same treatment as <TT>lo0</TT>:<BR> X<TT> pass out quick on xl0<BR> X pass in quick on xl0<BR> X</TT>Finally, there's the <TT>tun0</TT> interface, which we've Xbeen half-filtering with up until now:<BR> X<TT> block out quick on tun0 from any to 192.168.0.0/16<BR> X block out quick on tun0 from any to 172.16.0.0/12<BR> X block out quick on tun0 from any to 127.0.0.0/8<BR> X block out quick on tun0 from any to 10.0.0.0/8<BR> X block out quick on tun0 from any to 0.0.0.0/8<BR> X block out quick on tun0 from any to 169.254.0.0/16<BR> X block out quick on tun0 from any to 192.0.2.0/24<BR> X block out quick on tun0 from any to 204.152.64.0/23<BR> X block out quick on tun0 from any to 224.0.0.0/3<BR> X pass out quick on tun0 from 20.20.20.0/24 to any<BR> X block out quick on tun0 from any to any<BR> X block in quick on tun0 from 192.168.0.0/16 to any<BR> X block in quick on tun0 from 172.16.0.0/12 to any<BR> X block in quick on tun0 from 10.0.0.0/8 to any<BR> X block in quick on tun0 from 127.0.0.0/8 to any<BR> X block in quick on tun0 from 0.0.0.0/8 to any<BR> X block in quick on tun0 from 169.254.0.0/16 to any<BR> X block in quick on tun0 from 192.0.2.0/24 to any<BR> X block in quick on tun0 from 204.152.64.0/23 to any<BR> X block in quick on tun0 from 224.0.0.0/3 to any<BR> X block in log quick on tun0 from 20.20.20.0/24 to any<BR> X block in log quick on tun0 from any to 20.20.20.0/32<BR> X block in log quick on tun0 from any to 20.20.20.255/32<BR> X pass in all<BR> X</TT>This is a pretty significant amount of filtering already, Xprotecting 20.20.20.0/24 from being spoofed or being used for Xspoofing. Future examples will continue to show one-sideness, Xbut keep in mind that it's for brevity's sake, and when setting Xup your own ruleset, adding rules for every direction and every Xinterface is necessary.<BR> X<A NAME=TOC_15> X<H2> XControlling Specific Protocols; The "proto" Keyword X</H2> X</A><BR> X<P> X<P> XDenial of Service attacks are as rampant as buffer overflow exploits. XMany denial of service attacks rely on glitches in the OS's TCP/IP Xstack. Frequently, this has come in the form of ICMP packets. XWhy not block them entirely?<BR> X<TT> block in log quick on tun0 proto icmp from any to any<BR> X</TT>Now any ICMP traffic coming in from <TT>tun0</TT> will be Xlogged and discarded.<BR> X<A NAME=TOC_16> X<H2> XFiltering ICMP with the "icmp-type" Keyword; Merging XRulesets X</H2> X</A><BR> X<P> X<P> XOf course, dropping all ICMP isn't really an ideal situation. XWhy not drop all ICMP? Well, because it's useful to have partially Xenabled. So maybe you want to keep some types of ICMP traffic Xand drop other kinds. If you want ping and traceroute to work, Xyou need to let in ICMP types 0 and 11. Strictly speaking, this Xmight not be a good idea, but if you need to weigh security against Xconvenience, IPF lets you do it.<BR> X<TT> pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0<BR> X pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11<BR> X</TT>Remember that ruleset order is important. Since we're doing Xeverything <TT>quick</TT> we must have our <TT>pass</TT>es before Xour <TT>block</TT>s, so we really want the last three rules in Xthis order:<BR> X<TT> pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0<BR> X pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11<BR> X block in log quick on tun0 proto icmp from any to any<BR> X</TT>Adding these 3 rules to the anti-spoofing rules is a bit Xtricky. One error might be to put the new ICMP rules at the beginning:<BR> X<TT> pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0<BR> X pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11<BR> X block in log quick on tun0 proto icmp from any to any<BR> X block in quick on tun0 from 192.168.0.0/16 to any<BR> X block in quick on tun0 from 172.16.0.0/12 to any<BR> X block in quick on tun0 from 10.0.0.0/8 to any<BR> X block in quick on tun0 from 127.0.0.0/8 to any<BR> X block in quick on tun0 from 0.0.0.0/8 to any<BR> X block in quick on tun0 from 169.254.0.0/16 to any<BR> X block in quick on tun0 from 192.0.2.0/24 to any<BR> X block in quick on tun0 from 204.152.64.0/23 to any<BR> X block in quick on tun0 from 224.0.0.0/3 to any<BR> X block in log quick on tun0 from 20.20.20.0/24 to any<BR> X block in log quick on tun0 from any to 20.20.20.0/32<BR> X block in log quick on tun0 from any to 20.20.20.255/32<BR> X pass in all<BR> X</TT>The problem with this is that an ICMP type 0 packet from X192.168.0.0/16 will get passed by the first rule, and never blocked Xby the fourth rule. Also, since we <TT>quick</TT>ly pass an ICMP XECHO_REPLY (type 0) to 20.20.20.0/24, we've just opened ourselves Xback up to a nasty smurf attack and nullified those last two block Xrules. Oops. To avoid this, we place the ICMP rules after the Xanti-spoofing rules:<BR> X<TT> block in quick on tun0 from 192.168.0.0/16 to any<BR> X block in quick on tun0 from 172.16.0.0/12 to any<BR> X block in quick on tun0 from 10.0.0.0/8 to any<BR> X block in quick on tun0 from 127.0.0.0/8 to any<BR> X block in quick on tun0 from 0.0.0.0/8 to any<BR> X block in quick on tun0 from 169.254.0.0/16 to any<BR> X block in quick on tun0 from 192.0.2.0/24 to any<BR> X block in quick on tun0 from 204.152.64.0/23 to any<BR> X block in quick on tun0 from 224.0.0.0/3 to any<BR> X block in log quick on tun0 from 20.20.20.0/24 to any<BR> X block in log quick on tun0 from any to 20.20.20.0/32<BR> X block in log quick on tun0 from any to 20.20.20.255/32<BR> X pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0<BR> X pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11<BR> X block in log quick on tun0 proto icmp from any to any<BR> X pass in all<BR> X</TT>Because we block spoofed traffic before the ICMP rules are Xprocessed, a spoofed packet never makes it to the ICMP ruleset. XIt's very important to keep such situations in mind when merging Xrules.<BR> X<A NAME=TOC_17> X<H2> XTCP and UDP Ports; The "port" Keyword X</H2> X</A><BR> X<P> X<P> XNow that we've started blocking packets based on protocol, we Xcan start blocking packets based on specific aspects of each protocol. XThe most frequently used of these aspects is the port number. XServices such as rsh, rlogin, and telnet are all very convenient Xto have, but also hideously insecure against network sniffing Xand spoofing. One great compromise is to only allow the services Xto run internally, then block them externally. This is easy to Xdo because rlogin, rsh, and telnet use specific TCP ports (513, X514, and 23 respectively). As such, creating rules to block them Xis easy:<BR> X<TT> block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513<BR> X block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514<BR> X block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23<BR> X</TT>Make sure all 3 are before the <TT>pass in all</TT> and they'll Xbe closed off from the outside (leaving out spoofing for brevity's Xsake):<BR> X<TT> pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0<BR> X pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11<BR> X block in log quick on tun0 proto icmp from any to any<BR> X block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513<BR> X block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514<BR> X block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23<BR> X pass in all<BR> X</TT>You might also want to block 514/udp (syslog), 111/tcp & X111/udp (portmap), 515/tcp (lpd), 2049/tcp and 2049/udp (NFS), X6000/tcp (X11) and so on and so forth. You can get a complete Xlisting of the ports being listened to by using <TT>netstat -a</TT> X(or <TT>lsof -i</TT>, if you have it installed).<BR> X<P> X<P> XBlocking UDP instead of TCP only requires replacing <TT>proto Xtcp</TT> with <TT>proto udp</TT>. The rule for syslog would be:<BR> X<TT> block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 514<BR> X</TT>IPF also has a shorthand way to write rules that apply to Xboth <TT>proto tcp</TT> and <TT>proto udp</TT> at the same time, Xsuch as portmap or NFS. The rule for portmap would be:<BR> X<TT> block in log quick on tun0 proto tcp/udp from any to 20.20.20.0/24 port = 111<BR> X</TT> X<A NAME=TOC_18> X<H2> XAdvanced Firewalling Introduction X</H2> X</A><BR> X<P> X<P> XThis section is designed as an immediate followup to the basic Xsection. Contained below are both concepts for advanced firewall Xdesign, and advanced features contained only within ipfilter. XOnce you are comfortable with this section, you should be able Xto build a very strong firewall.<BR> X<A NAME=TOC_19> X<H2> XRampant Paranoia; or The Default-Deny Stance X</H2> X</A><BR> X<P> X<P> XThere's a big problem with blocking services by the port: sometimes Xthey move. RPC based programs are terrible about this, lockd, Xstatd, even nfsd listens places other than 2049. It's awfully Xhard to predict, and even worse to automate adjusting all the Xtime. What if you miss a service? Instead of dealing with all Xthat hassle, let's start over with a clean slate. The current Xruleset looks like this:<BR> X<P> X<P> XYes, we really are starting over. The first rule we're going Xto use is this:<BR> X<TT> block in all<BR> X</TT>No network traffic gets through. None. Not a peep. You're Xrather secure with this setup. Not terribly useful, but quite Xsecure. The great thing is that it doesn't take much more to Xmake your box rather secure, yet useful too. Let's say the machine Xthis is running on is a web server, nothing more, nothing less. XIt doesn't even do DNS lookups. It just wants to take connections Xon 80/tcp and that's it. We can do that. We can do that with Xa second rule, and you already know how:<BR> X<TT> block in on tun0 all<BR> X pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80<BR> X</TT>This machine will pass in port 80 traffic for 20.20.20.1, Xand deny everything else, including responses from port 80. To Xfix this, you have to allow the response back out as well:<BR> X<TT> block in on tun0 all<BR> X pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80<BR> X pass out quick on tun0 proto tcp from 20.20.20.1/32 port = 80 to any<BR> X</TT>For basic firewalling, this is all one needs. However, there Xis an easier way; by using stateful rules.<BR> X<A NAME=TOC_20> X<H2> XImplicit Allow; The "keep state" Rule X</H2> X</A><BR> X<P> X<P> XThe job of your firewall is to prevent unwanted traffic getting Xto point B from point A. We have general rules which say "as Xlong as this packet is to port 23, it's okay." We have general Xrules which say "as long as this packet has its FIN flag Xset, it's okay." Our firewalls don't know the beginning, Xmiddle, or end of any TCP/UDP/ICMP session. They merely have Xvague rules that are applied to all packets. We're left to hope Xthat the packet with its FIN flag set isn't really a FIN scan, Xmapping our services. We hope that the packet to port 23 isn't Xan attempted hijack of our telnet session. What if there was a Xway to identify and authorize individual TCP/UDP/ICMP sessions Xand distinguish them from port scanners and DoS attacks? There Xis a way, it's called keeping state.<BR> X<P> X<P> XWe want convenience and security in one. Lots of people do, that's Xwhy Ciscos have an "established" clause that lets established Xtcp sessions go through. Ipfw has established. Ipfwadm has setup/established. XThey all have this feature, but the name is very misleading. XWhen we first saw it, we thought it meant our packet filter was Xkeeping track of what was going on, that it knew if a connection Xwas really established or not. The fact is, they're all taking Xthe packet's word for it from a part of the packet anybody can Xlie about. They read the TCP packet's flags section and there's Xthe reason UDP/ICMP don't work with it, they have no such thing. XAnybody who can create a packet with bogus flags can get by a Xfirewall with this setup.<BR> X<P> X<P> XWhere does IPF come in to play here, you ask? Well, unlike the Xother firewalls, IPF really can keep track of whether or not a Xconnection is established. And it'll do it with TCP, UDP and XICMP, not just TCP. Ipf calls it keeping state. The keyword Xfor the ruleset is <TT>keep state</TT>.<BR> X<P> X<P> XUp until now, we've told you that packets come in, then the ruleset Xgets checked; packets go out, then the ruleset gets checked. Actually, Xwhat happens is packets come in, the state table gets checked, Xthen *maybe* the inbound ruleset gets checked; packets go out, Xthe state table gets checked, then *maybe* the outbound ruleset Xgets checked. The state table is a list of TCP/UDP/ICMP sessions Xthat are unquestionadely passed through the firewall, circumventing Xthe entire ruleset. Sound like a serious security hole? Hang Xon, it's the best thing that ever happened to your firewall.<BR> X<P> X<P> XAll TCP/IP sessions have a start, a middle, and an end (even though Xthey're sometimes all in the same packet). You can't have an Xend without a middle and you can't have a middle without a start. XThis means that all you really need to filter on is the beginning Xof a TCP/UDP/ICMP session. If the beginning of the session is Xallowed by your firewall rules, you really want the middle and Xend to be allowed too (lest your IP stack should overflow and Xyour machines become useless). Keeping state allows you to ignore Xthe middle and end and simply focus on blocking/passing new sessions. XIf the new session is passed, all its subsequent packets will Xbe allowed through. If it's blocked, none of its subsequent packets Xwill be allowed through. Here's an example for running an ssh Xserver (and nothing but an ssh server):<BR> X<TT> block out quick on tun0 all<BR> X pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep state<BR> X</TT>The first thing you might notice is that there's no "pass Xout" provision. In fact, there's only an all-inclusive "block Xout" rule. Despite this, the ruleset is complete. This Xis because by keeping state, the entire ruleset is circumvented. XOnce the first SYN packet hits the ssh server, state is created Xand the remainder of the ssh session is allowed to take place Xwithout interference from the firewall. Here's another example:<BR> X<TT> block in quick on tun0 all<BR> X pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state<BR> X</TT>In this case, the server is running no services. Infact, Xit's not a server, it's a client. And this client doesn't want Xunauthorized packets entering its IP stack at all. However, the Xclient wants full access to the internet and the reply packets Xthat such privledge entails. This simple ruleset creates state Xentries for every new outgoing TCP session. Again, since a state Xentry is created, these new TCP sessions are free to talk back Xand forth as they please without the hinderance or inspection Xof the firewall ruleset. We mentioned that this also works for XUDP and ICMP:<BR> X<TT> block in quick on tun0 all<BR> X pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state<BR> X pass out quick on tun0 proto udp from 20.20.20.1/32 to any keep state<BR> X pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state<BR> X</TT>Yes Virginia, we can ping. Now we're keeping state on TCP, XUDP, ICMP. Now we can make outgoing connections as though there's Xno firewall at all, yet would-be attackers can't get back in. XThis is very handy because there's no need to track down what Xports we're listening to, only the ports we want people to be Xable to get to.<BR> X<P> X<P> XState is pretty handy, but it's also a bit tricky. You can shoot Xyourself in the foot in strange and mysterious ways. Consider Xthe following ruleset:<BR> X<TT> pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23<BR> X pass out quick on tun0 proto tcp from any to any keep state<BR> X block in quick all<BR> X block out quick all<BR> X</TT>At first glance, this seems to be a good setup. We allow Xincoming sessions to port 23, and outgoing sessions anywhere. XNaturally packets going to port 23 will have reply packets, but Xthe ruleset is setup in such a way that the pass out rule will Xgenerate a state entry and everything will work perfectly. At Xleast, you'd think so.<BR> X<P> X<P> XThe unfortunate truth is that after 60 seconds of idle time the Xstate entry will be closed (as opposed to the normal 5 days). XThis is because the state tracker never saw the original SYN packet Xdestined to port 23, it only saw the SYN ACK. IPF is very good Xabout following TCP sessions from start to finish, but it's not Xvery good about coming into the middle of a connection, so rewrite Xthe rule to look like this:<BR> X<TT> pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state<BR> X pass out quick on tun0 proto tcp from any to any keep state<BR> X block in quick all<BR> X block out quick all<BR> X</TT>The additional of this rule will enter the very first packet Xinto the state table and everything will work as expected. Once Xthe 3-way handshake has been witness by the state engine, it is Xmarked in 4/4 mode, which means it's setup for long-term data Xexchange until such time as the connection is torn down (wherein Xthe mode changes again. You can see the current modes of your Xstate table with <TT>ipfstat -s</TT>.<BR> X<A NAME=TOC_21> X<H2> XStateful UDP X</H2> X</A><BR> X<P> X<P> XUDP is stateless so naturally it's a bit harder to do a reliable Xjob of keeping state on it. Nonetheless, ipf does a pretty good Xjob. When machine A sends a UDP packet to machine B with source Xport X and destination port Y, ipf will allow a reply from machine XB to machine A with source port Y and destination port X. This Xis a short term state entry, a mere 60 seconds.<BR> X<P> X<P> XHere's an example of what happens if we use nslookup to get the XIP address of www.3com.com:<BR> X<TT> $ nslookup www.3com.com<BR> X</TT>A DNS packet is generated:<BR> X<TT> 17:54:25.499852 20.20.20.1.2111 > 198.41.0.5.53: 51979+<BR> X</TT>The packet is from 20.20.20.1, port 2111, destined for 198.41.0.5, Xport 53. A 60 second state entry is created. If a packet comes Xback from 198.41.0.5 port 53 destined for 20.20.20.1 port 2111 Xwithin that period of time, the reply packet will be let through. XAs you can see, milliseconds later:<BR> X<TT> 17:54:25.501209 198.41.0.5.53 > 20.20.20.1.2111: 51979 q: www.3com.com<BR> X</TT>The reply packet matches the state criteria and is let through. XAt that same moment that packet is let through, the state gateway Xis closed and no new incoming packets will be allowed in, even Xif they claim to be from the same place.<BR> X<A NAME=TOC_22> X<H2> XStateful ICMP X</H2> X</A><BR> X<P> X<P> XIPFilter handles ICMP states in the manner that one would expect Xfrom understanding how ICMP is used with TCP and UDP, and with Xyour understanding of how <TT>keep state</TT> works. There are Xtwo general types of ICMP messages; requests and replies. When Xyou write a rule such as:<BR> X<TT> pass out on tun0 proto icmp from any to any icmp-type 8 keep state<BR> X</TT>to allow outbound echo requests (a typical ping), the resultant Xicmp-type 0 packet that comes back will be allowed in. This state Xentry has a default timeout of an incomplete 0/0 state of 60 seconds. XThus, if you are keeping state on any outbound icmp message that Xwill elicit an icmp message in reply, you need a <TT>proto icmp X[...] keep state</TT> rule.<BR> X<P> X<P> XHowever, the majority of ICMP messages are status messages generated Xby some failure in UDP (and sometimes TCP), and in 3.4.x and greater XIPFilters, any ICMP error status message (say <TT>icmp-type 3 Xcode 3</TT> port unreachable, or <TT>icmp-type 11</TT> time exceeded) Xthat matches an active state table entry that could have generated Xthat message, the ICMP packet is let in. For example, in older XIPFilters, if you wanted traceroute to work, you needed to use:<BR> X<TT> pass out on tun0 proto udp from any to any port 33434><33690 keep state<BR> X pass in on tun0 proto icmp from any to any icmp-type timex<BR> X</TT>whereas now you can do the right thing and just keep state Xon udp with:<BR> X<TT> pass out on tun0 proto udp from any to any port 33434><33690 keep state<BR> X</TT>To provide some protection against a third-party sneaking XICMP messages through your firewall when an active connection Xis known to be in your state table, the incoming ICMP packet is Xchecked not only for matching source and destination addresses X(and ports, when applicable) but a tiny part of the payload of Xthe packet that the ICMP message is claiming it was generated Xby.<BR> X<A NAME=TOC_23> X<H2> XFIN Scan Detection; "flags" Keyword, "keep frags" XKeyword X</H2> X</A><BR> XLet's go back to the 4 rule set from the previous section:<BR> X<TT> pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state<BR> X pass out quick on tun0 proto tcp from any to any keep state<BR> X block in quick all<BR> X block out quick all<BR> X</TT>This is almost, but not quite, satisfactory. The problem Xis that it's not just SYN packets that're allowed to go to port X23, any old packet can get through. We can change this by using Xthe <TT>flags</TT> option:<BR> X<TT> pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state<BR> X pass out quick on tun0 proto tcp from any to any flags S keep state<BR> X block in quick all<BR> X block out quick all<BR> X</TT>Now only TCP packets, destined for 20.20.20.1, at port 23, Xwith a lone SYN flag will be allowed in and entered into the state Xtable. A lone SYN flag is only present as the very first packet Xin a TCP session (called the TCP handshake) and that's really Xwhat we wanted all along. There's at least two advantages to this: XNo arbitrary packets can come in and make a mess of your state Xtable. Also, FIN and XMAS scans will fail since they set flags Xother than the SYN flag.[[dagger]] [[footnote: [[dagger]] Some Xexamples use <TT>flags S/SA</TT> instead of <TT>flags S</TT>. X<TT>flags S</TT> actually equates to <TT>flags S/AUPRFS</TT> and Xmatches against only the SYN packet out of all six possible flags, Xwhile <TT>flags S/SA</TT> will allow packets that may or may not Xhave the URG, PSH, FIN, or RST flags set. Some protocols demand Xthe URG or PSH flags, and <TT>S/SAFR</TT> would be a better choice Xfor these, however we feel that it is less secure to blindly use X<TT>S/SA</TT> when it isn't required. But it's your firewall. X]] Now all incoming packets must either be handshakes or have Xstate already. If anything else comes in, it's probably a port Xscan or a forged packet. There's one exception to that, which Xis when a packet comes in that's fragmented from its journey. XIPF has provisions for this as well, the <TT>keep frags</TT> keyword. XWith it, IPF will notice and keep track of packets that are fragmented, Xallowing the expected fragments to to go through. Let's rewrite Xthe 3 rules to log forgeries and allow fragments:<BR> X<TT> pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state keep frags<BR> X pass out quick on tun0 proto tcp from any to any keep state flags S keep frags<BR> X block in log quick all<BR> X block out log quick all<BR> X</TT>This works because every packet that should be allowed through Xmakes it into the state table before the blocking rules are reached. XThe only scan this won't detect is a SYN scan itself. If you're Xtruely worried about that, you might even want to log all initial XSYN packets.<BR> X<A NAME=TOC_24> X<H2> XResponding To a Blocked Packet X</H2> X</A><BR> X<P> X<P> XSo far, all of our blocked packets have been dumped on the floor, Xlogged or not, we've never sent anything back to the originating Xhost. Sometimes this isn't the most desirable of responses because Xin doing so, we actually tell the attacker that a packet filter Xis present. It seems a far better thing to misguide the attacker Xinto believing that, while there's no packet filter running, there's Xlikewise no services to break into. This is where fancier blocking Xcomes into play.<BR> X<P> X<P> XWhen a service isn't running on a Unix system, it normally lets Xthe remote host know with some sort of return packet. In TCP, Xthis is done with an RST (Reset) packet. When blocking a TCP Xpacket, IPF can actually return an RST to the origin by using Xthe <TT>return-rst</TT> keyword.<BR> XWhere once we did:<BR> X<TT> block in log on tun0 proto tcp from any to 20.20.20.0/24 port = 23<BR> X pass in all<BR> X</TT>We might now do:<BR> X<TT> block return-rst in log proto tcp from any to 20.20.20.0/24 port = 23<BR> X block in log quick on tun0<BR> X pass in all<BR> X</TT>We need two <TT>block</TT> statements since <TT>return-rst</TT> Xonly works with TCP, and we still want to block protocols such Xas UDP, ICMP, and others. Now that this is done, the remote side Xwill get "connection refused" instead of "connection Xtimed out".<BR> X<P> X<P> XIt's also possible to send an error message when somebody sends Xa packet to a UDP port on your system. Whereas once you might Xhave used:<BR> X<TT> block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111<BR> X</TT>You could instead use the <TT>return-icmp</TT> keyword to Xsend a reply:<BR> X<TT> block return-icmp(port-unr) in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111<BR> X</TT>According to <I>TCP/IP Illustrated</I>, port-unreachable Xis the correct ICMP type to return when no service is listening Xon the port in question. You can use any ICMP type you like, Xbut port-unreachable is probably your best bet. It's also the Xdefault ICMP type for <TT>return-icmp</TT>.<BR> X<P> X<P> XHowever, when using <TT>return-icmp</TT>, you'll notice that it's Xnot very stealthy, and it returns the ICMP packet with the IP Xaddress of the firewall, not the original destination of the packet. XThis was fixed in ipfilter 3.3, and a new keyword; <TT>return-icmp-as-dest</TT>, Xhas been added. The new format is:<BR> X<TT> block return-icmp-as-dest(port-unr) in log on tun0 proto udp from any to 20.20.20.0/24 port = 111<BR> X</TT>Additionally, you should be careful to use response packets Xonly in situations where you understand ahead of time what it Xis that you're responding to. For example, if you happened to Xreturn-icmp to a local network broadcast address, you would end Xup flooding your network in short order.[[dagger]] [[footnote: X[[dagger]] This is especially true in a DHCP/BOOTP environment Xsuch as a typical consumer broadband connection where you run Xthe risk of "attacking" your own ISP's DHCP server. XThey won't appreciate it. ]]<BR> X<A NAME=TOC_25> X<H2> XFancy Logging Techniques X</H2> X</A><BR> X<P> X<P> XIt is important to note that the presence of the <TT>log</TT> Xkeyword only ensures that the packet will be available to the Xipfilter logging device; <TT>/dev/ipl</TT>. In order to actually Xsee this log information, one must be running the <TT>ipmon</TT> Xutility (or some other utility that reads from <TT>/dev/ipl</TT>). XThe typical usage of <TT>log</TT> is coupled with <TT>ipmon -s</TT> Xto log the information to syslog. As of ipfilter 3.3, one can Xnow even control the logging behavior of syslog by using <TT>log Xlevel</TT> keywords, as in rules such as this:<BR> X<TT> block in log level auth.info quick on tun0 from 20.20.20.0/24 to any<BR> X block in log level auth.alert quick on tun0 proto tcp from any to 20.20.20.0/24 port = 21<BR> X</TT>In addition to this, you can tailor what information is being Xlogged. For example, you may not be interested that someone attempted Xto probe your telnet port 500 times, but you are interested that Xthey probed you once. You can use the <TT>log first</TT> keyword Xto only log the first example of a packet. Of course, the notion Xof "first-ness" only applies to packets in a specific Xsession, and for the typical blocked packet, you will be hard Xpressed to encounter situations where this does what you expect. XHowever, if used in conjunction with <TT>pass</TT> and <TT>keep Xstate</TT>, this can be a valuable keyword for keeping tabs on Xtraffic.<BR> X<P> X<P> XAnother useful thing you can do with the logs is to keep track Xof interesting pieces of the packet in addition to the header Xinformation normally being logged. Ipfilter will give you the Xfirst 128 bytes of the packet if you use the <TT>log body</TT> Xkeyword. You should limit the use of body logging, as it makes Xyour logs very verbose, but for certain applications, it is often Xhandy to be able to go back and take a look at the packet, or Xto send this data to another application that can examine it further.<BR> X<A NAME=TOC_26> X<H2> XPutting It All Together X</H2> X</A><BR> X<P> X<P> XSo now we have a pretty tight firewall, but it can still be tighter. XSome of the original ruleset we wiped clean is actually very useful. XI'd suggest bringing back all the anti-spoofing stuff. This leaves Xus with:<BR> X<TT> block in on tun0<BR> X block in quick on tun0 from 192.168.0.0/16 to any<BR> X block in quick on tun0 from 172.16.0.0/12 to any<BR> X block in quick on tun0 from 10.0.0.0/8 to any<BR> X block in quick on tun0 from 127.0.0.0/8 to any<BR> X block in quick on tun0 from 0.0.0.0/8 to any<BR> X block in quick on tun0 from 169.254.0.0/16 to any<BR> X block in quick on tun0 from 192.0.2.0/24 to any<BR> X block in quick on tun0 from 204.152.64.0/23 to any<BR> X block in quick on tun0 from 224.0.0.0/3 to any<BR> X block in log quick on tun0 from 20.20.20.0/24 to any<BR> X block in log quick on tun0 from any to 20.20.20.0/32<BR> X block in log quick on tun0 from any to 20.20.20.255/32<BR> X pass out quick on tun0 proto tcp/udp from 20.20.20.1/32 to any keep state<BR> X pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state<BR> X pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 flags S keep state<BR> X</TT> X<A NAME=TOC_27> X<H2> XImproving Performance With Rule Groups X</H2> X</A><BR> X<P> X<P> XLet's extend our use of our firewall by creating a much more complicated, Xand we hope more applicable to the real world, example configuration XFor this example, we're going to change the interface names, and Xnetwork numbers. Let's assume that we have three interfaces in Xour firewall with interfaces <TT>xl0</TT>, <TT>xl1</TT>, and <TT>xl2</TT>.<BR> X<TT>xl0 is connected to our external network 20.20.20.0/26<BR> Xxl1 is connected to our "DMZ" network 20.20.20.64/26<BR> Xxl2 is connected to our protected network 20.20.20.128/25<BR> X</TT>We'll define the entire ruleset in one swoop, since we figure Xthat you can read these rules by now:<BR> X<TT> block in quick on xl0 from 192.168.0.0/16 to any<BR> X block in quick on xl0 from 172.16.0.0/12 to any<BR> X block in quick on xl0 from 10.0.0.0/8 to any<BR> X block in quick on xl0 from 127.0.0.0/8 to any<BR> X block in quick on xl0 from 0.0.0.0/8 to any<BR> X block in quick on xl0 from 169.254.0.0/16 to any<BR> X block in quick on xl0 from 192.0.2.0/24 to any<BR> X block in quick on xl0 from 204.152.64.0/23 to any<BR> X block in quick on xl0 from 224.0.0.0/3 to any<BR> X block in log quick on xl0 from 20.20.20.0/24 to any<BR> X block in log quick on xl0 from any to 20.20.20.0/32<BR> X block in log quick on xl0 from any to 20.20.20.63/32<BR> X block in log quick on xl0 from any to 20.20.20.64/32<BR> X block in log quick on xl0 from any to 20.20.20.127/32<BR> X block in log quick on xl0 from any to 20.20.20.128/32<BR> X block in log quick on xl0 from any to 20.20.20.255/32<BR> X pass out on xl0 all<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state<BR> X pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state<BR> X pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state<BR> X block out on xl1 all<BR> X pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state<BR> X block out on xl2 all<BR> X pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state<BR> X</TT>From this arbitarary example, we can already see that our Xruleset is becoming unwieldy. To make matters worse, as we add Xmore specific rules to our DMZ network, we add additional tests Xthat must be parsed for every packet, which affects the performance Xof the <TT>xl0</TT> <-> <TT>xl2</TT> connections. If you Xset up a firewall with a ruleset like this, and you have lots Xof bandwidth and a moderate amount of cpu, everyone that has a Xworkstation on the <TT>xl2</TT> network is going to come looking Xfor your head to place on a platter. So, to keep your head <-> Xtorso network intact, you can speed things along by creating rule Xgroups. Rule groups allow you to write your ruleset in a tree Xfashion, instead of as a linear list, so that if your packet has Xnothing to do with the set of tests (say, all those <TT>xl1</TT> Xrules) those rules will never be consulted. It's somewhat like Xhaving multiple firewalls all on the same machine.<BR> XHere's a simple example to get us started:<BR> X<TT> block out quick on xl1 all head 10<BR> X pass out quick proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10<BR> X block out on xl2 all<BR> X</TT>In this simplistic example, we can see a small hint of the Xpower of the rule group. If the packet is not destined for <TT>xl1</TT>, Xthe <TT>head</TT> of rule <TT>group 10</TT> will not match, and Xwe will go on with our tests. If the packet does match for <TT>xl1</TT>, Xthe <TT>quick</TT> keyword will short-circuit all further processing Xat the root level (rule group 0), and focus the testing on rules Xwhich belong to <TT>group 10</TT>; namely, the SYN check for 80/tcp. XIn this way, we can re-write the above rules so that we can maximize Xperformance of our firewall.<BR> X<TT> block in quick on xl0 all head 1<BR> X block in quick on xl0 from 192.168.0.0/16 to any group 1<BR> X block in quick on xl0 from 172.16.0.0/12 to any group 1<BR> X block in quick on xl0 from 10.0.0.0/8 to any group 1<BR> X block in quick on xl0 from 127.0.0.0/8 to any group 1<BR> X block in quick on xl0 from 0.0.0.0/8 to any group 1<BR> X block in quick on xl0 from 169.254.0.0/16 to any group 1<BR> X block in quick on xl0 from 192.0.2.0/24 to any group 1<BR> X block in quick on xl0 from 204.152.64.0/23 to any group 1<BR> X block in quick on xl0 from 224.0.0.0/3 to any group 1<BR> X block in log quick on xl0 from 20.20.20.0/24 to any group 1<BR> X block in log quick on xl0 from any to 20.20.20.0/32 group 1<BR> X block in log quick on xl0 from any to 20.20.20.63/32 group 1<BR> X block in log quick on xl0 from any to 20.20.20.64/32 group 1<BR> X block in log quick on xl0 from any to 20.20.20.127/32 group 1<BR> X block in log quick on xl0 from any to 20.20.20.128/32 group 1<BR> X block in log quick on xl0 from any to 20.20.20.255/32 group 1<BR> X pass in on xl0 all group 1<BR> X pass out on xl0 all<BR> X block out quick on xl1 all head 10<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state group 10<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state group 10<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state group 10<BR> X pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state group 10<BR> X pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state<BR> X pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state group 10<BR> X pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state<BR> X block out on xl2 all<BR> X pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state<BR> X</TT>Now you can see the rule groups in action. For a host on Xthe <TT>xl2</TT> network, we can completely bypass all the checks Xin <TT>group 10</TT> when we're not communicating with hosts on Xthat network.<BR> X<P> X<P> XDepending on your situation, it may be prudent to group your rules Xby protocol, or various machines, or netblocks, or whatever makes Xit flow smoothly.<BR> X<A NAME=TOC_28> X<H2> X"Fastroute"; The Keyword of Stealthiness X</H2> X</A><BR> X<P> X<P> XEven though we're forwarding some packets, and blocking other Xpackets, we're typically behaving like a well behaved router should Xby decrementing the TTL on the packet and acknowledging to the Xentire world that yes, there is a hop here. But we can hide our Xpresence from inquisitive applications like unix traceroute which Xuses UDP packets with various TTL values to map the hops between Xtwo sites. If we want incoming traceroutes to work, but we do Xnot want to announce the presence of our firewall as a hop, we Xcan do so with a rule like this:<BR> X<TT> block in quick on xl0 fastroute proto udp from any to any port 33434 >< 33465<BR> X</TT>The presence of the <TT>fastroute</TT> keyword will signal Xipfilter to not pass the packet into the Unix IP stack for routing Xwhich results in a TTL decrement. The packet will be placed gently Xon the output interface by ipfilter itself and no such decrement Xwill happen. Ipfilter will of course use the system's routing Xtable to figure out what the appropriate output interface really Xis, but it will take care of the actual task of routing itself.<BR> X<P> X<P> XThere's a reason we used <TT>block quick</TT> in our example, Xtoo. If we had used <TT>pass</TT>, and if we had IP Forwarding Xenabled in our kernel, we would end up having two paths for a Xpacket to come out of, and we would probably panic our kernel.<BR> X<P> X<P> XIt should be noted, however, that most Unix kernels (and certainly Xthe ones underlying the systems that ipfilter usually runs on) Xhave far more efficient routing code than what exists in ipfilter, Xand this keyword should not be thought of as a way to improve Xthe operating speed of your firewall, and should only be used Xin places where stealth is an issue.<BR> X<A NAME=TOC_29> X<H2> XNAT and Proxies X</H2> X</A><BR> X<P> X<P> XOutside of the corporate environment, one of the biggest enticements Xof firewall technology to the end user is the ability to connect Xseveral computers through a common external interface, often without Xthe approval, knowledge, or even consent of their service provider. XTo those familiar with Linux, this concept is called <I>IP Masquerading</I>, Xbut to the rest of the world it is known by the more obscure name Xof <I>Network Address Translation,</I> or NAT for short.[[dagger]] X[[footnote: [[dagger]] To be pedantic, what IPFilter provides Xis really called NPAT, for Network and Port Address Translation, Xwhich means we can change any of the source and destination IP XAddresses and their source and destination ports. <I>True NAT</I> Xonly allows one to change the addresses. ]]<BR> X<A NAME=TOC_30> X<H2> XMapping Many Addresses Into One Address X</H2> X</A><BR> X<P> X<P> XThe basic use of NAT accomplishes much the same thing that Linux's XIP Masquerading function does, and it does it with one simple Xrule:<BR> X<TT> map tun0 192.168.1.0/24 -> 20.20.20.1/32<BR> X</TT>Very simple. Whenever a packet goes out the <TT>tun0</TT> Xinterface with a source address matching the CIDR network mask Xof 192.168.1.0/24 [[dagger]][[dagger]] this packet will be rewritten Xwithin the IP stack such that its source address is 20.20.20.1, Xand it will be sent on to its original destination. The system Xalso keeps a list of what translated connections are in progress Xso that it can perform the reverse and remap the response (which Xwill be directed to 20.20.20.1) to the internal host that really Xgenerated the packet. [[footnote: [[dagger]][[dagger]] This is Xa typical internal address space, since it's non-routable on the XReal Internet it is often used for internal networks. You should Xstill block these packets coming in from the outside world as Xdiscussed earlier. ]]<BR> X<P> X<P> XThere is a drawback to the rule we have just written, though. XIn a large number of cases, we do not happen to know what the XIP address of our outside link is (if we're using <TT>tun0</TT> Xor <TT>ppp0</TT> and a typical ISP) so it makes setting up our XNAT tables a chore. Luckily, NAT is smart enough to accept an Xaddress of 0/32 as a signal that it needs to go look at what the Xaddress of that interface really is and we can rewrite our rule Xas follows:<BR> X<TT> map tun0 192.168.1.0/24 -> 0/32<BR> X</TT>Now we can load our <TT>ipnat</TT> rules with impunity and Xconnect to the outside world without having to edit anything. XYou do have to run <TT>ipf -y</TT> to refresh the address if you Xget disconnected and redial or if your DHCP lease changes, though.[[dagger]][[dagger]][[dagger]] X[[footnote: [[dagger]][[dagger]][[dagger]] Typically you'd do Xthis in your network interface setup scripts for your ppp client, Xbut that is well beyond the scope of this document. ]]<BR> X<P> X<P> XSome of you may be wondering what happens to the source port when Xthe mapping happens. With our current rule, the packet's source Xport is unchanged from the original source port. There can be Xinstances where we do not desire this behavior; maybe we have Xanother firewall further upstream we have to pass through, or Xperhaps many hosts are trying to use the same source port, causing Xa collision where the rule doesn't match and the packet is passed Xuntranslated. ipnat helps us here with the <TT>portmap</TT> keyword:<BR> X<TT> map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000<BR> X</TT>Our rule now shoehorns all the translated connections (which Xcan be <TT>tcp</TT>, <TT>udp</TT>, or <TT>tcp/udp</TT>) into the Xport range of 20000 to 30000.<BR> X<P> X<P> XAdditionally, we can make our lives even easier by using the <TT>auto</TT> Xkeyword to tell ipnat to determine for itself which ports are Xavailable for use, and allocate a proportional amount of them Xper address in your pool versus addresses being natted:<BR> X<TT> map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp auto<BR> X</TT>Keep in mind that these <TT>portmap</TT> rules only apply Xto the protocols that you have specified (e.g.: tcp, udp, or tcp/udp), Xand do not apply to other protocols like ICMP or IPSec ESP/AH. XFor these, you need to have an additonal <TT>map</TT> statement Xthat applies to all other protocols:<BR> X<TT> map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000<BR> X map tun0 192.168.1.0/24 -> 0/32<BR> X</TT> X<A NAME=TOC_31> X<H2> XMapping Many Addresses Into a Pool of Addresses X</H2> X</A><BR> X<P> X<P> XAnother use common use of NAT is to take a small statically allocated Xblock of addresses and map many computers into this smaller address Xspace. This is easy to accomplish using what you already know Xabout the <TT>map</TT> and <TT>portmap</TT> keywords by writing Xa rule like so:<BR> X<TT> map tun0 192.168.0.0/16 -> 20.20.20.0/24 portmap tcp/udp 20000:60000<BR> X</TT>Also, there may be instances where a remote application requires Xthat multiple connections all come from the same IP address. We Xcan help with these situations by telling NAT to statically map Xsessions from a host into the pool of addresses and work some Xmagic to choose a port. This uses a the keyword <TT>map-block</TT> Xas follows:<BR> X<TT> map-block tun0 192.168.1.0/24 -> 20.20.20.0/24<BR> X</TT>As with <TT>map</TT>, <TT>map-block</TT> has it's own version Xof <TT>portmap</TT>. This is accomplished with either the <TT>auto</TT> Xkeyword:<BR> X<TT> map-block tun0 192.168.1.0/24 -> 20.20.20.0/24 auto<BR> X</TT>or the <TT>ports</TT> keyword, if you want to specify your Xown number of ports belonging to each ip address:<BR> X<TT> map-block tun0 192.168.1.0/24 -> 20.20.20.0/24 ports 64<BR> X</TT> X<A NAME=TOC_32> X<H2> XOne to One Mappings X</H2> X</A><BR> X<P> X<P> XOccasionally it is desirable to have a system with one IP address Xbehind the firewall to appear to have a completely different IP Xaddress. One example of how this would work would be a lab of Xcomputers which are then attached to various networks that are Xto be put under some kind of test. In this example, you would Xnot want to have to reconfigure the entire lab when you could Xplace a NAT system in front and change the addresses in one simple Xplace. We can do that with the <TT>bimap</TT> keyword, for bidirectional Xmapping. <TT>Bimap</TT> has some additional protections on Xit to ensure a known state for the connection, whereas the <TT>map</TT> Xkeyword is designed to allocate an address and a source port and Xrewrite the packet and go on with life.<BR> X<TT> bimap tun0 192.168.1.1/32 -> 20.20.20.1/32<BR> X</TT>will accomplish the mapping for one host.<BR> X<A NAME=TOC_33> X<H2> XPolicy NAT X</H2> X</A><BR> X<P> X<P> XQuite often, we will find ourselves in need of having NAT behave Xdifferently based on which source and destination addresses are Xbeing used. For example, we might want to always NAT unless Xwe are speaking with a specific subnet:<BR> X<TT> map tun0 from 192.168.1.0/24 ! to 5.0.0.0/20 -> 20.20.20.1/32<BR> X</TT>We might also want to do something like the following:<BR> X<TT> map tun0 from 192.168.1.5/32 port = 5555 to 1.2.3.4/32 -> 20.20.20.2/32<BR> X map tun0 from 192.168.1.0/24 to 5.0.0.0/20 -> 20.20.20.2/32 portmap auto<BR> X</TT> X<A NAME=TOC_34> X<H2> XSpoofing Services X</H2> X</A><BR> X<P> X<P> XSpoofing services? What does that have to do with anything? XPlenty. Let's pretend that we have a web server running on 20.20.20.5, Xand since we've gotten increasingly suspicious of our network Xsecurity, we desire to not run this server on port 80 since that Xrequires a brief lifespan as the root user. But how do we run Xit on a less privledged port of 8000 in this world of "anything Xdot com"? How will anyone find our server? We can use the Xredirection facilities of NAT to solve this problem by instructing Xit to remap any connections destined for 20.20.20.5:80 to really Xpoint to 20.20.20.5:8000. This uses the <TT>rdr</TT> keyword:<BR> X<TT> rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000<BR> X</TT>We can also specify the protocol here, if we wanted to redirect Xa UDP service, instead of a TCP service (which is the default). XFor example, if we had a honeypot on our firewall to impersonate Xthe popular Back Orifice for Windows, we could shovel our entire Xnetwork into this one place with a simple rule:<BR> X<TT> rdr tun0 20.20.20.0/24 port 31337 -> 127.0.0.1 port 31337 udp<BR> X</TT>We can also alter <TT>rdr</TT>'s behavior based on the source Xand destination addresses:<BR> X<TT> rdr tun0 from 10.1.1.1/32 to 20.20.20.5/32 port = 80 -> 192.168.0.5 port 8001<BR> X rdr tun0 from 10.1.1.1/32 port = 12345 to 20.20.20.5/32 port = 80 -> 192.168.0.5 port 8002<BR> X</TT>An extremely important point must be made about <TT>rdr</TT>: XYou cannot easily[[dagger]] use this feature as a "reflector". XE.g:<BR> X<TT> rdr tun0 20.20.20.5/32 port 80 -> 20.20.20.6 port 80 tcp<BR> X</TT>will not work in the situation where .5 and .6 are on the Xsame LAN segment. [[footnote: [[dagger]] Yes. There is a way to Xdo this. It's so convoluted that I refuse to use it, though. XSmart people who require this functionality will transparently Xredirect into something like TIS plug-gw on 127.0.0.1. Stupid Xpeople will set up a dummy loop interface pair and double rewrite. X]] The <TT>rdr</TT> function is applied to packets that enter Xthe firewall on the specified interface. When a packet comes Xin that matches a <TT>rdr</TT> rule, its destination address is Xthen rewritten, it is pushed into <TT>ipf</TT> for filtering, Xand should it successfully run the gauntlet of filter rules, it Xis then sent to the unix routing code. Since this packet is still X<I>inbound</I> on the same interface that it will need to leave Xthe system on to reach a host, the system gets confused. Reflectors Xdon't work. Neither does specifying the address of the interface Xthe packet just came in on. Always remember that <TT>rdr</TT> Xdestinations must exit out of the firewall host on a different Xinterface. [[dagger]][[dagger]] [[footnote: [[dagger]][[dagger]] XThis includes 127.0.0.1, by the way. That's on lo0. Neat, huh? X]]<BR> X<A NAME=TOC_35> X<H2> XTransparent Proxy Support; Redirection Made Useful X</H2> X</A><BR> X<P> X<P> XSince you're installing a firewall, you may have decided that Xit is prudent to use a proxy for many of your outgoing connections Xso that you can further tighten your filter rules protecting your Xinternal network, or you may have run into a situation that the XNAT mapping process does not currently handle properly. This Xcan also be accomplished with a redirection statement:<BR> X<TT> rdr xl0 0.0.0.0/0 port 21 -> 127.0.0.1 port 21<BR> X</TT>This statement says that any packet coming in on the <TT>xl0</TT> Xinterface destined for any address (0.0.0.0/0) on the ftp port Xshould be rewritten to connect it with a proxy that is running Xon the NAT system on port 21.<BR> X<P> X<P> XThis specific example of FTP proxying does lead to some complications Xwhen used with web browsers or other automatic-login type clients Xthat are unaware of the requirements of communicating with the Xproxy. There are patches for <I>TIS Firewall Toolkit's</I><TT>ftp-gw</TT> Xto mate it with the nat process so that it can determine where Xyou were trying to go and automatically send you there. Many Xproxy packages now work in a transparent proxy environment (Squid Xfor example, located at <I>http://squid.nlanr.net</I>, works fine.)<BR> X<P> X<P> XThis application of the <TT>rdr</TT> keyword is often more useful Xwhen you wish to force users to authenticate themselves with the Xproxy. (For example, you desire your engineers to be able to surf Xthe web, but you would rather not have your call-center staff Xdoing so.)<BR> X<A NAME=TOC_36> X<H2> XFiltering Redirected Services X</H2> X</A><BR> X<P> X<P> XQuite a lot of users will want to combine both filtering and address Xtranslation in order to provide a service to only known hosts Xbehind their NAT system. For example, to provide a web server Xbehind your machine 20.20.20.5 (which is really 192.168.0.5 on Xyour inside network) for your friend over on 172.16.8.2, you would Xwrite the following in ipnat.rules:<BR> X<TT> rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000<BR> X</TT>and the following in ipf.rules:<BR> X<TT> pass in on tun0 proto tcp from 172.16.8.2/32 to 192.168.0.5/32 port = 8000 flags S keep state<BR> X</TT>That might look a little strange at first glance, but that's Xbecause the NAT stage happens first, and the packet's destination Xaddress and port is rewritten before it is processed by the filter Xcode.<BR> X<A NAME=TOC_37> X<H2> XMagic Hidden Within NAT; Application Proxies X</H2> X</A><BR> X<P> X<P> XSince <TT>ipnat</TT> provides a method to rewrite packets as they Xtraverse the firewall, it becomes a convenient place to build Xin some application level proxies to make up for well known deficiencies Xof that application and typical firewalls. For example; FTP. XWe can make our firewall pay attention to the packets going across Xit and when it notices that it's dealing with an Active FTP session, Xit can write itself some temporary rules, much like what happens Xwith <TT>keep state</TT>, so that the FTP data connection works. XTo do this, we use a rule like so:<BR> X<TT> map tun0 192.168.1.0/24 -> 20.20.20.1/32 proxy port ftp ftp/tcp<BR> X</TT>You must always remember to place this <TT>proxy rule</TT> X<B>before</B> any <TT>portmap</TT> rules, otherwise when <TT>portmap</TT> Xcomes along and matches the packet and rewrites it before the Xproxy gets a chance to work on it. Remember that ipnat rules are Xfirst-match.<BR> X<P> X<P> XThere also exist proxies for "rcmd" (which we suspect Xis berkeley r-* commands which should be forbidden anyway, thus Xwe haven't looked at what this proxy does) and "raudio" Xfor Real Audio PNM streams. Likewise, both of these rules should Xbe put before any <TT>portmap</TT> rules, if you're doing NAT.<BR> X<A NAME=TOC_38> X<H2> XMore Magic; Using NAT As a Load Balancer X</H2> X</A><BR> X<P> X<P> XSince <TT>ipnat</TT> is already rewriting packets for us, we can Xuse it to support one of the simpler features of those expensive Xload-balancing systems and assign sessions to multiple destination Xaddresses. This is accomplished using the <TT>round-robin</TT> Xkeyword:<BR> X<TT> rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5, 192.168.0.6, 192.168.0.7 port 8000<BR> X</TT> X<A NAME=TOC_39> X<H2> XLoading and Manipulating Filter Rules; The ipf Utility X</H2> X</A><BR> X<P> X<P> XIP Filter rules are loaded by using the <TT>ipf</TT> utility. XThe filter rules can be stored in any file on the system, but Xtypically these rules are stored in <TT>/etc/ipf.rules</TT>, <TT>/usr/local/etc/ipf.rules</TT>, Xor <TT>/etc/opt/ipf/ipf.rules</TT>.<BR> X<P> X<P> XIP Filter has two sets of rules, the <I>active set</I> and the X<I>inactive set</I>. By default, all operations are performed Xon the active set. You can manipulate the inactive set by adding X<TT>-I</TT> to the <TT>ipf</TT> command line. The two sets can Xbe toggled by using the <TT>-s</TT> command line option. This Xis very useful for testing new rule sets without wiping out the Xold rule set.<BR> X<P> X<P> XRules can also be removed from the list instead of added by using Xthe <TT>-r</TT> command line option, but it is generally a safer Xidea to flush the rule set that you're working on with <TT>-F</TT> Xand completely reload it when making changes.<BR> X<P> X<P> XIn summary, the easiest way to load a rule set is <TT>ipf -Fa X-f /etc/ipf.rules</TT>. For more complicated manipulations of Xthe rule set, please see the <TT>ipf(1)</TT> man page.<BR> X<A NAME=TOC_40> X<H2> XLoading and Manipulating NAT Rules; The ipnat Utility X</H2> X</A><BR> X<P> X<P> XNAT rules are loaded by using the <TT>ipnat</TT> utility. The XNAT rules can be stored in any file on the system, but typically Xthese rules are stored in <TT>/etc/ipnat.rules</TT>, <TT>/usr/local/etc/ipnat.rules</TT>, Xor <TT>/etc/opt/ipf/ipnat.rules</TT>.<BR> X<P> X<P> XRules can also be removed from the list instead of added by using Xthe <TT>-r</TT> command line option, but it is generally a safer Xidea to flush the rule set that you're working on with <TT>-C</TT> Xand completely reload it when making changes. Any active mappings Xare not affected by <TT>-C</TT>, and can be removed with <TT>-F</TT>.<BR> X<P> X<P> XNAT rules and active mappings can be examined with the <TT>-l</TT> Xcommand line option.<BR> X<P> X<P> XIn summary, the easiest way to load a NAT rule set is <TT>ipnat X-CF -f /etc/ipnat.rules</TT>.<BR> X<A NAME=TOC_41> X<H2> XMonitoring and Debugging X</H2> X</A><BR> X<P> X<P> XThere will come a time when you are interested in what your firewall Xis actually doing, and ipfilter would be incomplete if it didn't Xhave a full suite of status monitoring tools.<BR> X<A NAME=TOC_42> X<H2> XThe ipfstat utility X</H2> X</A><BR> X<P> X<P> XIn its simplest form, <TT>ipfstat</TT> displays a table of interesting Xdata about how your firewall is performing, such as how many packets Xhave been passed or blocked, if they were logged or not, how many Xstate entries have been made, and so on. Here's an example of Xsomething you might see from running the tool:<BR> X<TT> # ipfstat<BR> X input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0<BR> X output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0<BR> X input packets logged: blocked 99286 passed 0<BR> X output packets logged: blocked 0 passed 0<BR> X packets logged: input 0 output 0<BR> X log failures: input 3898 output 0<BR> X fragment state(in): kept 0 lost 0<BR> X fragment state(out): kept 0 lost 0<BR> X packet state(in): kept 169364 lost 0<BR> X packet state(out): kept 431395 lost 0<BR> X ICMP replies: 0 TCP RSTs sent: 0<BR> X Result cache hits(in): 1215208 (out): 1098963<BR> X IN Pullups succeeded: 2 failed: 0<BR> X OUT Pullups succeeded: 0 failed: 0<BR> X Fastroute successes: 0 failures: 0<BR> X TCP cksum fails(in): 0 (out): 0<BR> X Packet log flags set: (0)<BR> X none<BR> X</TT><TT>ipfstat</TT> is also capable of showing you your current Xrule list. Using the <TT>-i</TT> or the <TT>-o</TT> flag will Xshow the currently loaded rules for in or out, respectively. XAdding a <TT>-h</TT> to this will provide more useful information Xat the same time by showing you a "hit count" on each Xrule. For example:<BR> X<TT> # ipfstat -ho<BR> X 2451423 pass out on xl0 from any to any<BR> X 354727 block out on ppp0 from any to any<BR> X 430918 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags<BR> X</TT>From this, we can see that perhaps there's something abnormal Xgoing on, since we've got a lot of blocked packets outbound, even Xwith a very permissive <TT>pass out</TT> rule. Something here Xmay warrant further investigation, or it may be functioning perfectly Xby design. ipfstat can't tell you if your rules are right or Xwrong, it can only tell you what is happening because of your Xrules.<BR> XTo further debug your rules, you may want to use the <TT>-n</TT> Xflag, which will show the rule number next to each rule.<BR> X<TT> # ipfstat -on<BR> X @1 pass out on xl0 from any to any<BR> X @2 block out on ppp0 from any to any<BR> X @3 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags<BR> X</TT>The final piece of really interesting information that <TT>ipfstat</TT> Xcan provide us is a dump of the state table. This is done with Xthe <TT>-s</TT> flag:<BR> X<TT> # ipfstat -s<BR> X 281458 TCP<BR> X 319349 UDP<BR> X 0 ICMP<BR> X 19780145 hits<BR> X 5723648 misses<BR> X 0 maximum<BR> X 0 no memory<BR> X 1 active<BR> X 319349 expired<BR> X 281419 closed<BR> X 100.100.100.1 -> 20.20.20.1 ttl 864000 pass 20490 pr 6 state 4/4<BR> X pkts 196 bytes 17394 987 -> 22 585538471:2213225493 16592:16500<BR> X pass in log quick keep state<BR> X pkt_flags & b = 2, pkt_options & ffffffff = 0<BR> X pkt_security & ffff = 0, pkt_auth & ffff = 0<BR> X</TT>Here we see that we have one state entry for a TCP connection. XThe output will vary slightly from version to version, but the Xbasic information is the same. We can see in this connection Xthat we have a fully established connection (represented by the X4/4 state. Other states are incomplete and will be documented Xfully later.) We can see that the state entry has a time to live Xof 240 hours, which is an absurdly long time, but is the default Xfor an established TCP connection. This TTL counter is decremented Xevery second that the state entry is not used, and will finally Xresult in the connection being purged if it has been left idle. XThe TTL is also reset to 864000 whenever the state IS used, ensuring Xthat the entry will not time out while it is being actively used. XWe can also see that we have passed 196 packets consisting of Xabout 17kB worth of data over this connection. We can see the Xports for both endpoints, in this case 987 and 22; which means Xthat this state entry represents a connection from 100.100.100.1 Xport 987 to 20.20.20.1 port 22. The really big numbers in the Xsecond line are the TCP sequence numbers for this connection, Xwhich helps to ensure that someone isn't easily able to inject Xa forged packet into your session. The TCP window is also shown. XThe third line is a synopsis of the implicit rule that was generated Xby the <TT>keep state</TT> code, showing that this connection Xis an inbound connection.<BR> X<A NAME=TOC_43> X<H2> XThe ipmon utility X</H2> X</A><BR> X<P> X<P> X<TT>ipfstat</TT> is great for collecting snapshots of what's going Xon on the system, but it's often handy to have some kind of log Xto look at and watch events as they happen in time. <TT>ipmon</TT> Xis this tool. <TT>ipmon</TT> is capable of watching the packet Xlog (as created with the <TT>log</TT> keyword in your rules), Xthe state log, or the nat log, or any combination of the three. XThis tool can either be run in the foreground, or as a daemon Xwhich logs to syslog or a file. If we wanted to watch the state Xtable in action, <TT>ipmon -o S</TT> would show this:<BR> X<TT> # ipmon -o S<BR> X 01/08/1999 15:58:57.836053 STATE:NEW 100.100.100.1,53 -> 20.20.20.15,53 PR udp<BR> X 01/08/1999 15:58:58.030815 STATE:NEW 20.20.20.15,123 -> 128.167.1.69,123 PR udp<BR> X 01/08/1999 15:59:18.032174 STATE:NEW 20.20.20.15,123 -> 128.173.14.71,123 PR udp<BR> X 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<BR> X 01/08/1999 16:03:51.754867 STATE:NEW 20.20.20.13,1019 -> 100.100.100.10,22 PR tcp<BR> X 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<BR> X</TT>Here we see a state entry for an external dns request off Xour nameserver, two xntp pings to well-known time servers, and Xa very short lived outbound ssh connection.<BR> X<P> X<P> X<TT>ipmon</TT> is also capable of showing us what packets have Xbeen logged. For example, when using state, you'll often run Xinto packets like this:<BR> X<TT> # ipmon -o I<BR> X 15:57:33.803147 ppp0 @0:2 b 100.100.100.103,443 -> 20.20.20.10,4923 PR tcp len 20 1488 -A<BR> X</TT>What does this mean? The first field is obvious, it's a Xtimestamp. The second field is also pretty obvious, it's the Xinterface that this event happened on. The third field <TT>@0:2</TT> Xis something most people miss. This is the rule that caused the Xevent to happen. Remember <TT>ipfstat -in</TT>? If you wanted Xto know where this came from, you could look there for rule 2 Xin rule group 0. The fourth field, the little "b" says Xthat this packet was blocked, and you'll generally ignore this Xunless you're logging passed packets as well, which would be a Xlittle "p" instead. The fifth and sixth fields are pretty Xself-explanatory, they say where this packet came from and where Xit was going. The seventh ("PR") and eighth fields tell Xyou the protocol and the ninth field tells you the size of the Xpacket. The last part, the "-A" in this case, tells Xyou the flags that were on the packet; This one was an ACK packet. XWhy did I mention state earlier? Due to the often laggy nature Xof the Internet, sometimes packets will be regenerated. Sometimes, Xyou'll get two copies of the same packet, and your state rule Xwhich keeps track of sequence numbers will have already seen this Xpacket, so it will assume that the packet is part of a different Xconnection. Eventually this packet will run into a real rule Xand have to be dealt with. You'll often see the last packet Xof a session being closed get logged because the <TT>keep state</TT> Xcode has already torn down the connection before the last packet Xhas had a chance to make it to your firewall. This is normal, Xdo not be alarmed. [[dagger]] [[footnote: [[dagger]] For a technical Xpresentation of the IP Filter stateful inspection engine, please Xsee the white paper <I>Real Stateful TCP Packet Filtering in IP XFilter</I>, by Guido van Rooij. This paper may be found at <I><http://www.iae.nl/users/guido/papers/tcp_filtering.ps.gz></I> X]] Another example packet that might be logged:<BR> X<TT> 12:46:12.470951 xl0 @0:1 S 20.20.20.254 -> 255.255.255.255 PR icmp len 20 9216 icmp 9/0<BR> X</TT>This is a ICMP router discovery broadcast. We can tell by Xthe ICMP type 9/0.<BR> XFinally, <TT>ipmon</TT> also lets us look at the NAT table in Xaction.<BR> X<TT> # ipmon -o N<BR> X 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]<BR> X 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<BR> X</TT>This would be a redirection to an identd that lies to provide Xident service for the hosts behind our NAT, since they are typically Xunable to provide this service for themselves with ordinary natting.<BR> X<B>0. Specific Applications of IP Filter - Things that don't fit, Xbut should be mentioned anyway.<BR> X</B> X<A NAME=TOC_44> X<H2> XKeep State With Servers and Flags. X</H2> X</A><BR> X<P> X<P> XKeeping state is a good thing, but it's quite easy to make a mistake Xin the direction that you want to <TT>keep state</TT> in. Generally, Xyou want to have a <TT>keep state</TT> keyword on the first rule Xthat interacts with a packet for the connection. One common mistake Xthat is made when mixing state tracking with filtering on flags Xis this:<BR> X<TT> block in all<BR> X pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S<BR> X pass out all keep state<BR> X</TT>That certainly appears to allow a connection to be created Xto the telnet server on 20.20.20.20, and the replies to go back. XIf you try using this rule, you'll see that it does work--Momentarily. XSince we're filtering for the SYN flag, the state entry never Xfully gets completed, and the default time to live for an incomplete Xstate is 60 seconds.<BR> XWe can solve this by rewriting the rules in one of two ways:<BR> X<CENTER> X1)<BR> X</CENTER> X<TT> block in all<BR> X pass in quick proto tcp from any to 20.20.20.20/32 port = 23 keep state<BR> X block out all<BR> X</TT>or:<BR> X<CENTER> X2)<BR> X</CENTER> X<TT> block in all<BR> X pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S keep state<BR> X pass out all keep state<BR> X</TT>Either of these sets of rules will result in a fully established Xstate entry for a connection to your server.<BR> X<A NAME=TOC_45> X<H2> XCoping With FTP X</H2> X</A><BR> X<P> X<P> XFTP is one of those protocols that you just have to sit back and Xask "What the heck were they thinking?" FTP has many Xproblems that the firewall administrator needs to deal with. XWhat's worse, the problems the administrator must face are different Xbetween making ftp clients work and making ftp servers work.<BR> X<P> X<P> XWithin the FTP protocol, there are two forms of data transfer, Xcalled active and passive. Active transfers are those where the Xserver connects to an open port on the client to send data. Conversely, Xpassive transfers are those where the client connects to the server Xto receive data.<BR> X<A NAME=TOC_46> X<H2> XRunning an FTP Server X</H2> X</A><BR> X<P> X<P> XIn running an FTP server, handling Active FTP sessions is easy Xto setup. At the same time, handling Passive FTP sessions is a Xbig problem. First we'll cover how to handle Active FTP, then Xmove on to Passive. Generally, we can handle Active FTP sessions Xlike we would an incoming HTTP or SMTP connection; just open the Xftp port and let <TT>keep state</TT> do the rest:<BR> X<TT> pass in quick proto tcp from any to 20.20.20.20/32 port = 21 flags S keep state<BR> X pass out proto tcp all keep state<BR> X</TT>These rules will allow Active FTP sessions, the most common Xtype, to your ftp server on 20.20.20.20.<BR> X<P> X<P> XThe next challenge becomes handling Passive FTP connections. XWeb browsers default to this mode, so it's becoming quite popular Xand as such it should be supported. The problem with passive Xconnections are that for every passive connection, the server Xstarts listening on a new port (usually above 1023). This is Xessentially like creating a new unknown service on the server. XAssuming we have a good firewall with a default-deny policy, that Xnew service will be blocked, and thus Passive FTP sessions are Xbroken. Don't despair! There's hope yet to be had.<BR> X<P> X<P> XA person's first inclination to solving this problem might be Xto just open up all ports above 1023. In truth, this will work:<BR> X<TT> pass in quick proto tcp from any to 20.20.20.20/32 port > 1023 flags S keep state<BR> X pass out proto tcp all keep state<BR> X</TT>This is somewhat unsatisfactory, though. By letting everything Xabove 1023 in, we actually open ourselves up for a number of potential Xproblems. While 1-1023 is the designated area for server services Xto run, numerous programs decided to use numbers higher than 1023, Xsuch as nfsd and X.<BR> X<P> X<P> XThe good news is that your FTP server gets to decide which ports Xget assigned to passive sessions. This means that instead of Xopening all ports above 1023, you can allocate ports 15001-19999 Xas ftp ports and only open that range of your firewall up. In Xwu-ftpd, this is done with the <TT>passive ports</TT> option in X<TT>ftpaccess</TT>. Please see the man page on <TT>ftpaccess</TT> Xfor details in wu-ftpd configuration. On the ipfilter side, all Xwe need do is setup corresponding rules:<BR> X<TT> pass in quick proto tcp from any to 20.20.20.20/32 port 15000 >< 20000 flags S keep state<BR> X pass out proto tcp all keep state<BR> X</TT>If even this solution doesn't satisfy you, you can always Xhack IPF support into your FTP server, or FTP server support into XIPF.<BR> X<A NAME=TOC_47> X<H2> XRunning an FTP Client X</H2> X</A><BR> X<P> X<P> XWhile FTP server support is still less than perfect in IPF, FTP Xclient support has been working well since 3.3.3. As with FTP Xservers, there are two types of ftp client transfers: passive Xand active.<BR> X<P> X<P> XThe simplest type of client transfer from the firewall's standpoint Xis the passive transfer. Assuming you're keeping state on all Xoutbound tcp sessions, passive transfers will work already. If Xyou're not doing this already, please consider the following:<BR> X<TT> pass out proto tcp all keep state<BR> X</TT>The second type of client transfer, active, is a bit more Xtroublesome, but nonetheless a solved problem. Active transfers Xcause the server to open up a second connection back to the client Xfor data to flow through. This is normally a problem when there's Xa firewall in the middle, stopping outside connections from coming Xback in. To solve this, ipfilter includes an <TT>ipnat</TT> proxy Xwhich temporarily opens up a hole in the firewall just for the XFTP server to get back to the client. Even if you're not using X<TT>ipnat</TT> to do nat, the proxy is still effective. The following Xrules is the bare minimum to add to the <TT>ipnat</TT> configuration Xfile (<TT>ep0</TT> should be the interface name of the outbound Xnetwork connection):<BR> X<TT> map ep0 0/0 -> 0/32 proxy port 21 ftp/tcp<BR> X</TT>For more details on ipfilter's internal proxies, see section X3.6. Additionally, IPF's ftp proxy does work the "wrong way", Xand can be used to support a natted FTP server, but you <I>really</I> Xdon't want to do this for security reasons. Really. This is Xa huge security hole. See http://www.false.net/ipfilter/2001_11/0273.html Xfor reasons why you should forget you ever thought about this.<BR> X<A NAME=TOC_48> X<H2> XAssorted Kernel Variables X</H2> X</A><BR> X<P> X<P> XThere are some useful kernel tunes that either need to be set Xfor ipf to function, or are just generally handy to know about Xfor building firewalls. The first major one you must set is to Xenable IP Forwarding, otherwise ipf will do very little, as the Xunderlying ip stack won't actually route packets.<BR> XIP Forwarding:<BR> X<CENTER> Xopenbsd:<BR> X</CENTER> Xnet.inet.ip.forwarding=1<BR> X<CENTER> Xfreebsd:<BR> X</CENTER> Xnet.inet.ip.forwarding=1<BR> X<CENTER> Xnetbsd:<BR> X</CENTER> Xnet.inet.ip.forwarding=1<BR> X<CENTER> Xsolaris:<BR> X</CENTER> Xndd -set /dev/ip ip_forwarding 1<BR> XEphemeral Port Adjustment:<BR> X<CENTER> Xopenbsd:<BR> X</CENTER> Xnet.inet.ip.portfirst = 25000<BR> X<CENTER> Xfreebsd:<BR> X</CENTER> Xnet.inet.ip.portrange.first = 25000 net.inet.ip.portrange.last X= 49151<BR> X<CENTER> Xnetbsd:<BR> X</CENTER> Xnet.inet.ip.anonportmin = 25000 net.inet.ip.anonportmax = 49151<BR> X<CENTER> Xsolaris:<BR> X</CENTER> Xndd -set /dev/tcp tcp_smallest_anon_port 25000<BR> Xndd -set /dev/tcp tcp_largest_anon_port 65535<BR> XOther Useful Values:<BR> X<CENTER> Xopenbsd:<BR> X</CENTER> Xnet.inet.ip.sourceroute = 0<BR> Xnet.inet.ip.directed-broadcast = 0<BR> X<CENTER> Xfreebsd:<BR> X</CENTER> Xnet.inet.ip.sourceroute=0<BR> Xnet.ip.accept_sourceroute=0<BR> X<CENTER> Xnetbsd:<BR> X</CENTER> Xnet.inet.ip.allowsrcrt=0<BR> Xnet.inet.ip.forwsrcrt=0<BR> Xnet.inet.ip.directed-broadcast=0<BR> Xnet.inet.ip.redirect=0<BR> X<CENTER> Xsolaris:<BR> X</CENTER> Xndd -set /dev/ip ip_forward_directed_broadcasts 0<BR> Xndd -set /dev/ip ip_forward_src_routed 0<BR> Xndd -set /dev/ip ip_respond_to_echo_broadcast 0<BR> XIn addition, freebsd has some ipf specific sysctl variables.<BR> X<TT> net.inet.ipf.fr_flags: 0<BR> X net.inet.ipf.fr_pass: 514<BR> X net.inet.ipf.fr_active: 0<BR> X net.inet.ipf.fr_tcpidletimeout: 864000<BR> X net.inet.ipf.fr_tcpclosewait: 60<BR> X net.inet.ipf.fr_tcplastack: 20<BR> X net.inet.ipf.fr_tcptimeout: 120<BR> X net.inet.ipf.fr_tcpclosed: 1<BR> X net.inet.ipf.fr_udptimeout: 120<BR> X net.inet.ipf.fr_icmptimeout: 120<BR> X net.inet.ipf.fr_defnatage: 1200<BR> X net.inet.ipf.fr_ipfrttl: 120<BR> X net.inet.ipf.ipl_unreach: 13<BR> X net.inet.ipf.ipl_inited: 1<BR> X net.inet.ipf.fr_authsize: 32<BR> X net.inet.ipf.fr_authused: 0<BR> X net.inet.ipf.fr_defaultauthage: 600<BR> X</TT> X<A NAME=TOC_49> X<H2> XFun with ipf! X</H2> X</A><BR> X<P> X<P> XThis section doesn't necessarily teach you anything new about Xipf, but it may raise an issue or two that you haven't yet thought Xup on your own, or tickle your brain in a way that you invent Xsomething interesting that we haven't thought of.<BR> X<A NAME=TOC_50> X<H2> XLocalhost Filtering X</H2> X</A><BR> X<P> X<P> XA long time ago at a university far, far away, Wietse Venema created Xthe tcp-wrapper package, and ever since, it's been used to add Xa layer of protection to network services all over the world. XThis is good. But, tcp-wrappers have flaws. For starters, they Xonly protect TCP services, as the name suggests. Also, unless Xyou run your service from inetd, or you have specifically compiled Xit with libwrap and the appropriate hooks, your service isn't Xprotected. This leaves gigantic holes in your host security. XWe can plug these up by using ipf on the local host. For example, Xmy laptop often gets plugged into or dialed into networks that XI don't specifically trust, and so, I use the following rule set:<BR> X<TT> pass in quick on lo0 all<BR> X pass out quick on lo0 all<BR> X block in log all<BR> X block out all<BR> X pass in quick proto tcp from any to any port = 113 flags S keep state<BR> X pass in quick proto tcp from any to any port = 22 flags S keep state<BR> X pass in quick proto tcp from any port = 20 to any port 39999 >< 45000 flags S keep state<BR> X pass out quick proto icmp from any to any keep state<BR> X pass out quick proto tcp/udp from any to any keep state keep frags<BR> X</TT>It's been like that for quite a while, and I haven't suffered Xany pain or anguish as a result of having ipf loaded up all the Xtime. If I wanted to tighten it up more, I could switch to using Xthe NAT ftp proxy and I could add in some rules to prevent spoofing. XBut even as it stands now, this box is far more restrictive about Xwhat it presents to the local network and beyond than the typical Xhost does. This is a good thing if you happen to run a machine Xthat allows a lot of users on it, and you want to make sure one Xof them doesn't happen to start up a service they wern't supposed Xto. It won't stop a malicious hacker with root access from adjusting Xyour ipf rules and starting a service anyway, but it will keep Xthe "honest" folks honest, and your weird services safe, Xcozy and warm even on a malicious LAN. A big win, in my opinion. XUsing local host filtering in addition to a somewhat less-restrictive X"main firewall" machine can solve many performance issues Xas well as <I>political</I> nightmares like "Why doesn't XICQ work?" and "Why can't I put a web server on my own Xworkstation! It's MY WORKSTATION!!" Another very big win. XWho says you can't have security and convienence at the same time?<BR> X<A NAME=TOC_51> X<H2> XWhat Firewall? Transparent filtering. X</H2> X</A><BR> X<P> X<P> XOne major concern in setting up a firewall is the integrity of Xthe firewall itself. Can somebody break into your firewall, thereby Xsubverting its ruleset? This is a common problem administrators Xmust face, particularly when they're using firewall solutions Xon top of their Unix/NT machines. Some use it as an arguement Xfor blackbox hardware solutions, under the flawed notion that Xinherent obscurity of their closed system increases their security. XWe have a better way.<BR> X<P> X<P> XMany network admins are familiar with the common ethernet bridge. XThis is a device that connects two separate ethernet segments Xto make them one. An ethernet bridge is typically used to connect Xseparate buildings, switch network speeds, and extend maximum Xwire lengths. Hubs and switches are common bridges, sometimes Xthey're just 2 ported devices called repeaters. Recent versions Xof Linux, OpenBSD, NetBSD, and FreeBSD include code to convert X$1000 PCs into $10 bridges, too! What all bridges tend to have Xin common is that though they sit in the middle of a connection Xbetween two machines, the two machines don't know the bridge is Xthere. Enter ipfilter and OpenBSD.<BR> X<P> X<P> XEthernet bridging takes place at Layer2 on the ISO stack. IP Xtakes place on Layer3. IP Filter in primarily concerned with XLayer3, but dabbles in Layer2 by working with interfaces. By Xmixing IP filter with OpenBSD's bridge device, we can create a Xfirewall that is both invisible and unreachable. The system needs Xno IP address, it doesn't even need to reveal its ethernet address. XThe only telltale sign that the filter might be there is that Xlatency is somewhat higher than a piece of cat5 would normally Xmake it, and that packets don't seem to make it to their final Xdestination.<BR> X<P> X<P> XThe setup for this sort of ruleset is surprisingly simple, too. XIn OpenBSD, the first bridge device is named <TT>bridge0</TT>. XSay we have two ethernet cards in our machine as well, <TT>xl0</TT> Xand <TT>xl1</TT>. To turn this machine into a bridge, all one Xneed do is enter the following three commands:<BR> X<TT> brconfig bridge0 add xl0 add xl1 up<BR> X ifconfig xl0 up<BR> X ifconfig xl1 up<BR> X</TT>At ths point, all traffic ariving on <TT>xl0</TT> is sent Xout <TT>xl1</TT> and all traffic on <TT>xl1</TT> is sent out <TT>xl0</TT>. XYou'll note that neither interface has been assigned an IP address, Xnor do we need assign one. All things considered, it's likely Xbest we not add one at all.<BR> X<P> X<P> XRulesets behave essentially the as the always have. Though there Xis a <TT>bridge0</TT> interface, we don't filter based on it. XRules continue to be based upon the particular interface we're Xusing, making it important which network cable is plugged into Xwhich network card in the back of the machine. Let's start with Xsome basic filtering to illistrate what's happened. Assume the Xnetwork used to look like this:<BR> X<TT> 20.20.20.1 <---------------------------------> 20.20.20.0/24 network hub<BR> X</TT>That is, we have a router at 20.20.20.1 connected to the X20.20.20.0/24 network. All packets from the 20.20.20.0/24 network Xgo through 20.20.20.1 to get to the outside world and vice versa. XNow we add the Ipf Bridge:<BR> X<TT> 20.20.20.1 <-------/xl0 IpfBridge xl1/-------> 20.20.20.0/24 network hub<BR> X</TT>We also have the following ruleset loaded on the IpfBridge Xhost:<BR> X<TT> pass in quick all<BR> X pass out quick all<BR> X</TT>With this ruleset loaded, the network is functionally identical. XAs far as the 20.20.20.1 router is concerned, and as far as the X20.20.20.0/24 hosts are concerned, the two network diagrams are Xidentical. Now let's change the ruleset some:<BR> X<TT> block in quick on xl0 proto icmp<BR> X pass in quick all<BR> X pass out quick all<BR> X</TT>Still, 20.20.20.1 and 20.20.20.0/24 think the network is Xidentical, but if 20.20.20.1 attempts to ping 20.20.20.2, it will Xnever get a reply. What's more, 20.20.20.2 won't even get the Xpacket in the first place. IPfilter will intercept the packet Xbefore it even gets to the other end of the virtual wire. We Xcan put a bridged filter anywhere. Using this method we can shrink Xthe network trust circle down an individual host level (given Xenough ethernet cards:-)<BR> X<P> X<P> XBlocking icmp from the world seems kind of silly, especially if Xyou're a sysadmin and like pinging the world, to traceroute, or Xto resize your MTU. Let's construct a better ruleset and take Xadvantage of the original key feature of ipf: stateful inspection.<BR> X<TT> pass in quick on xl1 proto tcp keep state<BR> X pass in quick on xl1 proto udp keep state<BR> X pass in quick on xl1 proto icmp keep state<BR> X block in quick on xl0<BR> X</TT>In this situation, the 20.20.20.0/24 network (perhaps more Xaptly called the <TT>xl1</TT> network) can now reach the outside Xworld, but the outside world can't reach it, and it can't figure Xout why, either. The router is accessible, the hosts are active, Xbut the outside world just can't get in. Even if the router itself Xwere compromised, the firewall would still be active and successful.<BR> X<P> X<P> XSo far, we've been filtering by interface and protocol only. Even Xthough bridging is concerned layer2, we can still discriminate Xbased on IP address. Normally we have a few services running, Xso our ruleset may look like this:<BR> X<TT> pass in quick on xl1 proto tcp keep state<BR> X pass in quick on xl1 proto udp keep state<BR> X pass in quick on xl1 proto icmp keep state<BR> X block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.<BR> X pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state<BR> X pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state<BR> X pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state<BR> X pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state<BR> X block in quick on xl0<BR> X</TT>Now we have a network where 20.20.20.2 is a zone serving Xname server, 20.20.20.3 is an incoming mail server, and 20.20.20.7 Xis a web server.<BR> X<P> X<P> XBridged IP Filter is not yet perfect, we must confess.<BR> X<P> X<P> XFirst, You'll note that all the rules are setup using the <TT>in</TT> Xdirection instead of a combination of <TT>in</TT> and <TT>out</TT>. XThis is because the <TT>out</TT> direction is presently unimplemented Xwith bridging in OpenBSD. This was originally done to prevent Xvast performance drops using multiple interfaces. Work has been Xdone in speeding it up, but it remains unimplemented. If you Xreally want this feature, you might try your hand at working on Xthe code or asking the OpenBSD people how you can help.<BR> X<P> X<P> XSecond, using IP Filter with bridging makes the use of IPF's NAT Xfeatures inadvisable, if not downright dangerous. The first problem Xis that it would give away that there's a filtering bridge. The Xsecond problem would be that the bridge has no IP address to masquerade Xwith, which will most assuredly lead to confusion and perhaps Xa kernel panic to boot. You can, of course, put an IP address Xon the outbound interface to make NAT work, but part of the glee Xof bridging is thus diminished.<BR> X<A NAME=TOC_52> X<H2> XUsing Transparent Filtering to Fix Network Design Mistakes X</H2> X</A><BR> X<P> X<P> XMany organizations started using IP well before they thought a Xfirewall or a subnet would be a good idea. Now they have class-C Xsized networks or larger that include all their servers, their Xworkstations, their routers, coffee makers, everything. The horror! XRenumbering with proper subnets, trust levels, filters, and so Xare in both time consuming and expensive. The expense in hardware Xand man hours alone is enough to make most organizations unwilling Xto really solve the problem, not to mention the downtime involved. XThe typical problem network looks like this:<BR> X<TT> 20.20.20.1 router 20.20.20.6 unix server<BR> X 20.20.20.2 unix server 20.20.20.7 nt workstation<BR> X 20.20.20.3 unix server 20.20.20.8 nt server<BR> X 20.20.20.4 win98 workstation 20.20.20.9 unix workstation<BR> X 20.20.20.5 intelligent switch 20.20.20.10 win95 workstation<BR> X</TT>Only it's about 20 times larger and messier and frequently Xundocumented. Ideally, you'd have all the trusting servers in Xone subnet, all the work- stations in another, and the network Xswitches in a third. Then the router would filter packets between Xthe subnets, giving the workstations limited access to the servers, Xnothing access to the switches, and only the sysadmin's workstation Xaccess to the coffee pot. I've never seen a class-C sized network Xwith such coherence. IP Filter can help.<BR> X<P> X<P> XTo start with, we're going to separate the router, the workstations, Xand the servers. To do this we're going to need 2 hubs (or switches) Xwhich we probably already have, and an IPF machine with 3 ethernet Xcards. We're going to put all the servers on one hub and all Xthe workstations on the other. Normally we'd then connect the Xhubs to each other, then to the router. Instead, we're going Xto plug the router into IPF's <TT>xl0</TT> interface, the servers Xinto IPF's <TT>xl1</TT> interface, and the workstations into IPF's X<TT>xl2</TT> interface. Our network diagram looks something like Xthis:<BR> X<TT> | 20.20.20.2 unix server<BR> X router (20.20.20.1) ____________| 20.20.20.3 unix server<BR> X | / | 20.20.20.6 unix server<BR> X | /xl1 | 20.20.20.7 nt server<BR> X ------------/xl0 IPF Bridge <<BR> X  xl2 | 20.20.20.4 win98 workstation<BR> X ____________| 20.20.20.8 nt workstation<BR> X | 20.20.20.9 unix workstation<BR> X | 20.20.20.10 win95 workstation<BR> X</TT>Where once there was nothing but interconnecting wires, now Xthere's a filtering bridge that not a single host needs to be Xmodified to take advantage of. Presumably we've already enabled Xbridging so the network is behaving perfectly normally. Further, Xwe're starting off with a ruleset much like our last ruleset:<BR> X<TT> pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state<BR> X pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state<BR> X pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state<BR> X pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state<BR> X block in quick on xl0<BR> X pass in quick on xl1 proto tcp keep state<BR> X pass in quick on xl1 proto udp keep state<BR> X pass in quick on xl1 proto icmp keep state<BR> X block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.<BR> X pass in quick on xl2 proto tcp keep state<BR> X pass in quick on xl2 proto udp keep state<BR> X pass in quick on xl2 proto icmp keep state<BR> X block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.<BR> X</TT>Once again, traffic coming from the router is restricted Xto DNS, SMTP, and HTTP. At the moment, the servers and the workstations Xcan exchange traffic freely. Depending on what kind of organization Xyou are, there might be something about this network dynamic you Xdon't like. Perhaps you don't want your workstations getting Xaccess to your servers at all? Take the <TT>xl2</TT> ruleset Xof:<BR> X<TT> pass in quick on xl2 proto tcp keep state<BR> X pass in quick on xl2 proto udp keep state<BR> X pass in quick on xl2 proto icmp keep state<BR> X block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.<BR> X</TT>And change it to:<BR> X<TT> block in quick on xl2 from any to 20.20.20.0/24<BR> X pass in quick on xl2 proto tcp keep state<BR> X pass in quick on xl2 proto udp keep state<BR> X pass in quick on xl2 proto icmp keep state<BR> X block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.<BR> X</TT>Perhaps you want them to just get to the servers to get and Xsend their mail with IMAP? Easily done:<BR> X<TT> pass in quick on xl2 proto tcp from any to 20.20.20.3/32 port=25<BR> X pass in quick on xl2 proto tcp from any to 20.20.20.3/32 port=143<BR> X block in quick on xl2 from any to 20.20.20.0/24<BR> X pass in quick on xl2 proto tcp keep state<BR> X pass in quick on xl2 proto udp keep state<BR> X pass in quick on xl2 proto icmp keep state<BR> X block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir.<BR> X</TT>Now your workstations and servers are protected from the Xoutside world, and the servers are protected from your workstations.<BR> X<P> X<P> XPerhaps the opposite is true, maybe you want your workstations Xto be able to get to the servers, but not the outside world. After Xall, the next generation of exploits is breaking the clients, Xnot the servers. In this case, you'd change the <TT>xl2</TT> Xrules to look more like this:<BR> X<TT> pass in quick on xl2 from any to 20.20.20.0/24<BR> X block in quick on xl2<BR> X</TT>Now the servers have free reign, but the clients can only Xconnect to the servers. We might want to batten down the hatches Xon the servers, too:<BR> X<TT> pass in quick on xl1 from any to 20.20.20.0/24<BR> X block in quick on xl1<BR> X</TT>With the combination of these two, the clients and servers Xcan talk to each other, but neither can access the outside world X(though the outside world can get to the few services from earlier). XThe whole ruleset would look something like this:<BR> X<TT> pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state<BR> X pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state<BR> X pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state<BR> X pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state<BR> X block in quick on xl0<BR> X pass in quick on xl1 from any to 20.20.20.0/24<BR> X block in quick on xl1<BR> X pass in quick on xl2 from any to 20.20.20.0/24<BR> X block in quick on xl2<BR> X</TT>So remember, when your network is a mess of twisty IP addresses Xand machine classes, transparent filtered bridges can solve a Xproblem that would otherwise be lived with and perhaps someday Xexploited.<BR> X<A NAME=TOC_53> X<H2> XDrop-Safe Logging With dup-to and to. X</H2> X</A><BR> X<P> X<P> XUntil now, we've been using the filter to drop packets. Instead Xof dropping them, let's consider passing them on to another system Xthat can do something useful with this information beyond the Xlogging we can perform with ipmon. Our firewall system, be it Xa bridge or a router, can have as many interfaces as we can cram Xinto the system. We can use this information to create a "drop-safe" Xfor our packets. A good example of a use for this would be to Ximplement an intrusion detection network. For starters, it might Xbe desirable to hide the presence of our intrusion detection systems Xfrom our real network so that we can keep them from being detected.<BR> X<P> X<P> XBefore we get started, there are some operational characteristics Xthat we need to make note of. If we are only going to deal with Xblocked packets, we can use either the <TT>to</TT> keyword or Xthe <TT>fastroute</TT> keyword. (We'll cover the differences between Xthese two later) If we're going to pass the packets like we normally Xwould, we need to make a copy of the packet for our drop-safe Xlog with the <TT>dup-to</TT> keyword.<BR> X<A NAME=TOC_54> X<H2> XThe dup-to Method X</H2> X</A><BR> X<P> X<P> XIf, for example, we wanted to send a copy of everything going Xout the <TT>xl3</TT> interface off to our drop-safe network on X<TT>ed0</TT>, we would use this rule in our filter list:<BR> X<TT> pass out on xl3 dup-to ed0 from any to any<BR> X</TT>You might also have a need to send the packet directly to Xa specific IP address on your drop-safe network instead of just Xmaking a copy of the packet out there and hoping for the best. XTo do this, we modify our rule slightly:<BR> X<TT> pass out on xl3 dup-to ed0:192.168.254.2 from any to any<BR> X</TT>But be warned that this method will alter the copied packet's Xdestination address, and may thus destroy the usefulness of the Xlog. For this reason, we recommend only using the known address Xmethod of logging when you can be certain that the address that Xyou're logging to corresponds in some way to what you're logging Xfor (e.g.: don't use "192.168.254.2" for logging for Xboth your web server and your mail server, since you'll have a Xhard time later trying to figure out which system was the target Xof a specific set of packets.)<BR> X<P> X<P> XThis technique can be used quite effectively if you treat an <I>IP XAddress</I> on your drop-safe network in much the same way that Xyou would treat a <I>Multicast Group</I> on the real internet. X(e.g.: "192.168.254.2" could be the channel for your Xhttp traffic analysis system, "23.23.23.23" could be Xyour channel for telnet sessions, and so on.) You don't even Xneed to actually have this address set as an address or alias Xon any of your analysis systems. Normally, your ipfilter machine Xwould need to ARP for the new destination address (using <TT>dup-to Xed0:192.168.254.2</TT> style, of course) but we can avoid that Xissue by creating a static arp entry for this <I>"channel"</I> Xon our ipfilter system.<BR> X<P> X<P> XIn general, though, <TT>dup-to ed0</TT> is all that is required Xto get a new copy of the packet over to our drop-safe network Xfor logging and examination.<BR> X<A NAME=TOC_55> X<H2> XThe to Method X</H2> X</A><BR> X<P> X<P> XThe <TT>dup-to</TT> method does have an immediate drawback, though. XSince it has to make a copy of the packet and optionally modify Xit for its new destination, it's going to take a while to complete Xall this work and be ready to deal with the next packet coming Xin to the ipfilter system.<BR> X<P> X<P> XIf we don't care about passing the packet to its normal destination Xand we were going to block it anyway, we can just use the <TT>to</TT> Xkeyword to push this packet past the normal routing table and Xforce it to go out a different interface than it would normally Xgo out.<BR> X<TT> block in quick on xl0 to ed0 proto tcp from any to any port < 1024<BR> X</TT>we use <TT>block quick</TT> for <TT>to</TT> interface routing, Xbecause like <TT>fastroute</TT>, the <TT>to</TT> interface code Xwill generate two packet paths through ipfilter when used with X<TT>pass</TT>, and likely cause your system to panic.<BR> X<A NAME=TOC_56> X<H2> XBogus Network Filtering, the ultimate in current anti-spoofing Xtechnology. X</H2> X</A><BR> X<P> X<P> XWe've spent a little bit of time tracking down the current vast Xtracts of IP address space that have been reserved by the IANA Xfor various reasons, or are otherwise not currently in use at Xthe time this document was written. Since none of these address Xranges should be in use currently, there should be no legitimate Xreason to ever see them as a source address, or to send them traffic Xas a destination address, right? Right!<BR> X<P> X<P> XSo without further ado, the complete list of bogus networks:<BR> X<TT> #<BR> X # s/OUTSIDE/outside-interface (eg: fxp0)<BR> X # s/MYNET/network-cidr-address (eg: 1.2.3.0/24)<BR> X #<BR> X block in on OUTSIDE all<BR> X block in quick on OUTSIDE from 0.0.0.0/7 to any<BR> X block in quick on OUTSIDE from 2.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 5.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 10.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 23.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 27.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 31.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 69.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 70.0.0.0/7 to any<BR> X block in quick on OUTSIDE from 72.0.0.0/5 to any<BR> X block in quick on OUTSIDE from 82.0.0.0/7 to any<BR> X block in quick on OUTSIDE from 84.0.0.0/6 to any<BR> X block in quick on OUTSIDE from 88.0.0.0/5 to any<BR> X block in quick on OUTSIDE from 96.0.0.0/3 to any<BR> X block in quick on OUTSIDE from 127.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 128.0.0.0/16 to any<BR> X block in quick on OUTSIDE from 128.66.0.0/16 to any<BR> X block in quick on OUTSIDE from 169.254.0.0/16 to any<BR> X block in quick on OUTSIDE from 172.16.0.0/12 to any<BR> X block in quick on OUTSIDE from 191.255.0.0/16 to any<BR> X block in quick on OUTSIDE from 192.0.0.0/19 to any<BR> X block in quick on OUTSIDE from 192.0.48.0/20 to any<BR> X block in quick on OUTSIDE from 192.0.64.0/18 to any<BR> X block in quick on OUTSIDE from 192.0.128.0/17 to any<BR> X block in quick on OUTSIDE from 192.168.0.0/16 to any<BR> X block in quick on OUTSIDE from 197.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 201.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 204.152.64.0/23 to any<BR> X block in quick on OUTSIDE from 219.0.0.0/8 to any<BR> X block in quick on OUTSIDE from 220.0.0.0/6 to any<BR> X block in quick on OUTSIDE from 224.0.0.0/3 to any<BR> X block in quick on OUTSIDE from MYNET to any<BR> X # Your pass rules come here...<BR> X block out on OUTSIDE all<BR> X block out quick on OUTSIDE from !MYNET to any<BR> X block out quick on OUTSIDE from MYNET to 0.0.0.0/7<BR> X block out quick on OUTSIDE from MYNET to 2.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 5.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 10.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 23.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 27.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 31.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 69.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 70.0.0.0/7<BR> X block out quick on OUTSIDE from MYNET to 72.0.0.0/5<BR> X block out quick on OUTSIDE from MYNET to 82.0.0.0/7<BR> X block out quick on OUTSIDE from MYNET to 84.0.0.0/6<BR> X block out quick on OUTSIDE from MYNET to 88.0.0.0/5<BR> X block out quick on OUTSIDE from MYNET to 96.0.0.0/3<BR> X block out quick on OUTSIDE from MYNET to 127.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 128.0.0.0/16<BR> X block out quick on OUTSIDE from MYNET to 128.66.0.0/16<BR> X block out quick on OUTSIDE from MYNET to 169.254.0.0/16<BR> X block out quick on OUTSIDE from MYNET to 172.16.0.0/12<BR> X block out quick on OUTSIDE from MYNET to 191.255.0.0/16<BR> X block out quick on OUTSIDE from MYNET to 192.0.0.0/19<BR> X block out quick on OUTSIDE from MYNET to 192.0.48.0/20<BR> X block out quick on OUTSIDE from MYNET to 192.0.64.0/18<BR> X block out quick on OUTSIDE from MYNET to 192.0.128.0/17<BR> X block out quick on OUTSIDE from MYNET to 192.168.0.0/16<BR> X block out quick on OUTSIDE from MYNET to 197.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 201.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 204.152.64.0/23<BR> X block out quick on OUTSIDE from MYNET to 219.0.0.0/8<BR> X block out quick on OUTSIDE from MYNET to 220.0.0.0/6<BR> X block out quick on OUTSIDE from MYNET to 224.0.0.0/3<BR> X # Your pass rules come here...<BR> X</TT>If you're going to use these, we suggest that you become Xfamiliar with whois.arin.net and keep an occasional eye on these, Xas the IANA isn't going to notify you when they allocate one of Xthese to a new corporation or something. You have been warned.<BR> X<P> X<P> X<P> X<P> X<!-- Stop Mirror Here --> X</BODY> X</HTML> END-of-bitlbee/ipf-howto.html echo c - bitlbee/files mkdir -p bitlbee/files > /dev/null 2>&1 echo x - bitlbee/files/patch-ab sed 's/^X//' >bitlbee/files/patch-ab << 'END-of-bitlbee/files/patch-ab' X*** bitlbee.h.orig Tue Jun 24 19:55:19 2003 X--- bitlbee.h Tue Jul 22 16:18:52 2003 X*************** X*** 67,72 **** X--- 67,83 ---- X #include "commands.h" X #include "account.h" X X+ typedef struct settings X+ { X+ char *interface; X+ signed int port; X+ int nofork; X+ int verbose; X+ int listen_socket; X+ int mode; X+ } settings_t; X+ X+ X int root_command_string( irc_t *irc, user_t *u, char *command ); X int root_command( irc_t *irc, char *command[] ); X int bitlbee_init( irc_t *irc ); X*************** X*** 74,80 **** X--- 85,93 ---- X int bitlbee_save( irc_t *irc ); X void http_encode( char *s ); X void http_decode( char *s ); X+ settings_t *set_load( int argc, char *argv[] ); X X extern irc_t *IRC; X+ extern GList *connection_list; X X #endif END-of-bitlbee/files/patch-ab echo x - bitlbee/files/patch-a sed 's/^X//' >bitlbee/files/patch-a << 'END-of-bitlbee/files/patch-a' X*** bitlbee.c.orig Mon Apr 28 19:18:54 2003 X--- bitlbee.c Tue Jul 22 16:18:52 2003 X*************** X*** 32,47 **** X #include <signal.h> X X irc_t *IRC; /* :-( */ X X static void sighandler( int signal ); X X int main( int argc, char *argv[] ) X { X- irc_t *irc; X- struct timeval tv[1]; X- fd_set fds[1]; X int i; X! X if( 1 ) X { X /* Catch some signals to tell the user what's happening before quitting */ X--- 32,68 ---- X #include <signal.h> X X irc_t *IRC; /* :-( */ X+ GList *connection_list = NULL; X+ settings_t *set; X X static void sighandler( int signal ); X+ static int bitlbee_daemon_main_loop( void ); X+ static int bitlbee_inetd_main_loop( void ); X+ static int bitlbee_daemon_init( void ); X+ static int bitlbee_inetd_init( void ); X X int main( int argc, char *argv[] ) X { X int i; X! X! if( !( set = set_load( argc, argv ) ) ) X! return( 1 ); X! X! if( set->mode == 1 ) X! { X! i=bitlbee_inetd_init( ); X! if( i!=0 ) X! return( i ); X! } X! else if( set->mode == 2 ) X! { X! i = bitlbee_daemon_init( ); X! if( i!=0 ) X! return( i ); X! } X! X! nogaim_init(); X! X if( 1 ) X { X /* Catch some signals to tell the user what's happening before quitting */ X*************** X*** 57,85 **** X sigaction( SIGTERM, &sig, &old ); X } X X- if( !( IRC = irc = irc_new( 0 ) ) ) X- return( 1 ); X- X- nogaim_init(); X- set_add( irc, "save_on_quit", "true", set_eval_bool ); X- X while( 1 ) X { X! FD_ZERO( fds ); X! FD_SET( irc->fd, fds ); X! tv->tv_sec = 0; X! tv->tv_usec = 200000; X! if( ( i = select( irc->fd + 1, fds, NULL, NULL, tv ) ) > 0 ) X { X! if( !irc_process( irc ) ) break; X } X- else if( i == -1 ) break; X- g_main_iteration( FALSE ); X } X X! if( irc->status && set_getint( irc, "save_on_quit" ) ) X! if( !bitlbee_save( irc ) ) X! irc_usermsg( irc, "Error while saving settings!" ); X X return( 0 ); X } X--- 78,254 ---- X sigaction( SIGTERM, &sig, &old ); X } X X while( 1 ) X { X! if( set->mode == 1 ) { X! i = bitlbee_inetd_main_loop(); X! if( i!=0 ) X! break; X! } X! else if( set->mode == 2 ) X { X! i = bitlbee_daemon_main_loop(); X! if( i!=0 ) X! break; X } X } X+ X+ return( 0 ); X+ } X+ X+ static int bitlbee_daemon_init(void) { X+ struct sockaddr_in listen_addr; X+ int i, listen_socket; X+ X+ listen_socket=socket( AF_INET, SOCK_STREAM, 0 ); X+ if( listen_socket == -1 ) { X+ perror("socket"); X+ return 1; X+ } X+ listen_addr.sin_family = AF_INET; X+ listen_addr.sin_port = htons( set->port ); X+ listen_addr.sin_addr.s_addr = inet_addr( set->interface ); X+ i=bind( listen_socket, ( struct sockaddr * )&listen_addr, X+ sizeof( struct sockaddr ) ); X+ if( i == -1 ) { X+ perror( "bind" ); X+ return 1; X+ } X+ i=listen( listen_socket, 10 ); X+ if( i == -1 ) { X+ perror( "listen" ); X+ return 1; X+ } X+ if( set->verbose && set->nofork ) X+ printf( "Listening on port: %d, interface: %s\n", set->port, set->interface ); X+ set->listen_socket = listen_socket; X+ X+ if( !set->nofork ) X+ { X+ i = fork(); X+ if( i == -1 ) { X+ perror( "fork" ); X+ exit( 1 ); X+ } X+ else if( i!=0 ) X+ exit( 0 ); X+ } X+ return( 0 ); X+ } X+ X+ static int bitlbee_inetd_init( void ) { X+ X+ if( !( IRC = irc_new( 0 ) ) ) X+ return( 1 ); X+ X+ connection_list = g_list_append( connection_list, IRC ); X+ X+ return( 0 ); X+ } X+ X+ static int bitlbee_daemon_main_loop( void ) { X+ GList *temp; X+ irc_t *new_connection; X+ fd_set fds[1]; X+ struct timeval tv; X+ int i, highest, size, new_socket; X+ struct sockaddr_in conn_info; X+ X+ FD_ZERO( fds ); X+ FD_SET( set->listen_socket, fds ); X+ temp = connection_list; X+ highest = set->listen_socket; X+ X+ while( temp != NULL ) X+ { X+ FD_SET( ( ( irc_t * )( temp->data ) )->fd, fds ); X+ if( ( (irc_t * )( temp->data ) )->fd > highest ) X+ highest = ( ( irc_t * )( temp->data ) )->fd; X+ temp = temp->next; X+ } X+ tv.tv_sec = 0; X+ tv.tv_usec = 200000; X+ if( ( i = select( highest + 1, fds, NULL, NULL, &tv ) ) > 0 ) X+ { X+ if( FD_ISSET( set->listen_socket, fds ) ) X+ { X+ size = sizeof( struct sockaddr_in ); X+ new_socket = accept( set->listen_socket, ( struct sockaddr * )&conn_info, X+ &size ); X+ new_connection = irc_new( new_socket ); X+ if( !new_connection ) X+ return 1; X+ if( set->verbose && set->nofork ) X+ puts("Adding new connection"); X+ X+ connection_list = g_list_append( connection_list, new_connection ); X+ } X+ temp = connection_list; X+ while( temp != NULL ) X+ { X+ if( FD_ISSET( ( ( irc_t *)( temp->data ) )->fd, fds ) ) X+ { X+ IRC = temp->data; X+ if( !irc_process( IRC ) ) X+ { X+ if( set->verbose && set->nofork ) X+ puts("Destroying connection"); X+ if( ( (irc_t * )( temp->data ) )->status && set_getint( (irc_t *)( temp->data ), "save_on_quit" ) ) X+ if( !bitlbee_save( temp->data ) ) X+ irc_usermsg( temp->data, "Error while saving settings!" ); X+ X+ /* [MD] FIXME: fix memory leak/possible illegal free() X+ * Wilmer, can you make an irc_free()? X+ */ X+ X+ free( temp->data ); X+ if( ( temp->next == NULL ) && ( temp->prev == NULL ) ) X+ { X+ g_list_free_1( temp ); X+ connection_list = NULL; X+ X+ } X+ else X+ { X+ connection_list = g_list_remove_link ( connection_list, temp ); X+ g_list_free_1( temp ); X+ } X+ } X+ } X+ temp = temp->next; X+ } X+ } X+ else if( i == -1 ) X+ return -1; X+ g_main_iteration( FALSE ); X X! return 0; X! } X! X! static int bitlbee_inetd_main_loop( void ) { X! struct timeval tv[1]; X! fd_set fds[1]; X! int i; X! GList *temp; X! X! FD_ZERO( fds ); X! FD_SET( IRC->fd, fds ); X! tv->tv_sec = 0; X! tv->tv_usec = 200000; X! temp = connection_list; X! X! if( ( i = select( ( ( irc_t * )( temp->data ) )->fd + 1, fds, NULL, NULL, tv ) ) > 0 ) X! { X! if( !irc_process( ( (irc_t * )( temp->data ) ) ) ) X! { X! if( ( ( irc_t * )( temp->data ) )->status && set_getint( ( (irc_t * )( temp->data ) ), "save_on_quit" ) ) X! if( !bitlbee_save( ( (irc_t * )( temp->data ) ) ) ) X! irc_usermsg( ( (irc_t * )( temp->data ) ), "Error while saving settings!" ); X! return 1; X! } X! } X! else if( i == -1 ) return( -1 ); X! g_main_iteration( FALSE ); X X return( 0 ); X } X*************** X*** 359,377 **** X free( t ); X } X X static void sighandler( int signal ) X { X if( signal == SIGPIPE ) X { X /* SIGPIPE is ignored by Gaim. Looks like we have to do X the same, because it causes some nasty hangs. */ X! if( set_getint( IRC, "debug" ) ) X! irc_usermsg( IRC, "Warning: Caught SIGPIPE, but we probably have to ignore this and pretend nothing happened..." ); X return; X } X else X { X! irc_write( IRC, "ERROR :Fatal signal received: %d. That's probably a bug.. :-/", signal ); X exit( 1 ); X } X } X--- 528,604 ---- X free( t ); X } X X+ /* [MD] FIXME: SIGPIPE makes bitlbee crash for some reason */ X static void sighandler( int signal ) X { X if( signal == SIGPIPE ) X { X /* SIGPIPE is ignored by Gaim. Looks like we have to do X the same, because it causes some nasty hangs. */ X! if( set_getint( NULL, "debug" ) ) X! irc_write_all( "ERROR :Caught SIGPIPE, but we probably have to ignore this and pretend nothing happened..." ); X return; X } X else X { X! irc_write_all( "ERROR :Fatal signal received: %d. That's probably a bug.. :-/", signal ); X exit( 1 ); X } X+ } X+ X+ settings_t *set_load( int argc, char *argv[] ) X+ { X+ settings_t *set; X+ int opt, i; X+ X+ set = malloc( sizeof( settings_t ) ); X+ if( set==NULL ) { perror( "malloc" ); exit( 1 ); } X+ memset( set, 0, sizeof( settings_t ) ); X+ X+ set->interface = "0.0.0.0"; X+ set->port = 6667; X+ set->nofork = 0; X+ set->verbose = 0; X+ set->mode=1; X+ X+ while( ( opt = getopt( argc, argv, "i:p:hvncd" ) ) >= 0 ) X+ { X+ if( opt == 'i' ) X+ { X+ set->interface = strdup( optarg ); X+ } X+ else if( opt == 'p' ) X+ { X+ if( ( sscanf( optarg, "%d", &i ) != 1 ) || ( i <= 0 ) || ( i > 65535 ) ) X+ { X+ fprintf( stderr, "Invalid port number: %s\n", optarg ); X+ return( NULL ); X+ } X+ set->port = i; X+ } X+ else if( opt == 'n' ) X+ set->nofork=1; X+ else if( opt == 'v' ) X+ set->verbose=1; X+ else if( opt == 'c' ) X+ set->mode=1; X+ else if( opt == 'd' ) X+ set->mode=2; X+ else if( opt == 'h' ) X+ { X+ printf( "Usage: bitlbee [-d [-i <interface>] [-p <port>] [-n] [-v]] [-c] \n" X+ "An IRC-to-other-chat-networks gateway\n" X+ "\n" X+ " -c Classic mode(default). Reads from stdin, writes to stdout. Ignores all other options.\n" X+ " -d Daemon mode(EXPERIMENTAL). Will fork into background and accept connections.\n" X+ " -i Specify the interface (by IP address) to listen on.\n" X+ " (Default: 0.0.0.0 (any interface))\n" X+ " -p Port number to listen on. (Default: 6667)\n" X+ " -n Don't fork.\n" X+ " -v Be verbose (only works in combination with -n)\n" X+ " -h Show this help page.\n"); X+ return( NULL ); X+ } X+ } X+ return( set ); X } END-of-bitlbee/files/patch-a echo x - bitlbee/files/patch-ac sed 's/^X//' >bitlbee/files/patch-ac << 'END-of-bitlbee/files/patch-ac' X*** irc.c.orig Tue Jun 10 23:21:14 2003 X--- irc.c Tue Jul 22 16:18:52 2003 X*************** X*** 52,62 **** X if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof(sock->sin_addr), AF_INET ) ) ) X irc->host = strdup( peer->h_name ); X #ifndef NO_TCPD X! i = hosts_ctl( "bitlbee", irc->host?irc->host:STRING_UNKNOWN, inet_ntoa( sock->sin_addr ), STRING_UNKNOWN ); X } X else X { X! i = 0; X #endif X } X X--- 52,64 ---- X if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof(sock->sin_addr), AF_INET ) ) ) X irc->host = strdup( peer->h_name ); X #ifndef NO_TCPD X! if( set->mode == 1) X! i = hosts_ctl( "bitlbee", irc->host?irc->host:STRING_UNKNOWN, inet_ntoa( sock->sin_addr ), STRING_UNKNOWN ); X } X else X { X! if( set->mode == 1) X! i = 0; X #endif X } X X*************** X*** 73,78 **** X--- 75,86 ---- X return( NULL ); X } X #endif X+ X+ /* [MD] FIXME: now that bitlbee has a global set X+ * (use NULL as irc_t * parameter) some of these X+ * need to be set as global... Can someone who knows X+ * which ones should be global do this? X+ */ X X set_add( irc, "private", "false", set_eval_bool ); X #ifdef DEBUG X*************** X*** 82,88 **** X #endif X set_add( irc, "to_char", ": ", set_eval_to_char ); X set_add( irc, "ops", "both", set_eval_ops ); X! X irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, "BitlBee-IRCd initialized, please go on" ); X X return( irc ); X--- 90,102 ---- X #endif X set_add( irc, "to_char", ": ", set_eval_to_char ); X set_add( irc, "ops", "both", set_eval_ops ); X! set_add( irc, "save_on_quit", "1", set_eval_bool ); X! set_add( irc, "html", "nostrip", NULL ); X! set_add( irc, "typing_notice", "false", set_eval_bool ); X! set_add( irc, "away_devoice", "true", set_eval_away_devoice ); X! set_add( irc, "charset", "none", NULL ); X! set_add( irc, "handle_unknown", "root", NULL ); X! X irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, "BitlBee-IRCd initialized, please go on" ); X X return( irc ); X*************** X*** 480,494 **** X return( irc_msgfrom( irc, u->nick, text ) ); X } X X! int irc_write( irc_t *irc, char *format, ... ) X { X- char line[IRC_MAX_LINE]; X va_list params; X int n, start = 0; X X- va_start( params, format ); X vsnprintf( line, IRC_MAX_LINE - 3, format, params ); X- va_end( params ); X strcat( line, "\r\n" ); X X while( line[start] ) X--- 494,517 ---- X return( irc_msgfrom( irc, u->nick, text ) ); X } X X! int irc_write( irc_t *irc, char *format, ... ) X { X va_list params; X+ int i; X+ X+ va_start( params, format ); X+ i = irc_vawrite( irc, format, params ); X+ va_end( params ); X+ X+ return i; X+ X+ } X+ int irc_vawrite( irc_t *irc, char *format, va_list params ) X+ { X+ char line[IRC_MAX_LINE]; X int n, start = 0; X X vsnprintf( line, IRC_MAX_LINE - 3, format, params ); X strcat( line, "\r\n" ); X X while( line[start] ) X*************** X*** 505,510 **** X--- 528,550 ---- X X return( 1 ); X } X+ X+ void irc_write_all( char *format, ... ) X+ { X+ va_list params; X+ GList *temp; X+ X+ va_start( params, format ); X+ X+ temp = connection_list; X+ while( temp!=NULL ) { X+ irc_vawrite( temp->data, format, params ); X+ temp = temp->next; X+ } X+ X+ va_end( params ); X+ return; X+ } X X void irc_names( irc_t *irc, char *channel ) X { END-of-bitlbee/files/patch-ac echo x - bitlbee/files/patch-ad sed 's/^X//' >bitlbee/files/patch-ad << 'END-of-bitlbee/files/patch-ad' X*** irc.h.orig Sat May 3 13:40:37 2003 X--- irc.h Tue Jul 22 16:18:52 2003 X*************** X*** 95,101 **** X--- 95,103 ---- X int irc_process( irc_t *irc ); X int irc_process_string( irc_t *irc, char *line, int bytes ); X X+ int irc_vawrite( irc_t *irc, char *format, va_list params ); X int irc_write( irc_t *irc, char *format, ... ); X+ void irc_write_all( char *format, ... ); X int irc_reply( irc_t *irc, int code, char *format, ... ); X int irc_usermsg( irc_t *irc, char *format, ... ); X END-of-bitlbee/files/patch-ad echo x - bitlbee/files/patch-ae sed 's/^X//' >bitlbee/files/patch-ae << 'END-of-bitlbee/files/patch-ae' X*** set.c.orig Mon Apr 28 19:18:55 2003 X--- set.c Tue Jul 22 16:19:27 2003 X*************** X*** 25,34 **** X--- 25,51 ---- X X #include "bitlbee.h" X X+ set_t *global_set=NULL; X+ X set_t *set_add( irc_t *irc, char *key, char *def, void *eval ) X { X set_t *s = set_find( irc, key ); X X+ if( !s && !irc ) X+ { X+ if( ( s = global_set ) ) X+ { X+ while( s->next ) s = s->next; X+ s->next = malloc( sizeof( set_t ) ); X+ s = s->next; X+ } X+ else X+ { X+ s = global_set = malloc( sizeof( set_t ) ); X+ } X+ memset( s, 0, sizeof( set_t ) ); X+ s->key = strdup( key ); X+ } X if( !s ) X { X if( ( s = irc->set ) ) X*************** X*** 64,70 **** X X set_t *set_find( irc_t *irc, char *key ) X { X! set_t *s = irc->set; X X while( s ) X { X--- 81,92 ---- X X set_t *set_find( irc_t *irc, char *key ) X { X! set_t *s; X! X! if( !irc ) X! s = global_set; X! else X! s = irc->set; X X while( s ) X { X*************** X*** 139,151 **** X X void set_del( irc_t *irc, char *key ) X { X! set_t *s = irc->set, *t = NULL; X X while( s ) X { X if( strcasecmp( s->key, key ) == 0 ) X break; X! s = (t=s)->next; X } X if( s ) X { X--- 161,178 ---- X X void set_del( irc_t *irc, char *key ) X { X! set_t *s, *t = NULL; X! X! if( !irc ) X! s = global_set; X! else X! s = irc->set; X X while( s ) X { X if( strcasecmp( s->key, key ) == 0 ) X break; X! s = ( t = s )->next; X } X if( s ) X { END-of-bitlbee/files/patch-ae echo x - bitlbee/files/patch-af sed 's/^X//' >bitlbee/files/patch-af << 'END-of-bitlbee/files/patch-af' X*** protocols/nogaim.c.orig Sun Jun 15 00:33:22 2003 X--- protocols/nogaim.c Tue Jul 22 16:19:09 2003 X*************** X*** 50,57 **** X }; X static char *proto_away_alias_find( GList *gcm, char *away ); X X- static char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ); X- X static int remove_chat_buddy_silent( struct conversation *b, char *handle ); X X GSList *connections; X--- 50,55 ---- X*************** X*** 76,87 **** X proto_prpl[PROTO_JABBER] = malloc( sizeof( struct prpl ) ); X memset( proto_prpl[PROTO_JABBER], 0, sizeof( struct prpl ) ); X jabber_init( proto_prpl[PROTO_JABBER] ); X- X- set_add( IRC, "html", "nostrip", NULL ); X- set_add( IRC, "typing_notice", "false", set_eval_bool ); X- set_add( IRC, "away_devoice", "true", set_eval_away_devoice ); X- set_add( IRC, "charset", "none", NULL ); X- set_add( IRC, "handle_unknown", "root", NULL ); X } X X struct gaim_connection *gc_nr( int i ) X--- 74,79 ---- X*************** X*** 785,791 **** X return( NULL ); X } X X! static char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ) X { X int st; X X--- 777,783 ---- X return( NULL ); X } X X! char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ) X { X int st; X END-of-bitlbee/files/patch-af echo x - bitlbee/files/patch-ag sed 's/^X//' >bitlbee/files/patch-ag << 'END-of-bitlbee/files/patch-ag' X*** protocols/nogaim.h.orig Mon May 5 02:48:40 2003 X--- protocols/nogaim.h Tue Jul 22 16:19:27 2003 X*************** X*** 258,263 **** X--- 258,264 ---- X void nogaim_init(); X struct gaim_connection *gc_nr( int i ); X int proto_away( struct gaim_connection *gc, char *away ); X+ char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ); X X /* multi.c */ X struct gaim_connection *new_gaim_conn( struct aim_user *user ); END-of-bitlbee/files/patch-ag echo x - bitlbee/files/patch-ah sed 's/^X//' >bitlbee/files/patch-ah << 'END-of-bitlbee/files/patch-ah' X*** configure Tue Jul 22 22:13:39 2003 X--- configure.moje Tue Jul 22 22:14:21 2003 X*************** X*** 7,13 **** X ## Copyright 2002 Lucumo ## X ############################## X X! prefix='/usr/local/' X bindir='$prefix/sbin/' X etcdir='$prefix/etc/' X mandir='$prefix/share/man/' X--- 7,13 ---- X ## Copyright 2002 Lucumo ## X ############################## X X! prefix=${PREFIX} X bindir='$prefix/sbin/' X etcdir='$prefix/etc/' X mandir='$prefix/share/man/' END-of-bitlbee/files/patch-ah echo x - bitlbee/tcp_filtering.pdf sed 's/^X//' >bitlbee/tcp_filtering.pdf << 'END-of-bitlbee/tcp_filtering.pdf' X%PDF-1.2 X%쏢 X4 0 obj X<</Length 5 0 R/Filter /FlateDecode>> Xstream Xx\koFr~|W4 އ 뗀Ef({g29#Y&%"UNf]]ޟ>'x??<:m';O?gzwZZZ#vBsݟk_.{wqc]vK7]? EmiiWySp7_~.g*e)k~θ'MUkvy0S?u>GGWFݝ0 z懱ϻ/w?V?T~I̿9?ߘFwt]نu֟kwv.xlχiy! vhp/hM[cV`m\2:l X,t1*^aVrI?T`Z4 ш^:v]^eԵmf*Q:^NX!r'_\~Ol`o^ X6&ޫ;ߥ[dFT"#^u/ecATʮ 8NC}8vb!_(pZH|2OK7,?wsq!l2YTl|HWHe|Qwx,DU-4<aާKw>mX)ym5Boqx<؎ѦC2UW*-O^pU&=_i]˴Q=E Xe+Wkp]x,7\V\zȬMutzpXxB\h_ XGIYpo-&@SBBJ:YRh50VWJGrƥ`CIH Xkr&Fr};u_Nne]~ZχT7ϗ5l D3#-y0.)p>HU;,c_훁᭱wG G_n{ DO_IiztFƩh! $pb+1w-43|b#7Jh$1::E͡RVs鑐_)DzcP-`L={7d09_ɦErD>-42RI-7!<E(Su(˅t-e2vEgƺdѥ·' wn 6隞1B;5{}@Lq{6K $HJIT/4#@!MdJ(Pl*G X(>Ug 3cFDXصI6(*I4v+!&iɊl)PB"^B]@Lg)j1LVNÕLK4䗰~o+J$JP9P4|cQN.\Fx Rsrف)ZVj 攘Mk0% *Uo6 pN$P& ui lJ X'9̼= O?sE^*kNAٶo7GMIi+ȖunMRmRO} XJ Xgn8[֗ȼyʾQ3^0"\qٝ X3J_|j鼔~3a1PEhkHzjmwb ZN-q@YteO,%CH6рƛ"zq@HGh٫IFdt=uϥւRuƟF=l!|`<\KK#ф"}fĥ lbdMV|ES5>=G}"+Կmˢ -p=]#"L;N5 H+Up|,EX2LB*Tx+̊wV7lYԱ0~"#p%5UUTv14AC7^;.oi#H*\ES.z6R*"i#`V31Ks-=|eyb&aAc,1ܬaAMὢ,r)t.cԞٺURl&5%O2,l$\ *ڥ L+Z] EE}#Bdd;BrDeKR_I4aKHJ]*0qYW6c}g7D(,P"u|aXZc XB\㠐괚s<,oz^͇G+;g-툢A9n@%wNʩ5{z_JT)!tꧠFLQvX X;@*̯C(J%6TjUB//P5S$YRS%ZAAmvh!fLK0g:lhm<y돤S!`lUx(X5`C1Ny}~mdHpKtc s+r\T!zbm+H[РBLW'|&Vz;M`SFhi"Cj»T(^&S;T$3T{4~2*K?usn_]xR1埋= $0N X kR(g[cC}fxLHN]KFQ-T\HFФmyht4=ZG'D< %U9z.<w.wr?qZ'XÁ+p'@ĺ|쎢aUMxLP}e*& &@1Vy\I:g_g%5$0\&Gj"1TbFۏ}h RVrb2[6ɊH+ =/gXLt6r3XUvab !O\q%a9j7Q׆KiBDQ6EKZa-=III$dx=yC_(Pe yez}KTQ"mԉz/J P1Ԅ$`#NssP{O4erdQ-iH~W&Õ&I.1mVK+73`=72-U/\_ X0VʪRuLqϕi8a m`L<\t.'%̍3M[ Xi{P'~gB2&Ih(ׯxEmlbIKj8#%[Әd|1MeTAO3j4=Ɂs7[GXkeάxvJK'2N>Au,\(+bX+x]+J%7"B,"%3i }_H@<tCͨ97qX:7pn<KP\zX%beWԿ,_sMFϼZ $=rTMŀ CٖYʒ22 5qƄlf3LG5lΔ r*7F }\q'X߹ȐuD<u_6LjjFkk}$ MΓXRlnRrgqKKa0&SKiP@HV'W UN8vY=v-qԴ!WŌdAy)#~ƯH,sGUDoy*r[F Kd6,@葀[0X[2x\MS`bs[FFqYxڑK/"l]t]AGéb~'%[߅pOZ!%6F<Ly곦o6D?;ю'P-"% J6Kg@9⨁ڶb*+n+|֦^gHa eِl";0Yvml<#LJ-/$VҞʈV&6үN<}>kS R=%-z)~H C>=PCwξҘ%kA:kY,UhIL3ެq:Vb2;r̮lT]XhK3s7kfI@7@@k؋J28v3Y2GdX*OtuR=cMcoW8hUCrYPMU:Ԧ)Zx MS502D7T|ϬdBشF$}V-P}\NnPVD4=fӣH|b+47 X]$4džHYY`~ X;J܄( 6 Qegn붋=% /G9bӦ%.v!(-tLD$qhĝ1OZjLr.y2~C*H2P6XUcĤr=M%f2WxxӅ츋`f?S:ihoeM_EcXKSK&(sK-~3[iF:Z<8H)nVeM9P:Á-~Cv|7Ee2I^/~Nga#Lq_$h-,0lVHsq9ǥ<T/K+LqMƧtDb0iLlB{,Px+ XvPj!p 1q3P$.&>ál[@A{4X:OAdYScP,BՖ>9x;><[SrEQlkլlZt; RuQ9皪QTO;vuY(8>Xf&I8].9҇k7p=6ib(.Z1m v"j lS(_jC},Q \#M[nU5 3X!>j_T_s 3?=-S:R?6=#)4x\i$)؛:p{>XB,ϓz!P$ X+&l֊v5*@| X6jΔYyCm CpCh_{EluP~lR/t3xDXL.tecVRzsXh;WHb%RC401 6 O'&ϱG0a{1]`~vS1^:Qe,Cv41uMԔwn0-Dd`}u)~x;Ar7al,y=]2lh;J\0OޓXO$ɔCNJmɻ@tFr٭u3Kd[g9G2lgLؿՍqg"0oE^rl.NsP)GD XqPo+:q+BR>S*BkHؐzLLj8\R\ p-`9[>a*|&qtghԒ{KXRht\-;$_ȗMDv?qwn}<Ȋďe\&a4$T ea,9nt潸۩eBFqץ,Î6z 3QN0K#Yi 3qN<[|.g|?WnA/nK>1Řc8 R >Release-Note: >Audit-Trail: >Unformatted: >:$vK7>=(&}檞Am{,(hq=]]wȷ FeG|}#esj~캻Ɔ${:44_?4I'/'hwL_9ypAM~]26o=;o\e;$6BAox`XiA`לϜ9{Gi=gz銭u[64i_cBduFâ3}XILӔ ѧh/C&$(_$.v XqqٹOKr9`ۍo&f}?.:}?b6F'yǾ;ٻ_׃vR6N]1='O?}_<endstream Xendobj X5 0 obj X6177 Xendobj X3 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 4 0 R X>> Xendobj X9 0 obj X<</Length 10 0 R/Filter /FlateDecode>> Xstream Xx]rǑ}WMR0olF06%83 Wh.߬SՐw7,Hٗ<yPmM}z뻿Qῧmnt?4?=6U]ekus}7euMW44{<z˭kM;]l:߸}0ݧoUqUtU<\6Θ6nS#_tzc8> R&\&^1>'᪖~_K ʘxQ>q8BX>rutx[MͭRU+tpug;XKx~8ishmEm_?}j^K՛W]a7Zbez*Kj7-6.-ӸU^MPSC}zuZZ.{#,AC{lR*{q%\enmZWa?>B(uO3d,m X/즉wi}*GQutx9Gv댛=>U3"c//}aWoUC-x;FGS6Z`6ф20l/'sR; X6P?^J9iҮ/¦-´nҝKvshJ:d'Jf^Y7ޟ蓰HȐ><,ۘzޖтdBLKFbM+H*YF/~bSPȤ[Ö!Bv;<T)}O6EGۛ|v3a+T)jNlv1ͰK>Hy˝.x@LSǯjU=]$[F ўge<."j'y/]p^])uWF|v\U2դ=:EJ`W=Ѷ4AR]\bgյ|RFr~/)°+rLԦMXy*AMAUYp@`zJ^ L| X XLo\&hfYd?H 8sX>YIi͝z*e˹AkBa:zv}!F(r55&>VXAi1sɪ*ŤJ^.c>.!\CE)5ϝra ֳ~QqtM1J+w~@qvpmgrSzuLS6boziI3wpswR4@xφ YwN5}{{>/߫&*f@,yS+=$)^4wl/c,h,G8_0Th;K/.x(|7 7ɇVӰCXtﯲDP[גCc&nfjX| 1*.؋ɛ%B5W3>{ZM9 {wR}0SibR&SpYuj2UgUץ+R[+1R حJ1T*חL[ hDrVqu\` L/:-\4M5DUD0vwi7N4\σ+!B}+B}+sk)c*mxRӮ`dz@Cc%bJg)*cZ7@E!LQvuhUһtK!@̱dgZrfnh d8>_o=ߓGQ~Ĩx9Q.0*Aͼ[qY{z1Mv trGkxO"?d۷#hϷ+M>{>Ocn&֔Wd*\䠧aB AvY؉Mv'2[+1[5EL\b^ }lyQT%LY#A X1Hi菫Tp{×P2%Le'i9tᏅ㳚Bz⼑ߥuw|[(D!ޕm\6z=?Ogͤܰ.i<\ 6㣦t.hߧ+p()tiҫ8:c&y<-zUxo)!*.VTV܀(h27GǫN%y8}tːS_ iޙ;n0j4=}'Q@0E]< 0l7u)<913d^Aa2i=H˂lͣ(`:@'ǚD+]L"ugo$nj(e0BHZuNwg2Qn|fK)6%z-,Hd}[ʬCYCŀC`UOK/BiKу,0Rdp(ж,蒼ּ 0g+AGZ9NpKe<z*&$'_K&vR] X X|R*&LV#QNrn|`W{Oo^=K2#jK)Hҷ+4g4+F6Z"KX䱵@ VPkkI6Yñumbpm^yo731AQd5obhc̉[o_1bT6%?O-u ed VnZ9"s?QB/o(wK'f@eVgRC M-\b>`N0sM%:4$v6bUqxxzO(Ϝ3vAB^ J'm!F*m(ƣ U@!ԠD) bxBckFH%%%J[& 7}!erOw鍱 YqD) f(}~+F,u;'S`a7zT^DҔ)vh S.f0τfybn=-gcEY7樋KB%;KkJ)<Jutx)2Xf]%x9n%>fl;3c8tK*;~/Vvr= Ew!6.waX:v9m%z~Ƽ3qEv դӧ,lT".LƢ<VQxʺe{XNZLjE1CQ'*Y Qn:m jtOJ%dR5ޚнw^Z~x}әo_~VA?_<GB:^lj|?/Éa 6Y2+QJ2Ck͜ywMq&RbRl%ؠ4in|A[VMfQp,):ۀpM}7XIS;= C" *aASmrQq/aqd4ү rмbA4=lMx t|X~RZBK\/=d9ȇC_h6XAW Hպf&pXF3'@OwᾴF&W?#!.%WB;kY2i67Û2N]S۾x=މ52<!ދ?[gr2kp:r<'ds6Y/Kkc X<:ݷC˫2i925c b84Rh?RNʌtؒcଊ8F*r}XedTP}Z4tXqW1_8\ XjT}Hh@h-̟w#RsBoҺiTgr|Ph2ñJ|T>4Jdb>1PnVgT2Ȱ9;MB\k1[9̒L<kН`~cFz*ڑ<<Ӡ,"2YjЕ|ox0((5H BeLL&'P) XS9;+2|oʈ.?0O6JH~&:$;q}%T%5~^_~"Be1eElhЫSS3$bVk<<OOdul;K45 Iwm*K<. Xg X_D5HQ]PhGk X,W@~N>AdQ?<:Y3O^U:`],^OGV=[J 5-yj4-, O5E"HV,_#rҵifX_+4_5Lxt%)⨷]Kr@.Q۬Sv&'@S~h>{z.ΜL|<>Ҧ_.M_hr% 彩*Lς\I(_ʷlz.d'_SRVp$Z"_* x>N0<6Űɞcʘ x?{(c24.:Yn,K_ϗ|C?H ['Btڴ-S2PkR sgTKHسLd֦8lR C)SWGh\:Ui%e"].烉>ACn̉τS廰ijs9M ;h?U6~{ l:ZRoi,3( @ƣ_J]hǔ泲Q' TKKZdpAsh4%JpX^L$Xڣ Xp;yP[*5x5ǧ}Ʌeez5J_⧅{QyҤ[-|= DљDpktAހ<Nz+bϯYk,jvsh&KO_?LC`"5AOCw,R!W^Hh]`"4͙[Hw0/ک* .3N J(pd#udp kD^$I$<C^y5 TDE,_agIdj.-<r$"3KqzVJ lNgGe[zm`<S1n/M`H˰EMΡa<Q? X"ήw.u?Rb7p|1ɛ%$m^I]&B4̀W"L߿>Moӟ~~;Za g?m*c'?8ۉ[+kdOe;0Fw^N!W"v0M vX v~#fH]2CKVMM&EtPLax`Ai1fʸDc XqNc ycF3{))0`KR\%.J0 ڍ5cײ@Ylʵaot!@8;(äF2 s"%>%x9]*J\zkCoQ"x(z!!)đ1*2y~? X.)OR9C5e4f [.!jf5@fJT6+ &>'hpH{B1:5X:-.L}蟐|ӢhG|%|FJeZo/Tcue{O(LE(9(af-S{I%JA%[n&u]jS;%2&xFH֜P@my'=%Bؾп 'os~*! ӘQUy8j)}yrHrtL3A[;PyL4ySiy4S*G a0Ҋì P8kM&IMîɾq1Ƨy1SYf<27?riӰc>˔0i%2:~c'@L伥NPH XC^D.1BϪQQOƣbbQdWy.;UY0I|dH'᳟vx[YFÐڛX2<͢r{MZwA\T*pJlщUզXc:y/'ryBd4AcQD|(gRqΫ"T¼Y~"4:e} ӳ9 ~jؐTϲ+1~Gwe[huқh&§ V(Liʇfg]r,hY{y"$t8-q 4#ngTYy)6}J Xu#{tt&ߔdZ{^q҈ %J#V]-i<z]zG_ד|TRULo+Z]H2t8rIPh XF9 X5 Y9 Xa4A)SuwA;FpZњ8z7 I:e_.HPI,=ֳN7f89K;nzXCH7_'VL X̛~} 8<`Ll[|#{U7Iì,kGUЯt%5q1Jxk90y+0V9BG8^@vڦS`)iIEzh̖d|e^9_ U<m9?3%e rN*l>S^uJ:hQu/P'qOa-)(= Y 4|l3*! @9]S 9Q%56'8Y"od< Je*Kç#fqpk**Wh^L'E+Mä:r{m/p16#zA1Dӽ4$?P⇏q]sT26A߹SHYP {UoNrdSf#g]b@Ϻt !wP:4LgVPȎ>2_09]Cw վC8몟oOr7 .Zf+zϳH Xq>O5z5rg XV^WE2O/3.dX BjŦ=k^DX4zנu,";VApk/.Ta(DiSFhԼNj5`|,yqm1c<Sg3xV+(+D4Ǿ8 0d".y-`VZ[V>`3J`,G22wفzEyt :J].Iې䣕\2d[RRX-Z ۮm)fXV ~Ҩ)81Zjp|}M@E!#-A)Qcc^O<-GnTH^:n6NzAh$bmOk=c9l& X&AG yn~ 6 ?ťT|kRPPLA!An(t|mk{*-olgj3>n6kv [ogFܫ'Q$fZ)yøJf8ee?a)Rb`_,2}qfBZЈvz"Y:T%XbsQ{+ᙂky XP]mJΡU D_q-Y~v1'udP3@J4;+3Q`C';Mn~2fk:Dec% X{ff X[svb:oi6?yԸ4r~OOƉRL>;I:Xrww?q4endstream Xendobj X10 0 obj X8155 Xendobj X8 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 9 0 R X>> Xendobj X12 0 obj X<</Length 13 0 R/Filter /FlateDecode>> Xstream XxZmo_~ lCGsw@R4QMb (5u<N˓6bnog93̲*IQ>l.W7UY&+#;Rh^Ri^\ݿx}ϋ 0q]j7WW]rk` v]AIi7w+v"*Ƶۢ*_ X8UmKXtQBi?Hߥ%*'C=[2öndJ>TkכWJ9WnaRimU:U+o?CY WRDh<`p*cۍ2FJin>pd8x==dIhO9/n9/`dh>RK]`ߴMa "tH'pLS" XP虊k+vez|n+fxA-]?۸1LpRAȒv>7UrFqL~{/DO)vI+<x@j`!}ܷҘʭa9QăIE\1PSGkl6A'4sMq"I5(YȥCs_CgNz%ة0ۮɄV48O?!LR(`] O0>Oa1$8UQ)}˰T4C*ݹyItd.рpOzRyYN2)RQO 8D;1/G6ɋ]Y3L!]eob˦{+cWLvlC[BB3{sZ0^kcJ-Y9XuJ'˯Ϋ@Dݺ5.0 Xi&Px@O\ʩZ0RK&Ee!M=E&ȴT!'VmN$)Fĵx{|0JY[ IF >Ew0^f($G4؋'^bE)(zŋ.C.I:J{ /5` X:e"bA)#hţČ R |BLL04LUy0ZƁb$á}DI":PWcQqƻIČ#N,tmJ{ͣFr}=n$# Jq 1rA)&fdh&O(PZ h%NeöUZC<h %j XN¹8C-JO;@qwA X] <>7'Z(;0C%4dL$6b lMm3!iW$)6Dseˤٕ-氕bBA[8@fVk+mT\a[93M!_RDR渡@=7`:&{R"6nw_6F4~@"I.Bp_̢O}#?&ѸJ䏖t!KBK~2bUdJɴ-X<x%@sN/ ZJ`0CY䞳Lar0WE3|Mry NT5VDCmphvOms(O-q(DP:cǏQzdJթW=bҊ9h&)w2N><L"AiSDU%:!Jy2i$xG` <=cݵNWh2pwIϖ!&}jYܶi*"XU5Y%IhZ;/AT'$h L SM8M$;JAAޜ_dHc5Ҝ8*(fιhfT%C4t="QnY$CdIB0mgdhv!J%%(Z,؛ðA?5E4P** ]k9S%`[+LZ.!x~fCG XERȶqlh(@-I@6l3]P\]JPԜ 2)oS1I n/*\W;sߣ;k]B$iTgx-8|;-R8|d˪pZOgU,'Vd9CO$A?2$};Bo'PUqj| XXM<:vU~Y57c2Q g+'!7Gd=Nw_)=zcY|sk X hݜY$/%/ iigGB:&hĚ&h<;\ǤZ:fn8Fo>"-Ezg<+c᾽ANv|S;WiTTTO;,n/"h4(z&uq%kwȬc]hb{!;WKޓ+@n~Q .j9PA<+©Z!@Oe Xb"TD4iC X*k"ELk;̈kv"+L;K6J<ۢ]j_;4D7P; Zed6u-:3vSYЄ`pmv0_dz3i|i|< XL Xbe\/\+^G\S~demb%c$!a@x2WfY3xEksy<y*A4_gpcېc 1܍ҟbR晨uԾRD~Eը260K|E<qVPd#1n@9$lr9<PXLTsJC'< $'?4 mѿ70k̕w7K]dz~mƓ;;[|9ތu`C\pӬ7CtC&OyI\ejdj낤u]"ö|6qMΰoEqP M"Ţi;q0Wl10e*4V%U*$Js8j^u:#3}ʁ=ԃޙz֛yKБxOTU YMaߎ]9zwEo~n >O&JKwWʏQcX|Xt"Ӹ 4R]#MdP7>⻜:#vBLc8 c|BM7ס/KjNVY8ӿFR%H)(rDNRG\tu_wי X_ʆrPzN=۠oxe7i}UlTHxSh(vMshf|r +<Mzpf 3|nmZ2b?wWaV=c[?g?kW-}u8lK P_|8OwG4GޏFfSs4ә~n X[G/ XY's=Yçp]%,g>2'%<p8;7V3PT_,K?n_^l~ᄅo9)>Kn>ݲExmgAkV3Md/U/a7)LuK6S.ܳX><ǚ'>v8@Ls}qx}gaMDzfRs\;ɝَ{g2{ry&RDp^ 6SA[PbP6{HN|X{ 1D'[2'k>6."W?_e\`endstream Xendobj X13 0 obj X3934 Xendobj X11 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R14 14 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 12 0 R X>> Xendobj X16 0 obj X<</Length 17 0 R/Filter /FlateDecode>> Xstream Xx\َ$}GP-X1/ *3+̌R.]K\femcH,5}!`/W,xXnn~W~5L(Ƙ^,/ªƙE+XcZl[\k}W?-]|o5Kln"pׇzyHm=mcmhy+ h^JOAmN8km &l} 45[Aon35t:\Dtf|Xo3vx~w[ГƲDU"Jph%`KSa&J DQaY6J X_N~?,kJ[~>l-x϶ X@]س*im,cƆ/ڹ$yfuap :<B&lUFÜ<H6>y?as* w_ݤj$ sE~S/@ iE kMTtZۭ^hxt KUhoȄn_H[&ʴ2(t X<XA5__ IwTeݺ߬<`-dqx6?)vTFQ00˥'l\օ-asN:k3)ᄎ;cMѨWʚ6Omږ'yP"MXvif`iS1Bp=w ^ XP,9?>! CR,⍕i3Mr+a/qD\%%`Z0sY#ZYFѭo2Cu!ۤ=ӱ>].}ÊB5wU(&YAXj}wݲ&K"օ;mxhdK*t(Z5gM@S6_T3C3)ڊhZ&OLpL$5:y\/9) ^ǐ?$nl^BwOO3?D2gOJ Xq~9r+1܌{͌NV3v,핸. 06~0ݚ䪤,C8m_SZQ˩ݴ6h'fr˝\'`]pWVh\VY臨kd_@0#K_B\Zv0!U] UgBL'^9K5AK],d؊#b9oc+n5!Zkc?>D9 p1DFA X8ẖ.,!Oʩ-Hq1-u0\)ɡacE\zel4GQŐ2lk@AY9Xֶn@ dirv~rO`=U 4 X] n [t.&EjI$6RҿL(p0&y-Y@FFyP 80tb8t6SxS'81>-&$pA4a/ҕȫ3ݗnQKж[P_SÖ ɗ}/<`,jTWr}l ցJL:G<(AR=AY 4QݒdE!HZe5Pstqm*-u?L49&Ϡ`|ƋKt6R XpZ|eY6%pÙiuh3`_*W߾-|'E VIz8SQt7X5' )'?7?_J(J-x/}D"<xc#sbst"Ws}T"fŧg~`Ɓ)2*@G>?ᘀ"u(xW4P<d 5wRX@.yOayWfwXDByP3 BaQ\f *N~ROId! V#(ԓdTNH>=ҚiTU$ߊR Xr!-&m!wZ3a X/-/.P Y\TY4me7)F#PfGGN۔tLyÏ(cL}@ N$|bӱ:W2)OwiI<ƫ8Td<'QpEE"Gsn IiNFTPF%@*_ aa _kUVC`U$GCz/M,+s6nN7!r2SDn}_&U5HW5ƾmT <CY:)@r{]jE <JhU"@X$@r`IRQ uXs`6mJlTЕi}l-YL nx/ģi8Q J<X1\G_-%R̹-c!}=\T+*^n3 ާi3n֝qK1ij_@PM wbq' :Sxs_[XPdqd+u>]#PخF {S߭j?B! :5%̪dF6a)]-tyJв8c\!"Q(O3!jTD`JM")'OqU)vANzss_g>G4JM˲Ár.W6r`}a LM/C>q7L Ta@8hS g$oix_Va)ϟi|C =5j$F֯d٘־_;j,.V(xOB V)T!Q|`\4Da>i~Qt$~Z~+J]60xFu` m-6\PAewfcRZ2aWB`V\w!<'Ecn*/ ChB >Nct*ὔa@m%1"Ja:kd9Xsw&WQ:Ú#< z c;[)7HKLLѲV[<HsaW`{];nL9E+ʠ"dA'"Ϩ٣,EI^FEYS+PT\wFp{"I :Kci>r<ޘ EF5 X73EP9Y*_vY&PJDxN_. X)VoV&n-N UMiT8\fݏe~U/_lڟe}ke&ae #폗ȠwVg>L<~;0|h3}ujOFs,\zpfGe`1(>᧿dAx}{9s1сpP_z"ą0gLYj:qy<T']k_ze ::<kEIy:I{_)id]*!'Q{PF^Nv ]bH.N=^FTs@ԩ@ԯҧ=CCzm0^ee2T_ħ3 ԽEX2:2*$u#Tz͍ 0\ZlWˮ㲤BK5L8S̅hZ`5yAFY$ncS&gc 2&frz"O;s0 5TdԐJDSiRu(wIovG"OgugL'-}.uE0ڔǜmcɲ7ݷ3KK;|EyEn_%⅚B*°59SbPvT5F]%yZUmȨr+eLuLO_-_Y4fnapwS72 e\CIK)1$Lp4} 6` qNrlJ|I3_: Xвɼ]^>= X#ϝ@nrMWlUeˑKM?SX8GNDg m/ѝxz^ I?4hc˹2GJdn궿bOE#W?F!U}+5n{yg1YwD6-ߝo{ZxяƟ67ܦ47L_9?+[nG wrAla{iE^@&?cf )Đ^a \B@x&` Gr%E6r`?gTBDl6F:oF`ټdIiF-x3ɋ+cx)D;/ k&quჭs" .nb^_F^y~&5*=C+aK1+=XlNU&ACx0"6J89Ƽķs{&Z3 P#P@ᝣ('C0G^o&7SIf7ZJ[W#]ԧs.T+#l 4+-dH^ΎKE_ q3jйC'Z+#dZ"ƳQw"(oטe2u$H_rίK(qL~2@j~!4v`_kR3K55ZCwHE!4flj#6QF-kЉ*osYs&8̟|2'%"4vlI'|++7/]k?O!͜k rM8f6AZnӞ+ XU:Sa*Ozx;|pyUJ=W]3xK#,仠\x3ZvKk\y;ZDo֕p.j3!k/}&xcX|_v/}ڦx=dC>>3q_'orѼj5llxcP^WOHnȉY]r//:V&TiKiwvAjywqʵr ]`ю3/V_BP6ۀ։DeUHvVp$!<_sA XF$eUH@$vf }t=gZ T6=L5 Xyw u: Xxl!rm6j,7=bKKoDI,2E!rL+"etܯҒuaX/(Int4'in_}uM^|BP, Xd]Fv=u6jaZB&b¸71 7cSB{^p/<$\};UBNf1iewJ&y *R;g Dr_Io~ݱșhe³ n,g'qvF&p-=Tۡ~QbzcyɆ>Jhr#jSJloL~P8u"!r)Qv3fV; |<" BLendstream Xendobj X17 0 obj X5692 Xendobj X15 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R21 21 0 R X/R20 20 0 R X/R19 19 0 R X/R18 18 0 R X/R14 14 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 16 0 R X>> Xendobj X23 0 obj X<</Length 24 0 R/Filter /FlateDecode>> Xstream Xx\ێƑ}GP{~ZXÖ؇`W.UjO7n5dmv!ٰ<32"2.'"mئIݯmo7?O?tmږVji.mlcퟶoOx|wWm6W4L>9liZ-+p#%c8+wq;5!cbv<=5c"6֥oC[,?Tc[ `o_c2mml"~ɂi;1.?] X,2F`=4Z0gmRk,O'cN ~O<D&d&Q]"Q]5|M_^5.F0ԕ8gA5>^3:0X[uZ:f4LIv!i 2 :w+-%90f! LpÎdk^UEmS&k& -^"u`E&}jO57 *j(OY4gM@r.hRyEK<Wdyi!f256H.隣"Qxd%*oW`a^X'br8َ?pp̠P 0p0a)A%ja2@hG0PI XvNxU>`T?=2(69ٸ#q9Wk3 X+g:j[-/4o.Yܚ9 X#I'C!(-oo<67zj6?7^WY{l7{w{7<nS_xƩH|d ,8WZڙfOQFɣf`eөM?4H8Y[>}wrJ@N$Q A$JY)y"̿k~VjN#3MKr|s!T=S_?m!7?Fjo{o`f bk$ Ř!QZ`p-ɫt}XdVfظ]~uU?D XBLclhLDȤ;tDx?X-E ,}Z҅ x\!DB@+ȥɊ/o"C\-!k&N X e[UMل08u2ʓQ<#熋mYU9jk@W9.'U9ˋ? !`:lDŽM{vUʓWPg{!@\X0V_-^x]텂uَ? -x:wicl]'wBCyԼGwHS@ʳOR:~"aA\6*s?R: 4ih/|1* XF}p@Q.OLu:×bj3w}AOHb%dÑ$Fprc < =m,ir+ 2j5wHw7֭~FRYo;~s.jeMKT8xveO.PՑC28@+-̅L+6) (^}Tz &C`ArlƝ T+ XPa2"#h8Xdv{eX3CH(Aio{Yj/a X+t#o l}=*cM^`Z>\L#ݺ** '.j؟#EN[!lKLp"P2)|^UpȨGXKW*B)xBKIHLRFbC.#h#JT8QIka .Vҋπ6N[+FIVR;Rs!-R-OkZ+Ӎ33ŌnrވTB1J$Zl@IΎZL( 2fWÑ [WbU)ƖWܟC~ XkX#5\X*$Lg|dä1cʎ2α{L=Aw4fn&@Qaz(#Dֳ]~Xmm24!~W+p{/`JSw=g_8|_37q\>VK}& g4&@mxvR)ӂ1Z$ُ !pRڲ:,fZ.P6[ʔHafx+ʒOu7,`\%3azPZGZ YUYʥ֯~pR22(Zb%L&kE1%N!n"kkdhnHM\>t#N;m}!=&U@!w7*?paIbnD,֕ XOMJe"AHj g UR8]$<y! @LtPY59!-BqkY%{2u8AlS-)ܰ@9L_z[L+KItR4D X"MO! +!]`,Pj J>B X+_|oU@p%B;s_֏C$<wu4O\tE?!IK"L&3r: clx28@YD}G\&֊$d. e+prP9wϨb&*sgd[!pd5D*Ez2A^<THȅ@tͫ}}jMD_Aʪ{Z\".H/cM<8If[ ͤ哼"m.pyօT%yq~ yAf[UHLZW!W.p<LE!"cM(J,W X,B+/[m"쳅QOԞ),)%eKe|3]YV?u"%e֒js-0=Eh0 L X iNړH[ XkHF#Hsi"XUfgS2E7eiDUWH+JZi!\#g<aۧnG<!?'π$U̽(L%;v=)".dӒF-@^@?-Gt'7%3WO~K7w חVxl)/}ȼO0_6c7 Ck+>eַ= nם9S~|aǷamho8\? Pp7\_?\\z`w_EFY#Cw}c?W=o Yj[_|nKmN-(We)ƤK+}yfU6O!JK8m+l ZXO9BT q_>n6acy4'%|[XUa$h\NbH*ZVh9~ XHԇ`1ɴ)i "!Yn(CH~c X# M 4C#7TsyG7E952}d$u2#m{-0.D&CFq5"ux1֗M6m.9.49f`dVJފ?\ִlV5*zR)BjeTvtLGY,zk?֒--?yIGTk@K 3%H鋽A7*MHlV.KkκY+pcMk6n#V5W DYvR?]e0U[$m8AXcgaW'+Kczw<L4]czԊήf?6GŏŒ2|W-P_ /z X0<K:DYHqIt X)vD1V@%}3<l5Yߌ5N+5T?^ VӎkmkxAuSnRC z}$ X0HG=Hˎy]㚄fzKlG-s|[ T"ȸ©s VHrp5ʃ˵9bϻhǺ;s$vsabݼ ew;ȓMm0}HD,Ad|+WqC(|$*7 |?>ΔI#AU# *U>,|ߎc?ݍ d5m^#W ^r\.=i9`K&$5£fT>SdD)Ա&(ʖ7*5);mwCiP%Vv8K[Y>"K&iIjW,Ƭ-8c]Ci'A,UzxTz`cXB/ Y%5L5eE#>=Jt&z X!Hb}ه+rrwư]d8y%o}m% .j8Gn_DBG|C%|ANP2j)]b&nHam `>dϷW:(kZkxN%roGӰ>ҹIDB|*We&2BK#~zGm逝?uz8+y"5YX;N)i]ɟz @ DqIfΏ]S.I!l|uI\g>ׅ3nqUoM:[TG\qP㡶'ə"^mSF){-55hmR+.ciqݒ[Wnk?P_d*W2)A,oW6;ü$Uz7(YΆcOpI!ql8NKHr2yG]xJDvv+ =ިc븊Od xݾo"V83R@Yi(6.~X.b̬3],{jZ_Ѯjt$9Hܨ&yip촉e"0U%Ao]T6EH}R1 3/bjGZfyH* XFb=meV<R{sg'n0A6_i&>y}8K.N{_K!H^"P籫Mq4ṕ T XMƵzq5yBݣ*z`2NPH$?C}Ea]''pޕL|2 VS^U4Z×g} S@k5iPp.̞бVg(fWFZա"BPA쥨*?:_B،YZEIdF:Yuf6^jD˫y X<?<5W-\eηw!((8+#xY&GLU躹()m*E <Vʕ@:c=SGX8(`0N_0Q20x63`spmnxoէqw?"$"ԡɷ.1O2~!! X@ M]^ގ~iP1`m \*U<z]m18h$bUnH17MZM+VLg2F}@A*`D@2*i~Êu毖ۿm{mv8v@^]4HwNbufW=h+XYL&asoMh;Dd|m]쬃zM_;=E')G?U7h `X6LrV˵i7НF'֒ Xܚ0pAEr=8I]]d^ m $y%jK0?] ?H/ tMMܺ|^a?HU:X.mٯRZ<eBdJ^2%^XKИ*E/I+(_7+AAHW,F&<Mcx渥&@}G5D"xEN1Rsu{endstream Xendobj X24 0 obj X6356 Xendobj X22 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R21 21 0 R X/R20 20 0 R X/R14 14 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 23 0 R X>> Xendobj X26 0 obj X<</Length 27 0 R/Filter /FlateDecode>> Xstream Xx\ێFr}(?IȖ10ޕiUizbմz ԑKDY=+ˀ%@)^2r"D$Y7=>Yy{oW7av*7HmSgxy_[cvEʦE}@r3U2.a1ɴH[.ڎhʹ/Q S.\r/bF*/r&4%0 O6\-/hg Cy2XAHݶmb<r oprX2</g& $.<Hpwiiv'%S1Dz5/WlhpX%nopoY8 ^JT/2^W)Lٸ6^OtYy]B7:xzN~f9*?ޠVs6t#@e>܁QGn'Rm9+ } G6?R3ZF&[|GtbdRJ+pbP3:f!n긊S9pZ| Ui$>G]0L0!_m沰g3Ųɗ10&8oBsragEwqajU&"r#pEhezKw 9*nnֈmlWY`VWDD'ԍ1T7y$qw+ Kk_M.ƪ76] 4waM!\Ct4\8Ηp~&WmSZe@iJO7~]+a &:mmCW-C:> *8o):#"~S5ED X/$"2g!MъNی X6=yl)?x\wd='1<n=é? Xhˑ`}Q~ a;ԃp,J4.;wЊ>ʍĽ3EUJ 0$;8.cI2v?Q~(heÓ}{#yNQtEYKו0#@ȑۨ$7_例>$Z2QI*`6EE(lqF2θ X9xZ=8V$&.Sq=!xYӃl䕳9fǨ)!̨u,Qȭ;,/ ߏ0+lXM-/R#p1HOhКmG`fHgtL0D͖@n@ۂ$9'+U}Ou!a|Q,z|5)r|N $$:j!!XٮVVHgMyRq|2 7(-ΙrkX c5.T(u `h /(x q4#(8 X y=Z`y$&?΅$- U YZ0}ɛO}ÂEBP?~+7Sޒ\uhj̥̊?v}%,#ao@Z9U Uad9\3r9:FJUj\.ϸ\iyF_Ԝ4#P.TN7!s`vfv{&44 Pড়_4B5Hn*,@YP*`2RիuKs0 hAc C1IQ(\e?ݞԀـl2Dc=Che,2a#Bߑ[ͤM2|f)H>EVgj|2Wʔ)2JR%:-ͪ:%2re/U$ŎºNIsVd$4cLcuQFRF#)>T|w$_!6tbTz ͘_ XgR8"<H<t,,X$YDA#HN߃?u*2 X#e.* X i"@lO`)8<;y-n%5RGQ=%(Tp왊+5z}l;hβ@*]2}$Ræz&[K̨.h,f0Q1&sg.>tSOiNx0oAAK\m2ihxL4]G`UTh$v8 u-CgHC=E7 e̒xiȒ"]ZNWa0B5Q} Q|d=Ҽ4>kG/W14|$vb 2oTt qC"QbTt_V|!*lGn XR`UKIVN}w?rV e͖=lYq4ߘXa"n9QMcF|>CaTT@̰5ͯș(!2t$DW~%E>yCO+ 5DInv=o X4_fyNjxs ɏmGl`')#OvUpwDz85h43V>UO<GR}~m,GMt<KL&h{'Lok9ud X`6 nr41a]NSg(µ X4귯+Xc_"Vb#4hAoAm?|" %4iae<6[cg I0@,ڑA;`<"j X}N':e@ {[dSå?nr!~[WljNJ\ tt\laVP0OfDvv5bܓ<W)f)VJR&kM,Qg)J.e}%D-JH7&!;ŭqxF1ӾLrCT8ǟĉt{%g03@8T~|CdH%Ǹ1yH$}$A;G "ZE4.5p b(*$H笩rdgiL)Qv$L#$JɆ,1sЩhhŸ 6 +Ń0UPu]@0Tl}i֕QCZj\D0PGذxPJ8fxJu^~{+㸡.z`BԚ4SExLZ64OYlo /儞C#]qYG@ޕɥ4\83,8,( ݉TZ]/g8 [P9&bUS1R]y2-z}q CS1 *+V!<% Xm:3PX~xC l!ǎ"kvo=w'xA{}xP1, XsaR[y(0vێ`Z yD-ħ1g묃k&(wG3q/Bt/ S&8o+\Id3m:i$[#)NGVFՓ8m.Np[ؕgLKnz~s敌SmC kxF{-Qa,rPmM 8L3*̶<⢼%e:Kl XL`LbeЎ4[%}6ddȑdtbx{>1 M3↤]6(CDɕ:AלhTqeoSOڄvGqBM\j CpgfC扅,`b) 0~ж`*,%1$Q)Y}kr>ՁtPL[ۂ,?)ՖiJl+x"dKv!J.;g$Hff.Ǜ[:,5WaƏ- XP̥&df rdhsd(vX<AC91©9=1nϠWȎF0bZe,*,fu+9t?!͆PPPզ4%mǜIt(N%9 pqD(Eq[b.!*S3ړ)w}] X5s)^W$竊bDr,6oÊrHu)/C?Xv@Bb\X镻!q1KF,ҫeޭ9tKfUFA`O#Zk$N⻟+&0ϲIχ=?~'ݭ-4[xpO9x2AIz qaD6j~4'o8mI=ΔV,C ~4KݦWI˙-4& X:b%RW7k(y?Ҭa;&g/߮7w⼤ kd}RIڕ}<aީ_ O7/}fC)A ؼK6,@3 mk؋옏ʇ#o)ߢ@U$%<JC]@'bkO&Ŏ< y;)U 7 VCmaoRKiŢi|R>[ }3OJxؔ VS9|O7s֧,+-m-} &wio%,!?.Dze~ 9pp'=}].uw/=_"{u0ė/!~#y_w߯0x{ %tW8ESL_6gkqLْ;Ufp± \ZyN+ Ź+=H։̇-hz1Q3c@wd нV\*P&NfrO8,D~ XG|V/<k2ڿNX2{AHeV /Vttk.ŹfDK:Ժ8JzҫC/g?63A?BKZ<?V ɧ<j<,?~[)ʳoO)l^@?ބ?u#RM_6'1^49sNq<Y[3n\),7 /3ix\(jK U4θИ y8Hl"9ۆO 0ڤ~js8ύ3jCՒ^Xرp]4UIVfQ b#gpsQ),;?!'f8yz9}E<g*էzfSYx}:HD:&sD`Ғ$~7R֞kթi|],:}Q,ҸBO$$]$']v<qή8J7jw3Olm1^{2> 0fF@Wcf?'i{zT'u ~_LC2Og!$:F =G@fbl3LW i(z_@,|C)jsq֒:8̞Qw ?(@N jIK^Sʱq<XDt[I6_+}`$qhZtgnX|Jm4C5+אrI`WǿHuYڷ#N"<0ɑyL~zbS]&8C} c8BF$ƋVEsg{&˓'QAAS'%leEB,`T_` ]o(5=@$H|"_F<X~VC5fـ$a cAQYi=y Xd) 3 2:}Es}|>0_9PIӏ)99Տ`"(BgΖUߪdz$'E92i@2{m߬$T`?+o1SDb XHZLP.>Bcթo6ߎ3K=aԖro]5&~˴/ ~h_Xu"|dҾxQ}:*U$㫾j X_"T,2mH1ػ{<pq_r%{ej4ߖm L2snp^/=GYo~{>MOx+seO?ӫvendstream Xendobj X27 0 obj X6142 Xendobj X25 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R20 20 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 26 0 R X>> Xendobj X29 0 obj X<</Length 30 0 R/Filter /FlateDecode>> Xstream Xx\ێɑ}WMX]o]`v~K5YRMl X?߲Ȫ,vKC<̠U'"2ttEܿ?iEw_ퟵ#Dbz"<GWFtV4`bu}v<~W0RΨټzy#S6"?6~{2)?tV!vB1v00|v2+|舌qrɧ!9oSGBպ(rOCGD Sa= ޏ̭9i wi5"VNPHm<7!qi_tJ:g<|ʝ {(| ! Xv.N/K"V]TRmb_I.|csg@NEv_+VLJ㏕.ͰCS8T'p#)HTi(y^rH?ih<<@+vD AG,>T(t"qR7 X%AIEW6Q2%rP pIXFY1DQ+> $&ik5{a<fwc# YBzm GcBG } ([/hMRa?YO]K|a:a]^(?PՐΔ"J XMBp<>ݟVK[\V(ك> fRwIq?Aa3 0 S?*C @TTPA]@w0049~}N-2' +ʫzنʪdJg˻<,OwMj ,lN!:ִwhQJ(& p8nK@Z9 b7!nAMd04)KZM1?c?~N!A:-YcdfD_җ--D[4J 0'4 (,(6^vf():xy>nJT&H\Ӡ`pTgS4DA4 CxPt@6Ilhሰt;?';2xlğhg2Df6 XF3j߆S]Ҙ7'{env6 xx@/l9[)DD:6tDJY!ŔQQxŢnw(xB1gݼݚs@t*p8H"{}A[(FՕ}.~pJ7 {|O4L?bޜ@'=hXiFûEebs?""{0yYߴz@P\)ʢ\i iP2̴.g X!+<rTc4Blk3<;%}6*%C9, 6%"?+(76%,?toAE ǫ+6fόD/-ם":p#<x83c7#? 9~UD;}@w;\WY+qu } 4/:N2> gX>yD-sexU88Dw T>/q?W|Fno©)u] gte=yފ"^aL:/3ܱzMt$gŀ g." Tw'&?Бj>\,#2)~fIhXK@: ǍS'$^ͧiM"}uDN> (ӑ^Q;~ =<G^ @{&iHH]X:!㧾v!kDʧhI>%R &DK0G_uh#E~V=}}.,gk)熟&6B2Ї̼{su2stUfQOv4 9(PaգKPEoe Ǟn6D;@>c}8.ZSp@%<@-K:+PnG荱 n7LcƷq"mh3eXc631oci !Ys2 P.w40QmV.zq4l3X̱ ԧiq&8kǹ`@z>@QqOF=L9o g/\wX5SeMB!5MX|LC'om/&)&4H,;i,!>ֺdh>39u |s kZZ9Yk#ms6H2_ XmֲA}pkė`kB62p)%K⑩~teWp/M Ryd)̣:Ź6d+}@sǷcOOz+TXkeTꢓgX>G;@i2TMj~z/~_. :P>i)2Y10-Eyr) X6. PsВ{w2!>K Xg>l X3h'd`mQ`?O&\.yj| XJJ^>˘靯 H9Y #.D%z8 g9p#]HHN(үO,@(W9t3OL"ERSwv)IBQZfHObD)3Rȥ-)h3ZD7і覹xtsH(Yg}nq)>Ο_g}ZgSVg!W;Y7usR9 DjJ]K1.6x-~Ib,Q si?CgE X%x85U p)m[N-gd`z@;/Z^reFt=Y\* ?p6~/L:"+<@OBqEioMtVarn.T:kڌ-mTj&~MWRVr\'@yY*&w/QBvor*M0(1VI4°Ff\w,][t.*5;TZQJ(-[Hhi G0Rb0T庲 ̈X%ͤ@/{t 1/*߱uM1WԶ RNUEHy@>=[|U֪p Xÿj9rO9_(7|T͋|5y>>XxX6%5oaIECҁJ5݆c je0s)^Ͱ?5ETWq꿇CUj<Λ(Dd˸[8sF}׀tywiT Xgj.~$>v5)`O7F3yj8<oD\"c_NT۞ۢ7L+ڰː X>Uʠ"t4DR!6u`Xݴ(qXT+m XXm!H=k<vcKM7y)L=Wy:֝*;F\Fm6CIԢnV7ҲXphi|vh-H8[Eh1P]PO4;hB»Մ&J%lڹaWEǢr!:j+DO$^cK1I?G/Hs3`ȥW.L6[hmfFz1FԱ$aq bBAat4lXMYR(T[ X-@Lc͚$r&0NǕ篱AbK]j).m 焇qP&T] X.CStS|{iR7<<^h0:3jLlt:8˜Ȝócg0sMr[M3#~g]YDN$&.4DP#UZy*6Q9yёwm()OV`('{KRs{H*d X1jnWn0q$}(;ؿ)\@8bT"Te3"~"E䐸.@#>$-oP 4vpM/Alrk,q36u-]&kOC8A6vυmAf_l'̆LO#K<]:*+;NF'}uyYKiiTcHM"4us&Tjϭ %pߤ+/:G}aj)__h=A</>R둋].}V.twм0kZж,*1^Pw5R㳉od%̲N+1seZ<OhkεK'Kyv=o"u0?5;(Eڬ-䟘bi&B#XL^8fo2L8Ҭ'P۞jي6-JںBl似 3a^Y!jPhqZR'b!uj%jԩնleli^xGхTܤUfgf.H_եp0<Š>0<$(OͰw>Dͷ{ekQ<Dzn=l$tm[8Odh좟vsJQکT}شa^][",V04kCWX)u`1ҥ7ƴчNۢ#qjs[N[: JnqXۛ ,cD:nsAU1+wVY[Bʘ0&PI&-]lxQ~Ũ"R':_3WㆋSa}3tDDLbͺ`:r %_NſEvRRf@p X _k O:wu2[7Ζ#$JA[|hntE%k,Qw*}K(9 "%Kl~K"Mw$Ɲeii I(]rN2.<3wP5/=ïeduQt;4rr82Yg ԑ&1B}1h7SC5`N$gp%)g6H`)eH9Ls~T.^H=r\nˁ KTah-ƭ͐&i:ULߢVތ')\o]01ZR2]1}h>.Ĵ.uJխ6|EZr[hoN9yV3dF7upb6r%ޖڅLl:7Wzc|z!endstream Xendobj X30 0 obj X5509 Xendobj X28 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R20 20 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 29 0 R X>> Xendobj X32 0 obj X<</Length 33 0 R/Filter /FlateDecode>> Xstream Xx[YFv~ׯ[lX}$;Fd5!ԌҺÿ*0CnۓI$2`SgB҆ÓwO5.=4o|v}P)5IXH#ZMmhn~jL}ݝO}oܖLbQ0>_H<~/Sm-e XmTpk[aF+Xi*4h^|CpOE+ 4<39Zp8kCY)so?ZW(V2MCm㷿][SZM5?z\[b|9iqaj;{ݹ"<h!)ؐwo[Io_0P@W4D#I f'ذZ4T0(Zʕ3_eƜfLR-[n [vVഝ[kXcyHyd)ͭIg4kZo u۷Ԥww9ilOǩc~M]MFy]z2Ct6릮Ix1n=wy1EMw7VaMw5$2\a4m 6~W XTn?*f,2l8p&DI C?-RS$+R\`YM2 Q#_e7QI$j@OpԮ$,[qwKoqSSS%m5Ee̴2)S=lWvb7}*Le26yu;ـ*wȏnfb,8=.SUuyCR.G .q綼%}s њ"m )LY\*|1Ēr>?n(WxW-%)`/Gz@ݢCso"Qm+情CJUr#F٥lQ]4uSO?&Yɧv-=g7q], L.L Q"a\uH'%@6ţ!dpH %:}$r"Kޟ@R 1@@H6)m2 P|fr>NƯ`wqt w"a7HЩ?!aֲVJq2227HWy r5 X[BDPաq04HQa_$Kb1!qŜ bFap. 68RلBMtc&1&GXͣO>y>ѧ?zQ^D:,5,ZD',H[%g7sV$́>8BPk4 6Ht:vKZ X;[ҽBSoEqp2qI.x[ţy!ԅhSw2cpb1Q n0Q=`G۷Ӈ}{ӏk3+)R1}$sicRSJ!LKQϛL(IL Xqݴn!1s)TQNS.ns/bE}ͳ>M,b2|[?>ƋӋUUG`%dB:]䴝R XIz)e&V%/.["a39rԳ-[gTK[Y|fǤl101uJ)3wAezO)P'!g} u+Ӿ8dAW9g0_29*G$+q*MxAG8vDBa-7v?IqzΘ6Kgo=]cIA3fR)d d_+ܱ⺴yŮH;[Hdv &e$w<T5XO8G!$)MoߖB(鏻(%GlVIĐrb.(h0o"}]\kȞ}\L~frq!ӑθwo.`n m+kt X M Xpphz8p/"+%72RY*,Pimj%+b7Z,R!j6AqwP\X Rm&_p_s\wWJYI\ݼf;xK֕QJIڬGnA')aS-l/Amuѥn'p+K6e+e偀8+CY} XT-ҹ*|2"g!<ŕ)N`31`f+ neRpDø=Ig퇷@Jiɺ CMr}=TjR/Wd*ؤ{pâ,Ln; XZ3'J]t>])|m'*H,C*&>-M5.\9Bv]f X^HSrєsmp7jЏHsYVo;6Qt74JAFPDHʸtvk8d˰z4A XBe.4$geە0_o{9192sb38]8DdH)|fJ%Og|C+D> Xk=0FbhBPeo~i3:ƣj%Msn4ݢ;sbiF:pCa0wf`"94;`)B xK3Hms$E[d+Ӭ2N8 \f6$КRnÕrE>uq16;jJ$ƹd$%gvQգ%46&e4E\- $Оġ̣R^Zz#Hbt Pt<Yj&)_uf I`60h$wWu-ET|0@~w T(u@qwBb{JPb+ԮK%4iHx7}TciW8,<l!)_8/ry;cJHXt*C"ɍ|ݡD0b+kf L[rᄎ+G:?N`ӛi0 XQY\^~Wen*1Vc?_?ћ>$jEW>:$3_R<<巯wy٫){w_w}ޥE~)hHUQ }g\>{0@_ݐD7Fx7n0g+Z!.8iㆵ1%$݆Z_А5+x&t9мv*[9tp)IY >_?֙rpb+Ѻ!ڃm,-i?uRP-CSB5|,T#*mV /7G2yǴdpp)>B-/Ji7ىJpspL+)$9uLqHABs-TUU^3WtG1LP_jܿ+]̓ \82~!q;Q4{@U 2߹bHALH ΅&t_v|v>b(5O5PO4/ (T("*i7?]7"yū]!St_M~mkZ ^TiC_~,қ2ZX uqTRD}l*2kβH;A1;VT2`QSiJx*Y3VFKA_WBPk٢44Ě!aL,Qĕ $}uJ?{O*=w;*R)tv@5sh0 :L羛x 4+{/{s<5x<u0VHQc&5(&%A6u*0WRU3iʬLdLlIyx-**EYf,:U5 P yzsUx:W7I7.+ OU 4Z;՚\u.' X]'68m>bشEƏ3 ^ XԠhl4wL =*5] X3x&7J*;JpCE¡/<Vxv 7e slʟ]*#f\VTILL7cgO.%tX9pMPelh4Psu6W3,5{7D]CL2'}d}uUK/}-U:]}ҋEή4~C755`& &f?2X$mE-ƍ*!x!+8,}y!Zd_ p 𗆮zc_5pZ3KZ.qq<eQ'OL.tg)6g2 P9⧎0&ww5pėCpZnt_10}DtJUJE"*1nޣ X;Vӽq_ XږюY/7Ƒ |LlsS(\-E懹 X%WΉ˥/S2iU2(Q>Šaj0,Hzλ7ϓxP<9F/+|ɟ' endstream Xendobj X33 0 obj X4879 Xendobj X31 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R20 20 0 R X/R14 14 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 32 0 R X>> Xendobj X35 0 obj X<</Length 36 0 R/Filter /FlateDecode>> Xstream Xx[rFv}4.(L(x&lic,$$T*TM|o@zays]@jZ;?ouyT#5a";$UiJk×y]{nw}kw˟~n~YTw'mKf7In?_#<8?#1_?7|"WEQNXMcn{wݩ 1^3@Idz3mquÌ_Y;4ZZ2݄-mp߳)J9ڄ]m XH3 ݂cZ@k\xnK7)tJbMMLX5!}B>S[I;Yj;xUXn%7RY)aan_qwݔIlj̮%KQ=W$&$QoeO\g5ETjNߏJ KRKkA7/J5bm{5j0XF-?5gs'pM# J|TZ24ƷVO PJif"<JI"ϗvg6D5S, XJdn⥋ɬNg彽,tc*8=sW:,)2b>@f,Fj XȲ=u?hc<S_TNbTm?CW'yA4sX퇮= TY=N| IR`?ߟB +Yh(@Cz[;I!6ۆ3Mpp# 'DH&?)"%r<_~ |̮ځC0p>{O>?쒳 XJV1E.ZG@i `i-9q̀ñE?ѶS0us?+Q#0։VHEI(:aB<Doٿ`4Qp!"KLtLi'A@zj;OQ6oJ,IWM1J Ugqm-H,rNeB0̥0\DNC"O4@&RT5"P%.J"Ԙxi )AxPU.,>ۋ۳WVQH@t`ߠ]D XFcY]r2xW_f=,TڢH|dafCo&vjN_{!Y=78˃U0"x Rʊ,iHVt;u on aP}Ͷd*Bf2a_&GcյSߝ4txnNVC~Yq=G`iwoa^n[! 9Do,ՏݾN+GHk Xj ?ƥ<e&꾝o[ANktԔ-ܷdoX3RjO;un!i5`v>|uDHuAQ@B1hN%JmRBfY(l\ !mΎ+!Y :!d(2bc"1oxUҔRmAīX[`uaTY{w@!D4!\JFՔMZXm3l-+CZZ))8?b?2 Yl ȧgz5?iDADzlnD'$@DN@I~cx X")t*sY3J X.tQ֠Tv2Qլ))l߁3-֑XX\G'fʖ\Yg'b{lS9gX&.JR)bR&,obW2SPFrRqՍZc1)T4sn,j&mѕ`q|ɯ`{MO_HyhSUW.CkJOwR:WPS)C5 U6ほBpQ_vxL$X$x%N"ޏ\\P 0son`@Yї}yR⭲CwT- ZiEݦ<lw*V+gXeX#1Hu [EgHڅ14lvV%TPp4 XJQ/O5z[q" }7tVdž"%s'{},ka~XpM~7#`c\O4П_$#3Si$ܥ)(ƸsN"d=qm$.=XALCw7,rPy1 .RAܟp(kX)iP *w>PͱE&mFR,;鵰$c 6+6^jF y)U2q %$Fm(xyTH"@^Kp:\%a*izݡ4%#Vcӄe~XB$F`S1LpFDcKN:Sm^j@aJ#@ștoڢ2"炮 X~:cܶLzMn ᶉѣV?Qk$q@dw{ XrH}}>SSwz$>Ynef1<n23m&TLSh<(B859LJDh͊,R)8woqb`.ufo:j,sRgbi(-")i1m\InSٵL@73z.ۂ̦; @J=Sy<>,>kN`C6 @U,4 .BmiY"TƅNcNQԨX@ |'pX~p.#i}_[ lKGyDX!%R1,J? 1[nQ|Jfe0}-g?k*ޤMqO"KCA{/(>R#$BCL):Y"qx"i8DtS`I'sdD=BbS @>Vc^ X`e} ї-`4o#E68EJ3ॊ}k gBe88>5p&/w.y5=gӶÓmN2Kf%0 Ҭ6p+).ZEtBW_T#$SR[y(2^,hh C@s HYZn[k%YwƖRdrNO fbskJµ5cեERӷNLM<b}l/.ԲAYX 0O$ҟR̦ Xle6r5`5-ҥY\axq?fB79dn uWWMiFE#iG8M*E-,B6*HXHB:bMBe26 AQ!mgsX_sk]d\Af} XMN:4I@ 'RNa 챩bCQE"LE"t,;d/nt;\MiF\lhPp摆:F-R-%EnbLfGT2̒¾8u^!ssXʊ2kߤ2/iT,lS{jNcHn,iù[$5_B͠S}:zg%3 LaAݠO$}ə Q}Qu")h|R]$_}NSY8Lbsx/1;s-$G\Z6Y18rs[bhv3 {E@NRuDxQM#TW%ݏ0>wTRr ,}MVB&3Zouڲnkn Xy/{=tFJrk^J^ǡ>02kC8yRTGHc3>k()@\zoiFs80_|$ykuqHJ"WJ`7Q"(c_v-CI^t\Jhǻe}^|g,(++v}L=! XG\Ch} M;c8y$*dB=a\`>WW9x=j^4;pvVn;IOQfmE}fxG{ 3(_*{0mƒqc6_~)g]ٛ<&y>p/\̤#bn=*n6=vsѣ=#vPWv0s!daz2_;;W?(n<v̶<[d5$o]Y endstream Xendobj X36 0 obj X4486 Xendobj X34 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R20 20 0 R X/R14 14 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 35 0 R X>> Xendobj X38 0 obj X<</Length 39 0 R/Filter /FlateDecode>> Xstream XxY[s6~@_$`I4lu4Sg<Il$&i{nJ4gH><w?bwr}rh^ء'gTw櫓 BCʼn{"%(s滧.vqbYů#nfDо6vsјg;Tbkhl[ǭ8fgDҊxkUg់MEqj~1+s42^mu.>'`D w^+CI,HLB X4gSo1(0&Dk¸($\oڞ<q2h6ߒX>$$M4f\p/&ce?ruH1Q^b5ՙNQʱbQܬ# Zy'aJ<]hyֱZE XFsAt'a{]+(WwA*(gĒ{F?GY\*prU|VEt.Ľkf,y7kljT,dqI3N'.-J711ˣhH|\ݦh:JsB̃jejdR],zUWc@R%%d I^˶,E[VI6\318.R@gaޖƉru9G¬C !9tg>(blfo1.)S$$u D1T*: X XL+^;eI)n$zgBZkڢ nw֠}$?N'v:9UL4ɡb}ٞO#<^B&"$ i|g>adHE$D坠_Rr G:favſ&éLI_Ł&LpyVNz$ūC{c<3(<t Xȃ_Y0 "+;w r XtQ,khaڷ']o5{)*b]WMlض:Ƞ/;;Tڂ ]!F!c+xc:0g[4@/mWmU}jPѠUe^bܰ{nB,nn.岶oV^'#I%eNI)T% (3q*Xߘ Hm̍(NuiZyڀIcZns6"ɊK!qH MqS3)4Kq3D\dm4h<(1bv5LFǜPӦؙ{Ȳän=1^nMӌ!`9 Xa%8Ywϲe:(Xoq4OQ @w@L9f%<6^lgmjh9Bd\1f-<0mQ%8b/P@B0EGb̠+usSƎ]j4t&W)ad@4m,.r{a4IJt5- fF55@?~ޜ:vg'aa685ǥo>$ ϯ= 3%6o&?)@W_g.$Ҵޕ{)~K78LhB]O$L&<wrb!mQwʾ(Ͽ<?n+@zuӮ+ >{P-zJd~:%1ׁ6_O&(}5x~s nwNg?7f?iXRp5aBD6LM$<?s}SlI XH/B(24\LPERO,#69%rrc9 &Ll۱x:$ CGq&k.O%-/Mx\K$"xi!I$8߾/̏EdA*^Hlf]g>G?Jmwv@;y}Pyni<hrA#C>4zW)ƹ; /u NT,+;?X V Ly_citӴ^K X>َ0WOS erVcڤS_v XN͎ Xd(pvƅd~b].`Ćcl|=XsAt0MbV5y457-.ݕ/L. X`fTe n m1v@i>v+1vهy^}+s/''Cendstream Xendobj X39 0 obj X2324 Xendobj X37 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R19 19 0 R X/R14 14 0 R X/R7 7 0 R X>> X>> X/Contents 38 0 R X>> Xendobj X41 0 obj X<</Length 42 0 R/Filter /FlateDecode>> Xstream XxYmo_@Du%\( Xn!Mb;˙K}ˑw.@d3<3r?3)/\|Azf$%'u\?@B8p(A:1/K4l.Y\WURV ]А5ܼAeRM[okJQzhG^6#т@on(W6e-[ئ*}m7# a膱 \'VDzaqR#УkDR? q lDCԫB`%A8$Z")u#N+p!XK?cl X)NG$"^(pDVx3@Qm1v아73C0@ VxF֒ wݯqRl@ñ!//yղ6 %Qh<bǵ Xގ-0Ǝ.<ρ0/tqB?:GFFb[|`N9s|\X|>b||ҟb<Li)c?ʈȄ;V+y7 v5'> c%C("OFB)!6zT3;z9VIV A`HO l|, 6QcJ|zd3< u8&#C!#&57C g:Ύ(S)1o0E:\LL[zzݜY XCHRB0!ҐޱmLduLn)>ԕCC%A U@ tQcDl@MD v;>2[ (nj{xVBte}D Vj>3CY!5bkQUY5mxGU# R5Xcx^FԢ稍%iQ;} X`%(3HxTe9)IGYxQFuoQ#+)ӯS+f@r7vu}E!B%52 ԟ0NlcT#*<J)٩01oǾ|P㻦>.j( thV43CD48 g2j%gU+gU`'?ЖD˺1)`~(jOL^ 1PKCxՏn+G~8~J~s ;!sϼ5EHvl(]Em0(q=`lI%>=|l#4L2>F|W/?_>!h}Q;+QNp pJ:5L$<4i`K%z$1 :5wT%a~0@ǫ+̤.E]CfӮ`PďK<(0f%oDM'AQ| g%r@ 2JT\,%6տmN:oM@)r@F0_KU}P[.vfۺe9}A69X'rdVj6uZP)2gn9hԆ72e7}<2'a>+KZh\`4u@:*HhJ펀WBU1(rFM>'N`KC#n?E#Xy͕!vRs5 $Woz+]P1)|3ľnZxQØZ-:</d.E7ܸ%tו:5RӓY|EW.WY^YrvhmE7'{ޣjR[rfm)})ſg͜f\CJX% j[m~1"_>72|c]?Ld{% u hǗOV}$Sq_^NnɾU5uepyMY^ Tf+fM3RGKa6TΕfO0l5]S0}(GR=P= XMd^b?0OtT&̷@U X :7Tۣ-*DMgXTIU;on7j!rv}9ά5+^<Lx+]NviY_(Z&}bc:2Uh27Lzxq_.-jendstream Xendobj X42 0 obj X2220 Xendobj X40 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R14 14 0 R X/R7 7 0 R X>> X>> X/Contents 41 0 R X>> Xendobj X44 0 obj X<</Length 45 0 R/Filter /FlateDecode>> Xstream Xx\mƑ_1m@ٯqdž$vb/N2 ~jGv%ꩧf۰]ܟ^؟v{OWmӶR0#n*"1cݝ{4χ2y8e\ܿ~籿?e<aOeλy:|?:![!9|<p=åq87\mqm#ܽ ᬁyoycǾvOȿl eO1WOn_s?u\%3~zۦ~0cOq8 `zJçFk?;8tBemjZV#8,]Z\˕Э_`NN}\l.O=y~r`V0?I)!lO8 *?7,-Nw~l8<X 6~&h/O9? #_=|Ǽ~80s )[3vCD7ޤM<s'" Lϟp4Ӫk|ŻwgպÓyTLRmNJi:W8`4ZbGZ)wR&ʻH)1OmeCF84,<U,zS9Foqڻxnt8neN TwM0ݩ.4M2dRi XHvw(,Tۆ:PvWK8<}v<[`UhUҫ1"zq#. !3[r}~SbDlNx$4ia:!R:p]6O[txw!l=eR2n`q>x ֫iO}*2a s:!X p-ƕO/_6d[XA8,ݥp,mlʫ 8ǘ"=G#s~liLi XP x#S懁--4e_ J##uPf֝!c d4?-dǏ "m=6t!v0̪hiq8?'%jLLneZDO4u)LD4 ,B=ă8g5o8 ] F|8O/`@;¾8A*w\hOəxJw' ^K *uzC0y26bK?"KX[4-i<3diJKJp/q+pnw^q_] MVS)p\3SVD2>؆jKK1ټ5>نX{c6a-[$T;b~嚬TR?Un,; X6)L|8a@b K_y]#.#D^)(wKJWɔnKރ Xy-M u'j@@:b(XIÀ!jeE2U֣p@#Lp zD%C Ӛ*gach>@즠 iddD`å 1;1&XMEcs?)Hw?_6;T}7BcHFIB '0T2\`@\JuaxHH ]#2",_ѯV34cǣ[ u:N<%3qB8&`Ip;E3QIz*ɳh&H(tp:l&UT #M,@rENCGSg+o3I{õwpx!=MFsǍ?8[mHa$/UgfkZAQ68=`,CNnI>$rԣ*ӆ l0Oe>L&̃M}@^^s! XYieT䛆y*C@oC91"\XSU?([?rp$rVhyLZL˺҄1wL;>1icā*$PzO<nĄRxͮ@t[.TCl|,p;UC-ى'/g)i:#YL'U&#Nq>%n,jp# I aMa]`hO xǸHE8:>j-|-Uؚ.,focz$nHYoi?;t&M| PQ891$J$l$B^>!'N)UeTƋbmM;u >Vv1C+Qh%Rv\pV8\hedH@Σ@S6J0sKI$8Ӭ}& G2X 췛A1ɥ,b/>@* O 'O:|}Ϋ\H)Ai| dx].\a㳌V]Y3!+[WƾOr_AV kAIy J&2As=DaH<FYk :mA.3irt]`ۍyg"8V,co"FOH.FJ.MY\XƲx6ю 6ƳH7&@OZQ20ѨKeR:X TN !5.ŃN,[t-jDM(^y:\ȶ ѽl≮{$3[TKG68;UȘyI%Di!{:MȀ`9azO!VW+U:֔ݮɛh$V X%K#c;2֩חa&v!.L$bL5pe%DRi0\d5+R H.pN62rS|U.x#[ar6YZMcS( X[QDw`1Қ[oJ:H Xg&|br/S5wgQ(xsÚB.*9:,<ĎTÁ*e}YMVq$6s`D,X q5 X2uA`v<i0kL\ 'ZE) =f@d9aBN%f53(1~\<6;xK(mFf.P; ny[1P1tRUx hbV3|Gva>B,Q"ݨƲ-8P9;2J XH$rCHIfa>$Ae`+i8M3QR]܆jOenm|QὐLeS彀>V-8,\_$oi$")RK,SI6*,ƾ%EApY12)TdI17p>D2Z>_H%Z*jYBA1Dʆ~ay}MJ5g:QaceD[C3X";sy\2j?yg2f L:p>fN@c,۬p`F*y yLظ,<9])!$dfy].I`H~ZiSe,xY&ftFM(7a,"Q #'J(;}DnsSqʔ|>ODİE9EX*2&~"mqKYqxTTK$N*&ILhȕ@?FܸRf5Zj!KSD*]EMR/ kU;lRj -UtOB$FF\['E\J1u JN!6CsBIp?/۴w9_*}axU[ZfƉK/ZntHY}C.W0y!k4`W6A,8N8K.6)z*őj?z*ܴCRkSfa0~gs dMѸƤk.1.42_k5ABvϲR MN&hi( e2 XCPAbR&OWzZ;BYp|2-5pqeEB X'Ϡ8b NLZHAenz<,ü%]nڿo`Tyw%0ҋGXeH~BS1܃A@aG@;i/ҵft(7Ts8EvWͫE,;V\YflΚTwQnycHVgԟw%G*4?-9b#n`x,2f1%ٺ:@]]H+V*VzX1LUFzQG2 4xiljvpN&\&+/S`&% po]-qUzS&9ח~Dv9|%hm(g81](U㜚MzBj#7@n+Vv%<5w4p"`pW0 XZk>VNNnZfy%J*8pAtѱHRHwsۆo\M!Wb ,Ñ;Q݅Nhk7UECe;PHoQs[Rk+Y>"j?Z,R04YdFRw$LL^ Z H'.iҟpHTU>GUem0Rç?@w.!h?PĒ ?łp,]^*dmd-l59C^]XRҖJq_Bn̍toŔ &0rIf& d a<\ Re XVqrݑڐ[;]żxmQSYPhŜք6wBIHy[goa$x@/HȗS}7 Y;9Cj9IIu؉K$UZԛ .e rC\<Uy$-7n钰XQe0" XJ&幟bIJZ0@jYi}Mt Fekdsw"Nd Xֵ(Y>lRE87YԪCC|^ߠFZ=0geW4q7*L$.g0|yicfS2"EX XiZFoY6O,wPKx㴝ISYXHRA+uC9 \$Pw?TJ+&qIsw뱸!db}r<_:_'Bg$Yk.'R+-FGӱ^mD<$V.T`ݒH""u7VE|*?1"ظ<ѫ{>_{Zmp_)*ux+ OW! 35,9fU4hPRiiII5CL'<6:;0syZ8S7i+_q妖9pWOSq*LLT2w"ELP&S{Ye^;Iӟ'fDhbЄBrDՆo|?>ݨM2a*` ڲEoh.'Y~Rr]JKP6Tr\ L[{!eןBɀH<NE7pBG|Ώ4)ˤ XxQ.h{"ѶhJ4HKi2Ϻ8fݜKn©Z32sEB!] W~KEpEA&]A-rY%lV+sSZs⺞_#pUt3Tрmjxx(c0ܕvk- /`n,?TIw"n|%JS'"eÒ+` m X{xTK·D[BTV]x_!K&'GILu)ϊ XP6htGCv~$:~)xΏXoocXs<yC4+g$s;P0JZFpB?m&M]ʴTWhYe^%.KRh}e+;RjL\ڜnB/"8d*嘉 ȢG,*.d:Je:^oHx`;I8jtbur{Uej| }h Wi XƫK}z6)R,BDvVIOWNjp$i!}դ%|PC5),EO2' XR{>!*H!,7PE-mtO=I[;nWAendstream Xendobj X45 0 obj X6674 Xendobj X43 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R19 19 0 R X/R14 14 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 44 0 R X>> Xendobj X47 0 obj X<</Length 48 0 R/Filter /FlateDecode>> Xstream Xx]M丑=@,_nÃ]gLU3STf{%(1=;>0`|xAו¿w7x;17澮j!ݛU3wVʶyw=AZq0wֵEt}/TÔnu%k<qx3_YjݶZ'3۬{N&y, <wD-ﰕ6.lrO_#c/4 .=nd+zӅ$jN)|_i:,9')U5p|ǿom '$ӊ&OCƙ!ʹWd<xY1]DhuЪYy8$Y/Wty%t_TJ Ksø`EI;5|VCjlʆN;uO^J n E$R X0>=2ajmMXzݨ$S~ʤhaשh)]8QPwF>FhZ8v羛Jr7D5cs/F,VoئtjUtlՍb82FH7k#njEUy*YHˢ)^"͂X5(({ Mi<HHMTR2q@~hy^9m]:߿i44I ~O J)dr(Ԋ<ѯ%Jqi:FQrf$&t1L;.=s~_FU'mt)*p|9,* BhLGNNQc6i(TS!:i|?g~HqJ\}>k|FkD-5̎-2US_fq. Jt6m f룰,܁j)Dw0L<'HϮ ^tM:A'f5j-\?fqF~6JF2YHY/OQTECmde)yjDݺKQ\>oB֔DGer9f%uUFl]Kংjg1Nݑ]xQfq8 SGF: Xu4}wa%MS'-y/hvO׳7j8ٴ6QtUid:!; ,ZvcxH"D ֖Eie$O n4vuҟéfd_28va3]2b4#5x.hbArd;R҆aWaT/zW+"ѺY@X X+ɐ^qXe=zo7k<r_cמ~a|.W|T^y[Klo]$;<8>w~6w>zC5w$c!ڻQލ:{坱0;~͒c~~:i+ 9!E[dE|f7'GtcTxH=/P [$.F<(cDf#=B[ q Dd)W`GdyjDBҀfS 'Mغox?.atm*E3`1QH X8q*V;HuΒ1iu<*X.aڴ"r (YPEUiD,&ppΟ:_)a0>6/thm_sW~icÔly aE*fa|+\ɊOSVnFP)ϸKmkC6J0OSެDNz ]]/wh)y2@Ҵ6h|i_KoTjދ]O e?|wV sm9|W8`_Nۃ⢳J-bكm8WV4IY^Bib??H`e)nH=(??]'x\Rx6h<7(IIR}bEQc8Ju/:NÂw@Xrd"r9,GφKR]:+=wK2Ee3-FᚦmCi:<Nʳ"3 ꥼI&-gG`HM(;%;?ݡ/$duP#HR Lg BI>1J^6Mh<Psy@IV,6hk7 X$ɠAS_gd~@S˩tq+W5,ijG 5@HOezC* XKZr)Ηz|a1ZX낲JxKڥ5E!()$e1F(,@$QYvM==H|cfX4:X;ҬI!jttԇ ބA# R)y{u/:drd)S!>~x'~㭛?UwB5? X}qv,8?P,v<JZSJ?oZvo}?_VZ)|ˈƋ4v%zoVa[}K5$v5·G[v%s_G[VȂMַDZYڗ.-ϯKyb[إJoqW#t=pm|- b&¸j[c[Ky+!ޢQ&_oc [/JMRKtV5$;N?uHۼ~3S ;tHT%a>nNR]sd^ʕ$ܑ "P:`Bi.(s.&mjrBf<͔R1[К8A>%#M7# T"8|K\D4Tv@>vwN>BS"f)R'>i f>t,Frobk#j9 (|ZQlJ|ܟ/@YZS^@1I0!~"ߐ0{[ ,_6J}B]:Fm4..|rOżK3(5D3inH8Y2\ ad +Nrx<}նL" '+ZgRO:Cz,Zw*fJP\ȏ,Xt|CU2&:;yN0 y;Y-SbDTu10 K?meX9@CE`!<^}ֳ\02 XQ Zd@cmIMϞ@L)st2lg5r4fS ״N8C4r! XѯOu)R sRX\_Umk>$%/L:Vfʖؗ=BuG^#Xm\{q!S(@jŊr=4T/=]k7եq,iAV<X{Vh#x::Qb)YQ+tX{G1fC#h7c% 0bΥv͒1\ۤ¥vGfһVE~6" 2gQBYO *dI XXxN86lAѐ?3PU~n܅KRyJ'[9QxsMLTߍDh>DjiC%/XPP^Ӈm#$~TՕKA+6t\cȹ ZoPoMtX(̈́oyM5Se3)*r Xd u!뷖|*+`ZVWɂ(~j>2_{b_rg Xf榑N?:Se;hxkʠHiR"KΓEwO2Jz" X<Vcr&W%ԲVBņ#$wt(ֻ'9}ʂ3$ElE)S,B[;ԌHs{[X-&|{,bbSxbZOKx4 X~uiȊ@ĖW!+&#t04ߦIWCR9Aw8sNk.[`;Ŕ:A8ˑuNNF/KwPF?hJ1片lrǞbu{pp Xd3OA 1i<3""E"'2i/FJ/;P$GJ'*=[}T!#q?DR9q8!j+Q@DFgFw=L uEG"Lϴ=p32NkɻIumqH%KI?`l°w+4 9 _\Nce\ʥu(kQΕf.9'H,b gmԂ1;?wÞ26 ϹD|j:S XJ,V+f|Qt2ע<=gWpjtJV,;9|\Z<A9җTX=/3]T$徿^<<vy'6^3##ڴ D=m$b5WbzY['QsF"*p\OLo[T>3JMob0kaJqwrNnhC 8G*L<7 !һ LJz%2Jr3>@__rp`ym!]O9x#رrr(b<d/ӄ\ z>\K{KԞzz>>t?v/'h6~<?:UGtx=]*VkG<"RRO>.N'@i<|`ݍ6gpkO-iRV#GNMcU.zǗM)y2Kd*05Hv@+ Cxc]Ӝ5| 5rfT!-wŌ5HFaP<{1*7wJRK1ML Z4Ip)$jv8_і{&uTYv4sc~[cE|2Jw+&G6|wMֳm䭰s2oB>mP=~ X4"j>.))?EGKc&ܷY) Ʃz?{bj"Ź.S:;{fȓ'2Ub Hcy쉊 X)ц:bS#MKtut:ӢMr{<a8 !,q<࿆hM6d7<TA2#};VoCj2 Y@}% X%\t>xu]<5"6AxtV)7N{F䫔}q}]6xOF.5$&e(|\\JIyiZ"@U.1s+0&$"7I(EZg4_ߩWŋQP&&=ȔTc') |۬}|p})HE ͆33a%qW,2d"U$0={UcM_H?@ ^a(|t>걿B2͏*]Lh@j X|R'YXMk:R:(xҺ!5[*$hQ@/eF-+EFn*uWw&_;r5pbu`1Śn^FI~njpT.!њ]L|>Ͼ99PTӐrخu/tZ XfɄ0L H_'aag,ܴ2+#`xe X܂$qo+nv[!0I|cvҖshat N8ܱKH8R $PP@/'A~["6А X-U.63 XBŕ%A .ǀeeԽ]w8`GC90{V.7H Nk4_|Jf""=#qáxo6d(ا r˾A)<!,5h-pQ XRm!+G;GʁteLN73cXJfʗ0Sǻ<cLW\gג$DuS)f mn&86\< [i"3Gm_5^Kw;З(kM>?&4Wf7<9T540"V4Tn~|XJ]QguvEo4ݸ^ XU%ʷ*ò4G.'2?)KFd@lwx=c8B m16/6M 紱5n^qza@)`4~yWR]s"n!ܟ㽩.7PEFMtסF /!q(}Jlb :?,Vy5Y/9TiRj[ad! 7%5v?+:R!;w\:PRRdIE#vg:}ǩ80 GkNEDo }ox X@+)۽xq."s_Z#/MV× Q#MktiK^шW`tt [|TnR{l:pSJDHP~7:pc'5B$8: $$~A*KrCжi=2?(13&VfʃlsNqdV;ׇ7nGڈCS $7|e⨾Gƴ=Z~ۊ9*< Xɓ`WI%\Iy:<:&nKLK)AgXHDb=rɽTr)?jA*vTM`U6Gz9u#yxo֢endstream Xendobj X48 0 obj X7185 Xendobj X46 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R14 14 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 47 0 R X>> Xendobj X50 0 obj X<</Length 51 0 R/Filter /FlateDecode>> Xstream Xx[rF}WtI_&i3mɱbVlh4Uw Ek7K(pE4*/'&Y^ ,/.פ i!z1}n(hjm|:}?_'#D02BXNS=ħ$!ڎO1[=}zs1=#ǍB^ J§PYXx Xew"<ۗq-Tۂ(y =;;nbǹ;矐 ~vX?N4X{*6,s?#iHP%LqF XUXL3;Y_6Dg.Cu/BYVط+"=fPOFV0cDP=-۪28"ʌ;SO1cdrZĆoXO_Z,lun=y(?י .L XQ5ZmI?{0!'[H2C9`O*iQD0qd L!C>iSpeֆe ).bIb܆pY"Y1Ħ+#%K4֛ZBr*MXf?]\$)N?tͩ,a>EhSeߖ.ULCHD$z86oER%8u<יUt~W}[r<Ľ] zN6;b(h{,mnPLf_a"4x^ ov~Txz(&R XE|ȶ>B",G| GxI0NЖs F!Vܙ<.M&$ e\jVi42FHIB)U-(~fC kupe6Z"GEUEUJ'xC}\C"b ?(8'1r >nDӑbHH.%D3-?VqD]{`ی$}.'[K=Nqsy4UxN elZIvb 3$Mnrd/G[K`.,87dE5bMb Gjl4ݯiA9iKogC٭@Lʶɯ?<P)3)< 9|lϡg>}a_sK||D>$aRDM XC#Ie*a#hNXdVQES&&*D(+ϹrA'<1r@˟ `' Ub961zc jWOV𠷢yhF7.|k}2ʨz-"jԼjģ X|~ncC4) GI-(v LbCJ.Xʪ7CSJ@& X x5rP/@fU#6FY&WaW+<5"XCT }wg,S8/#<bh7˭=PDRR&_Dz:t;$֪DRҰQ0- XuQTj3R:E@=kq[$'N#X!CsXɓ,+?;saoҾF4GTlt@ֳ@8)H&UHrt2OTdX,JʅEAU! QJxȦ(-&VD Ƅc{sՙ_hiPN6y6d$,?\ⰙPefE[b{Ft@JVAĆ *cCph%-}2ltօne{4̩ cyu)g[q<M$xJE(H:=x.钣f%F+C,v:T;SSbddqMNv<eV85(TD~}~y +݆00<(p8QwǧP=N/7-cЉ&fZ7 %A ~RS+`^ nP6"v۸]T 5Ck*e? 2AZz\3e$**e KjԎ.gNϒ!6О뇏\O*~GVD\cW*9[ c!"a4s%AR.)5wpD;V<T|bD*,By!k6$*NKxht)TZFQ(|$ArEtlsMub-! "Y93TbZ9wuu,] [=6PbHH@ X6#@ut.#)&td x ➂&W,YSpnVV]sU>` L!8S_UCAaQј(g1xG+@&u+ԺHMtI GdwYՃֹϫAfK1HpOmxP^0A8Kz uTRf(U.T%6sDv=x;4wmٸY_7=/amc~^YXYӶ ͊X -Η'p@eo}R1#gHYNtOԱ~hv*ړ"-5?6e]3>,B <e'ẈM&6g#OXj;px2Unqθ X$'B;PQLQJ@gxĘx%8gA2/gΗh 2,~Cb61:!ALC1`Nt! tzjv2^sSf{8 X#YmlŤȔ,w껏봆Jծrte_o`BqbO<C^fb`61o>NB\,(I*{x(P<Ie_ʮ1 %"XۮGǗG<K X@ , hv;~\,ܬ39= <P:.$Ix%IH]#10k/P8N'':2s#:/vm3M@mH,*vDfPS.8o礵GCS;UbA$`Db6w{/- losYڹ{<wZ%ML1b9rLk7ڀN8ti\J{b IiA Fx̫#%z L8 Sy{qs}j۲ys]uU1sd Q嶮OE]}sz{.WpاKѻ%w7qjj98Р>/UNu)O_姦G#[Q1I'~{,uaܦLpF PUOp>68zpZPp+ǁ>% o>8XN8tP4^(MWPݮR %J٠d@IG4osTe9<½E O㇐ XTd`E2wW+V XS3T Y%u<J>b߮'מ7$(i2ERt0(;1Qbf=P˅'É*-& ǿ醲{S+pzB\8Q;M3 3[#?qǸP Q$a+K`F1Wʥ }sSFt@|E;MeN4_E,Q@_BUu9l/muѕ<| -H˾ eW_6m OiM??|<.iw?(<b@y:h8NQSw(smw}Q|P1I!o>ntKmX Ɓ/×nc_W.ҽErw) ]@$OdBA'W@}AchMWV@)6 F,hwpbڔYhiή=$_6b'P X5Hh#v]%b}.v`ͧdvˈtv]8iلy]"4{y]vnItxBmXgIx/nѥPߒx"Fz>LTr-%Y}ˋY`K0G+4cW@&Ƚir"YscLRYJ[T XI ?#2k|ڻ %#hFqr6#z?{9^ %b?o@)Ct!EQR{a.(P0wgvϙHvނl`SS3zPWu7Ă8Qh1vHޕ&h8h ! g'4% 84xl4"Ӭa7bxYM;?TWg*>M3qӂ*W(_+47<be6-<]V4DxH ;~->)JczC͢yg/Y]nÄ fTX%Y'T}<fDƁܟgM@sV "ca%r J3)PQd+`""Rs_ZƧގ#S,od/:έyX{s2s )&סrC?}'"6d䳲7P8Gr]|[ikb{D(H @;̐4,)+\`#A$/u*&X(Q&[u]9bQF72+B='n}-(PPP-,:b"Y@Qcs=YuHTX9et0L=0#$fK뇏uMP6/ܰMUnξąꮧA#zF؋͏B@A`q_vy{? _༅rendstream Xendobj X51 0 obj X5121 Xendobj X49 0 obj X<< X/Type /Page X/MediaBox [0 0 612 792] X/Parent 2 0 R X/Resources << /ProcSet [/PDF /Text] X/Font << X/R14 14 0 R X/R7 7 0 R X/R6 6 0 R X>> X>> X/Contents 50 0 R X>> Xendobj X21 0 obj X<</Type/Font/Name/R21/Subtype/Type1/BaseFont/Times-Italic>> Xendobj X20 0 obj X<</Type/Font/Name/R20/Subtype/Type1/BaseFont/Symbol>> Xendobj X19 0 obj X<</Type/Font/Name/R19/Subtype/Type1/BaseFont/Helvetica-Bold>> Xendobj X18 0 obj X<</Type/Font/Name/R18/Subtype/Type1/BaseFont/Courier-Oblique>> Xendobj X14 0 obj X<</Type/Font/Name/R14/Subtype/Type1/BaseFont/Courier>> Xendobj X7 0 obj X<</Type/Font/Name/R7/Subtype/Type1/BaseFont/Times-Roman>> Xendobj X6 0 obj X<</Type/Font/Name/R6/Subtype/Type1/BaseFont/Times-Bold>> Xendobj X2 0 obj X<< /Type /Pages /Kids [ X3 0 R X8 0 R X11 0 R X15 0 R X22 0 R X25 0 R X28 0 R X31 0 R X34 0 R X37 0 R X40 0 R X43 0 R X46 0 R X49 0 R X] /Count 14 X>> Xendobj X1 0 obj X<< /Type /Catalog /Pages 2 0 R X>> Xendobj X52 0 obj X<< /CreationDate (D:20010205161435) X/Producer (Aladdin Ghostscript 5.50) X>> Xendobj Xxref X0 53 X0000000000 65535 f X0000079316 00000 n X0000079166 00000 n X0000006282 00000 n X0000000015 00000 n X0000006262 00000 n X0000079094 00000 n X0000079021 00000 n X0000014687 00000 n X0000006440 00000 n X0000014666 00000 n X0000018872 00000 n X0000014845 00000 n X0000018851 00000 n X0000078950 00000 n X0000024829 00000 n X0000019044 00000 n X0000024808 00000 n X0000078871 00000 n X0000078793 00000 n X0000078723 00000 n X0000078647 00000 n X0000031498 00000 n X0000025049 00000 n X0000031477 00000 n X0000037929 00000 n X0000031694 00000 n X0000037908 00000 n X0000043703 00000 n X0000038101 00000 n X0000043682 00000 n X0000048847 00000 n X0000043875 00000 n X0000048826 00000 n X0000053610 00000 n X0000049031 00000 n X0000053589 00000 n X0000056211 00000 n X0000053794 00000 n X0000056190 00000 n X0000058698 00000 n X0000056385 00000 n X0000058677 00000 n X0000065627 00000 n X0000058860 00000 n X0000065606 00000 n X0000073089 00000 n X0000065811 00000 n X0000073068 00000 n X0000078475 00000 n X0000073261 00000 n X0000078454 00000 n X0000079365 00000 n Xtrailer X<< /Size 53 /Root 1 0 R /Info 52 0 R X>> Xstartxref X79457 X%%EOF END-of-bitlbee/tcp_filtering.pdf echo x - bitlbee/Makefile sed 's/^X//' >bitlbee/Makefile << 'END-of-bitlbee/Makefile' X# New ports collection makefile for: bitlbee X# Date created: 22 July 2003 X# Whom: Dusan Marjanovic <dbm@root.co.yu> X# $FreeBSD$ X# X XPORTNAME= bitlbee XPORTVERSION= 0.80 XCATEGORIES= irc XMASTER_SITES= http://www.lintux.cx/downloads/ X XMAINTAINER= dbm@root.co.yu XCOMMENT= An IRC to other chat networks gateway X XMAN8= bitlbee.8 XMAN8PREFIX= ${PREFIX}/share/ XUSE_GMAKE= yes XHAS_CONFIGURE= yes X.include <bsd.port.mk> END-of-bitlbee/Makefile echo x - bitlbee/distinfo sed 's/^X//' >bitlbee/distinfo << 'END-of-bitlbee/distinfo' XMD5 (bitlbee-0.80.tar.gz) = 96d947bef8c6c40c865beaeee59737eb END-of-bitlbee/distinfo echo x - bitlbee/pkg-descr sed 's/^X//' >bitlbee/pkg-descr << 'END-of-bitlbee/pkg-descr' XThis is port of bitlbee, An IRC to other chat networks Xgateway. Bitlbee supports a wide range of different IM protocols like Xjabber, icq, msn... X XWWW: http://www.lintux.cx/bitlbee.html X X- Dusan Marjanovic Xdbm@root.co.yu END-of-bitlbee/pkg-descr echo x - bitlbee/pkg-plist sed 's/^X//' >bitlbee/pkg-plist << 'END-of-bitlbee/pkg-plist' Xshare/bitlbee/help.txt Xsbin/bitlbee Xetc/motd.txt X@dirrm share/bitlbee END-of-bitlbee/pkg-plist exit --- bitlbee-0.80.shar ends here ---
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030725004232.AEC89621B>