Web Development on Port 80 and 443 in Vagrant
Thu, 2013-01-17 21:27 — dmuth
In this post I'm going to talk about using port 80 and 443 for web
development on a Mac running 1 or more virtual machines under Vagrant.
Why use port 80 and port 443?
Port 80 is the
standard port for HTTP and 443 is the
standard port
for HTTPS. While other ports can be used, they're non-standard, and
some (if not most) webapps make assumptions about those port numbers.
You can really get burned on matters of HTTP redirection, such as when
a form is submitted or when
redirection from HTTP to HTTPS happens. While applications can certainly be built to take the port numbers into account, many are not.
Unfortunately, it's not a simple matter of telling configuring your
Vagrant instance to listen on ports 80 and 443. Any port under 1024
requires the program to be running as root. And running an app as the
root user is generall y never a good idea.
Can I forward ports from the Vagrant instance?
Why yes, you can! It's as simple as putting these lines in your Vagrantfile:
config.vm.forward_port 80, 8080
config.vm.forward_port 443, 8443
|
Wait, those are ports 8080 and 8443!
Yes, they are. Remember what I said about needing to be the root
user? But, under Mac OS/X we can forward ports 80 and 443 to ports 8080
and 8433. The trick is to use the
ipfw utility which comes with OS/X and is used to manage its built in firewall.
Here's a "quick and dirty" way to do it from the command line:
sudo ipfw add 100 fwd 127.0.0.1,8080 tcp from any to me 80
sudo ipfw add 101 fwd 127.0.0.1,8443 tcp from any to me 443
|
From that point on, attempting to connect to http://localhost/ and
https://localhost/ will be forwarded by ipfw to ports 8080 and 8433,
which will be received by Vagrant which will in turn forward any traffic
sent there to ports 80 and 443 on its virtual machine.
Until you reboot, at least.
Is there a way to make this forwarding permanent?
Yes, there is. It involves setting up a service through OS/X that is started at bootup.
The first step is to set up a plist in the file
/Library/LaunchDaemons/org.dmuth.ipfw.plist:
xml version = "1.0" encoding = "UTF-8" ?>
< plist version = "1.0" >
< dict >
< key >Label</ key >
< string >org.dmuth.ipfw</ string >
< key >Program</ key >
< string >/sbin/ipfw</ string >
< key >ProgramArguments</ key >
< array >
< string >/sbin/ipfw</ string >
< string >-q</ string >
< string >/etc/ipfw.conf</ string >
</ array >
< key >RunAtLoad</ key >
< true >
</ true ></ dict >
</ plist >
|
This will tell the machine that there is a new service which, when started, tells ipfw to load firewall rules out of the file
/etc/ipfw.conf. That means we next need to populate /etc/ipfw.conf as follows:
flush
add 100 fwd 127.0.0.1,8080 tcp from any to me 80
add 101 fwd 127.0.0.1,8443 tcp from any to me 443
|
Now we just need to enable the service. Run this on the command line
sudo launchctl load -w /Library/LaunchDaemons/org .dmuth.ipfw.plist
|
That was a lot of work!
It sure was. But it can be automated. This is the part where you should read my
Chef 101 article because things like the above can be completely automated. In fact, I
created a cookbook for the above. It can be installed with the following Chef command:
sudo
chef-solo -c .
/config
.rb -o mac-os-x-ipfw