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
Avleen Vig is a Systems Administrator at Google.
Return to the BSD DevCenter.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 3 of 3.
-
PFCTL will fail.
2006-04-18 22:13:18 UrbanRiot [Reply | View]
The suggested pf.conf won't work as pf requires a default ALTQ queue to be set, which is why mkosinski is having problems.
-
errors in altq config
2006-03-16 05:59:39 mkosinski [Reply | View]
# pfctl -nf /etc/pf.conf.os
pfctl: should have one default queue on sis0
pfctl: should have one default queue on sis1
pfctl: errors in altq config
-
error on setting up PF with SQUID (transparent proxy)
2006-02-24 07:37:10 rezmuh [Reply | View]
I'm fairly new to FreeBSD, but I've been using OpenBSD for a while. I was trying to setup SQUID to do transparent proxy with PF in FreeBSD but it wouldn't work. The setup was rather similar to what I'm using in OpenBSD (similar squid.conf and pf.conf). It seems that when clients are trying to browse, it's not redirected to PF, instead it will browse directly. Here's what I did with my setup:
Installing Squid with PF transparent proxy:
------------------------------------
# cd /usr/ports/www/squid/
# make WITH_SQUID=PF=YES install
squid.conf:
----------
http_port 127.0.0.1:3128
cache_mem 20 MB
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours
auth_param basic casesensitive off
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern . 0 20% 4320
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443 563
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 563 # https, snews
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_reply_access allow all
icp_access allow all
coredump_dir /var/squid/cache
http_access deny to_localhost
acl our_networks src 192.168.0.0/24
http_access allow our_networks
http_access deny all
visible_hostname blowfish
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
pf.conf:
-------
ext_if="rl0"
int_if="rl1"
internal="192.168.0.0/24"
# queue
altq on $ext_if priq bandwidth 1000Kb queue { q_pri, q_def }
queue q_pri priority 7
queue q_def priority 1 priq(default)
set skip on lo
# nat
nat on $ext_if from $internal -> ($ext_if:0)
rdr on $int_if inet proto tcp from any to any port www -> 127.0.0.1 port 3128
antispoof quick for { lo $int_if }
pass in on $int_if inet proto tcp from any to 127.0.0.1 port 3128 keep state
pass out on $ext_if inet proto tcp from any to any port www keep state
pass out on $ext_if proto tcp from $ext_if to any flags S/SA \
keep state queue (q_def, q_pri)
pass in on $ext_if proto tcp from any to $ext_if flags S/SA \
keep state queue (q_def, q_pri)
#pass in on $ext_if proto tcp to ($ext_if) port > 49151 user proxy keep state
Can anyone point me out on what I did wrong? I assume I didn't install Squid the right way (support for PF is not enabled?) Because other PF rules works OK, and also, if I run squid not in transparent mode (user has to explicitly enter the proxy server's address), it also works fine.
Btw, the machine is running FreeBSD 5.4-RELEASE-p11.


