Ipfw(8), the command frontend to ipfirewall(4), is the most common IP filtering and traffic shaping facility in FreeBSD, and the one for which FreeBSD is ready to handle by default (although the firewall itself is disabled by default in the kernel). The logical operation if its rules is similar to many other packet filters, with the exception of IPFilter, whose default operation in handling rules is rather less efficient and requires greater care to tune it (if you're familiar with it, note the 'quick' keyword required for ipf(8) not to traverse the entire ruleset every time, etc). This is not to minimize the power of ipf(8), which has its own advantages. The ultimate decision as to which packet filtering facility one uses is a personal choice, unless one requires particular functionality not available in one or the other, although, we will delve into a rough comparison of the two later on.

As indicated above, ipfirewall(4) is a packeting filteringfirewall, which means that it acts by inspecting connexions on apacket-by-packet basis, and as of FreeBSD 4.0, can also performrudimentary connexion oriented (stateful) filtering. On either count, itacts by filtering packets through one or more network interfaces. Thisbehaviour is always transparent, that is, one will probably not be awarethat a firewall is present until something is blocked.

Firewall designs take on many shapes, but all can be broken downinto two general policies: open and closed. The open firewall approachlets all packets through by default and only blocks that which is NOTdesired, while on the other hand, the closed approach blocks all packetsby default, and only lets through was IS desired. The latter allows for amuch tighter firewall configuration, but is much trickier to setup becauseone can easily block out traffic that one's net requires, but one isn'taware of.

2.Enabling Ipfirewall(4)

Ipfirewall(4) can be enabled in two ways: add the appropriateoptions into your kernel configuration file and rebuild the kernel, or usekldload(8) to dynamically load the basic ipfw.ko module into the kernel.Either approach works well for enabling basic ipfirewall(4) operations,however, only the former allows you to add additional configurationoptions, such as logging.

To dynamically load ipfw one can simply issue the followingcommand:

(root@nu)~># kldload ipfw(root@nu)~>#

Enabling ipfirewall(4) statically, the equivalent would be to addthe following line into your kernel configuration file:

optionsIPFIREWALL

Then, rebuilding and rebooting would enable ipfirewall(4) in thekernel statically.

However, things are not as simple as they may seem; one can onlydo things exactly as above when one is in front of the console. Additionaloptions are necessary to make the box usable. If you recall the discussionabove concerning firewall policies (open and closed), you will understandwhy things can get very messy when you realize that the default firewallpolicy is closed. As such, if you simply enable ipfirewall(4) without anyfurther actions, all network traffic will be blocked. This can become anightmare when enabling ipfirewall(4) remotely. Diasaster can be avoided,although, it is never recommened to remotely enable ipfirewall(4), eitherdynamically or statically.

If you wish to dynamically load ipfirewall(4) remotely, anyhow,the follow command is recommended:

(root@nu)~># kldload ipfw && \ipfw -q add 65000 allow all from any to any (root@nu)~>#

This will automatically set a rule to allow all traffic instead ofblocking it, so you don't cut yourself off from your remote box. Likewise,this is recommended on local boxes as well if they are connected to anetwork and you don't want to lose your connexion.

Enabling ipfirewall(4) in the kernel statically in a remote boxtakes a little extra work. Once one has added the kernel option specifiedearlier, in the kernel configuration file, and rebuilt the kernel, one hasto then set at least two ipfirewall(4) options in rc.conf so that when thebox reboots, it will not be locked out by its own firewall with thedefault-to-close policy.

firewall_enable="YES"firewall_type="OPEN"

There are other firewall types defined in /etc/rc.firewall, but wewill concern ourselves with those later. For now, a default open policy isgood practice for the beginner. Alternatively, one can enable a defaultopen policy for ipfw(8) in the kernel, instead, by also adding thefollowing option into the kernel configuration file:

optionsIPFIREWALL_DEFAULT_TO_ACCEPT

In this case, the rc.conf options noted above will not be*necessary* as we will not *need* to use /etc/rc.firewall to enable anopen policy because it will be enabled by default in the kernel. However,even if one chooses to enable this in the kernel, it is good practice toenable the /etc/rc.conf options anyhow, because later we will be using/etc/rc.firewall to load custom rulesets. This also applies if one loadsthe kernel dynamically, because eventually one will reboot, and the kernelipfw.ko module will not be automatically loaded. The /etc/rc.conf firewallenabling functions allow for a convenient place to load the ipfw.komodule.

With the additional options for ipfirewall(4) that are availablefor enabling statically in the kernel, one soon realizes this is thebetter method for enabling ipfirewall(4), at least as FreeBSD is designedcurrently. Aside from IPFIREWALL_DEFAULT_TO_ACCEPT, we also have:

IPFIREWALL_VERBOSE allows one to log traffic with ipfirewall(4) byverbosely printing packet activity to syslogd(8) for every rule that hasthe "log" keyword. This will be more clearly explained later.

IPFIREWALL_FORWARD allows one to forward packets to other hostswith the 'fwd' command for ipfirewall(4), which will be dealt with in moredepth later.

IPFIREWALL_VERBOSE_LIMIT=# specifies a limit to logging packetsfrom a particular rule. With this, syslogd(8) and one's console (unlessdisabled in /etc/syslog.conf, as will be shown later) will not beoverwhelmed with messages from ipfirewall(4) activity. The "#" isreplaced with the number of consecutive times one wishes to log a givenrule being activated.

If one has IPv6 enabled, then the following rules will apply tothe corresponding firewall actions on IPv6 packets:

In addition, there are four more options associated withipfirewall(4) that can be enabled in the kernel, but will not be discussedat this moment as they are not necessary for the basic firewallactivities, and involve more complex routing situations.

2.1.rc.firewall and OPEN firewalls

Whether one specifies a firewall type or not, oncefirewall_enable="YES" is put into rc.conf and the system reboots,/etc/rc.firewall is started from rc.conf, and the following two commandsare issued to ipfw(8) from within it:

${fwcmd} add 100 pass all from any to any via lo0${fwcmd} add 200 deny all from any to 127.0.0.0/8

{fwcmd} is defined early on in the rc.firewall script, dependingon whether one specified that ipfw(8) run quietly (with the -q option) ornot. The first rule allows all traffic via the loopback device (lo0) topass, and the second rule blocks all traffic aimed at the localhost(127.0.0.0) network. The first rule is necessary to allow local IPC(inter-process communication) traffic, and the second rule is necessary sothat no external packets can ever be allowed to reach the localhostaddress, which is the address on the loopback device, thus protectingone's local traffic. If these rules are missing, and the firewall defaultsto a closed policy, you will see RPC(3) services break during startup,among other things.

Next, when one specifies a firewall type of "OPEN" in rc.conf, thefollowing line in rc.firewall is activated:

${fwcmd} add 65000 pass all from any to any

This allows all external traffic in (except to the localhost), andall internal traffic out. It fulfills the same task as enabling theIPFIREWALL_DEFAULT_TO_ACCEPT in the kernel. If the open policy is enabledin the kernel, then rule # 65535 will be automatically set to "allow ipfrom any to any" instead of "deny ip from any to any," thus making rule #65000 as set in rc.firewall for the open policy redundant. As such, it ismore apropos to indicate firewall type "UNKNOWN" if one enables an openpolicy in the kernel, and does not wish to enable any other rules. For onewishes to, for instance, simply enable the firewall to play with and seehow it work,s or simply block packets from a single host, then leaving thefirewall type open like this is sufficient and one can safely skip tosection 3.

However, if one wishes to use one of the pre-built rulesets inrc.firewall, or create one's own custom rulesets, then neither options(OPEN or UNKNOWN) are sufficient.

2.2.Loading Rulesets

There are two generally different things that can be doneconcerning rulesets: use one of the pre-built ones in rc.firewall, orcreate your own. The author recommends the latter for two reasons:

- You can customize the firewall rules to your liking and needswithout touching rc.firewall, which can be kept as a general reference.

- You will be forced harder to become familiarized withipfw(8) syntax, and as such, will become more comfortable with usingipfw(8).

2.2.1.Pre-defined Firewall Types

Of course, the final decision is the administrator's. If onewishes to use one of the pre-built rulesets, then one should read througheach of them in rc.firewall to become familiar with them before activatingany of them. Which ruleset is loaded is controlled by thefirewall_type="" option in rc.conf. Aside from the "OPEN" type, there arethree more predefined types available:

"CLIENT" This ruleset enables some basic rules. It allows alltraffic from the local network (which could be a private network behindNAT) to itself. It blocks fragmented packets. It allows mail, DNS and NTPpackets in and out of the network, and does not allow any host outside theprivate network to initiate TCP connexions with internal hosts. This wouldalready be impossible if the network was behind a vanilla NATconfiguration without any special proxies. This configuration will workwith both a default open or closed policy.

"SIMPLE" This ruleset is somewhat of any oxymoron - it is morecomplex than the CLIENT configuration and requires some knowledge ofinternet RFCs to make sense of at first glance. It will attempt to stopspoofing by not allowing in external packets that have return addressesthe same as that of any internal host. It will block allprivate-net-addressesed packets as defined by RFC 1918 from leaking in orout, and will block all additional non-routable networks as defined in theManning internet draft( http://www.ietf.org/internet-drafts/draft-manning-dsua-03.txt ). It willallow mail, www, DNS, NTP traffic and fragmented packets to pass through,and will not only block attempts for connexions to be initiated by outsidehosts, like CLIENT, but will also log these attempts.

"CLOSED" This is technically not a rulest, because it does notenable any rules. In fact, it does everything we've been warning not todo: allow the default closed policy to take hold over all traffic (exceptfor traffic via lo0 as controlled by the rules explained earlier). It willessentially disable all IP services, unless, one enabled the default openpolicy in the kernel. Don't do this.

2.2.2.Custom Firewall Types

If one has decided to instead load one's oen ruleset(s), then oneshould specify a file instead of one of the above types in thefirewall_type option in rc.conf. For instance, one might have thefollowing in their rc.conf:

firewall_enable="YES"firewall_type="/etc/rc.firewall.rules"

This will allow one to define one's custom ipfirewall(4) rulesetin /etc/rc.firewall.rules and have it run everytime during bootup.Furthermore, if one wanted to have the rules start quietly, one could alsoinclude the following in rc.conf:

firewall_quiet="YES"

The format of the ruleset in this file will be slightly differentfrom that which is encountered in rc.firewall. This is because rc.firewallis an sh(1) script designed to run on its own. The ipfirewall(4) rule fileis there solely to be processed by ipfw(8). The primary difference will bethat where the shell variable {fwcmd} is invoked in rc.firewall, you willsee nothing corresponding to it invoked in the ipfirewall(4) rule file -simply the rules on their own. Later on, when we construct a sample rulefile, we will go through this step by step.

3.Basic Ipfw(8) Rule Syntax

The rule syntax for ipfw(8) is pretty simple. Any rule can beenabled from the console with the ipfw(8) command. Before we delve intothe rule syntax, however, we will quickly overview how to list theipfirewall(4) rules that have been activated.

3.1.Listing Rules

In its simplest form, we can list the rules with:

ipfw list

This will list all of the rules ordered by their rule number. Toalso list the timestamp of the last moment a packet was matched on aspecific rule, the following command will accomplish this:

ipfw -t list

Finally, if we wish to list the packet count for matched rulesalong with the rules themselves, we can issue the following:

ipfw -a list

OR

ipfw show

Both will display the same information in the same way. The firstcolumn is the rule number, followed by the number of outgoing matchedpackets, followed by the number of incoming matched packets, and finallyfollowed by the rule itself.

3.2.Basic Commands and Actions

We will now gradually go through the various options available forthe construction of a stateless filtering ruleset. In our examples we willonly state the rule not including the firewall control utility(/sbin/ipfw) which must precede each one if we're manually setting theserules from the command prompt; otherwise, if we're construction a rulefile to be passed to ipfw(8) we can use the sample lines as-is.

add 1000 allow all from any to any

This is the most benign example of a rule. We have alreadyencountered the same rule, except for the rule #, in section 2.1 whendiscussing the OPEN firewall type. Note: the "pass" parameter used in thatrule, as written in rc.firewall, is synonym for "allow" and "permit" -they are interchangable. In this rule, "all" packets from "any" source to"any" destination are allowed to pass.

With ipfirewall(4), under most circumstances, the moment a rulematches a particular packet, then ruleset examination halts there.

As we see, the simplest syntax for ipfw(4) is:

<command> [<rule #>] <action> <proto> from <source> to<destination>

The important commands are "add" and "delete." They areself-explanatory. Rule numbers start count at 0 and end at 65535. The lastrule number is always defined by the default firewall policy in thekernel. Even if you have an open policy defined in rc.conf, the last rulewill always reflect the kernel policy. This is fine because ruleset searchhalts at the first matching rule (usually), so if the penultimate (secondto last) rule is number 65000 and defined by rc.firewall to allow allpackets, all packets will be allowed by default even if the last rule(65535) defines a closed kernel firewall policy, because the last rulewill never be reached.

"deny" | "drop" - Any packets matching a rule with this action aresilently blocked by the firewall and search of ruleset terminates.

add 1100 deny all from any to any

This would deny all packets from anywhere to anywhere.

"reset" - Any packets matching a rule with this action are blockedand the ipfirewall(4) attempts to send a TCP reset (RST) notice to thesource. The ruleset search is terminated. Naturally, because this onlyapplies for TCP packets, the protocol must be "tcp," which matches onlyTCP packets, and not "all," which matches all IP packets.

This action is sometimes useful for fooling network scanners thatwould otherwise be able to detect a service behind a filtered port. On theother hand, it can become a liability if one is flooded at a particular IPand port for which ipfirewall(4) is set to reply with a RST packet, thusdoubling the usage of your bandwidth.

add 1200 reset tcp from any to any

This would deny all TCP packets from any to anywhere, and sent aTCP RST responce packet to the source for each.

"count" - Any packets matching a rule with this action will promptipfirewall(4) to increment its packet counter. Search through the rulesetcontinues.

add 1300 count all from any to any

This would increment the packet counter for this rule, whichmatches all packets coming from anywhere and going anywhere.

"skipto <number>" - Any packets matching a rule with this actionwill prompt ipfirewall(4) to continue its search through the rulesetstarting with the rule number equal to or greater than that which isindicated by <number>.

add 1400 skipto 1800 all from any to any

This would skip ruleset search to rule 1800 for any packets thatmatched this rule in the first place.

3.3.Specifying Protocols

The "proto" is the protocol that is desired to be matched. Thekeywords "ip" or "all" are catch-alls that match all protocols. Thecommonly matched packet procotols are icmp, udp, and tcp, although, thatis by no means an exhaustive list. For the complete list of possibleprotocols one can match, 'more /etc/protocols'.

3.4.Specifying the Source and Destination Addresses

The "source" and "destination" both take on the same format. Theycan be a name, as defined in /etc/hosts or through DNS, an IP address, anetwork address with bitmask (or netmask), and can be optionally followedby one or more ports numbers if the protocol is udp or tcp. Using names orIPs is straightforward, for instance:

add 1000 allow all from myhost to hishostadd 1100 deny all from 10.0.0.5 to any

The first rule will allow all traffic from "myhost" to "hishost,"and the second rule will deny all traffic from 10.0.0.5 to any host. Oncea packet matches one of these, ruleset examination for that packet ceases,and it is either passed or dropped, according to the action specified inthe rule it matched. This is a simple example of host-based filtering;that is, of filtering according to which hosts a packet is destined for,or arriving from. Network-based filtering works similarly, and the networknotation there utilizes either bitmasks or netmasks, for instance:

add 2000 allow all from 192.168.0.0/16 to anyadd 2100 deny all from any to 10.0.0.0:255.0.0.0

The first rule allows all traffic from the network whose IP rangeis 192.168.0.0-192.168.255.255. It uses a bitmask to indicate this. Abitmask specifies how many bits from the network address (192.168.0.0)should remain the same for matching packets. In this instance, the first16 bits out of the 32 bit address will remain the same, and as the first16 bits happen to be the first two octets, 192.168, all addresses whosesource addresses have the first two octets as 192.168 will be matched bythis rule. The second rule accomplishes a similar thing using netmasks.The netmask indicate how many bits from the indicated network addressshould be used for rule matching. In the above example, for rule two, thenetmask is 255.0.0.0. Its first octet is set with high bits; in otherwords, the first 8 bits are set high. This indicates to ipfw(8) that onlypackets with the first 8 bits of the network address (10.0.0.0) should bematched. As the first 8 bits of the network address equal 10, then allpackets whose destination address have a 10 for the first octet (alladdresses between 10.0.0.0 and 10.255.255.255) will be matched by thisrule, and then dropped, as indicated by the action.

Rule matches can also be inverted with the "not" keyword. Forinstance, in the following ipfw(8) commands, all packets not from192.168.0.3 are dropped:

add 1000 deny all from not 192.168.0.3

3.4.1.Introduction to Bitmasks and Netmasks

The principle behind bitmasks and netmasks is simple, but oftenconfusing to new users, as it requires knowledge of binary numbers. Itmakes far more sense if one worked with IP addresses in their binary form,however, the confounding of decimal and binary concepts easily throwsnewcomers off. For a quick reference, the following table illustrates whatnetwork ranges are indicated by the corresponding bitmasks/netmasks up toa default class C netmask and a couple quick examples of additionalbitmask/netmask entries for larger networks:

As you can see, there is a definite pattern. The number if totalIPs always doubles, and the number of usable IPs is always total - 2. Thisis because for every IP network/subnet there are two IPs reserved for thenetwork and broadcast addresses. The netmask's last octet starts at 255and constantly decreases by multiples of 2, while the bitmask decreases bymultiples of 1, because in binary, each shift over to the left halves thenumber, not divides by ten, like in the decimal number system. This samepattern goes for all possible netmasks and bitmasks.

For a quick example in using the above table/pattern, let usfigure out the IP range for the subnet indicated by:

172.16.100.32/28

First we notice that the network address is 172.16.100.32, so weknow that the subnet begins with this address. Second, we notice that thebitmask of 28 indicates that the last 4 bits (32-28) are set low and 28bits set high. Because there are far less bits set low, it'll be easier tocompute this using them. Because each bit has two possible values, 2^4indicates how many hosts are referenced by this bitmask. In this case, 16.172.16.100.32 + 16 = 172.16.100.48, so the IP range is 172.16.100.32 -172.16.100.48. Looking at the table, we see that 16 IPs correspond to abitmask of 28, so we could've used that to add to our network address andavoided the other math, but it's so much better to know how to do it allon your own - learn once and use always.

3.4.2.Specifying Ports and Port Ranges

One can also do port-based filtering along with host andnetwork-based filtering. Ports can be simply specified following theaddress of either a source of destination. Port ranges can be specifiedwith a dash, be comma-separated, or use a bitmask to specify a range. Mostimportantly, one can not use the "all" protocol when specifying portsbecause not all protocols are port-sensitive.

add 1000 allow tcp from any to 172.16.0.5 25add 1100 allow tcp from any to 172.16.0.5 1021-1023 add 1200 allow tcp from any to 172.16.0.5 21,22,23add 1300 deny udp from any to 192.168.0.5 1024:8

In the first rule all TCP packets which are destined for port 25on 172.16.0.5 are matched. In the second rule, all TCP packets which aredestined for ports 1021 through 1023, inclusive, on host 172.16.0.5 arematched. In the third rule, all TCP packets which are destined for ports21, 22 or 23 on host 172.15.0.5 are matched; and finally, in the fourthrule, all UDP packets which are destined for ports 1024 through 1028 onhost 172.16.0.5 are matched. The last rule can be tricky as it uses abitmask on the port to make matches. The port 1024 contains 10 bits. Thebitmask indicates that all hosts matching the last 8 bits on that port,destined for host 192.168.0.5, are matched. 10 - 8 gives one 2 bits whichcan be anything. 2^2 = 4, so we have 4 port numbers, starting with 1024,that can be the destination ports for packets aiming for that host, andwill result in a match.

Bitmasks for ports are rarely used and are even trickier thanbitmasks or netmasks for IP addresses, because the number of bits in aport varies depending on the port specified before the mask. As such, itis recommended that one stick to specifying port ranges with a dash ( -) or separate the list of ports with commas.

4.Advanced ipfw(8) Rule Syntax

Although the above overview of ipfw(8) rule creation will covermany of the simple scenarios, it sorely falls short for many more complexsituations, such as when a system has more than one network interface, onewishes to make special responces to certain matches, or one wants morecontrol over the direction of traffic flow. We will first expand thetemplate for the ipfw(8) syntax to the follow:

Everything in brackets comprises new functionality we will discussin this section. We will also cover an additional "action" that was notcovered earlier. The syntax may suddenly seem daunting, but we will takeit slowly, and add each part as we go along, so as not to overwhelm you.

4.1."unreach" Action

Firstly, we will introduce a new "action:"

"unreach <code>" - Any packet which matches a rule with thisaction will reply with an ICMP unreach code, after which time the rulesetsearch will terminate. The possible unreach codes can be indicated bynumber or name. The following is a quick list of ICMP unreach codes andcorresponding names. If you don't know what these are used for, you won'thave a reason to use them:

One important functionality missing from the basic description ofipfw(8) syntax in part 3 was interface and flow control; that is, theability to match packets according to which interface (if you have amultihomed system) packets are moving through, and in which directionthey're moving. Up until now, direction was only loosely gauged by usingthe source and destination addresses, but using just them to guesstimatewhether a packet is really coming or going when it moves through thefirewall is unreliable. If you wish to match packets only coming in orgoing out, the keywords "in" and "out" can be used. Both correspond to the"interface-spec" area of the syntax template given earlier, and therefore,are placed near the end of every rule, prior to any posible options. Forinstance, if we wish to match all packets coming in from anywhere andgoing anywhere, we could have:

add 1000 allow all from any to any in

To match packets going through a particular interface, use the"via" option followed by the interface name. For instance, if you areusing a PCI 3Com 3c59x, then your interface device will be xl0. To matchall packets coming in through that interface specifically, sourced fromanywhere and destined anywhere, the following would suffice:

add 1100 allow all from any to any in via xl0

Or, perhaps, if one has a multihomed system and wishes to matchany packets coming from anywhere and going anywhere at least movingoutside through *some* interface, he can do the following:

add 1200 allow all from any to any out via any

One will notice, when listing firewall rules, that when usingeither "in" or "out" in combination with "via" the rule as it actuallylooks does not contain a "via" but either "recv" or "xmit," depending onwhether an "in" or "out" was specified, respectively. For instance:

(root@nu)~># ipfw add 7000 allow all from any to any out via xl0(root@nu)~># ipfw list | grep 7000 07000 allow ip from any to any out xmit xl0(root@nu)~>#

Indeed, one can use either "recv" or "xmit" in place of "via" when using"in" or "out," however, doing so is not required, and can add to someconfusion for the newcomer.

In all, these options allow a lot more control over networktraffic on a multihomed system and any system in general, by allowing oneto filter packets specifically coming into the firewall, exiting it, andmoving through a specified interface.

4.3.Matching specific ICMP and TCP Packet Types

ICMP, TCP, and IP packets come in various types. These types aredefined by the various flags that each of those packets sets. We can matcheach of those types by using one of the following ipfw(8) options at theend of our rules.

4.3.1.icmptypes

"icmptypes <type>" - This will match the specified ICMP packet<type>, and conversely, if a '!' is put before the <type> then all ICMPpackets that are not of this type are match. There are currently 15different ICMP packet types that can be matched; each is specified by thecorrect number. Ranges can be specified with dashes or be comma-separated.The 15 possible ICMP types are:

If one is curious how these ICMP type, specifically type 3,correspond with the Unreach codes that can be generated with the "unreach"action, then, simply type 3 matches any of those Unreach codes. FilteringICMP packet types can be very useful for controlling ping; specifically,for allowing internal hosts to ping out while blocking outside hosts frompinging the gateway or any other host. The following three rules canaccomplish this easily:

1000 allow icmp from any to any out icmptypes 81100 allow icmp from any to any in icmptypes 01200 deny icmp from any to any in icmptypes 8

The first rule allows all icmp packets of type 8 (echo request) togo out. The second rule allows all icmp packets of type 0 (echo reply) in,and the final rule blocks all icmp packets of type 8 from entering. Inshort, it allows echo requests to go out and echo replies to come in, butblocks echo requests from coming in. As such, hosts behind the firewallcan ping anyone on the outside, while hosts on the outside can't pinganyone behind the firewall. Naturally, this option can only be specifiedwhen the indicated procotol is "icmp."

4.3.2.tcpflags, setup and established

"tcpflags <flag>" - This will match any TCP packet whose headercontains one of the following flags, or conversely, if '!' is presentedbefore the <flag>, match all TCP packets that do not have the <flag> set:

The SYN flag is of most interest as it is sent for initiation ofTCP connecions. Because it is so important, there is a separateipfw(8) option dedicated specifically for matching TCP packets with theSYN flag set. This is called "setup." Naturally, this option can only bespecified when the indicated protocol is "tcp."

"setup" - Any rule containing this option will match any TCPpacket with the SYN flag set. For instance, if we wished to deny allincoming TCP SYN packets, we coul issue the following:

add deny tcp from any to any in tcpflags syn

OR

add deny tcp from any to any in setup

On either count, the same action is performed: all TCP SYN packetsfrom "any" destined to "any" will be matched, and denied. As stated abovefor "tcpflags", this option can only be used for rules when the indicatedprotocol is "tcp."

"established" - Just as there is a special option for indicatingthe request for TCP connexion initiation ("setup") there is a specialoption for matching an already established TCP connexion. Because it is ofparamount important to easily control TCP connexions, "established" and"setup" are available for quick rule formation. Given these options (ortheir corresponding "tcpflags" incarnations) we can have some simplisticcontrol of TCP connexion activity. This is the very base of statefulfirewall functionality, which shall be dealt with in more detail later.

4.3.3.ipoptions

"ipoptions <flag>" - Finally, we can match for some specific IPpacket flags, namely, for SSRR (Strict Source Route), LSRR Loose SourceRoute, RR Record Packet Route, and TS (Timestamp) flags. If you do notknow what any of these IP options do then you will not need to match forthem specifically.

4.4.Catching Fragmented Packets

Fragmented packets are matched with the "frag" ipfw(8) option.Under most circumstances fragmented packets should be blocked. Receivingmany fragmented packets may indicate a DoS (Denial of Service) attack,although FreeBSD and most other UNIX and UNIX-like systems will not bephased by such attacks, Windows systems are often quite vulnerable. Assuch, if one has one or more Windows systems on their network behind thefirewall, it is avisable to block fragmented packets.

When using the "frag" option to match [and block] fragmentedpackets, there are a couple guidelines that must be followed. Firstly, onecan not use the "frag" option when also specifying "tcpflags." Secondly,one can not use "frag" if also specifying any TCP or UDP ports. Giventhese guidelines, we can easily issue a rule to block all incomingfragmented packets:

add deny all from any to any in frag

4.5.UID and GID Based Filtering

One powerful function that IPFilter does not have is UID/GID-basedfiltering. Ipfirewall(4) is able to filter packets according to the UIDand/or the GID of the process from which they are arriving. Naturally,this can only be used to match packets which originate from processes onthe local host, however, it still offers a powerful functionality. Theoptions to be used are "uid" and "gid" followed by the UID/GID or name ofthe user or group by which we will be filtering.

One potential use is to restrict the use of IP vhosts on a shellserver. If one wants to ensure that one or more vhosts can not be used byanyone else, one can easily use UID-based filtering to block everyone'sbut one's own traffic from that vhost:

add allow tcp from any to 172.16.0.10 inadd allow tcp from 172.16.0.10 to any out uid georgeadd deny tcp from 172.168.0.10 to any

With the above rules, only user george would be able to use thealiased IP (IP vhost) 172.168.0.10 to establish TCP connexions to theoutside. No one else would be able to bind bots, IRC chat clients, or whathave you, to that IP and establish connexions with anything that requiredTCP (most things). Likewise, the UDP protocol can be used withUID/GID-based filtering, however, no other protocol can be.

Another possible use of UID/GID-based filtering would be to enablebandwidth limiting on a per-user basis, as opposed to per-host orper-network basis. As such, one could, for example, have a group of usersthat all have fast FTP accounts, and only moderately limit their GID,while on the other hand, have another group of shell users, who don'trequire much bandwidth, and therefore significantly cap the bandwidth onthe GID they all belong to. Such GID-based bandwidth capping will beillustrated later, once we cover the traffic shaping facilities ofipfirewall(8).

For security purposes, one may wish to log the traffic of aparticular user, and here too UID-based filtering would come in handy. Inshort, whenever one would wish to conduct firewall behaviour differentlyfor one or more users, UID/GID-based filtering would come inhandy. Because, in general, once a rule is matched, search through theruleset stops, UID/GID matching rules must be invoked before othersweeping rules can match the traffic. So, when creating one's ruleset, onemust take this into careful account if one wishes to enable UID/GID-basedfiltering.