BSD DevCenter
oreilly.comSafari Books Online.Conferences.


Network Filtering by Operating System
Pages: 1, 2, 3

The altq line then specifies the type of scheduler to use to queue packets. The example uses cbq. The schedulers decide which order the queues are processed in. Class Based Queuing (CBQ) splits the available network bandwidth between two or more queues, where each queue has packets assigned to it by source or destination addresses, port or other identifiable factor (in this case, operating system). Queues can also have a priority to deal with some packets before others. The OpenBSD Packet Queuing page has more detail on the different types of schedulers.

The end of this line specifies which queues to limit.

The next two lines define the queues themselves that altq will handle. The format is quite understandable and explicitly states how much bandwidth is available to each queue. You can specify this either as a percentage or a fixed amount. If you think of your internet connection as a road, a queue defines how many lanes different packets can travel on. The more lanes they can use, the more data gets transferred. This configuration then repeats for the incoming bandwidth.

The rdr line is the key to the filtering objective. It specifies that all TCP traffic (proto tcp) from the internal network ($internet_net) that comes from a Windows system and is going to any other address on port 80 (os "Windows" to any port www), should redirect to the proxy server on port 3128 ( -> $proxy_server port 3128).

The nat line sets up network address translation, which lets the internal network communicate with the internet.

Notice that each line of the pf rules also ends in either windows_in, windows_out, trusted_in, or trusted_out. These are the four queues set up previously as part of the altq rules; this lets pf know which queues pf and altq should use when processing the packets. These queues are entirely optional. Leaving them out of the pf rules would prevent altq from limiting the bandwidth of any packets matching those rules.

The simplest format of the pf rules is:

<pass|block> <in|out> on <interface> from <src> to <dst>
    [keep state] [queue <queue_name>]

In addition, you can also give port numbers and protocols.

This rule set includes a special rule for unknown OS traffic. Patches to operating systems and IP stacks can change the fingerprint of packets. Filtering all unrecognized traffic through the Windows queue helps avoid future problems.

The last two rules control inbound traffic. Because it is not possible to know whether the destination system is Windows, pf cannot filter the incoming traffic based on an operating system not already using the proxy. In practice, this does not pose a serious problem, as all of the web traffic from these systems is already traveling across the bandwidth-restricted proxy. If the Windows systems run peer-to-peer software such as BitTorrent, that traffic will not go through the proxy. In this case, queue such traffic by giving the port numbers used, as follows:

bittorrent_ports = "6881:6999"
pass out quick on $int_if proto { tcp, udp } from any to any \
  port $bittorrent_ports queue windows_in

Further Reading

Squid configuration guide

squidGuard home page

pf manual

Avleen Vig is a Systems Administrator at Google.

Return to the BSD DevCenter.

Sponsored by: