Back to Suricata

DNS

doc/userguide/lua/libs/dns.rst

latest3.5 KB
Original Source

DNS

.. role:: example-rule-emphasis

DNS transaction details are exposed to Lua scripts with the suricata.dns library, for example::

local dns = require("suricata.dns")

Setup ^^^^^

If your purpose is to create a logging script, initialize the buffer as:

::

function init (args) local needs = {} needs["protocol"] = "dns" return needs end

If you are going to use the script for rule matching, choose one of the available DNS buffers listed in :ref:lua-detection and follow the pattern:

For use in rule matching, the rule must hook into a DNS transaction state. Available states are request_complete and response_complete. For example:

.. container:: example-rule

alert dns::example-rule-emphasis:request_complete any any -> any any (...

Then to initialize the script::

function init (args) return {} end

Transaction


DNS is transaction based, and the current transaction must be obtained before use::

  local tx, err = dns.get_tx()
  if tx == err then
      print(err)
  end

All other functions are methods on the transaction table.

Transaction Methods

answers() ^^^^^^^^^^^^^

Get the answers response section as a table of tables.

Example::

local tx = dns.get_tx() local answers = tx:answers() if answers ~= nil then for n, t in pairs(answers) do rrname = t["rrname"] rrtype = t["type"] ttl = t["ttl"]

      print ("ANSWER: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
             ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
             dstip .. ":" .. dp)
  end

end

authorities() ^^^^^^^^^^^^^^^^^

Get the authorities response section as a table of tables.

Example::

local tx = dns.get_tx() local authorities = tx:authorities(); if authorities ~= nil then for n, t in pairs(authorities) do rrname = t["rrname"] rrtype = t["type"] ttl = t["ttl"] print ("AUTHORITY: " .. ts .. " " .. rrname .. " [] " .. rrtype .. " [] " .. ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " .. dstip .. ":" .. dp) end end

queries() ^^^^^^^^^^^^^

Get the queries request or response section as a table of tables.

Example::

local tx = dns.get_tx() local queries = tx:queries(); if queries ~= nil then for n, t in pairs(queries) do rrname = t["rrname"] rrtype = t["type"]

      print ("QUERY: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
             "TODO" .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
             dstip .. ":" .. dp)
  end

end

rcode() ^^^^^^^^^^^

Get the rcode value as an integer.

Example::

local tx = dns.get_tx() local rcode = tx:rcode() print (rcode)

rcode_string() ^^^^^^^^^^^^^^^^^^

Get the rcode value as a string.

Example::

local tx = dns.get_tx() local rcode_string = tx:rcode_string(); print (rcode_string)

recursion_desired() ^^^^^^^^^^^^^^^^^^^^^^^

Return the value of the recursion desired (RD) flag as a boolean.

Example::

local tx = dns.get_tx() if tx:recursion_desired() == true then print ("RECURSION DESIRED") end

rrname() ^^^^^^^^^^^^

Return the resource name from the first query object.

Example::

local tx = dns.get_tx() local rrname = tx:rrname() print(rrname)

txid() ^^^^^^^^^^

Return the DNS transaction ID found in the DNS message.

Example::

local tx = dns.get_tx() local txid = tx:txid() print(txid)