OpenBSD Journal

A brief introduction to altq

Contributed by deanna on from the straw-or-pipe dept.

Chris Kuethe (ckuethe@) writes:
It's been a good week for my home net - finally got around to dropping a gig card into my workstation and replacing my central switch with something gigabit-capable. Unfortunately that means I can now oversaturate my cable modem faster than ever before. Pf and altq to the rescue. I found I had two main requirements - traffic prioritization, and rate limiting. Or to put it another way: how do I make my bittorrent go fast, get my share ratio up, keep the finalgear.com forums responsive, and prevent the di.fm streams from losing bits?
First up is the workstation which generates most of the outbound traffic. This configuration doesn't do any filtering - it only assigns traffic to queues. I trust myself to keep my openbsd workstation from beating up on my openbsd laptop and vice versa. Note that I am using "flags any" - this allows pf to pick up a state in the middle of a connection. I do that so I can flush states and force all connections to be requeued.

Be careful when using "flags any" - I can get away with doing that here because I'm passing everything anyway, I'm using pass rules to assign flows to queues, and I have a front end box doing full scrubbing and filtering with "flags S/SA".

INT="re0"

#SLOW hosts will be throttled.
table <SLOW> persist { $INT }
#FAST does not get throttled. put friendly or important nets here.
table <FAST> persist { $INT:network }

# 300Kb is probably good if you have 500Kb up
UP="300Kb"

# re0 is a gigabit adapter, so even 1% blows the chips off the cable modem
# Since both the fast and zoom queues can borrow, they are effectively not
# rate-limited, but having one queue with slightly higher priority makes
# ACK prioritization possible.
altq on $INT cbq tbrsize 1500 queue {slow, fast, zoom}
queue slow bandwidth $UP priority 1 cbq(red default)
queue fast bandwidth 40% priority 5 cbq(borrow)
queue zoom bandwidth 59% priority 6 cbq(borrow)

# inbound connections (and their replies) will default to the slow queue
pass on $INT all flags any queue slow

# on-net traffic is uncapped.
pass quick on $INT inet from <FAST> to <FAST> \
flags any queue (fast, zoom)

# Useful protocols go first. SSH, mail, dns, time and web
# take priority over random unspecified drivel
FAST="{22,25,53,123,80,443}"
pass log quick on $INT inet proto {tcp udp} from port $FAST \
flags any queue (fast, zoom)
pass log quick on $INT inet proto {tcp udp} to port $FAST \
flags any queue (fast, zoom)
pass log quick on $INT inet proto icmp queue fast

# This rule will tag everything as fast, with TCP ACKs and IPTOS_LOWDELAY
# getting high priority. See /usr/share/pf/ackpri.
pass log on $INT inet flags any queue (fast, zoom)

# And if $INT's ip is in SLOW, then all traffic will be throttled.
pass log on $INT from <SLOW> flags any queue slow
pass log on $INT to <SLOW> flags any queue slow

Now it becomes an easy thing to control the network speed just by dropping a ip address of this machine into the SLOW table. Or removing it from the table. These can be done easily by a cron job, which is what I do; during times when I'd want the net to be responsive to interactive traffic, I have my server throttle itself, and during times when I'm unlikely to want to use the net, I let it uncap itself. I'm sure the simple rate limiting could be rolled into my main firewall's altq configuration, but I wanted a machine that I could use to experiment with various control strategies without having to munge my main ruleset, which we shall now examine.

INT="sis2"
EXT="sis0"
# 600Kb is probably a good rate if you have 640Kb up
UP="600Kb"
DN="5Mb"

# set up priority queuing. The two lowest classes are using the Random Early
# Detect (or Drop) to start dropping packets as the queue length increases.
# For general web-wanking and unclassified connections, some packet loss is
# acceptable. For the more interactive and time-sensitive protocols loss is
# unacceptable.
altq on $EXT priq bandwidth $UP queue {ultra, fast, norm, slow}
queue slow priority 1 priq(default, red)
queue norm priority 4 priq(red)
queue fast priority 5
queue ultra priority 6

# There is much wailing and gnashing of teeth if ssh, dns or ntp are laggy.
ULTRA="{22, 53, 123}"
# FTP, telnet, and various chat/instant messenger protocols
FAST="{21, 23, 706, 1863, 5050, 5190, 5222, 6667}"
# Bulk transfers that won't mind waiting for more interactive protocols
NORM="{25, 80, 443, 8080, 2401}"
# Everything not listed above gets the lowest priority
INBOUND="{3072, 4096, 5120}"

