Network Filtering by Operating Systemby Avleen Vig
You manage a heterogeneous network and want to provide different Quality of Service agreements and network restrictions based on the client operating system. With pf and altq, you can now limit the amount of bandwidth available to users of different operating systems, or force outbound web traffic through a transparent filtering proxy. This article describes how to install pf, altq, and Squid on your FreeBSD router and web proxy to achieve these goals.
In an ideal environment, there would be no need for bandwidth shaping, OS fingerprint-based filtering, or even Quality of Service (QoS). Several factors in the real world require a change of game plan. Bandwidth is not free, and many ISPs charge customers based on bandwidth usage. Worms, viruses, and compromised systems can all lead to higher bandwidth costs. In the wake of the W32.Slammer worm, which saturated the connections of infected networks, many companies saw their monthly connectivity bills skyrocket due to the worm's traffic.
Filtering your connections based on operating system can go partway to helping keep such situations from running away. While I will focus on filtering traffic from Windows systems, this process can equally apply to BSD, Linux, Mac OS, or a host of other operating systems listed in the pf.os file on your system. This may be especially useful to people running older versions of OSes that have not or cannot be patched but still require some network connectivity.
As an extension of transparent filtering, content filtering is also possible, with tools such as squidGuard allowing children and corporate desktops alike to browse in relative safety.
Tools of the Trade
During my research for this article, several people asked me why I chose to use BSD, pf, altq, and Squid for this task. Other tools come close to providing the required functionality, but none offers to fill the requirements as readily as these. Linux and iptables can work with Squid to provide a transparent proxy but cannot filter connections by operating system. Though other proxy servers exist, Squid is one of the best available today.
It is important to note that OS fingerprinting works only on TCP SYN packets, which initiate TCP sessions, and not on currently established connections or UDP sessions. While this will not be a problem for most systems and network administrators, you may want to pay more attention to your UDP filtering rules.
Installing pf and altq
pf and altq provide packet filtering and bandwidth shaping, respectively. Their relationship is not unlike that between
DUMMYNET, where the same rules file configures both pf and altq.
While pf is universally usable, altq requires a supported network card. The good news is that most network cards in common use are supported. Look at the Supported Devices section of
man 4 altq to find a list of supported network cards.
Once you've confirmed you have a supported device, add pf and altq to your kernel. You will need to recompile your kernel as described in the FreeBSD Handbook. First, add a few options to the end of your kernel configuration file:
device pf options ALTQ options ALTQ_CBQ options ALTQ_RED options ALTQ_RIO options ALTQ_HFSC options ALTQ_CDNR options ALTQ_PRIQ
Note: If you are installing altq on a multiprocessor system, add
options ALTQ_NOPPC to your configuration before you recompile your kernel.
After you have recompiled your kernel and rebooted, test pf to make sure it installed correctly with the command
pfctl -s rules. If you see the error
pfctl: /dev/pf: No such file or directory, pf did not install correctly. If you see the error
No ALTQ support in kernel ALTQ related functions disabled, pf is working but altq is not. In the latter case, you will still be able to force users through a transparent proxy, but you won't be able to limit bandwidth using altq.
Installing Squid with Transparent Filtering Support
Install Squid with the command:
% cd /usr/ports/www/squid && make config install clean
This will present you with a list of options for compiling Squid. To enable transparent proxy support, select
SQUID_PF. You can also select or deselect any other option. I often find
SQUID_SNMP useful for gathering and graphing statistics using RRDTool. Once Squid is installed, edit /usr/local/etc/squid/squid.conf. Set at least the options:
http_port YOUR_PROXY_IP:3128 http_access deny to_localhost acl our_networks src YOUR_NETWORK/24 http_access allow our_networks visible_hostname YOUR_HOSTNAME httpd_accel_host virtual httpd_accel_port 80 httpd_accel_with_proxy on httpd_accel_uses_host_header on
Replace YOUR_PROXY_IP with the IP address your proxy server will listen on,
YOUR_NETWORK/24 with your internal network address range (for example, 192.168.0.0/24), and YOUR_HOSTNAME with the hostname you want to show to users in error messages. YOUR_HOSTNAME is not required but extremely useful if you have a cluster of proxy servers sharing a common front end such as a load balancer.
While you can get by with changing only these options, you should spend some time going through the remainder of your squid.conf file and tuning it to your needs. Over time, you may need to tune various other options such as cache sizes or connection timeouts. The Squid configuration file is a behemoth; spending an hour now getting familiar with various options may save you time and trouble in the future.