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

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

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

Section 7.3: NAT Rules

147

 

 

Internet

(DMZ)

 

 

 

 

w.w.w.w:8080

 

 

 

 

 

HTTP

 

router

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

e.e.e.e:80

d.d.d.d

 

 

 

 

FTP

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

packet Œlter

hub/switch

 

 

 

 

 

 

 

 

 

 

 

 

 

 

p.p.p.p

 

 

 

 

 

 

 

 

 

 

 

 

 

 

NNTP

(Screened LAN)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SMTP

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 7.3: Rdr rules divert packets received by the Œrewall to the hosts hidden in the DMZ segment

#ext_ad -- the public IPv4 address assigned to the

#firewall's external interface

ext_ad = "e.e.e.e/32"

#www_ad -- the private IPv4 address assigned to the

#HTTP server in the DMZ

www_ad = "w.w.w.w/32"

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

# NAT rules: "rdr", "nat", "binat"

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

rdr on $ext_if inet proto tcp \

from any to $ext_ad port 80 -> $www_ad port 8080

The above rule redirects all TCP (proto tcp) packets arriving at the Œrewall's external address e.e.e.e/32 (on $ext_if), originating from any source address (from any) and destined to the HTTP server listening on port 80 (to $ext_ad port 80) to the address of the real HTTP server located in the DMZ at w.w.w.w/32 (-> $www_ad). The server listens on port 8080 (port 8080). That port is unprivileged, and the attacker has less chance of breaking things, should the server be compromised. As you will soon discover, when you try this rule in practice, it

148 Chapter 7: Packet Redirection

works for connections made from the outside to your web server, but not from your private screened LAN. This obstacle is easily removed by adding another rule:

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

# macro definitions

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

# ext_if --

the name of the firewalls's external

#

interface

ext_if = "ne1"

# prv_if --

the name of the firewalls's screened LAN

#

interface

prv_if = "ne2"

# ext_ad --

the public IPv4 address assigned to the

#

firewall's external interface

ext_ad = "e.e.e.e/32"

# prv_ad --

the range of private IPv4 addresses

#

assigned to hosts on the screened LAN

prv_ad = "p.p.p.p/24"

# www_ad --

the private IPv4 address assigned to the

#

HTTP server in the DMZ

www_ad = "w.w.w.w/32"

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

# NAT rules: "rdr", "nat", "binat"

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

rdr on $ext_if inet proto tcp \

from any to $ext_ad port 80 -> $www_ad port 8080 rdr on $prv_if inet proto tcp \

from $prv_ad to $ext_ad port 80 -> $www_ad port 8080

The second rule sets up redirection for packets sent from the screened LAN to the HTTP server residing in the DMZ. You can rewrite the above ruleset in the following way (notice that the interface names are now in curly braces):

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

# macro definitions

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

Section 7.3: NAT Rules

149

 

 

#ext_if -- the name of the firewalls's external

#interface

ext_if = "ne1"

#prv_if -- the name of the firewalls's screened LAN

#interface

prv_if = "ne2"

#ext_ad -- the public IPv4 address assigned to the

#firewall's external interface

ext_ad = "e.e.e.e/32"

#prv_ad -- the range of private IPv4 addresses

#assigned to hosts on the screened LAN prv_ad = "p.p.p.p/24"

#www_ad -- the private IPv4 address assigned to the

#HTTP server in the DMZ

www_ad = "w.w.w.w/32"

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

# NAT rules: "rdr", "nat", "binat"

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

rdr on {$ext_if, $prv_if} inet proto tcp \

from any to $ext_ad port 80 -> $www_ad port 8080

The last rule will be expanded into two, and when you check it with pfctl(8), you will see the following output:

$ sudo pfctl -s nat

rdr on ne1 inet proto tcp from any to e.e.e.e port www -> + w.w.w.w port 8080

rdr on ne2 inet proto tcp from any to e.e.e.e port www -> + w.w.w.w port 8080

The rdr rules can use the pass keyword to skip the packet Œltering stage and send the redirected packets straight to the target host. Note that the pass and tag keywords don't mix. If you use the pass keyword in an rdr rule and tag packets, then the packet Œltering section will be skipped and the tagged keyword will be redundant.

150

Chapter 7: Packet Redirection

 

 

7.3.3 Forcing Everyone to Use a Web Cache

What if you wanted to redirect all queries to port 80 on all addresses to a web cache? Return to an earlier setup with two separate rules and change the second rule:

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

# macro definitions

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

# ext_if --

the name of the firewalls's external

#

interface

ext_if = "ne1"

# prv_if --

the name of the firewalls's screened LAN

#

interface

