GNU/Linux netfilter admin with Ferm: For Easy Rule Making

Ferm rules them all when you need to manage complex netfilter (iptables/ip6tables/ebtables) firewall.

Project homepage :

First, a dumb `ferm` wrapper enhancing edit and debug usage: bash Ferm wrapper

Current file layout:

9:39 rboissat@dresda /etc/ferm% ls -R
conf.d  ferm.conf  ferm.conf.orig

00-vars.ferm  01-functions.ferm  02-policies.ferm  03-custom-chains.ferm  10-table-filter.ferm  20-table-mangle.ferm  30-table-nat.ferm


# -*- shell-script -*-
#  Configuration file for ferm(1).

@include 'conf.d/';

00-vars.ferm (edited out)

# FERM Variables;

## Interfaces;
@def $DEV_WAN4    = eth0;
@def $DEV_WAN6    = hev6;
@def $DEV_VPN     = brVPN;

## Networks;
@def $NET4_VPN    = (;
@def $NET4_CHUN   = (;
@def $NET6_VPN    = (2001:470:c8be:1::/64);
@def $NET6_CHUN   = (2001:470:c8be::/48);
@def $NET6_OVH    = (2001:41d0:1:8dc7::/64);


# FERM Hooks
@hook post  "echo 1 >| /proc/sys/net/ipv4/ip_forward";
@hook post  "echo 1 >| /proc/sys/net/ipv6/conf/all/forwarding";
@hook flush "echo 0 >| /proc/sys/net/ipv4/ip_forward";
@hook flush "echo 0 >| /proc/sys/net/ipv6/conf/all/forwarding";

# FERM Functions
@def &PORT_FORWARD($proto, $port, $outside, $inside) = {
  daddr $outside proto $proto dport $port DNAT to $inside;


# default policies
domain ( ip ip6 ) table filter {
  chain FORWARD policy DROP;
  chain INPUT   policy DROP;
  chain OUTPUT  policy ACCEPT;

Some cherry picked rules (did you really expect my entire ruleset? :P)

 # wan input
 mod conntrack ctstate NEW daddr @ipfilter(($ADDR4_WAN $ADDR6_WAN)) proto tcp dport $TCP_IN_WAN ACCEPT;
 mod conntrack ctstate NEW daddr @ipfilter(($ADDR4_WAN $ADDR6_WAN)) proto udp dport $UDP_IN_WAN ACCEPT;

# new to wan from local subnets
@if @eq($DOMAIN, ip) {
  outerface $DEV_WAN4 saddr $NET4_CHUN ACCEPT;
} @else {
  outerface $DEV_WAN6 saddr $NET6_CHUN ACCEPT;

That’s all folks. This setup should be further documented in my wiki.