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