7.5. Tcp Connection

Tcp state-full dissector module.

Usage:

local tcp_connection = require('protocol/tcp_connection')

7.5.1. Dissector

dissector TcpConnectionDissector
Name :'tcp_connection'
Extend :haka.helper.FlowDissector 

State-full dissector for TCP. It will associate each TCP packet with its matching connection and will build a stream from all received TCP packets.

<TcpConnectionDissector>.srcip
<TcpConnectionDissector>.dstip
Type:ipv4.addr 

Connection IP informations.

<TcpConnectionDissector>.srcport
<TcpConnectionDissector>.dstport
Type:number

Connection port informations.

<TcpConnectionDissector>:send([direction])
Parameters:
  • direction (string) – Direction to use ('up', 'down' or nil)

Send the data that are ready in the streams.

<TcpConnectionDissector>:drop()

Drop the TCP connection. All future packets that belong to this connection will be silently dropped.

<TcpConnectionDissector>:reset()

Reset the TCP connection. A RST packet will be sent to both end and all future packet that belong to this connection will be silently dropped.

<TcpConnectionDissector>:halfreset()

Reset the TCP connection. A RST packet will be only sent to the server and all future packet that belong to this connection will be silently dropped.

7.5.2. Events

event tcp_connection.events.new_connection(flow, tcp)
Parameters:

Event triggered whenever a new TCP connection is about to be created.

event tcp_connection.events.end_connection(flow)
Parameters:

Event triggered whenever a new TCP connection is being closed.

event tcp_connection.events.receive_data(flow, current, direction)

Event options:

streamed
Type:boolean

Run the event listener as a streamed function.

Parameters:

Event triggered when some data are available on a TCP stream.

Usage:

haka.rule{
    hook = tcp.events.receive_data,
    options = { streamed = true },
    eval = function(flow, current, direction)
        -- do some check and reaction
    end
}
event tcp_connection.events.receive_packet(flow, packet, direction)
Parameters:

Event triggered when a packet associated with the stream is received.

7.5.3. Helper

dissector tcp_connection.helper.TcpFlowDissector
TcpFlowDissector.dissect(cls, flow)
Parameters:

Enable the dissector on a given flow.

TcpFlowDissector.install_udp_rule(cls, port)
Parameters:
  • cls – Current dissector class.
  • port (number) – Tcp port to select.

Create a security rule to enable the dissector on a given flow.

<TcpFlowDissector>.__init(flow)
Param flow:Parent Tcp flow.
Ptype flow:TcpConnectionDissector
<TcpFlowDissector>.flow
Type:TcpConnectionDissector 

Underlying Tcp stream.

<TcpFlowDissector>:reset()

Reset the underlying Tcp connection.

<TcpFlowDissector>:receive_streamed(iter, direction)
Parameters:
  • iter (vbuffer_iterator) – Current position in the stream.
  • direction (string) – Data direction ('up' or 'down').

Function called in streamed mode that by default update the state machine instance. It can be overridden if needed.

7.5.4. 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
}