Hi, I've spent a fair amount of time minimizing open ports and I have a cool new program for other people allergic to unnecessary open ports.
The basic idea is called a dynamic firewall daemon, that provides a command-line like interface which can execute carefully controlled modification to your firewall rules on the fly. It has boatloads of applications, like creating firewall rules that expire after a certain period of time, creating fixed-length queues of shunned IP addresses, automatic blocking of IPs that are the source of NIDS alerts, a way to implement port-knocking, temporary enabling of bittorrent ports, extreme "islanding" in case of a severe intrusion, and lots of other applications. This specific implementation is called dfd_keeper, named after the bridge keeper in "The Holy Grail". As the origin of the name might suggest, it is written in python and making use of the "twisted" asynchronous I/O library. I have put a lot of effort into making it elegant and readable. This is not a one-trick pony. It is a programmatic interface and control of the packet filter from userland. Just for a quick demonstration of how to use dfd_keeper, I have created a script called keeper_example. This sets up a fully functional but somewhat minimal firewall that performs NAT. You will notice that all of the PF-related rules are written in pf.conf syntax - nothing new to learn! I think that anyone of moderate intelligence can use/modify it, even if they are completely ignorant of python. It also defines a few commands, like being able to block a specific IP address. It has an online help command that makes extensive use of python introspection, keeping the documentation with the implementation. You can command dfd_keeper merely using netcat or telnet. There may be cause for a twisted-based web front end as well. Just to anticipate a complaint, there is no authentication in this server beyond what you configure with the pf rules themselves. For me, this is good enough, but I may implement some kind of auth layer above it at a later time. I want to solve the problems correctly. For example, I don't want reusable passwords that will have to be embedded in any other program that wants to make use of dfd commands. For now, if you want authentication, use ssh tunnelling or IPSec. Comments, suggestions, volunteers, code submissions welcome. Justification, explanation, example, browsable code and tarballs here: http://www.lightconsulting.com/~travis/dfd/