OpenBSD Journal

PF acquires load balancing support

Contributed by jose on from the round-robin dept.

Robert Mooney was the first to send us this note:
"OpenBSD has acquired load balancing support: you can now specify more than one destination address with a RDR statement. This is a great enhancement to PF, and a definite selling point for OpenBSD.

From the commit message:

Date: Fri, 22 Nov 2002 22:22:25 -0700 (MST)
From: Ryan Thomas McBride

Subject: CVS: src

Module name:	src
Changes by:	2002/11/22 22:22:24

Modified files:
	sbin/pfctl     : parse.y pf_print_state.c pf_print_state.h 
	                 pfctl.c pfctl_parser.c pfctl_parser.h 

Log message:
code to support loading of pf rules with multiple
redirection addresses (in nat, rdr, route-to, dup-to and 

Syntax looks like this, see pf.conf(5) for details:

nat on wi0 proto { tcp, icmp } from any to -> source-hash random

rdr on wi0 proto { tcp } from any to port 22 ->
   {, } port 22 round-robin

ok dhartmei@ henning@

This is something people have been asking for for a while, and I know this was in the works for a bit. Excellent work! Give it a whirl and test it out, help find the bugs and get things fixed.

(Comments are closed)

  1. By Petr R. () on

    1. By Anonymous Coward () on

      I second that

      Once again, the OpenBSD team succeeded in making something great even better! Keep up the good work!

  2. By netzdamon () on

    /me cums

  3. By Anonymous Coward () on

    one word: "Awesome"

  4. By Anonymous Coward () on

    How would this behave if one of the hosts being redirected to failed ? I guess a quick script to monitor hosts and modify then reload rules accordingly is pretty easy but not too neat.

    1. By Anonymous Coward () on

      just like most load balancing devices (cisco local director) and userland applications (pen) do. when one of the hosts behind the load balancer is not responding (not ack'ing packets, for example) the load balancer detects this and implements a backoff period, temporarily removing it from the pool. it periodically tries to bring it back into the pool but will take it right back out if it doesn't ack packets right away.

      of course, this adds complexity to pf, but it'd be well worth it to be able to replace standalone devices with openbsd machines that can also do firewalling. since it'd be done in the kernel, you don't have to mess with (or have the overhead of) userland programs.

      1. By Anonymous Coward () on

        Thinking further, perhaps some kind of monitoring protocol is required. A machine can be in trouble and still respond to TCP packets (e.g. RDBMS failure or Apache problems etc..)..

        1. By Anonymous Coward () on

          I think anything other than TCP responsiveness is far beyond the scope of pf.

          1. By Anonymous Coward () on

            Agreed, but some sort of interrogation protocol asking a machine "Are you ok ?"

            1. By Anonymous Coward () on

              Inventing haphazard proprietary protocols to accomplish things that are beyond the scope of the design... that usually isnt a good idea! :)

              Heres the recipe you want:

              AutoUpdate PF Bread
              220 Calories Per Serving (Not including the beer)

              (1) Ounce wget
              (2) Cups awk
              (1) TSP sed
              (1024) Bottles beer


              Add wget to mixing bowl, stir in awk and one bottle of beer until batter is thick. Bake at 350 degrees until dough rises, sprinkle SED as topping.

              Eat one piece every 2 minutes. Drink extra beer regularly.

              1. By Anonymous Coward () on

                *mmmm* you made my mouth water..! ;-)

              2. By Anonymous Coward () on

                and here I am just using wget and md5 to check for changes from a known-good response.

            2. By Anonymous Coward () on

              Sounds like VRRPD. Search the -misc archives and you'll find some
              discussion on it, I'm sure. Short story is Theo refuses to implement
              it because of patent issues.

              1. By Anonymous Coward () on

                and Theo is once again correct.

                VRRP is encumbered.

                Dont' do it the 'linux way' by just 'reinventing' someone elses work.

            3. By Dam () on

              After using commercial LB for a long time I can tell you one thing: I don't want to install a thing on my webservers.

              The best method is to check http of the server:
              1. Write a dynamic webpage on the webservers which will check the backend servers (DB servers...)
              2. At the LB check for the availability of that specific web page.

              I wait for the documentation but:
              1. It's much better to write a userland daemon to monitor the servers with support for the folowing monitoring:
              1.1 - ping
              1.2 - tcp session
              1.3 - webpage status code
              1.4 - snmp
              2. PF should add API to remove and add servers without reloading all the rules. And API to check how much connections/packets each server has.
              3. PF should give the option for priority of servers or should allow to write the same server address twice or more (like old time SNA-SLDC)

              1. By Anonymous Coward () on

                After using commercial LB for a long time I can tell you one thing: I don't want to install a thing on my webservers.
                The best method is to check http of the server: 1. Write a dynamic webpage on the webservers which will check the backend servers (DB servers...)

                writing a specfic webpage is installing something on the webserver.

  5. By Anonymous Coward () on

    This sure as hell puts to rest everyone who was complaining about openbsd dropping with ipfilter. Not only would these recent additions have been frowned upon by Darren (since they would have been significant modifications to his code), but they were most likely inspired by that uber-coder and full-time madman Daniel Hartmeier. Three cheers and a beer should I see him (or another obsd guru) at the next conference I attend.

    1. By Dries Schellekens () on

      You're wrong. This was writen by Ryan Thomas McBride. The same guy did the initial IPv6 support for PF.

    2. By Strog () on

      Are you sure he would mind this one since round-robin is already in it?

  6. By Anonymous Coward () on

    Once again, pf is kicking ipf ass!
    what do you guys think?

    1. By Anonymous Coward () on

      ipf is super lame, I would rather masterbate with a handful of rusty razorblades than use that pos packet filter.

      1. By Shane J Pearson () on

        I would rather masterbate with a handful of rusty razorblades than use that pos packet filter.

        Hey, you used my favorite line! Does this mean I've "made it"? ; )

        Anyway, pf just never ceases to amaze me.

        Excellent performance, bandwidth throttling, load balancing, so is failover next...?

        How can it get better?

    2. By Strog () on

      I love OpenBSD and have been using on my firewall at home since 3.0. I've been playing with it since 2.5. I had considered going with NetBSD and IPF on my firewall because it already supported round-robin and I wanted to mess with it. I found enough other reasons to go with OBSD and pf to satisfy me (like wireless access point support, etc.).

      OpenBSD and pf are making leaps and bounds but that doesn't mean everything else is crap. The reason ipf was pulled wasn't because of it being a bad product. In fact it was highly regarded in OpenBSD circles for performance/security/stability reasons with OpenBSD patches applied. There was a change in the license (real or percieved, you be the judge) and the OpenBSD project was told that they can't modify it anymore without permission.

      We all know Theo won't be told what he can or can't do so he commissioned pf to be created. pf has some some differences from ipf but is largely inspire by it. pf beats ipf in many areas while ipf still holds some areas (for how long?). ipf still has a little less overhead but that shouldn't matter as long as you provision a little overhead in your packet filtering box. I think as pf matures that it will prove itself to be a superior product in all areas.

      I'm currently running a post-3.1 snapshot on the firewall and need to check out the load balancing on current. I keep an extra hard drive in there for just such ocassions

  7. By Anonymous Coward () on

    Watch the f**k out, pretty soon pf is gonna be controlling access in and out of your house, making sure the dog has plenty of food, and fairly distributing the toys among the children.

    1. By synfault () on

      That's ok with me, and judging from earlier comments with statements like "/me cums", it also takes care of a man's physical needs... So, pf is short for "perfekter frau" in my book. Now I'm gonna make a silly script that checks if pf is running, and beats it back to life if it isn't. Think I'll call it "bitchslap".

  8. By A non e-mouse cow herd. () on

    Not to diminish this improvement which is super keen. However, I'm guessing that pf still lacks failover, which is perhaps an even more useful feature for high availability scenarios. Could one presumably do a rdr hack to have a single pf machine load balance to multiple pf machines behind it? Thereby simulating failover so long as the main pf machine doesn't croak - still a single point of failure, so no real gains there. (behold! Shitty ascii!) /*pf / pflb (rdr)*----*pf *pf Bleh, not so nice - and then aggregating the loadbalanced fw's will be kinda nightmarish too. Awesome work again - but any word on a failover methodology that won't stomp on people's patents (or maybe even would as an option?).

    1. By Dries Schellekens () on

      Daniel's interview on kerneltrap explains it all, especially questions

      What patent issues are obstructing the work towards redundancy and fail-over?
      Are you currently looking into alternative methods for providing redundancy and automatic failover?

      And the comment VRRP patent issues by Daniel.

    2. By sap ( on

      Check out carp for failover:

  9. By Matt Van Mater () on

    I was asking Daniel only last week about getting some sort of name based port forwarding built into pf. For various reasons he described why it would be a bad idea (essentially shooting my ass down) but he was always quick to reply with well thought out explanations. While this isn't the same thing I was asking for, its in the same neighborhood and is overall pretty kickass.

    BTW: if anyone is interested in name based port forwarding, check out a project on sourceforge called portfwd, which can do this for a few protocols. Daniel suggested using squid in reverse proxy mode, but i thought this project might be easier to configure, haven't tried it out yet.

  10. By Anonymous Coward () on

    I have to admit I have a hard time trying out OpenBSD because every time I think "ah, I'll wait for the next release, it has this cool new feature!" :-)

      1. By click46 () on

        you're crazy. -current is no way to introduce someone to OpenBSD. Especially since most dont have a strong *nix background.

        1. By zil0g () on

          haha, you're funny operamail-guy

  11. By Anonymous Coward () on

    I'm in a situation where I'd like to use a transparent (ipless) bridging firewall but with my ISP, my IP's change about once a week from DHCP.

    Anyone know if there's a way on an ipless, bridging firewall with pf to detect the ip address changes on a host in the DMZ with say arp or reverse-arp and auto change the ip address in the bridges pf.conf?

    1. By Anonymous Coward () on

      I might be totally off base here, but I thought that there had been some somewhat recent changes to pf to allow for rule creation based more off of interfaces in almost all cases now, rather than IP's thus pppoe or dhcp connections can be utilized more effectively. Check manpages & changelogs for further information I suppose.

      1. By Anonymous Coward () on

        You can do that on say a NAT Router/Firewall. So long as the device has an 'ip address'... ;)

        In this case, this is a transparent bridging firewall (ip-less box).

    2. By zil0g () on

      since a while back you can use (if) to get the address of the interface, see the manpages if you haven't already, so does it really have to bridge?
      seems easier to just give it the dhcp interface and let pf do the job...

      1. By Anonymous Coward () on

        You can do that on say a NAT Router/Firewall. So long as the device has an 'ip address'... ;)

        In this case, this is a transparent bridging firewall (ip-less box).

      2. By Anonymous Coward () on

        Yeah, unfortunatly one box is Windows that can't be NAT'd, eveb binat. So that's protected by the bridge. Just the same, behind the bridge I'm also protecting the NAT router (OpenBSD of course) which I consider to be on the DMZ. Now of course, if the ip's change of either the NAT Router of Windows box from DHCP (seeing I don't have static on this DSL package) then it's a pain in the arse to have to change every day. I can live without it, but would be very nice!

        1. By Anonymous Coward () on

          You could add a local IP address (rfc1918, link-local, etc) to the bridge and the NAT box. Drop traffic to that address from the outside.

          Have the NAT box notify the bridge of any change to address via a hook in dhclient-script (and ssh or similar).

          Windows will be a bit messy, but you could schedule a script to run every few minutes to check for changes to 'ipconfig' output and notify... it would have to route through the NAT box to reach the bridge, since Windows (at least Win2k) won't let you have an IP alias on a dhcp interface.

          Not tested by me, but I don't immediately see a reason for it to not work (unless you really really don't want an IP address on the bridge or go by some other route, maybe rs232).

  12. By kremlyn () on

    Once again, the OpenBSD project astounds all. You guys rock, all of you.

    Now, to the point..

    A friend of mine and I were discussing last night implementing a perl script that can detect whether or not an uplink (on a firewall with multiple uplinks) has gone down and then load a new ruleset defining use of the next-preferenced uplink (after having changed the default route on the box).

    We're thinking of having an /etc/uplink.interfaces which lists each available interface, as well as it's preference (in relation to other uplinks), and the external IP to ping to for connectivity checks.

    The major problem we ran in to, was that ping doesn't support pinging from an interface - only from an IP with the `ping -I` command. We decided extracting the IP from ifconfig was the only way.

    Then, when one link stops responding to pings generated by the script, the interface of next preference is selected and set as the default route, and pfctl is called, loading the new pf ruleset (which has presumably been pre-defined with $ext_if). One of these rulests should be built for each failover interface, and live in /etc/uplink.$interface (note that here $interface is a variable whereas above it wasn't).

    We're confident we could get it to work as a perl script, but how about integration with pf?


    1. By Anonymous Coward () on

      (which has presumably been pre-defined with $ext_if). One of these rulests should be built for each failover interface, and live in /etc/uplink.$interface (note that here $interface is a variable whereas above it wasn't)

      since the functionality doesn't change when the interface changes (e.g. still need ports 22,80 open, rest closed, but on new interface), why not have one file with your rulesets and another with your definitions. when calling pfctl, use:
      cat definitions.$if rulesets | pfctl -f -

      that way when modifying rules only one file needs editing. You'll also want to modify pfctl -f ${pf_rules} in /etc/rc.

  13. By Anonymous Coward () on

    The "load balancing support" in pf looks like it will be a dog for handling dead-node detection. I can't see any code in there that makes it easy to do round-robin and be able to delete a node from a set in a redirect rule.

    It needs an external application to do this for it but that'll have to remove and add back a different rule. Sounds incredibly inefficient already.

    1. By Anonymous Coward () on

      So you want monitor (that probes http, ftp, ... whatever) in kernel. You're stupid. You should really do this in userland.

      For the same reason ftp-proxy works in userland, instead as in kernel like IPFilter did.

      Think about it. It all makes sense.

    2. By Dries Schellekens () on

      The DIOCCHANGEADDR ioctl will allow you to insert addresses into a pool and remove an address from
      a pool, without modifying the rule itself.

      Now you just have to write a daemon to (HTTP, FTP, ICMP, TCP, ...) pings the machines and adds or removes addresses in the pool.

    3. By Daniel Hartmeier () on

      You missed DIOCCHANGEADDR in pf_ioctl.c. Once it works and is documented, that will allow to manuipulate an address pool with a single ioctl call.

    4. By Anonymous Coward () on

      uhm. how often per second do you expect one of the nodes to go down and reappear? ;-)
      I just think "ineffeciency" doesn't matter if it is some script called once every few minutes if at all.


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 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.]