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

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

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

Section 10.2: Bandwidth Shaping

197

 

 

nections are timing out too often (see also Chapter 14, Ruleset Optimization for information about state timeout values). This part is optional.

ƒToken bucket regulator. The tbrsize keyword followed by a number of bytes that tell ALTQ how quickly it should send packets. This part is optional and may be omitted, ALTQ will automatically adjust it to the optimal level.

ƒThe list of queues. The queue keyword followed by a list of child queues in braces. Each queue name must be unique, but you do not need to list the default queue here (it is required anyway). The names of queues can be anything you want, as long as you do not use reserved pf(4) keywords. This part is required.

The following are examples of parent queue deŒnitions:

#define a parent queue and give it a total of 45Mb of

#bandwidth to manage; define four child queues: ssh, www,

#other (default), ctrl (control); managed with PRIQ

altq on $ext_if priq bandwidth 45Mb \ queue{ssh, www, other, ctrl}

#define a parent queue with a bandwidth of 45Mb and six child

#queues: accounting, developers, managers, users, other

#(default), ctrl (control); managed with CBQ

altq on $ext_if cbq bandwidth 45Mb \

queue{accounting, developers, managers, users, other, ctrl}

#define a parent queue with a bandwidth of 45Mb and six child

#queues: accounting, developers, managers, users, other

#(default), ctrl (control); managed with HFSC

altq on $ext_if hfsc bandwidth 45Mb \

queue{accounting, developers, managers, users, other, ctrl}

10.2.2 The Anatomy of a Queue Rule

Once you deŒne the parent queues, it is time to deŒne child queues attached to each parent queue:

ƒThe queue keyword. Marks the start of a child queue deŒnition. This part is required.

ƒQueue bandwidth. The bandwidth keyword followed by the maximum

198

Chapter 10: Bandwidth Shaping and Load Balancing

 

 

bandwidth available to the child queue. It can be deŒned in bits (b), kilobits (Kb), megabits (Mb), gigabits (Gb), or percentage (%) of the immediate parent queue of the current queue. This part is required, but not available in PRIQ.

ƒQueue priority. The priority keyword followed by an integer number (0-15 in PRIQ queues, 0-7 in CBQ queues). The higher value of that argument, the higher the priority of the queue (15 is the highest priority in PRIQ, 7 in CBQ, 0 is the lowest priority in both). This part is required.

ƒScheduler options. The name of the scheduler followed by a scheduler option in parentheses. These options can be one of the following:

* borrow Š (only in CBQ and HFSC) current queue can borrow band-

width from its parent queue when the parent is not utilizing its own bandwidth in full.

*default Š every parent queue must have a single default child queue which manages packets that do not belong to other child queues.

*ecn Š packets in this queue are scheduled using Explicit Congestion NotiŒcation (ECN), described in [RFC 3168]. In short, ECN is an extension of RED, which enables routers to notify the client and the server that the network is slowing down due to congestion.

*red Š packets are scheduled using Random Early Detection (RED). When you use it, packets will be dropped proportionately to the length of the queue. Packets in longer queues are dropped earlier than packets in short queues. In practice, this means that communications like instant messaging, ssh, telnet, or HTTP will become more responsive, while long FTP or HTTP downloads will become even more slower.

*rio Š packets are scheduled using RED IN/OUT. To enable it, you must enable RIO and rebuild the kernel. To do this, you should the following line to your kernel conŒguration Œle:

option ALTQ_RIO

For more information about rebuilding kernel, read Upgrade-MiniFAQ:

http://www.openbsd.org/faq/upgrade-minifaq.html (Upgrade-MiniFAQ)

This part is optional.

ƒThe list of child queues. The list of child queues of the current queue, in braces. Each queue name must be unique. This part is optional in CBQ or HFSC, not allowed in PRIQ (there is only one level of child queues).

Section 10.2: Bandwidth Shaping

