Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Building Firewalls With OpenBSD And PF, 2nd Edition (2003)

.pdf
Скачиваний:
39
Добавлен:
17.08.2013
Размер:
2.74 Mб
Скачать

Section 8.1: The Anatomy of a Filtering Rule

177

 

 

Example 1 above sets a very aggressive rule. If the connection is not established in 20 seconds, it will be dropped. In example 2, the connection will be dropped if the Œrewall does not receive a packet that is a part of the established TCP connection in 10 seconds. This is a very aggressive setting.

The protocol.connectionstate pair can be one of these values:

ƒtcp.first

ƒtcp.opening

ƒtcp.established

ƒtcp.closing

ƒtcp.finwait

ƒtcp.closed

These settings are static (you need to reload the rules that use them to change their values), but you can make them adaptive with:

ƒadaptive.start Š when the number of states exceeds this value, pf(4) begins linear scaling of all timeout values.

ƒadaptive.end Š when the number of states exceeds this value, pf(4) sets all timeout values to 0, which expires them.

The formula used in linear scaling takes the following values: adaptive.start, adaptive.end, the current number of states stored in memory:

adaptive. end - number of states = scaling factor adaptive. end - adaptive. start

So, if you set the following options (they can be set globally, in the options section, or on a per-rule basis):

set timeout {adaptive.start 5000, adaptive.end 20000}

and the number of states is 8500, the timeout values will be scaled down to the following fraction of their initial values:

20000 - 8500 = 11500 = 0. 77 (77%)

20000 - 5000 15000

178

Chapter 8: Packet Filtering

 

 

To learn more about the TCP connection state transition cycle, consult [RFC 761], and if you are still looking for more information, read [Stevens 1994, 1:240-242] and [Wright, Stevens 1994, 2:805-807].

It is possible to control other protocols, like UDP, or ICMP, but the number of protocol.state matches is more limited:

ƒudp.first

ƒudp.single

ƒudp.multiple

ƒicmp.first

ƒicmp.error

ƒother.first

ƒother.single

ƒother.multiple

The other keyword is a catch-all category for protocols which are neither TCP, UDP, nor ICMP.

The last timeout option, interval speciŒes the interval between •ushing expired states.

########################################################

# options: "set"

set timeout interval 20 set timeout frags 20

Because optimization rules reset various global timeout settings, you should always list optimization rules before your timeout settings.

Each keep state or modulate state can have its own set of options. These options are:

ƒmax n Š the maximum number (n) of concurrent states that can be created for this rule. See the earlier discussion of the limit states option

Section 8.1: The Anatomy of a Filtering Rule

179

 

 

ƒtimeout: timeout values for states created with this rule. See the earlier description of the timeout option.

A rule using state options could look like this:

pass in proto tcp all port 80 flags S/SA modulate \ state (max 1000, tcp.established 120, tcp.closing 10)

8.1.19 IP Options (allow-opts)

IP options are blocked by default, which is good from the point of view of security. If you want to allow them, you explicitly state your wish with the allow-opts keyword:

########################################################

# macro definitions

#-------------------------------------------------------

 

# ext_if --

the name of the firewall's external

#

interface

ext_if = "ne1"

########################################################

# packet filtering rules: "antispoof", "block", "pass"

#-------------------------------------------------------

pass in on $ext_if all allow-opts

In practice there is very little need for allowing these options, save for special application, as they may be used by attackers to mess with your network, or with other hosts on the Internet (in such cases, you might end up being accused of deliberate wrongdoing, if you enable these options and it results in problems for other hosts). IP options do have their legitimate uses, but if you don't explicitly need them, do not use allow-opts.

If you're curious, read [RFC 791] and [RFC 1108]. For a more detailed discussion, refer to [Wright, Stevens 1994] where you will Œnd details of operation and implementation of IP options processing in BSD systems.

The allow-opts keyword can only be used in pass rules.

180

Chapter 8: Packet Filtering

 

 

8.1.20 Labels (label)

Labels are used to mark rules for which pf(4) will keep separate statistics. You can display these stats with pfctl(1). A label is added with the label keyword followed by a text string. Labels are placed at the very end of rules:

