9. Rules

9.1. Events

Haka core will trigger various events emitted by dissectors for instance. This events allow the user to place rules to verify some property and react if needed.

To get the list of supported events and for each of them their parameters, check the documentation of the protocol dissectors (Haka dissectors).

9.2. Single Rule

haka.rule{...}
Parameters:
  • hook (Event) – Event to listen to.
  • eval (function) – Function to call when the event is triggered.
  • options (table) – List of options for the rule.

Register a new rule on the given event.

Note

Options are specific to the events you are hooking to. See Haka dissectors for more information.

9.2.1. Example:

------------------------------------
-- Loading dissectors
------------------------------------
local ipv4 = require('protocol/ipv4')

-- drop all packets originating from
-- blacklisted address 192.168.10.10
haka.rule{
    -- This rule is applied on each ip incoming packet
    hook = ipv4.events.receive_packet,
    eval = function (pkt)
        -- Parse the IP address and assign it to a variable
        local bad_ip = ipv4.addr('192.168.10.10')
        if pkt.src == bad_ip then
            -- Raise an alert
            haka.alert{
                description = string.format("Filtering IP %s", bad_ip),
                severity = 'low'
            }
            -- and drop the packet
            pkt:drop()
        end
        -- All other packets will be accepted
    end
}

9.3. Interactive rule

haka.interactive_rule(name) → func
Parameters:
  • name (string) – Rule name displayed in prompt.
Returns:
  • func (function) – Rule function.

Utility function to create an interactive rule. Use this function to build an eval function of one of your rule.

When the rule is evaluated, a prompt will enable the user to enter some commands. The parameters given to the rule are available through the table named inputs.

Usage:

haka.rule{
    hook = ipv4.events.receive_packet,
    eval = haka.interactive_rule("interactive")
}

9.4. Rule Group

object rule_group

Rule group allows customizing the rule evaluation.

haka.rule_group{...} → group
Parameters:
  • hook (event) – Event to listen to.
  • init (function) – Function that is called whenever the event is triggered and before any rule evaluation.
  • continue (function) – 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.
  • final (function) – If all the rules of the group have been evaluated, this callback is called at the end.
  • options (table) – List of options for the rule.
Returns:

Create a new rule group on the given event.

init(...)
Parameters:
  • ... – Parameter from the event.
continue(ret, ...) → should_continue
Parameters:
  • ret – Result from the previous rule evaluation.
  • ... – Parameter from the event.
Returns:
  • should_continue (boolean) – true if the next rule in the group should be evaluated.
final(...)
<rule_group>:rule(eval)
Parameters:
  • eval (function) – Evaluation function.

Register a rule for this group.

9.4.1. 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 {
    hook = tcp_connection.events.new_connection,
    init = function (flow, pkt)
        haka.log.debug("entering packet filtering rules : %d --> %d",
            pkt.srcport, pkt.dstport)
    end,
    final = function (flow, pkt)
        haka.alert{
            description = "Packet dropped : drop by default",
            sources = haka.alert.address(pkt.ip.src, pkt.srcport),
            targets = haka.alert.address(pkt.ip.dst, pkt.dstport)
        }
        pkt:drop()
    end,
    continue = function (ret, flow, pkt)
        return not ret
    end
}


group:rule{
    eval = function (flow, tcp)
        if client_network:contains(tcp.ip.src) and
            server_network:contains(tcp.ip.dst) and
            tcp.dstport == 80 then
            haka.log.warning("authorizing http traffic")
            http.dissect(flow)
            return true
        end
    end
}

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