pf sanity check

So I think I got my OpenBSD firewall woes worked out, but I could use a sanity check... What I have seems to be working, but I'd like some confirmation that my assumptions are true.

<LJ-CUT text=" Read on if you understand this crap. --More--( 6%) ">


  • OpenBSD 3.5 firewall PC with multiple interfaces;
  • Multiple 100baseT internal networks;
  • One uplink network to the T1.


  • Don't let any attempted bandwidth-hogging activity between any internal network and the T1 affect the stability of the webcast uplinks;
  • Beyond that, pretty much first-come first-serve.

How I did this (which may or may not be the only way):

  • From reading the documentation, I had been under the impression that if we did "pass in" with "keep state" to allow some packet to enter the firewall, then that packet could also automatically exit the firewall (pass through it on its way to the destination.)

    Everything I've read made it sound like once you did "keep state" to establish a state table entry, the state table took precedence over any rules: when there's a state table match, the rules aren't consulted at all.

    This doesn't seem to be the case. It seems that two rules must fire for each session: one to allow the first packet to enter the firewall on one interface (and establish a state table entry); and then a second rule to allow that same packet to exit the firewall on a different interface (and establish a second state table entry.) After that, subsequent packets are processed by the state table, and rules are never consulted for the rest of the session. But that first packet needs two rules.

    So, to ever make anything work, there needs to be a default "pass out" rule (either that, or two rules for every "session", which would be just ridiculously verbose.)

  • Secondly, it would seem that it is the "pass out" rules that must assign packets to queues. This is because my queues are intended to throttle packets that are going from the internal networks up the T1; this means they must be defined on the T1's network interface.

    So the way to accomplish this is, the "pass in" rules (wherein the knowledge of what connections we allow and what they are for is encoded) tag the packets with the name of the queue they are destined for. Then, the following "pass out" rules assign the packets to queues based on how they were tagged on the way in.

    This seems needlessly complicated to me: I don't understand why I can't assign the packets to the queues on the inbound packets (and have that be automatically carried over when the packets are outbound) but that seems to be how it works. (Right?)


    • mp3_queue -- Icecast uplink. Needs 128Kbps+.
    • real_queue -- RealProducer/RealVideo uplink. Needs 650Kbps+.
    • std_queue -- The default queue. Mostly this will be packets originating on office and DMZ hosts.
    • guest_queue -- All packets originating on kiosk and wireless networks. These are lowest priority.

    All queues have a minimum bandwidth guarenteed to them, and all are allowed to use more bandwidth if it is available/unused. Aside from that, they all have the same "priority", meaning that within their bandwidth limits, all packets are handled first-come-first-serve.

      altq on $ext_if cbq bandwidth 1.4Mb \
      queue { mp3_queue, real_queue, guest_queue, std_queue }
      queue mp3_queue bandwidth 160Kb cbq (borrow)
      queue real_queue bandwidth 700Kb cbq (borrow)
      queue std_queue bandwidth 200Kb cbq (borrow default)
      queue guest_queue bandwidth 200Kb cbq (borrow)


      block in log all # default deny

      pass out all keep state # goes to std_queue by default
      pass out on $ext_if tagged mp3_queue queue mp3_queue keep state
      pass out on $ext_if tagged real_queue queue real_queue keep state
      pass out on $ext_if tagged std_queue queue std_queue keep state
      pass out on $ext_if tagged guest_queue queue guest_queue keep state


      # icecast/mp3 uplink (tcp incoming)
      pass in proto tcp \
      from $external_icecast \
      to $internal_icecast port = 8000 \
      flags S/SA keep state \
      tag mp3_queue

      # realvideo uplink (tcp outgoing; udp both ways)
      pass in proto tcp \
      from $internal_real \
      to $external_real port { 554, 4040 } \
      flags S/SA keep state \
      tag real_queue

      pass in proto udp \
      from { $internal_real, $external_real } \
      to { $internal_real, $external_real } \
      keep state \
      tag real_queue


    Does that all make sense? Or could it be simplified?

Tags: , , , , ,
Current Music: Screamin

John Stewart on Crossfire

This is hilarious -- a transcript of John Stewart on Crossfire, and not once did he refer to Robert Novak as a Douchebag of Liberty!
    STEWART:     In many ways, it's funny. And I made a special effort to come on the show today, because I have privately, amongst my friends and also in occasional newspapers and television shows, mentioned this show as being bad.
    BEGALA:     We have noticed.
    STEWART:     And I wanted to -- I felt that that wasn't fair and I should come here and tell you that I don't -- it's not so much that it's bad, as it's hurting America.
    CARLSON:     But in its defense...
    STEWART:     So I wanted to come here today and say... Here's just what I wanted to tell you guys.
    CARLSON:     Yes.
    STEWART:     Stop.
    Stop, stop, stop, stop hurting America.
    STEWART:     No, no, no, you're not too rough on them. You're part of their strategies. You are partisan, what do you call it, hacks.

Schoolhouse Rock!

This is pretty great: Pirates and Emperors

Tags: , ,