1. Defining rules

This section introduces how to define security rules.

1.1. Single rule

As detailed hereafter, a rule is made of a list of hooks and an evaluation function:

class haka.rule
hooks

An array of hook names where the rule should be installed.

eval(self, d)

The function to call to evaluate the rule.

Parameters:
haka.rule(r)

Register a new rule.

Parameters:
  • r (rule) – Rule description.

Example:

------------------------------------
-- IP attacks
------------------------------------

haka.rule{
    hooks = { 'ipv4-up' },
    eval = function (self, pkt)
        if pkt.src == pkt.dst and pkt.src ~= ipv4.addr("127.0.0.1") then
            haka.alert{
                description = "Land attack detected",
                severity = 'high',
                confidence = 'medium',
                sources = { haka.alert.address(pkt.src) },
            }
            pkt:drop()
        end
    end
}

1.2. Rule group

Rule group allows customizing the rule evaluation.

class haka.rule_group
name

Name of the group.

init(self, d)

This function is called whenever a group start to be evaluated. d is the dissector data for the current hook (dissector_data).

fini(self, d)

If all the rules of the group have been evaluated, this callback is called at the end. d is the dissector data for the current hook (dissector_data).

continue(self, d, ret)

After each rule evaluation, the function is called to know if the evaluation of the other rules should continue. If not, the other rules will be skipped.

Parameters:
  • ret – Value returned by the evaluated rule.
  • d (dissector_data) – Data that where given to the evaluated rule.
rule(self, r)

Register a rule for this group.

See also

haka.rule().

haka.rule_group(rg)

Register a new rule group. rg should be a table that will be used to initialize the rule group. It can contains name, init, fini and continue.

Returns:The new group.
Return type:rule_group

Example:

------------------------------------
-- Firewall rules
------------------------------------

local client_network = ipv4.network("192.168.10.0/25");
local server_network = ipv4.network("192.168.20.0/25");

local 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),
            targets = haka.alert.address(pkt.tcp.ip.dst, pkt.tcp.dstport)
        }
        pkt:drop()
    end,
    continue = function (self, pkt, ret)
        return not ret
    end
}


group:rule{
    hooks = { 'tcp-connection-new' },
    eval = function (self, pkt)

        local tcp = pkt.tcp

        if client_network:contains(tcp.ip.src) and
            server_network:contains(tcp.ip.dst) and
            tcp.dstport == 80 then
            haka.log.warning("filter", "authorizing http traffic")
            pkt.next_dissector = "http"
            return true
        end
    end
}

group:rule{
    hooks = { 'tcp-connection-new' },
    eval = function (self, pkt)

        local tcp = pkt.tcp

        if client_network:contains(tcp.ip.src) and
            server_network:contains(tcp.ip.dst) and
            tcp.dstport == 22 then
            haka.log.warning("filter", "authorizing ssh traffic")
            haka.log.warning("filter", "no available dissector for ssh")
            return true
        end
    end
}