pass in on rl0 all label "incoming" pass out on rl0 all label "departing"

To view statistics, use:

$ sudo pfctl -s labels incoming 85 26 2024 departing 86 56 6960

When you add a lot of labels and want to see stats for just one label, use:

$ sudo pfctl -s labels | grep incoming incoming 85 26 2024

The numbers that follow the labels are the number of positive rule matches, packets, and bytes.

Labels can contain pre-deŒned macros:

ƒ$srcaddr Š source IP address. This is the source IP address listed after the from keyword in the rule, not the packet's source address, so if you use from any and label "from $srcaddr" in the same rule

you'll see a message similar to from any 86 56 6960.

ƒ$dstaddr: destination IP address.

ƒ$srcport: source port.

ƒ$dstport: destination port.

ƒ$proto: protocol name.

ƒ$if: interface name.

ƒ$nr: rule number.

8.2 Antispoof Rules

Source address spooŒng is used to sneak packets past Œrewalls by setting their source addresses to the address assigned to one of the Œrewall's inter-

Section 8.3: Filtering Rules for Redirected Packets

181

 

 

faces. Such packets ought to be dropped immediately, as they cannot be legitimate.

To help you quickly write secure anti-spoof rules, pf(4) deŒnes a special antispoof keyword rule, that has the following syntax:

ƒThe antispoof keyword. This part is required.

ƒThe log keyword, if you want to log packets caught by this rule. This part is optional.

ƒThe quick keyword, if you want to shorten the time taken to evaluate the whole ruleset. When you use that keyword, place antispoof rules at the beginning of the ruleset. This part is optional.

ƒThe for keyword followed by the name of the interface for which pf(4) will generate anti-spoof rules. It is a common mistake to use on instead of for, so watch out for this. It is OK to list more than one interface in braces here, or to refer to a macro. This part is required.

ƒThe addressing family, either inet for IPv4 or inet6 for IPv6. This part is optional.

For example, if you wanted to write anti-spoof rules for interface ne1, you'd use:

antispoof for ne1

8.3 Filtering Rules for Redirected Packets

The problem of Œltering redirected packets comes up over and over again in questions that the author receives from new users of pf(4). How does one write rules that match redirected packets? Well, the main thing to remember when you are designing your ruleset and plan to use NAT or port/interface redirection, is to design your Œltering rules to match packets after NATing and redirection, or you will waste a lot of time debugging the ruleset and scratching your head wondering what's wrong with your design and its implementation.

The rules of the road are quite simple (inbound and outbound qualiŒers are relative to the Œrewall host):

ƒrdr rules. Packets sent by hosts other than the Œrewall itself, are matched by block in or pass in rules on the same interface you use

182

Chapter 8: Packet Filtering

 

 

in the rdr rule, e.g.:

#redirect all packets sent from the internal private

#network ($prv_ad) to port 80 on any address arriving

#at the interface connecting the private network with

#the firewall ($prv_if) to port 8080 on the cache

#server whose address is $ch_ad

rdr on $prv_if proto tcp from $prv_ad \ to any port 80 -> $ch_ad port 8080

pass in on $prv_if proto tcp from $prv_ad \ to $ch_ad port 8080

ƒnat rules. Packets sent from NATed hosts appear as outbound packets on the Œrewall interface used in nat rules. Their source address and source

port are changed to those of the Œrewall's interface. Therefore, they are matched by block out or pass out rules on that interface, e.g.:

#NAT hosts in the private network ($prv_ad) on the

#interface connecting the firewall to the Internet

#($ext_if) using the firewall's external address

#($ext_ad)

nat on $ext_if from $prv_ad to any -> $ext_ad

pass out on $ext_if proto tcp from $ext_ad to any

ƒbinat rules. Packets sent from internal hosts appear as outbound packets on the interface used in binat rules. Their source address is changed to the external address used in the binat rule. Therefore, they are matched by block out or pass out rules on the interface used in the binat rule. Packets sent from external hosts appear as inbound packets on the interface used in binat rules. Their target address is changed to the internal address used in the binat rule. Therefore, they are matched by block in or pass in rules on the interface used in the binat rule.