199

 

 

10.2.3 Assigning Queues to Packet Filtering Rules

Once you deŒne the parent queue and its child queues, you will have to assign packets matched by various pass Œltering rules. This is done with the queue keyword placed at the very end of a Œltering rule, e.g.:

pass out quick on $ext_if from any to any queue users

It is allowed to list the names of two queues, e.g.:

pass out quick on $ext_if from any to any queue (users, admins)

When you list two queues, the second one will be used when:

ƒmatching packets have their TOS set to lowdelay.

ƒmatching TCP ACK packets with no data payload.

Packets not caught by rules assigning them to other queues will be automatically assigned to the default queue.

10.2.4 Priority Queuing (PRIQ)

The PRIQ scheduler uses a simple •at bandwidth division model, where you divide the bandwidth into smaller slices with different priority. It is an effective way to implement a simple queuing policy like `ssh connections are more important than http and nttp connections,' or `connections from the research department are more important than connections from the library, but both are less important than connections from the network administrators.'

Let's see how one could implement the following policy:

ƒDNS queries have the highest priority.

ƒconnections to SSH and TELNET servers have lower priority than DNS queries.

ƒconnections to various mail servers (SMTP, POP2, POP3, IMAP, IMAP3, POP3S) have lower priority than connections to SSH and TELNET servers.

ƒconnections to WWW servers (HTTP, HTTPS) have lower priority than connections to Mail servers.

200

Chapter 10: Bandwidth Shaping and Load Balancing

 

 

ƒ all other connections have the lowest, default priority.

A sample ruleset based on the PRIQ scheduler giving different priorities to different types of services that users connect to is shown below:

#MACROS

#external interface ext_if = "ne1"

#PARENT QUEUE DEFINITION

#define a PRIQ parent queue: bandwidth 45Mb, and

#five child queues: dns, ssh, www, mail, other (default) altq on $ext_if priq bandwidth 45Mb \

queue{dns, ssh, www, mail, other}

#CHILD QUEUE DEFINITIONS

#DNS lookups are given the highest priority, because we

#need them done asap

queue dns priority 14 priq(red)

#SSH connections are given one of the highest priorities,

#because they are often used for administrative purposes queue ssh priority 13 priq(red)

#mail connections are given lower priority than SSH, but

#higher than HTTP/HTTPS, because we want to send/receive our

#mail as quickly as possible

queue mail priority 12 priq(red)

#HTTP/HTTPS connections are given lower priority, because they

#are not as time-sensitive as the other queues

queue www priority 11 priq(red)

#other connections are assigned to the default queue queue other priority 10 priq(default)

#FILTERING RULES ASSIGNED TO QUEUES

#packets sent to port 53 (DNS) will be assigned to the dns

#queue, (note the use of keep state, instead of synproxy

#state or modulate state, as UDP packets can only be

#filtered with keep state

pass out quick on $ext_if inet proto udp \ from any to any port 53 keep state queue dns

pass out quick on $ext_if inet proto tcp \

Section 10.2: Bandwidth Shaping

201

 

 

outside world

ext_if

queue dns priority 14

queue ssh priority 13

queue mail priority 12

queue www priority 11

queue other priority 1

Figure 10.2: PRIQ-based ALTQ packet queuing setup for different external services.

from any to any port 53 synproxy state queue dns

#packets sent to port 22 (SSH), 23 (TELNET) will be assigned

#to the ssh queue

pass out quick on $ext_if inet proto tcp \

from any to any port {22, 23} synproxy state queue ssh

#packets sent to port 25 (SMTP), 109 (POP2), 110 (POP3),

#143 (IMAP), 220 (IMAP3), 995 (POP3S) will be assigned to

#the mail queue

pass out quick on $ext_if inet proto tcp \

from any to any port {25, 109, 110, 143, 220, 995} \ synproxy state queue mail

202

Chapter 10: Bandwidth Shaping and Load Balancing

 

 

#packets sent to port 80 (HTTP), 443 (HTTPS) will be assigned

#to the www queue

pass out quick on $ext_if inet proto tcp \

from any to any port {80, 443} synproxy state queue www

What if you wanted to give different priorities to connections initiated from different internal hosts?

ƒpackets sent from hosts used by administrators have the highest priority.

ƒpackets sent from hosts used by the accounts department have lower priority than packets sent from the hosts used by administrators.

ƒpackets sent from hosts used by programmers have lower priority than packets sent from the hosts used by the accounts department.

ƒpackets sent from hosts used by ordinary users have lower priority than packets sent from the hosts used by the programmers.

ƒall other connections have the lowest, default priority.

A sample ruleset based on the PRIQ scheduler giving different priorities to outbound connections from different internal hosts is shown on the next page:

#MACROS

#external interface ext_if = "ne1"

#administrators' machines admins_ad = "{a.a.a.a, a.a.a.b}"

#accounts' machines

accounts_ad = "{a.a.a.c, a.a.a.d, a.a.a.e}"

# coders' machines

coders_ad = "{a.a.a.f, a.a.a.g, a.a.a.h}"

# users' machines

users_ad = "{a.a.a.i, a.a.a.j, a.a.a.k}"

#PARENT QUEUE DEFINITION

#define a PRIQ parent queue: bandwidth 45Mb, and

#five child queues: admins, accounts, coders, users

#others (default)

altq on $ext_if priq bandwidth 45Mb \ queue{admins, accounts, coders, users, others}

Section 10.2: Bandwidth Shaping

203

 

 

#CHILD QUEUE DEFINITIONS

#admins get the higest priority queue admins priority 14 priq(red)

#the accounts department

queue accounts priority 13 priq(red)

# coders

queue coders priority 12 priq(red)

# ordinary users

queue users priority 11 priq(red)

# others

queue others priority 10 priq(default)

#FILTERING RULES ASSIGNED TO QUEUES

#admins

pass out quick on $ext_if inet proto tcp \ from $admins_ad to any synproxy queue admins

pass out quick on $ext_if inet proto udp \

from $admins_ad to any keep state queue admins

# accounts

pass out quick on $ext_if inet proto tcp \

from $accounts_ad to any synproxy state queue accounts pass out quick on $ext_if inet proto udp \

from $accounts_ad to any keep state queue accounts

# coders

pass out quick on $ext_if inet proto tcp \

from $coders_ad to any synproxy state queue coders pass out quick on $ext_if inet proto udp \

from $coders_ad to any keep state queue coders

# users

pass out quick on $ext_if inet proto tcp \

from $users_ad to any synproxy state queue users pass out quick on $ext_if inet proto udp \

from $users_ad to any keep state queue users

The above ruleset assumes that internal hosts have routable public addresses. What if you used NAT, which hides all hosts behind a single interface and sends all packets to the outside world with a source address of the Œrewall's external interface? You can still differentiate between hosts, if you deŒne which ports can be used by each host:

204

Chapter 10: Bandwidth Shaping and Load Balancing

 

 

#MACROS

#external interface ext_if = "ne1"

#administrators' machines admins_ad = "{a.a.a.a, a.a.a.b}"

#accounts' machines

accounts_ad = "{a.a.a.c, a.a.a.d, a.a.a.e}"

# coders' machines

coders_ad = "{a.a.a.f, a.a.a.g, a.a.a.h}"

# users' machines

users_ad = "{a.a.a.i, a.a.a.j, a.a.a.k}"

#PARENT QUEUE DEFINITION

#define a PRIQ parent queue: bandwidth 45Mb, and

#five child queues: admins, accounts, coders, users

#others (default)

altq on $ext_if priq bandwidth 45Mb \ queue{admins, accounts, coders, users, others}

#CHILD QUEUE DEFINITIONS

