2010-09-12

The Problem of Port 80

For those new to web serving on Mac OS X or other Unix-based computers, you face the problem of port 80.

The issue exists on Unix systems (Mac OS X, BSD, Linux, Solaris, etc.), but not MS Windows computers. By tradition port numbers 0-1024 are restricted to apps running as superuser, as a security precaution. Superuser can do anything, including wipe the entire boot drive. So normally we don't run apps as superuser. The default port for http (web servers) is 80, and is in that range. So we have a Catch-22.

A common solution is to run a web server on a port number higher than 1024, often 8080 or 8888. Those numbers are arbitrary, chosen for their cuteness. Then you can use the "ipfw" firewall built into BSD-based systems such as Mac OS X. Linux and other Unix systems have similar firewall tools. The firewall tool can do "packet forwarding" where an incoming packet is inspected and then blocked, allowed, or modified. By modifying, the packet's port number can be changed from 80 to 8080 (or whatever you chose). Then the packet is sent on its way, to arrive at your web server running on port 8080 (or whatever you chose).

'ipfw' is a command-line tool. It works by submitting each incoming or outgoing packet to a list of rules. The first rule whose criteria matches that particular packet is applied, and no further rules are checked. You can have up to about 64,000 rules.

The syntax for these rules is arcane, and not intuitive. Fortunately, I give you the very rule you need below.

Obviously, this 'ipfw' tool is critical. So you must access it with "sudo" before it, to run the tool as superuser. Mac OS X' Terminal app will prompt you for your system password before continuing.

To see your rules, in Terminal type:
sudo ipfw show

To add the port-forwarding rule, in Terminal type:
sudo ipfw add 100 fwd 127.0.0.1,8080 tcp from any to any 80 in

To delete all your rules, and reset to default, in Terminal type:
sudo ipfw flush

You need prepend "sudo" only once. It stays in effect for at least several minutes.

That's easy enough. If you wish, you can download a free gui app a gentleman created for the Mac-using 4D community, Simple Port Forwarder. That app does one simple thing: add the rule I listed above.

For another free gui tool that does more 'ipfw' work, you may download WaterRoof.

Keep in mind that for both those apps, you are entrusting your system password to their creators. Do so at your own risk.

I have done this port-forwarding with complete success when using both 4D and Apache Tomcat web server (a Java-based web server and Servlet engine, not to be confused with the "Apache Web Server").

Mac OS X always has at least one rule:
Allow all packets through regardless. 
A security-conscious admin may choose to add a rule before that:
Deny all packets. 
Then she will add more rules before that, to let through only the kinds of packets she expects. As a newbie, you don't need to think about that, but you may want to get there eventually.

Some people mistakenly perceive this packet-forwarding as a trick, a hack, or a burden to the computer. Packet-forwarding is none of those. It is completely "normal". 'ipfw' is built into the core of Mac OS X. Understand that ipfw has always been running on your Mac, already inspecting every packet coming in or going out. You are simply adding one more rule to be considered and applied.

The info above relates to Mac OS X and other BSD-derived systems. Linux is not BSD-derived, but does have a similar packet-inspecting firewall tool with similar behavior though different syntax.

By the way, you may be wondering how Apache Web Server and some other web servers solve the Catch-22. My understanding is this: They pull a trick when they launch. During the launch process, the app temporarily acts as superuser to grab access to port 80, then immediately switches back to being a normal user to complete launching.

Use at your own risk. Don't blame me, sue me, or hate me. But you may send me Peet's Coffee gift cards.

1 comment:

  1. Thanks for the post! For WaterRoof I used:
    fwd 127.0.0.1,8080 ip from any to any dst-port 80

    ReplyDelete