(Warning: this post is pretty geeky… not my usual entrepreneurial/life/business thoughts.)

I love Vagrant for quickly mocking up dev environments while building a website. At Van Patten Media, we have a custom internal Vagrant box we use that mirrors our server environment pretty darn closely, giving us the ability to fairly accurately understand how a website will perform in the live environment.

There’s one challenge: I sometimes have a dozen or so virtual machines kicking around, and might even have three or four actually running at one time. Our Vagrant setup maps each VM to two dedicated HTTP and SSH ports, 15XXX and 22XXX (15021 and 22021, for instance). For SSH, that works fine (and vagrant ssh handles it ports automatically anyway) but it’d be nice if our URLs didn’t have to look like and could look like instead; in other words, if each VM could be mapped to port 80, without triggering a collison.

In Mac OS X, that was easily accomplished with the ipfw utility, but as of OS X Mavericks ipfw has been fully deprecated and replaced with pf.

Here’s how to use pf and pfctl to make that happen.

Remapping/redirecting/forwarding ports with pfctl on Mavericks


The first step is creating the files you’ll need. The first file is your rules file. This is the file that actually contains your port redirection rules.

Here’s what mine looks like:

Don’t see the file? Click through to see it.

There’s a lot of stuff there you don’t need to understand, but pay attention to the last bit. All we’re doing is redirecting any request to port 80 on this computer (localhost) to port 15021. Easy!

Next, you’ll need to create your configuration file. This is the file that will load our rules file and tell the system how to use it.

Here’s how mine is set up:

Don’t see the file? Click through to see it.

This file is pretty easy to understand too. We’re setting up a new rdr-anchor (rdr meaning “redirect”) called “forwarding”, then loading it from our rules file. Replace the path in my example with the path to your own rules file.

I saved this file as pf.conf.

Running the command

Finally, we need to run the appropriate command in our terminal to add these rules.

First, verify that your syntax is correct by doing a dry run:

sudo pfctl -vnf /path/to/your/pf.conf

You can ignore the note about flushing rules. If everything else looks good, you’re ready to rumble:

sudo pfctl -evf /path/to/your/pf.conf

This command enables pf (it isn’t usually on already) and runs your custom pf.conf file. Cool!

Now you should be able to go to your web browser and point it to or If it all worked out, you should see your site!

Level up: automatically applying changes

As you probably figured out, to point port 80 to another port, you just need to edit your rules file and reload your pf.conf. But you can actually simplify this too with a simple shell script.

This is my simple file for simplifying your pf management.

Basically, you create a “template” version of your rules file, substituting the original port (15021) with “XXXX”. Then, depending on the name entered in the command, we use sed to replace “XXXX” with the appropriate port. That gets written to the rules file and then we reload pf.

If you have any questions about this setup, write in the comments below!

_photo credit: ajmexico via photopin cc

photo credit: Doha Sam via photopin cc_

Published by Chris Van Patten

I'm an entrepreneur and product lead, and owner of Tomodomo, through which I help companies build their digital publishing platform.

Join the Conversation


  1. Please, i need to redirect all traffic tcp to port 1935 localhost. I do this on linux: sudo iptables -t nat -A OUTPUT -p tcp –dport 1935 -j REDIRECT.
    How can i do in yosemite with pfctl?
    Can you help?

Leave a comment

Your email address will not be published. Required fields are marked *