#admins get the higest priority queue admins priority 14 priq(red)

#the accounts department

queue accounts priority 13 priq(red)

# coders

queue coders priority 12 priq(red)

# ordinary users

queue users priority 11 priq(red)

# others

queue others priority 10 priq(default)

# NAT

RULES

 

# admins

 

nat on $ext_if inet proto {tcp, udp} \

 

from

a.a.a.a to any -> ($ext_if) port

1024:6888

nat on $ext_if inet proto {tcp, udp} \

 

from

a.a.a.b to any -> ($ext_if) port

6889:12753

# accounts

 

nat on $ext_if inet proto {tcp, udp} \

 

from

a.a.a.c to any -> ($ext_if) port

12754:18618

Section 10.2: Bandwidth Shaping

205

 

 

nat on $ext_if inet proto {tcp, udp} \

from a.a.a.d to any -> ($ext_if) port 18619:24483 nat on $ext_if inet proto {tcp, udp} \

from a.a.a.e to any -> ($ext_if) port 24484:30348

# coders

nat on $ext_if inet proto {tcp, udp} \

from a.a.a.f to any -> ($ext_if) port 30349:36213 nat on $ext_if inet proto {tcp, udp} \

from a.a.a.g to any -> ($ext_if) port 36214:42078 nat on $ext_if inet proto {tcp, udp} \

from a.a.a.h to any -> ($ext_if) port 42079:47943

# users

nat on $ext_if inet proto {tcp, udp} \

from a.a.a.i to any -> ($ext_if) port 47944:53808 nat on $ext_if inet proto {tcp, udp} \

from a.a.a.j to any -> ($ext_if) port 53809:59673 nat on $ext_if inet proto {tcp, udp} \

from a.a.a.k to any -> ($ext_if) port 59674:65535

#FILTERING RULES ASSIGNED TO QUEUES

#admins

pass out quick on $ext_if inet proto {tcp, udp} \ from ($ext_if) port 1024 >< 6888 to any queue admins

pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 6889 >< 12753 to any queue admins

# accounts

pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 12754 >< 18618 to any queue admins pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 18619 >< 24483 to any queue admins pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 24484 >< 30348 to any queue admins

# coders

pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 30349 >< 36213 to any queue admins pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 36214 >< 42078 to any queue admins pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 42079 >< 47943 to any queue admins

# users

206

Chapter 10: Bandwidth Shaping and Load Balancing

 

pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 47944 >< 53808

to any queue admins

pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 53809 >< 59673

to any queue admins

pass out quick on $ext_if inet proto {tcp, udp} \

from ($ext_if) port 59674 >< 65535

to any queue admins

As you can see, PRIQ rules don't allow you to deŒne how much bandwidth will be assigned to each child queue, it merely lets you control child queue priority. If you would like to have better control over bandwidth usage, use CBQ or HFSC.

10.2.5 Class-Based Queuing (CBQ)

The CBQ scheduler allows a Œner degree of control over bandwidth. You can decide not only what priority each queue has, but also how much bandwidth can be used by each queue. Queues can be arranged in several levels of child queues. On top of that, it is possible to deŒne queues that borrow bandwidth from parent queues. With these features, it becomes possible to implement policies like `accounting must have at least 1Mb of bandwidth, developers may not use more than 2Mb, and managers may not use over 1Mb, but the boss must have at least 200Kb.'

The best way to learn CBQ is to start with a simple conŒguration. Suppose you want to share the bandwidth between two network segments connected to the Œrewall, and the Œrewall is doing NAT translation:

#MACROS

#external interface ext_if = "ne1"

#DMZ interface dmz_if = "ne2"

#private interface prv_if = "ne3"

#PARENT QUEUE DEFINITION

#define a CBQ parent queue with 45Mb of the total bandwidth

#and three child queues: dmznet (hosts in the DMZ),

#prvnet (hosts in the private segment),