Hi. I'm a long-time Linux and OpenBSD user. Used Linux for my router/firewall for a long time, then switched to OpenBSD 2.6 with IPF. I moved up to OpenBSD 3.4 with PF and ALTQ when it was new, and am still running it.

  My firewall/router works great, but successful traffic shaping has eluded me 
for some time.

I bought Jacek Artymiak's book to try to get a grasp on it, and have read FAQs, examples and man pages until I'm blue in the face.


Setup:

I have a Cisco 678 DSL modem with 1.5Mb down and 672K up with one static IP. It NATs and forwards all traffic on to the OBSD box right behind it. That machine has four interfaces, WAN (to the Cisco), LAN (to my local net, workstations, mail/SSH/DNS server), DMZ (to my Web/FTP server) and VOIP (to my VOIP phones).

I've tried to implement traffic shaping with queues (using priq for now until I get it working, then maybe move up to CBQ). However, everytime I think I get it figured out, I realize I'm overlooking something.

I understand that queues are only effective for throttling traffic going outbound on an interface, for obvious reasons. But, by throttling the traffic leaving the router towards my inside machines, I effectively throttle the ACKs going back out, and therefore the new traffic coming in.

  This makes sense. There's some things I can't seem to get a grip on:

I need an outbound queue that is limited to my upstream bandwidth (672K). Outgoing traffic needs to be put into the prioritized queues here. I've been told that queuing only works on pass out rules, but that doesn't make any sense. Sometimes the only place to identify which outbound queue the traffic needs to go into is at the pass in rule on the inbound interface. For example, my VOIP gear is all on a subnet and interface of its own. I want it to end up in the high-priority queue on the outbound interface. So, I need to do something like

pass in quick on $phone_if keep state queue(up_phone)

Is that right though? The up_phone queue is on the $ext_if, and the pass in rule is referring to the $phone_if. It looks to me (from the traffic counters in pfctl -vvsq) that no traffic is ending up in the outbound up_phone queue, so it must not be right. There are lots of examples that show queue assignment on a pass in rule. I assumed that if I marked it for a given queue, that when it ended up going out on the interface that had that queue that it would end up in that queue.

I also need an inbound queue to limit my downstream speed so we don't choke out. Most examples assume you have one $ext_if and one $int_if, and they create the outbound queue on $ext_if and the inbound queue on $int_if and all is happy.

But I have three internal interfaces, WAN, DMZ and VOIP. I don't want to create a 1.5Mb queue on each, because together they _share_ 1.5Mb of bandwidth coming from the DSL line. Where do I create this queue?

Thirdly, if I create a 1.5Mb queue on the inbound interfaces to keep by DSL line from getting swamped, it's going to throttle all traffic exiting the internal interface, right? So, if I try to copy a large file from my LAN to the DMZ webserver, I'm gonna be choked down to some fraction of 1.5Mbps when it's a wide-open 100Mbps link.

As I understand, if I do queuing on an interface, one of the queues on that interface is always the default and traffic not explicitly assigned to a queue goes into the default.

  Finally, I'm not clear on how NAT works with ALTQ. Jacek's book says (p218):

What you can do, is add ALTQ queues and pass out rules for interfaces connection the firewall host to the internal network segments. However, these limits will only work for connections initiated by external hosts.
Connections initiated by inside hosts and NAT-ed will not match those pass out rules, because they will be passed without checking thanks to the state mechanism invoked by the NAT rules (nat, binat, or rdr). This is why some users will be able to use all of
the available bandwidth even if you set hard limits, these limits apply to outbound packets, not inbound ones. The solution is to put a router before the firewall ... and implement ALTQ/filtering rules on the interface connecting
.. to the firewall.

So, despite all of my clever traffic shaping, if I fire up a web browser on a machine on the LAN and start a big HTTP download (NATed through the firewall) it'll just go ahead and eat all of my bandwidth anyway? And the only solution is to add a second router?





  I'm guessing I just have an inaccurate picture of how this is all supposed to 
work.

I'd be happy to post my pf.conf, but I know it's completely bogus as far as traffic control goes, so I'm not sure how much good it would be until I make some major changes. Also, I'm not sure what sanitizing it might need.


My goal is to make sure that my real-time and interactive services (VOIP, SSH) take priority over my bulk data (web, mail, FTP, etc). Doesn't seem like it ought to be as hard as I'm making it...



Thanks in advance for any advice. I'd be happy to post my finished pf.conf as an example for others, once it works, because I haven't ever found a good example of what I'm trying to do.



-- Chris 'Xenon' Hanson | Xenon @ 3D Nature | http://www.3DNature.com/ "I set the wheels in motion, turn up all the machines, activate the programs, and run behind the scenes. I set the clouds in motion, turn up light and sound, activate the window, and watch the world go 'round." -Prime Mover, Rush.

Reply via email to