ferm: a straightforward firewall configuration tool

December 14th, 2008 edited by Tincho

Article submitted by David A. Thompson. We’re running out of articles! If you like Debian Package of the Day please submit good articles about software you like!

Grumble… a postgresql server on an old Sun workstation isn’t visible to another old Sun workstation which (in theory…) is storing data on the postgresql server. The culprit was a misconfigured firewall. Rather than wading through a bunch of iptables commands, it seemed time to revisit the world of iptables front-ends on the off-chance there was an undiscovered treasure I’d missed on earlier visits. It turns out that there was one: ferm.

A revisit to firestarter, a straightforward GUI interface, ended when firestarter segfaulted and then, when started again, automatically started its firewall. Fortunately, I had altered the firestarter rule set and opened port 22 before firestarter segfaulted. Otherwise I would have been hundreds of miles away from an inaccessible server. After firestarter crashed again with a memory error, I decided to move on…

Like several other firewall front-ends, ferm is aware of the issues associated with working on servers hundreds of miles away from one’s physical location. Ferm starts with a default configuration which leaves the default SSH port open. Even better, ferm has a ‘try-before-you-buy’ feature (shared with a few other packages such as firehol): ferm --interactive activates a specific ruleset and, if a user response isn’t given within 30 sec, the system reverts to the previous ruleset.

Rather than using a GUI interface (e.g., firestarter, gnome lokkit, guarddog, kmyfirewall, knetfilter, …), ferm is configured via a text configuration file and can be controlled in a straightforward manner from the console. This may be a desirable feature for running on a box with limited disk space as GUI interfaces generally require the presence of X windows-related packages, often along with several KDE- or Gnome-related packages.

My main concern wasn’t with whether the application had a GUI or console interface but was with whether the application facilitated straightforward configuration of an iptables ruleset (translation: it shouldn’t take 20 min of reading documentation to get a simple firewall up). Other front-ends (e.g., shorewall and firewall builder) appear to be designed for complex rule-sets and require a substantial investment of effort to learn the syntax of configuration files or a ‘rule-making language’.

Along with ferm, another front-end, firehol seemed to also hit the mark with respect to having a straightforward syntax. Unfortunately, I found that firehol ended up being a time-consumer. In my experience, preparing a firehol configuration file which didn’t trigger multiple errors from firehol/iptables did not prove to be straightforward. In contrast, ferm gave me no such problems. A few tweaks of the default system configuration file —primarily opening a few ports—:

  proto tcp dport ssh ACCEPT;
  proto tcp dport http ACCEPT;
  proto tcp dport https ACCEPT;
  proto tcp dport postgres ACCEPT;

A simple /etc/init.d/ferm restart and things were running smoothly. Minimal effort, satisfying results…

The bottom line is that, for simple rulesets, using ferm is definitely easier than preparing iptables rules by hand. However, ferm can also be used to put together more complex firewall rulesets. It uses a reasonably powerful configuration language (including support for variables, function definitions, and arrays) which facilitates addressing more complex situations than the one I faced. To top it off, ferm seems to be under active development with bugs being squashed and features being added relatively regularly.

ferm has been available in Debian since Etch and in Ubuntu since Dapper.

Update, editor’s note: I’d like to add to this article my personal experience with ferm. Being a SysAdmin, I’ve been using netfilter/iptables for many years, after migrating away from ipchains; and the day I’ve found ferm my work changed completely. To me, being able to write your rules in clean structures, with blocks, variables and ‘functions’ is, by far, the most important feature of ferm. Thanks to this, I was able to write very complicated rule-sets, which were still readable to the point that the more junior SysAdmins, with little exprience on netfilter, have no difficult modifying it to open up ports or creating a new NAT rule.

Having said that, a warning to the newcomers to netfilter: there’s no tool that will magically allow you to write non-trivial rule-sets if you don’t understand the underlying stuff. You will be able to manage your home server, but if you want to do more serious work, you’ll need to really understand how TCP/IP works, and after that, read a lot about the details of routing and packet filtering in Linux. Having seen many people get frustrated by this, is better for you to know that this beast is quite tricky.

Posted in Debian, Ubuntu |