#######################################################

# workstation_int -- the internal IP address of the

#

binat-ed workstation

Section 8.3: Filtering Rules for Redirected Packets

183

 

 

 

#

workstation_ext -- the external IP address of the

 

#

binat-ed workstation

 

binat on $ext_if from $workstation_int to any \ -> $workstation_ext

pass in on $ext_if proto tcp from any \ to $workstation_int

pass out on $ext_if proto tcp \ from $workstation_ext to any

184

Chapter 9

Dynamic Rulesets

In case you haven't noticed, the days of static network layout are over. The world around us is changing at an increasingly higher rate and so do the networks we manage. Our jobs are more and more similar to Œxing planes while they are in the air. Fortunately, pf(4) is there to help us manage constant change.

One of the greatest challenges in network administration is managing and securing networks whose layout changes, often in an unorderly manner. Wireless Ethernet, telecommuting users, mergers and acquisitions, temporary alliances, etc. are all having a great impact on the networks we manage. It is very difŒcult to design and manage Œrewalls that can keep up with these changes. Fortunately, pf(4) is an advanced packet Œlter that can help administrators manage change and automate a lot of work. And because it runs of top of OpenBSD, it is possible to build advanced conŒgurations that run on autopilot most of the time. Knowing how to build such systems requires knowledge of Unix, scripting, pf(4), and other networking and security tools. In this chapter we will focus on those features of pf(4) that make it possible to build Œrewalls that adapt to change.

9.1 Designing an Automated Firewall

An automated Œrewall can adapt to changes in the local and the external environment. Changes to the Œrewall conŒguration can be periodic or dynamic, caused by unpredictable events.

Periodic changes are made with commands and scripts called from cron(8), which can be conŒgured to run pfctl(8) jobs like loading a different ruleset at different times of day (you can edit cron(8) jobs with crontab(1)). Such systems are not very •exible, but have their place. They are used to grant access to certain hosts at different times of day/night. Or they can be used to redirect connections from one host to another, while the Œrst one is going

186

Chapter 9: Dynamic Rulesets

 

 

through a backup routine. Such solutions are relatively rigid, with little space for the unpredictable.

More •exible solutions are those designed to react to dynamic, unpredictable events. These events can be friendly or unfriendly. A friendly event could be an attempt by one of the authorized users to log on the Œrewall to authenticate herself/himself. Such solutions are described in Chapter 12, Using authpf. An unfriendly event could be a port scan done on your Œrewall by the attacker looking for a way into your network. If such attempt was registered by your NIDS, the IP address of such host could be automatically added to the list of banned hosts, from which all connections are blocked. Such actions could be done automatically, without human intervention. One interesting project that lets snort (a very popular NIDS) automatically update pf(4) rulesets is snort2pf:

http://www.unix-geek.info/snort2pf.txt

(snort2pf)

Both kinds of automation require custom solutions as this territory is largely uncharted. Since each Œrewall is different, administrators write their own scripts that perform such tasks. Readers interested in building such solutions ought to have a good working knowledge of Unix and the following features of pf(4):

ƒThe (interface) notation. This simple notation solves the problem of not knowing the address assigned to the interface mentioned in a rule. Instead of giving an IP address, use something like (ne1), if the interface you will assign the IP address to is called ne1. When the name of the interface is stored in a macro, use the name of the macro in place of the name of the interface, e.g. ($ext_if). This particular feature is used in every ruleset where one or more addresses are assigned dynamically with DHCP. Of course, it can also be used when addresses are assigned statically. Remember to use the inet or inet6 keywords to specify which protocol should be Œltered by your rules, as some interfaces resolve to more than one IP address class.

ƒThe hostname notation. Similar to the (interface) notation, substitutes the hostname into address number. The inet or inet6 keywords might have to be used in such rules too.

ƒThe :broadcast notation. Expands into the broadcast address, see Chapter 4, ConŒguring OpenBSD. The inet or inet6 keywords might have to be used in such rules too.