# Block everything unless otherwise allowed, and queue any state that
# packet might flow into the slow class unless otherwise requeued.
block in on $EXT queue slow

#allow in some basic services
pass in on $EXT inet proto icmp icmp-type echoreq queue ultra
pass in on $EXT inet proto tcp to port {22, 443} synproxy state queue ultra
pass in on $EXT inet proto tcp to port {25, 80} synproxy state queue norm

pass in on $EXT proto {tcp udp} to port $INBOUND queue slow

# queue packets so they go faster
# "ULTRA" always goes first
pass out quick on $EXT inet proto icmp queue ultra
pass out quick on $EXT proto {tcp udp} to port $ULTRA queue ultra

# Each of the other queues is allowed to knock it up a notch if it's
# sending acks or uses the IPTOS_LOWDELAY TOS selector.
pass out quick on $EXT proto {tcp udp} to port $FAST queue (fast, ultra)
pass out quick on $EXT proto {tcp udp} to port $NORM queue (norm, fast)
pass out quick on $EXT queue (slow, norm)

Antispoofing and NAT are not discussed here. I've deleted a bunch of other stuff, such as anchors for ftp-proxy, authpf and spamd; they are not relevant to this discussion.

In this ruleset I am allowing in two ports at elevated priority, two ports at an intermediate priority, and a few others at reduced priority. You may need to experiment to determine your optimal upload bandwidth.

Thanks to everyone who contributed to the pf.conf(5) manpage and the examples in /usr/share/pf. While I did snoop at a few other people's pf configurations, everything I needed was in the pf.conf manpage.

(Comments are closed)


Comments
  1. By Jason L. Wright (65.101.74.153) jason@openbsd.org on http://www.thought.net/jason

    Dude, you're only -now- able to super-saturate your cable modem? At one point I had FDDI and gigabit ethernet in the apartment and a 28.8k dialup.

  2. By Anonymous Coward (69.70.207.240) on

    Nice write-up, thank you! It makes me want to start studying AltQ after my school studies...

    What I'm curious though is how a Gb NIC would affect cable modem speed; in other words, a 10/100/1000 NIC vs a 10/100 NIC - how would this make a difference? And over-saturating the link? Is this the same as prioritizing ACK's such as: http://www.benzedrine.cx/ackpri.html ?

    Thanks in advance!

    Comments
    1. By Joachim Schipper (82.134.241.64) on

      > Nice write-up, thank you! It makes me want to start studying AltQ after my
      > school studies...
      >
      > What I'm curious though is how a Gb NIC would affect cable modem speed; in
      > other words, a 10/100/1000 NIC vs a 10/100 NIC - how would this make a
      > difference? And over-saturating the link? Is this the same as prioritizing
      > ACK's such as: http://www.benzedrine.cx/ackpri.html ?

      I'm no expert, but I don't think a gigabit NIC is going to help much with usual
      cable speeds (as in, a couple of Mbps). It would be quite useful for inter-host
      communication, though.

      Prioritizing ACKs is a different matter altogether, although it's also a
      typical application of altq.

      Joachim

    2. By Chris Kuethe (68.148.116.122) ckuethe@ on

      The gig card/switch makes it easy to run backups of my laptop, and move DVD images from the my mac to the workstation with the dvd burner. That's the point of the gig card.

      Of course that just means it takes even less time to shove more traffic than my cable modem can handle. "Oversaturating" was a bit of hyperbole. Like Jason running FDDI behind a 28k8 modem, upgrading from fast ethernet to gigabit behind a 512k cable modem doesn't make the interspam flow any faster...

      The prioritized ACKs are handled by the second ruleset. Two queues are sufficient to accomplish that. I used more queues so that some types of traffic (as differentiated by port) are prioritized over others, but each class gets the benefits of the prioritized ACKs.

  3. By Anonymous Coward (60.51.114.69) on

    I read about above article and it's very nice but still want to hear any idea how to block Ares (http://www.aresgalaxy.org/) using OpenBSD as a firewall/router? I don't mind if I need to install any 3rd party applications to be able to do it.

    -anonymous coward-

Latest Articles

Credits

Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original deadly.org with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]