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