Fork me on GitHub

Setup basic firewall rules v0.1

The main purpose of the initial release of Haka is to allow users to define easily and quickly security rules and filter unwanted packets/streams. In this article, we show how to setup a simple firewall configuration.

We create first a rule group. A group is made of three functions: init, fini and continue, and a set of security rules. The first function is executed at group initialization. In our example, we log some info about connection establishment attempt (source and destination ports). Then, the continue function is executed whenever a rule of the group is evaluated. Finally, the function fini is executed if no rule matches the desired conditions. In the example below, we raise an alert and drop the connection.

require('protocol/ipv4')
require('protocol/tcp')

local my_group = haka.rule_group{
    name = "group",
    init = function (self, pkt)
        haka.log.debug("filter",
            "entering packet filtering rules : %d --> %d",
            pkt.tcp.srcport, pkt.tcp.dstport)
    end,
    fini = function (self, pkt)
        haka.alert{
            description = "Packet dropped : drop by default",
            sources = haka.alert.address(pkt.tcp.ip.src,
                pkt.tcp.srcport),
        }
        pkt:drop()
    end,
    continue = function (self, pkt, ret)
        return not ret 
    end 
}

Suppose now that we want to authorize only http traffic from internal network 192.168.10.0/24. To reach this goal we add the following rule which checks if the source address is in the range of the internal network and if the packet is directed to a http service. If this condition is met the next dissector (http) is set accordingly. Otherwise, the next rule of the group is evaluated.

local auth_network = ipv4.network("192.168.10.0/24");

my_group:rule{
    hooks = { 'tcp-connection-new' },
    eval = function (self, pkt)
        local tcp = pkt.tcp
        if auth_network:contains(tcp.ip.src) and
            tcp.dstport == 80 then
            pkt.next_dissector = "http"
            return true
        end
    end
}

Similarly, we can add additional rules. For instance, the following rule authorize ssh connections:

my_group:rule{
    hooks = { 'tcp-connection-new' },
    eval = function (self, pkt)
        local tcp = pkt.tcp
        if auth_network:contains(tcp.ip.src) and
            tcp.dstport == 22 then
            haka.log.warning("filter",
                "no available dissector for ssh")
            return true
        end
    end
}

Note that, we don't have an appropriate dissector to handle ssh traffic. However, the next release will feature a new grammar to specify easily new protocols.