prv_if = "ne2"

# prv_ad --

the range of private IPv4 addresses

#

assigned to hosts on the screened LAN

prv_ad = "p.p.p.p/24"

# ch_ad --

the private IPv4 address assigned to the

#

HTTP cache server

ch_ad = "w.w.w.w/32"

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

# NAT rules: "rdr", "nat", "binat"

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

rdr on $prv_if inet proto tcp \

from $prv_ad to any port 80 -> $ch_ad port 1080

In the example above, the web cache listens on port 1080. Note that this technique of forcing everyone on the internal network to connect to the Web through the cache server is controversial, and you must not impose it on your users without careful thought. For more information consult [Wessels 2001].

What if you want to bypass the cache yourself? Use the no modiŒer, as in:

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

# macro definitions

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

...

Section 7.3: NAT Rules

151

 

 

 

# boss_ad --

the address of the privileged user who can

 

 

bypass the HTTP cache.

 

boss_ad = "p.p.p.b/24"

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

# NAT rules: "rdr", "nat", "binat"

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

no rdr on $prv_if inet proto tcp \ from $boss_ad to any port 80

rdr on $prv_if inet proto tcp \

from $prv_ad to any port 80 -> $ch_ad port 1080

As you can see, the no modiŒer makes the -> ... part of the rule unnecessary (and such rules do not parse, as they do not make sense). Always list exceptions to general NAT rules before these rules, or the exceptions won't be matched.

Another useful modiŒer is !, which negates the values (interface names, source and target addresses) it precedes:

rdr on ! ne1 inet proto tcp from ! s.s.s.s/32 to \ ! e.e.e.e/32 port 80 -> d.d.d.d/32 port 8080

The above rule redirects all IPv4 TCP packets arriving on any interface except ne1 from any address except s.s.s.s/32 and destined to any address except e.e.e.e/32.

7.3.4 Other Uses of rdr Rules

The rdr rules are very handy because they can be used to conŒgure proxies, redirect trafŒc from a dead host to a backup host, and so on. For example, the FTP proxy setup described in Chapter 4, ConŒguring OpenBSD uses them, as does spamd(8) described in Chapter 12, Using spamd.

7.3.5 binat

The last of the three NAT rules are binat rules, which bind an external public address to an internal private address. VPN setups often use this bidirectional translation, and it can provide additional security for hosts exposing public services. Their syntax follows these rules:

152

Chapter 7: Packet Redirection

 

 

ƒThe no switch. Tells pf(4) to not perform packet redirection between two addresses bound by the binat rule it begins. It is used to selectively turn redirection off for certain source or target addresses (ports have no meaning in binat rules). This part is optional.

ƒThe binat keyword. This part is required.

ƒThe pass keyword. This part is optional. When you use it, the packet is sent to the destination host without matching it against the packet Œltering rules.

ƒThe name of the interface on which binding occurs. Starts with the on keyword. You need to tell pf(4) which interface each binat rule applies to, so this part is required.

ƒThe name of the IP address family. Possible values are inet (for IPv4 addresses) or inet6 (for IPv6 addresses). This part is required if the target address (listed after ->) expands to more than one address family; this happens when you use the hostname or the interface name in place of a single IPv4 or IPv6 address.

ƒProtocol speciŒcation. Discussed in Chapter 5, /etc/pf.conf.

ƒInternal address. This is the address of the internal host you want to do bidirectional mapping for. Addresses are discussed in Chapter 5,

/etc/pf.conf.

ƒTag marker. You can mark packets translated with binat for a doublecheck Œltering with the tag keyword followed by the identiŒer string. Such packets can later be matched with the tagged keyword. This part is optional. For more information on this subject, consult Chapter 5,

/etc/pf.conf.

ƒExternal address. This is the external address bound to the matching internal address with the given binat rule. Addresses are discussed in Chapter 5, /etc/pf.conf.

These rules are similar to rdr rule, but they do not allow such Œne degree of control, in particular it is not possible to redirect ports. While the following rule set works with rdr rules, it is not possible with binat rules.

rdr on $ext_if inet proto tcp from any to $ext_ad port 22 \ -> 192.168.1.1 port 1022

rdr on $ext_if inet proto tcp from any to $ext_ad port 25 \ -> 192.168.1.2 port 1025

rdr on $ext_if inet proto tcp from any to $ext_ad port 53 \ -> 192.168.1.3 port 1053

rdr on $ext_if inet proto tcp from any to $ext_ad port 80 \ -> 192.168.1.4 port 8080

Section 7.4: Proxy ARP

153

 

 

Compare it with binat rules:

binat on $ext_if inet proto tcp from 192.168.1.37 to any \ -> $ext_ad_1

binat on $ext_if inet proto tcp from 192.168.1.38 to any \ -> $ext_ad_2

binat on $ext_if inet proto tcp from 192.168.1.54 to any \ -> $ext_ad_3

As you can see, every internal address must have its own equivalent external address. They can all be bound to the same external interface, though. If you want to know more, consult the ifconŒg(8) man page (look for information about aliases).

Again, no and ! modiŒers are allowed, as are address class modiŒers (inet and inet6), and pass or tag keywords (the interactions between them are similar to those in nat and rdr rules).

Binat rules can bite you when you least expect it. They are bi-directional. Packets sent from internal hosts appear to be sent from the public external IP address and the packets arriving from the external hosts appear on the inside to be coming from the internal hosts, which can get messy. A combination of rdr and nat are a better choice in a vast majority of cases.

Whatever NAT rules you write, remember two things:

ƒdo not try to redirect packets to the same interface they arrive on, it will not work (routing options for Œlter rules may help you here, see Chapter 8, Packet Filtering);

ƒdo not redirect to the local interface on the Œrewall (127.0.0.1), because it creates a potential security risk (we break this rule with spamd, but such decisions should not be taken lightly).

7.4 Proxy ARP

Proxy ARP is sometimes thought of as an equivalent of NAT, but it is not an exact match. You can use it to connect two network segments and the proxy ARP host will answer requests for the host hiding behind it, but there

154

Chapter 7: Packet Redirection

 

 

will not be true NAT happening and packets sent from private addresses will not have their IP source address or port numbers changed.

Enabling proxy ARP is easy, the intermediate host that acts as a proxy has static ARP entries in its ARP cache that inform it that the address of the host hiding behind it (the internal host) is bound to the proxy host's external interface. No enable two-way communication, the administrator sets up routes that tell the proxy host where it should send the packets it receives. Static ARP and routing are discussed in Chapter 4, ConŒguring OpenBSD.

Chapter 8

Packet Filtering

Packet Œltering is something pf(4) does exceptionally well. No matter what conŒguration of OpenBSD and pf(4) you use, there is always a bit of packet Œltering to be done.

Packet Œltering rules, if present in pf.conf are examined after scrub rules (see Chapter 6, Packet Normalization) and NAT rules (see Chapter 7, Packet Redirection). There are three kinds of packet Œltering rules:

ƒblock Š block matching packets.

ƒpass Š let matching packets through.

ƒantispoof Š a special case of block rules.

8.1 The Anatomy of a Filtering Rule

Packet Œltering rules, just like other pf(4) rules, are written using specialized grammar, similar to that of NAT rules, but capable of describing much Œner detail:

ƒThe action (block or pass) keyword. Indicates what action will be taken when a matching packet is found. This part is required.

ƒThe direction (in or out) keyword. Decides which packets are matched, inbound or outbound. This part is required.

ƒThe log (log or log-all) keyword. Tells pf(4) to log matching packets. This part is optional.

ƒThe quick keyword. Tells pf(4) to not evaluate other Œltering rules once a matching packet is found. This part is optional.

ƒThe interface name(s). This part is optional, but rarely omitted. When it is missing, the rules apply to all interfaces, which is rarely desired.

ƒRouting options. These options can be use to Œne-tune routing of packets, logging, etc. This part is optional.

ƒAddress family (IPv4 and/or IPv6). This part is optional.

156

Chapter 8: Packet Filtering

 

 

ƒProtocol name(s). This part is optional.

ƒSource host address and port number (optional). This part is optional.

ƒTarget host address and port number (optional). This part is optional.

ƒOptions. This part is optional.

The large number of keywords and their possible conŒgurations make them a bit overwhelming for a beginner, but there is a method behind this madness. The following guide should make them easier to digest.

8.1.1 What Is pf Supposed to Do (block, pass)?

The block or pass keywords tell pf(4) what to do with the packet that matches all conditions listed after either block or pass (we are leaving the antispoof keyword aside until the end of this chapter, but think of it as a special case of block rules). These keywords are required and either of them must be used at the beginning of every Œltering rule. To block all inbound and outbound packets, use:

block in all block out all

The opposite would be pass rules that let all trafŒc in and out of the Œrewall:

pass in all pass out all

With such rules in place, all trafŒc can move freely in or out of the Œrewall. Both policies are too general for practical use, but they are handy for explaining the basics.

As a general rule, the more conditions you list after pass or block the more speciŒc the rule will be. Conversely the less conditions you use, the more general the rule will be. As you will see later on, it is always a good idea to start your packet Œltering section with a set of:

block in all block out all