Dear m0n0wall enthusiasts,
now that m0n0wall 1.2 is out and all (well, most) of the changes
since 1.11 are conserved in a (hopefully) stable release, we can
discuss what is going to become of m0n0wall in the future. I'm going
to present my point of view on what m0n0wall is today and what it
could become. Your (constructive) comments, suggestions and opinions
are very welcome, and I expect they'll be numerous as well. Please
post them to the m0n0wall-dev mailing list only (I'm just CC'ing this
to the main list to draw people's attention to this discussion).
First of all, I'd like to give a quick overview of m0n0wall as it
exists today - an experiment I started in 2003 that now runs about
15,000 firewalls worldwide. m0n0wall is based on a FreeBSD 4.11
system, stripped down to its bare minimum. To make it as reliable as
possible and to allow the system to be unplugged at any time (just
like most commercial firewall boxes), the root file system is a
memory file system, loaded at boot time from an image. This is also
what made the popular CD-ROM version possible. Instead of the usual
/etc/rc.* shell scripts, m0n0wall uses PHP scripts that are
interpreted by a PHP CGI binary used as a CLI. These scripts contain
functions that configure various aspects of the system - interfaces,
the firewall, services. The configuration for the whole system comes
out of a single XML file, config.xml. It is parsed into a
multi-dimensional array and then used directly by the functions that
configure the system. They do this by translating certain elements of
the configuration into configuration files for daemons (like dhcpd,
dnsmasq, etc.) or by calling system tools that interact with the
kernel (like ifconfig or ipf). So far, so good.
m0n0wall also contains a web interface, called the webGUI, which is
probably its most important feature. mini_httpd is used as the web
server, and once again, PHP (in CGI mode) is used for the pages that
the webGUI consists of. Just like the boot scripts, these pages parse
and manipulate the configuration directly, and also write it back
into XML as needed (i.e. when the user modifies the configuration).
To enable most changes to be applied immediately (instead of having
to reboot each time), the webGUI pages call the respective functions
in the boot scripts directly. To prevent problems with parallel
access, a very simple form of locking is used. Certain configuration
options are mutually exclusive, and some depend on other options
being enabled in order to work. It's each webGUI page's own
responsibility to check that all prerequisites are met, but obviously
due to the way the webGUI works, pages are not informed if any of the
options they depend on change.
Upon external events - most commonly when PPPoE, PPTP or DHCP
indicate that the dynamic WAN IP address has changed - another PHP
script is run to make the necessary adjustments.
So far, this has worked remarkably well. However, with each new
feature that was developed, it has become more obvious that things
are too intertwined. The main reason why OpenVPN support was buggy
and had to be removed was that it used optional interfaces in ways
that weren't planned when the optional interface support was written.
However, it is clear why the initial author of m0n0wall's OpenVPN
support chose to use optional interfaces: otherwise, major parts of
the firewall code and many webGUI pages would have had to be modified
(keep in mind that the OpenVPN support was supposed to be a module).
m0n0wall has grown "organically" without a specific plan, so this is
a logical consequence.
At this time, I believe that it wouldn't be wise to continue hacking
new features into m0n0wall with its current architecture. I don't
have a ready-made plan yet, but in my opinion the web interface and
the configuration subsystem need to be separated. There's too much
important logic in the webGUI right now. m0n0wall needs a core, a
daemon, something that is always running in the background to
coordinate configuration changes and external events. The webGUI
should only display the data and send change requests to the core,
and the core should handle all the "business logic". This would also
open possibilities for alternate configuration methods (console,
Windows application, etc.). It would also be nice if the core was
highly modular, with services like DHCP, DynDNS, DNS forwarder, PPTP
VPN etc. implemented as separate modules and only the essential stuff
(like interface handling or firewall rule generation) in the core.
I have thought about this in the past, but PHP doesn't lend itself
well to that kind of application. The core could also benefit from an
object-oriented approach, finally abstracting things like interfaces,
so that new features like OpenVPN could be integrated without having
to modify existing code everywhere. Java would be a possibility -
there are now ways (GCJ, for example) to use its advantages without
the usual extreme bloat. There may be other candidates - I don't know.
For the web interface, I still think PHP is a good choice. We'd just
need a standards based interface between the core and the webGUI.
What do you think? Is it time to perform a major architectural
overhaul on m0n0wall? Or would you rather continue with m0n0wall's
current architecture, perhaps making small adjustments where
necessary, and on the other hand spend more time rewriting code to
get new features integrated?
No matter how the web interface and configuration system are going to
work, there's also another important question: which base operating
system should be used in the future? FreeBSD 4.x is at the end of its
lifespan. It has been a very good, reliable, fast and secure
platform. However, its age has become evident with missing support
for new hardware (wireless gear in particular). There are several
options for an alternative, each with its advantages and
disadvantages. It'll most likely have to be a Unix-style operating
system - the three BSDs (FreeBSD, NetBSD, OpenBSD), its descendants
(e.g. DragonFly) and Linux come to mind. FreeBSD 5.x has already been
evaluated in 1.2b5-7 and found to be too slow in comparison with 4.x.
FreeBSD 6 is currently being used by pfSense and is supposed to be
better than 5.x. NetBSD hasn't been evaluated at all, but OpenBSD has
been suggested by a few due to its emphasis on security. With all
three BSDs, the choice of packet filter is between ipfilter and pf -
with Linux, it would be something different altogether (iptables).
One thing that is very important to me is that m0n0wall remains (at
least) as clean and easy to configure as it is today. Users should
not have to deal with or need to understand the underlying operating
system (except where it's inevitable, like when assigning interfaces
Finally, something needs to be done about the development style as
well. So far, I've coordinated all changes to m0n0wall and analyzed
and tested most contributed patches. While I think this has resulted
in a relatively high code quality, I'd like other talented people to
get more involvement. Volunteers, step forward! One of the ways to
enable this will be a common version control system for the code -
either CVS or SVN.
That's it for now - again, please post your comments, and be sure to
let everybody know if you think you can and would like to help with
one of the things I've mentioned. We can also start a new survey on
m0n0.ch if it looks like it would help and we manage to agree on a
set of questions.
m0n0wall forever! ;)