Skip to content
iptables firewall compiler
Perl Shell
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


husk %VERSION%

husk is a natural language wrapper around the Linux iptables packet filtering.
It is designed to abstract the sometimes confusing syntax of iptables into
a format that is easier and friendlier to read and understand.

husk can be used on either firewall/router computers (with multiple network
interfaces), or standalone systems (with one network interface)

Each interface (real or virtual) is called a 'zone' in husk. Zones are given
a friendly name which is what is used in the rule definitions. This abstracts
the Linux device names (eg, eth0, ppp0, bond0 etc) into much more intuitive
names such as NET, LAN and DMZ. This has the added benefit of moving interfaces
in the future can be done simply by changing the name-to-device mapping.



Husk can be installed using standard 'make' commands. You must be root to
install correctly.

Install everything:
    make all

Install only the script:
    make bin

Install only the docs:
    make docs

Install only the configuration examples:
    make config

Uninstallation is also catered for:
    make uninstall



First, give your interfaces friendly names in the file 'interfaces.conf'. An
example file might look like:
    zone ME is lo
	zone NET is eth0
	zone LAN is eth1
	zone DMZ is eth2
I recommend simple 3 letter friendly names for your zones.

IMPORTANT NOTE: loopback ('lo') *must* be called the special name 'ME'.



1. Common Firewalling
husk has built-in 'common' firewall rules, prefixed with the keyword 'common'
    NAT:        common nat ZONE
                Apply a Source NAT to traffic going out ZONE, usually 'NET'
                eg: common nat NET
    SPOOF:      common spoof ZONE ADDRESS/PREFIX
                Prevent address spoofing on the specified ZONE. ADDRESS/PREFIX
                defines the addresses that are expected to be seen on the given
                ZONE. You can add multiple 'spoof' rules per interface.
                eg: common spoof LAN
                    common spoof LAN
                    common spoof DMZ
    BOGON:		common bogon ZONE
                Block bogon traffic on the specified ZONE. Bogon traffic is
				packets with source addresses that should never be seen outside
				private networks such as RFC1918 addresses, etc.
	PORTSCAN:	common portscan ZONE
				Attempt to detect, log and drop portscans coming from the given
				zone. This is only rudimentary, but it's better than nothing.
    XMAS:		common xmas ZONE
                Block xmas packets on the specified ZONE. Xmas packets are
				packets with all flags set, or the packet "is lit up like
				a Christmas tree"
    SYN:        common syn
			    All packets that the kernel detects as belonging to a "NEW"
				connection should have the "SYN" flag set. If they don't, then
				we DROP them.
    LOOPBACK:   common loopback
                Create a rule to accept traffic in/out the 'lo' interface

2. define rules ZONE to ZONE
Traffic passing between zones is known as cross-zone traffic - eg LAN to NET
Defining rules for this cross-zone traffic is done in a 'define rules' block:
    define rules LAN to NET
    <rules go here>
    end define

There is a special in-built interface called 'ANY' which as the name suggests.
allows you to write a match calls that ignores one (or both) of the IN and OUT
interfaces. For example:

Allow the whole world to access Secure POP3 on our mail server.
	define rules ANY to DMZ
	accept protocol tcp port pop3s destination address
	end define

This is effectively the same as the FORWARD table, but only NEW connections
are passed through here:
	define rules ANY to ANY
	accept protocol tcp port 873	# rsync anywhere is fine
	end define

NOTE: 'ANY' *excludes* the other interface to avoid bounce routing issues. So
      a match calls for 'ANY to LAN' doesn't include traffic 'LAN to LAN'. If
	  you need to allow bounce routing, then add a rule such as:
	  	define rules FORWARD
		accept incoming LAN outgoing LAN
		accept incoming DMZ outgoing DMZ
		end define

3. define rules <USER DEFINED>
You can create your own user-defined chains (UDC) using 'define rules' block.
These user-defined chains can then be called from cross-zone blocks.
    define rules SMB_PORTS
    <rules go here>
    end define

4. define rules (INPUT|OUTPUT|FORWARD)
To add rules to the standard iptables filter table chains (INPUT, FORWARD and
OUTPUT), write a 'define rules' UDC block for the appropriate chain:
    define rules INPUT
    <rules go here>
    end define

5. Rule Keywords
Example rules are below. I think this will be the easiest way to explain
the keywords and functions of husk. All keywords can be mixed and matched
to suit the rule(s) you require.

    accept source address
        Accept anything from source address

    accept proto tcp port http destination address
        Allow TCP port 80 to whatever '' resolves to via DNS.

    accept proto tcp ports http,https source range to
        Allow any TCP port 80 and 443 traffic from addresses .1 to .10

    accept mac 00:14:22:d8:f9:55
        Anything from the given MAC Address is allowed.

    reject source address
        Reject with ICMP unreachable packet any traffic from the given IP

    SMB_PORTS destination address
        Jump to the user-defined chain "SMB_PORTS" for traffic to

    accept all
        Accept everything.

    accept proto icmp type echo-request limit 4/sec burst 8
        Allow 4 ICMP 'echo-request' packets per second, bursting to 8pps

    accept proto icmp type echo-reply limit 4/sec burst 12
        Allow 4 ICMP 'echo-reply' packets per second, bursting to 12pps

        Just drop all packets.

    accept in LAN protocol icmp
        Accept any icmp packets that come in the LAN interface.

6. Port Forwarding (DNAT)
If you need to forward incoming traffic from one interface to another using the
NAT feature of the kernel, you can use the 'map' rule. For example, to NAT port
80 traffic coming in the "NET" interface to an internal server:
    map in NET destination address protocol tcp port 80 to

You can also translate the ports from one to another by appending to the
destination address:
    map in NET destination address to

7. Intercepting / Redirection
Using the 'trap' or 'redirect' keyword, you can silently redirect traffic to
the local computer. This is useful for example to intercept all outgoing SMTP
traffic to force it through the local SMTP gateway:
    trap in LAN protocol tcp port 25

Redirecting to alternative ports is also possible:
    redirect incoming NET protocol tcp port 80 to 8080
    redirect incoming NET protocol tcp port 2222 to 22

8. Raw iptables rules
Directly writing iptables rules is also supported for putting your own rules in
using iptables syntax:
    iptables -t raw -A OUTPUT -d -j NOTRACK

9. Includes
If your ruleset is complicated, you can spread the rules over multiple files
then consoldate them all together at compile time by using the 'include'
    include outbound.rules
    include inbound.rules

Includes can be either relative paths (to the conf dir) or absolute paths.
You should be able to nest indefintiely, but be careful not to create loops
such as:
    include rules-two.conf

    include rules-one.conf

There is NO PROTECTION against this.



husk is Copyright 2010 Phillip Smith <fukawi2 (at) gmail (dot) com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <>.
Something went wrong with that request. Please try again.