13 Responses

  1. Sitaram Chamarty Says:

    Ferm is a heck of a lot more powerful than this article suggests.

    The most visible feature of ferm is the ability to use it in blocks; the example in the article could have been written:

    proto tcp {
    dport ssh ACCEPT;
    dport http ACCEPT;

    Ferm also lets you create functions and use them later, including function parameters, just like a programming language.

    Sitaram (

  2. Sitaram Chamarty Says:

    ok wait my previous comment, on second thought, appears to be criticising the article; that was not the intention. You can delete the first line or amend it as you feel appropriate.


  3. Tincho Says:


    in fact, the example can be reduced more to this:

    proto tcp dport (ssh http https postgres) ACCEPT;

  4. Vadim P. Says:

    And what do you think of ufw / gufw ?

  5. Tim Says:

    I also come from ipchains, and at the time I was looking to move to iptables, none of the assorted frontends did it for me, so I did it the hard way. So thanks for reminding me of such things, at least.

    Three random thoughts:
    a) you can always design your firewall on another machine and use iptables-save to copy it straight to another box
    b) do your edits in two phases: hack on a script in one location (eg /root/ and test it there, then copy it to /etc/init.d/ when you’re sure it works. This way you get a known-good configuration, which you can set to run in a cron job every 10 minutes, with the advantages that you get some leeway on remote machines, and someone cracking into the box is in for a surprise.
    c) Any system abstracting on top of iptables has to be well designed. In previous comments I see grouping a bunch of port-open statements by the fact they’re all proto TCP. This does not necessarily scale well; if your firewall is to juggle packets between the outside world, a LAN and a DMZ, then you use the packet-flows (to/from each pair of networks) for your grouping not just the protocols. Serious firewalls can be written using simple bash and shell functions eg to build up an open-port profile for a service and then instantiate it via DNAT (”machine A gets ports (22,80,443); machine B gets ports (22,25)” etc).

  6. flavio Says:

    Anyone using vuurmuur? Only in debian sid, but seems very interesting.

    Any thoughts?

  7. Max Kellermann Says:

    What about:

    proto tcp dport (ssh http https postgres) ACCEPT;

    Looks even easier, doesn’t it?

    ferm has been part of Debian well before Etch; in fact, it was already added to Debian in 2001.

  8. Benjamin Eckenfels Says:

    I wonder why this…

    proto tcp dport ftp ACCEPT;

    …does not work on my box (”425 failed to establish connection”).

    I know active/passive FTP has always been an issue on firewalling. But how to handle this with ferm? Documentation suggest something like this:

    proto tcp {
    dport ftp ACCEPT;
    dport 1024:65535 ! syn ACCEPT;

    Is this recommended?

  9. Tincho Says:


    no, that’s a very bad suggestion. For FTP the best solution is to load the kernel helper for connection tracking (and NAT if you’re using NAT): nf_conntrack_ftp

    Then you just add a rule that allows packages in ESTABLISHED or RELATED states

  10. Benjamin Eckenfels Says:

    This way tracking is used and eveything works for http, ssh,… but gives me an Err 425 for http://ftp. Any ideas?

    table filter {
    chain INPUT {
    policy DROP;

    # connection tracking
    mod state state INVALID DROP;
    mod state state (ESTABLISHED RELATED) ACCEPT;

    # allow local connections
    interface lo ACCEPT;

    # allow FTP connections
    proto tcp dport ftp ACCEPT;

    # the rest is dropped by the above policy

    # outgoing connections are not limited
    chain OUTPUT policy ACCEPT;

    # this is not a router
    chain FORWARD policy DROP;

  11. Tincho Says:

    I’d double check the module is there with lsmod. Then, you should check with iptables -nvL the counters of each rule to see that they are being applied to the packets. And finally, tcpdump on each end to reveal exactly what’s happening

  12. Benjamin Eckenfels Says:

    root@pollux:ferm# lsmod grep ftp
    root@pollux:ferm# modprobe nf_conntrack_ftp
    root@pollux:ferm# lsmod grep ftp
    nf_conntrack_ftp 14760 0
    nf_conntrack 78576 3 nf_conntrack_ftp,nf_conntrack_ipv4,xt_state

    Tincho: Excellent pointer, thanks. I just thought the module was loaded already (or ferm would tell me, if not). Now everything is running smothly.

  13. perfector Says:

    Very informative. I feel Firewall Builder is not as difficult to use as mentioned in this article. Its simply drag and drop. Most importantly its easy to understand the firewall at a glance than reading lines of text.