doc: add configuration
@ -0,0 +1,119 @@
|
|||||||
|
Global-Thresholds
|
||||||
|
=================
|
||||||
|
|
||||||
|
Thresholds can be configured in the rules themselves, see
|
||||||
|
:doc:`../rules/thresholding`. They are often set by rule writers based on
|
||||||
|
their intel for creating a rule combined with a judgement on how often
|
||||||
|
a rule will alert.
|
||||||
|
|
||||||
|
Next to these settings, thresholding can be configured on the sensor
|
||||||
|
using the threshold.config.
|
||||||
|
|
||||||
|
threshold/event_filter
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Syntax:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
threshold gen_id <gid>, sig_id <sid>, type <threshold|limit|both>, track <by_src|by_dst>, count <N>, seconds <T>
|
||||||
|
|
||||||
|
rate_filter
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
suppress
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
Suppressions can be used to suppress alerts for a rule or a
|
||||||
|
host/network. Actions performed when a rule matches, such as setting a
|
||||||
|
flowbit, are still performed.
|
||||||
|
|
||||||
|
Syntax:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
suppress gen_id <gid>, sig_id <sid>
|
||||||
|
suppress gen_id <gid>, sig_id <sid>, track <by_src|by_dst>, ip <ip|subnet>
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
suppress gen_id 1, sig_id 2002087, track by_src, ip 209.132.180.67
|
||||||
|
|
||||||
|
This will make sure the signature 2002087 will never match for src
|
||||||
|
host 209.132.180.67.
|
||||||
|
|
||||||
|
.. _global-thresholds-vs-rule-thresholds:
|
||||||
|
|
||||||
|
Global thresholds vs rule thresholds
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
**Note: this section applies to 1.4+ In 1.3 and before mixing rule and
|
||||||
|
global thresholds is not supported.**
|
||||||
|
|
||||||
|
When a rule has a threshold/detection_filter set a rule can still be
|
||||||
|
affected by the global threshold file.
|
||||||
|
|
||||||
|
The rule below will only fire if 10 or more emails are being
|
||||||
|
delivered/sent from a host within 60 seconds.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
alert tcp any any -> any 25 (msg:"ET POLICY Inbound Frequent Emails - Possible Spambot Inbound"; \
|
||||||
|
flow:established; content:"mail from|3a|"; nocase; \
|
||||||
|
threshold: type threshold, track by_src, count 10, seconds 60; \
|
||||||
|
reference:url,doc.emergingthreats.net/2002087; classtype:misc-activity; sid:2002087; rev:10;)
|
||||||
|
|
||||||
|
Next, we'll see how global settings affect this rule.
|
||||||
|
|
||||||
|
Suppress
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
Suppressions can be combined with rules with
|
||||||
|
thresholds/detection_filters with no exceptions.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
suppress gen_id 1, sig_id 2002087, track by_src, ip 209.132.180.67
|
||||||
|
suppress gen_id 0, sig_id 0, track by_src, ip 209.132.180.67
|
||||||
|
suppress gen_id 1, sig_id 0, track by_src, ip 209.132.180.67
|
||||||
|
|
||||||
|
Each of the rules above will make sure 2002087 doesn't alert when the
|
||||||
|
source of the emails is 209.132.180.67. It **will** alert for all other
|
||||||
|
hosts.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
suppress gen_id 1, sig_id 2002087
|
||||||
|
|
||||||
|
This suppression will simply convert the rule to "noalert", meaning it
|
||||||
|
will never alert in any case. If the rule sets a flowbit, that will
|
||||||
|
still happen.
|
||||||
|
|
||||||
|
Threshold/event_filter
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
When applied to a specific signature, thresholds and event_filters
|
||||||
|
(threshold from now on) will override the signature setting. This can
|
||||||
|
be useful for when the default in a signature doesn't suit your
|
||||||
|
evironment.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
threshold gen_id 1, sig_id 2002087, type both, track by_src, count 3, seconds 5
|
||||||
|
threshold gen_id 1, sig_id 2002087, type threshold, track by_src, count 10, seconds 60
|
||||||
|
threshold gen_id 1, sig_id 2002087, type limit, track by_src, count 1, seconds 15
|
||||||
|
|
||||||
|
Each of these will replace the threshold setting for 2002087 by the
|
||||||
|
new threshold setting.
|
||||||
|
|
||||||
|
**Note:** overriding all gids or sids (by using gen_id 0 or sig_id 0)
|
||||||
|
is not supported. Bug #425.
|
||||||
|
|
||||||
|
Rate_filter
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
TODO
|
@ -0,0 +1,11 @@
|
|||||||
|
Configuration
|
||||||
|
=============
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
|
||||||
|
suricata-yaml
|
||||||
|
global-thresholds
|
||||||
|
snort-to-suricata
|
||||||
|
log-rotation
|
||||||
|
lua-output
|
||||||
|
multi-tenant
|
@ -0,0 +1,31 @@
|
|||||||
|
Log Rotation
|
||||||
|
============
|
||||||
|
|
||||||
|
Starting with Suricata version 2.0.2 (#1200), log rotation is made a
|
||||||
|
lot easier. A HUP signal sent to Suricata will force it to reopen the
|
||||||
|
logfiles.
|
||||||
|
|
||||||
|
Example logrotate file:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
/var/log/suricata/*.log /var/log/suricata/*.json
|
||||||
|
{
|
||||||
|
rotate 3
|
||||||
|
missingok
|
||||||
|
nocompress
|
||||||
|
create
|
||||||
|
sharedscripts
|
||||||
|
postrotate
|
||||||
|
/bin/kill -HUP $(cat /var/run/suricata.pid)
|
||||||
|
endscript
|
||||||
|
}
|
||||||
|
|
||||||
|
newsyslog based log rotation (e.g. on OpenBSD) /etc/newsyslog.conf:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
/var/log/suricata/eve.json root:wheel 640 1 * 24 B /var/run/suricata.pid SIGHUP
|
||||||
|
|
||||||
|
The above rotates every 24h; the 'B' prevents a rotation logmessage in
|
||||||
|
eve.json. Fieldseperator is a TAB.
|
@ -0,0 +1,656 @@
|
|||||||
|
Lua Output
|
||||||
|
==========
|
||||||
|
|
||||||
|
Note: this page new Lua scripting available for outputs. It will be
|
||||||
|
available in 2.1.
|
||||||
|
|
||||||
|
Script structure
|
||||||
|
----------------
|
||||||
|
|
||||||
|
A script defines 4 functions: init, setup, log, deinit
|
||||||
|
|
||||||
|
* init -- registers where the script hooks into the output engine
|
||||||
|
* setup -- does per output thread setup
|
||||||
|
* log -- logging function
|
||||||
|
* deinit -- clean up function
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs["protocol"] = "http"
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
function setup (args)
|
||||||
|
filename = SCLogPath() .. "/" .. name
|
||||||
|
file = assert(io.open(filename, "a"))
|
||||||
|
SCLogInfo("HTTP Log Filename " .. filename)
|
||||||
|
http = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function log(args)
|
||||||
|
http_uri = HttpGetRequestUriRaw()
|
||||||
|
if http_uri == nil then
|
||||||
|
http_uri = "<unknown>"
|
||||||
|
end
|
||||||
|
http_uri = string.gsub(http_uri, "%c", ".")
|
||||||
|
|
||||||
|
http_host = HttpGetRequestHost()
|
||||||
|
if http_host == nil then
|
||||||
|
http_host = "<hostname unknown>"
|
||||||
|
end
|
||||||
|
http_host = string.gsub(http_host, "%c", ".")
|
||||||
|
|
||||||
|
http_ua = HttpGetRequestHeader("User-Agent")
|
||||||
|
if http_ua == nil then
|
||||||
|
http_ua = "<useragent unknown>"
|
||||||
|
end
|
||||||
|
http_ua = string.gsub(http_ua, "%g", ".")
|
||||||
|
|
||||||
|
ts = SCPacketTimeString()
|
||||||
|
ipver, srcip, dstip, proto, sp, dp = SCFlowTuple()
|
||||||
|
|
||||||
|
file:write (ts .. " " .. http_host .. " [**] " .. http_uri .. " [**] " ..
|
||||||
|
http_ua .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
|
||||||
|
dstip .. ":" .. dp .. "\n")
|
||||||
|
file:flush()
|
||||||
|
|
||||||
|
http = http + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function deinit (args)
|
||||||
|
SCLogInfo ("HTTP transactions logged: " .. http);
|
||||||
|
file:close(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
YAML
|
||||||
|
----
|
||||||
|
|
||||||
|
To enable the lua output, add the 'lua' output and add one or more
|
||||||
|
scripts like so:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
- lua:
|
||||||
|
enabled: yes
|
||||||
|
scripts-dir: /etc/suricata/lua-output/
|
||||||
|
scripts:
|
||||||
|
- tcp-data.lua
|
||||||
|
- flow.lua
|
||||||
|
|
||||||
|
The scripts-dir option is optional. It makes Suricata load the scripts
|
||||||
|
from this directory. Otherwise scripts will be loaded from the current
|
||||||
|
workdir.
|
||||||
|
|
||||||
|
packet
|
||||||
|
------
|
||||||
|
|
||||||
|
Initialize with:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs["type"] = "packet"
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
SCPacketTimeString
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Add SCPacketTimeString to get the packets time string in the format:
|
||||||
|
11/24/2009-18:57:25.179869
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function log(args)
|
||||||
|
ts = SCPacketTimeString()
|
||||||
|
|
||||||
|
SCPacketTuple
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
ipver, srcip, dstip, proto, sp, dp = SCPacketTuple()
|
||||||
|
|
||||||
|
SCPacketPayload
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
p = SCPacketPayload()
|
||||||
|
|
||||||
|
flow
|
||||||
|
----
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs["type"] = "flow"
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
SCFlowTimeString
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
startts = SCFlowTimeString()
|
||||||
|
|
||||||
|
SCFlowTuple
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
ipver, srcip, dstip, proto, sp, dp = SCFlowTuple()
|
||||||
|
|
||||||
|
SCFlowAppLayerProto
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Get alproto as string from the flow. If alproto is not (yet) known, it
|
||||||
|
returns "unknown".
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function log(args)
|
||||||
|
alproto = SCFlowAppLayerProto()
|
||||||
|
if alproto ~= nil then
|
||||||
|
print (alproto)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SCFlowStats
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
Gets the packet and byte counts per flow.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
tscnt, tsbytes, tccnt, tcbytes = SCFlowStats()
|
||||||
|
|
||||||
|
http
|
||||||
|
----
|
||||||
|
|
||||||
|
Init with:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs["protocol"] = "http"
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
HttpGetRequestBody and HttpGetResponseBody.
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Make normalized body data available to the script through
|
||||||
|
HttpGetRequestBody and HttpGetResponseBody.
|
||||||
|
|
||||||
|
There no guarantees that all of the body will be availble.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function log(args)
|
||||||
|
a, o, e = HttpGetResponseBody();
|
||||||
|
--print("offset " .. o .. " end " .. e)
|
||||||
|
for n, v in ipairs(a) do
|
||||||
|
print(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
HttpGetRequestHost
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Get the host from libhtp's tx->request_hostname, which can either be
|
||||||
|
the host portion of the url or the host portion of the Host header.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
http_host = HttpGetRequestHost()
|
||||||
|
if http_host == nil then
|
||||||
|
http_host = "<hostname unknown>"
|
||||||
|
end
|
||||||
|
|
||||||
|
HttpGetRequestHeader
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
http_ua = HttpGetRequestHeader("User-Agent")
|
||||||
|
if http_ua == nil then
|
||||||
|
http_ua = "<useragent unknown>"
|
||||||
|
end
|
||||||
|
|
||||||
|
HttpGetResponseHeader
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
server = HttpGetResponseHeader("Server");
|
||||||
|
print ("Server: " .. server);
|
||||||
|
|
||||||
|
HttpGetRequestLine
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
rl = HttpGetRequestLine();
|
||||||
|
print ("Request Line: " .. rl);
|
||||||
|
|
||||||
|
HttpGetResponseLine
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
rsl = HttpGetResponseLine();
|
||||||
|
print ("Response Line: " .. rsl);
|
||||||
|
|
||||||
|
HttpGetRawRequestHeaders
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
rh = HttpGetRawRequestHeaders();
|
||||||
|
print ("Raw Request Headers: " .. rh);
|
||||||
|
|
||||||
|
HttpGetRawResponseHeaders
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
rh = HttpGetRawResponseHeaders();
|
||||||
|
print ("Raw Response Headers: " .. rh);
|
||||||
|
|
||||||
|
HttpGetRequestUriRaw
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
http_uri = HttpGetRequestUriRaw()
|
||||||
|
if http_uri == nil then
|
||||||
|
http_uri = "<unknown>"
|
||||||
|
end
|
||||||
|
|
||||||
|
HttpGetRequestUriNormalized
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
http_uri = HttpGetRequestUriNormalized()
|
||||||
|
if http_uri == nil then
|
||||||
|
http_uri = "<unknown>"
|
||||||
|
end
|
||||||
|
|
||||||
|
HttpGetRequestHeaders
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
a = HttpGetRequestHeaders();
|
||||||
|
for n, v in pairs(a) do
|
||||||
|
print(n,v)
|
||||||
|
end
|
||||||
|
|
||||||
|
HttpGetResponseHeaders
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
a = HttpGetResponseHeaders();
|
||||||
|
for n, v in pairs(a) do
|
||||||
|
print(n,v)
|
||||||
|
end
|
||||||
|
|
||||||
|
DNS
|
||||||
|
---
|
||||||
|
|
||||||
|
DnsGetQueries
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
dns_query = DnsGetQueries();
|
||||||
|
if dns_query ~= nil then
|
||||||
|
for n, t in pairs(dns_query) do
|
||||||
|
rrname = t["rrname"]
|
||||||
|
rrtype = t["type"]
|
||||||
|
|
||||||
|
print ("QUERY: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
|
||||||
|
"TODO" .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
|
||||||
|
dstip .. ":" .. dp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
returns a table of tables
|
||||||
|
|
||||||
|
DnsGetAnswers
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
dns_answers = DnsGetAnswers();
|
||||||
|
if dns_answers ~= nil then
|
||||||
|
for n, t in pairs(dns_answers) do
|
||||||
|
rrname = t["rrname"]
|
||||||
|
rrtype = t["type"]
|
||||||
|
ttl = t["ttl"]
|
||||||
|
|
||||||
|
print ("ANSWER: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
|
||||||
|
ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
|
||||||
|
dstip .. ":" .. dp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
returns a table of tables
|
||||||
|
|
||||||
|
DnsGetAuthorities
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
dns_auth = DnsGetAuthorities();
|
||||||
|
if dns_auth ~= nil then
|
||||||
|
for n, t in pairs(dns_auth) do
|
||||||
|
rrname = t["rrname"]
|
||||||
|
rrtype = t["type"]
|
||||||
|
ttl = t["ttl"]
|
||||||
|
|
||||||
|
print ("AUTHORITY: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..
|
||||||
|
ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " ..
|
||||||
|
dstip .. ":" .. dp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
returns a table of tables
|
||||||
|
|
||||||
|
DnsGetRcode
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
rcode = DnsGetRcode();
|
||||||
|
if rcode == nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
print (rcode)
|
||||||
|
|
||||||
|
returns a lua string with the error message, or nil
|
||||||
|
|
||||||
|
DnsGetRecursionDesired
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
if DnsGetRecursionDesired() == true then
|
||||||
|
print ("RECURSION DESIRED")
|
||||||
|
end
|
||||||
|
|
||||||
|
returns a bool
|
||||||
|
|
||||||
|
TLS
|
||||||
|
---
|
||||||
|
|
||||||
|
Initialize with:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs["protocol"] = "tls"
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
TlsGetCertInfo
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Make certificate information available to the script through TlsGetCertInfo.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function log (args)
|
||||||
|
version, subject, issuer, fingerprint = TlsGetCertInfo()
|
||||||
|
if version == nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
SSH
|
||||||
|
---
|
||||||
|
|
||||||
|
Initialize with:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs["protocol"] = "ssh"
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
SshGetServerProtoVersion
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Get SSH protocol version used by the server through SshGetServerProtoVersion.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function log (args)
|
||||||
|
version = SshGetServerProtoVersion()
|
||||||
|
if version == nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SshGetServerSoftwareVersion
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Get SSH software used by the server through SshGetServerSoftwareVersion.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
function log (args)
|
||||||
|
software = SshGetServerSoftwareVersion()
|
||||||
|
if software == nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SshGetClientProtoVersion
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Get SSH protocol version used by the client through SshGetClientProtoVersion.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function log (args)
|
||||||
|
version = SshGetClientProtoVersion()
|
||||||
|
if version == nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SshGetClientSoftwareVersion
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Get SSH software used by the client through SshGetClientSoftwareVersion.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function log (args)
|
||||||
|
software = SshGetClientSoftwareVersion()
|
||||||
|
if software == nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Files
|
||||||
|
-----
|
||||||
|
|
||||||
|
To use the file logging API, the script's init() function needs to look like:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs['type'] = 'file'
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
SCFileInfo
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
fileid, txid, name, size, magic, md5 = SCFileInfo()
|
||||||
|
|
||||||
|
returns fileid (number), txid (number), name (string), size (number),
|
||||||
|
magic (string), md5 in hex (string)
|
||||||
|
|
||||||
|
SCFileState
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
state, stored = SCFileState()
|
||||||
|
|
||||||
|
returns state (string), stored (bool)
|
||||||
|
|
||||||
|
Alerts
|
||||||
|
------
|
||||||
|
|
||||||
|
Alerts are a subset of the 'packet' logger:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs["type"] = "packet"
|
||||||
|
needs["filter"] = "alerts"
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
SCRuleIds
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
sid, rev, gid = SCRuleIds()
|
||||||
|
|
||||||
|
SCRuleMsg
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
msg = SCRuleMsg()
|
||||||
|
|
||||||
|
SCRuleClass
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
class, prio = SCRuleClass()
|
||||||
|
|
||||||
|
Streaming Data
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Streaming data can currently log out reassembled TCP data and
|
||||||
|
normalized HTTP data. The script will be invoked for each consecutive
|
||||||
|
data chunk.
|
||||||
|
|
||||||
|
In case of TCP reassembled data, all possible overlaps are removed
|
||||||
|
according to the host OS settings.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs["type"] = "streaming"
|
||||||
|
needs["filter"] = "tcp"
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
In case of HTTP body data, the bodies are unzipped and dechunked if applicable.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init (args)
|
||||||
|
local needs = {}
|
||||||
|
needs["type"] = "streaming"
|
||||||
|
needs["protocol"] = "http"
|
||||||
|
return needs
|
||||||
|
end
|
||||||
|
|
||||||
|
SCStreamingBuffer
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function log(args)
|
||||||
|
data = SCStreamingBuffer()
|
||||||
|
hex_dump(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
Misc
|
||||||
|
----
|
||||||
|
|
||||||
|
SCThreadInfo
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
tid, tname, tgroup = SCThreadInfo()
|
||||||
|
|
||||||
|
It gives: tid (integer), tname (string), tgroup (string)
|
||||||
|
|
||||||
|
SCLogError, SCLogWarning, SCLogNotice, SCLogInfo, SCLogDebug
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Print a message. It will go into the outputs defined in the
|
||||||
|
yaml. Whether it will be printed depends on the log level.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
SCLogError("some error message")
|
||||||
|
|
||||||
|
SCLogPath
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
Expose the log path.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
name = "fast_lua.log"
|
||||||
|
function setup (args)
|
||||||
|
filename = SCLogPath() .. "/" .. name
|
||||||
|
file = assert(io.open(filename, "a"))
|
||||||
|
end
|
@ -0,0 +1,167 @@
|
|||||||
|
Multi Tenancy
|
||||||
|
=============
|
||||||
|
|
||||||
|
**Work In Progress**
|
||||||
|
|
||||||
|
This is part of Suricata 3.0RC1.
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
Multi tenancy support allows for different rule sets with different
|
||||||
|
rule vars.
|
||||||
|
|
||||||
|
YAML
|
||||||
|
----
|
||||||
|
|
||||||
|
In the main ("master") YAML, the suricata.yaml, a new section called
|
||||||
|
"multi-detect" should be added.
|
||||||
|
|
||||||
|
Settings:
|
||||||
|
|
||||||
|
* enabled: yes/no -> is multi-tenancy support enable
|
||||||
|
* default: yes/no -> is the normal detect config a default 'fall back' tenant?
|
||||||
|
* selector: direct (for unix socket pcap processing, see below) or vlan
|
||||||
|
* loaders: number of 'loader' threads, for parallel tenant loading at startup
|
||||||
|
* tenants: list of tenants
|
||||||
|
|
||||||
|
* id: tenant id
|
||||||
|
* yaml: separate yaml file with the tenant specific settings
|
||||||
|
|
||||||
|
* mappings:
|
||||||
|
|
||||||
|
* vlan id
|
||||||
|
* tenant id: tenant to associate with the vlan id
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
multi-detect:
|
||||||
|
enabled: yes
|
||||||
|
#selector: direct # direct or vlan
|
||||||
|
selector: vlan
|
||||||
|
loaders: 3
|
||||||
|
|
||||||
|
tenants:
|
||||||
|
- id: 1
|
||||||
|
yaml: tenant-1.yaml
|
||||||
|
- id: 2
|
||||||
|
yaml: tenant-2.yaml
|
||||||
|
- id: 3
|
||||||
|
yaml: tenant-3.yaml
|
||||||
|
|
||||||
|
mappings:
|
||||||
|
- vlan-id: 1000
|
||||||
|
tenant-id: 1
|
||||||
|
- vlan-id: 2000
|
||||||
|
tenant-id: 2
|
||||||
|
- vlan-id: 1112
|
||||||
|
tenant-id: 3
|
||||||
|
|
||||||
|
The tenant-1.yaml, tenant-2.yaml, tenant-3.yaml each contain a partial
|
||||||
|
configuration:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Set the default rule path here to search for the files.
|
||||||
|
# if not set, it will look at the current working dir
|
||||||
|
default-rule-path: /etc/suricata/rules
|
||||||
|
rule-files:
|
||||||
|
- rules1
|
||||||
|
|
||||||
|
# You can specify a threshold config file by setting "threshold-file"
|
||||||
|
# to the path of the threshold config file:
|
||||||
|
# threshold-file: /etc/suricata/threshold.config
|
||||||
|
|
||||||
|
classification-file: /etc/suricata/classification.config
|
||||||
|
reference-config-file: /etc/suricata/reference.config
|
||||||
|
|
||||||
|
# Holds variables that would be used by the engine.
|
||||||
|
vars:
|
||||||
|
|
||||||
|
# Holds the address group vars that would be passed in a Signature.
|
||||||
|
# These would be retrieved during the Signature address parsing stage.
|
||||||
|
address-groups:
|
||||||
|
|
||||||
|
HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"
|
||||||
|
|
||||||
|
EXTERNAL_NET: "!$HOME_NET"
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
port-groups:
|
||||||
|
|
||||||
|
HTTP_PORTS: "80"
|
||||||
|
|
||||||
|
SHELLCODE_PORTS: "!80"
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
Unix Socket
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Registration
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
register-tenant <id> <yaml>
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
register-tenant 1 tenant-1.yaml
|
||||||
|
register-tenant 2 tenant-2.yaml
|
||||||
|
register-tenant 3 tenant-3.yaml
|
||||||
|
register-tenant 5 tenant-5.yaml
|
||||||
|
register-tenant 7 tenant-7.yaml
|
||||||
|
|
||||||
|
unregister-tenant <id>
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
unregister-tenant 2
|
||||||
|
unregister-tenant 1
|
||||||
|
|
||||||
|
Unix socket runmode (pcap processing)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The Unix Socket "pcap-file" command can be used to select the tenant
|
||||||
|
to inspect the pcap against:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
pcap-file traffic1.pcap /logs1/ 1
|
||||||
|
pcap-file traffic2.pcap /logs2/ 2
|
||||||
|
pcap-file traffic3.pcap /logs3/ 3
|
||||||
|
pcap-file traffic4.pcap /logs5/ 5
|
||||||
|
pcap-file traffic5.pcap /logs7/ 7
|
||||||
|
|
||||||
|
This runs the traffic1.pcap against tenant 1 and it logs into /logs1/,
|
||||||
|
traffic2.pcap against tenant 2 and logs to /logs2/ and so on.
|
||||||
|
|
||||||
|
Live traffic mode
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
For live traffic currently only a vlan based multi-tenancy is supported.
|
||||||
|
|
||||||
|
The master yaml needs to have the selector set to "vlan".
|
||||||
|
|
||||||
|
Registration
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Tenants can be mapped to vlan id's.
|
||||||
|
|
||||||
|
register-tenant-handler <tenant id> vlan <vlan id>
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
register-tenant-handler 1 vlan 1000
|
||||||
|
|
||||||
|
unregister-tenant-handler <tenant id> vlan <vlan id>
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
unregister-tenant-handler 4 vlan 1111
|
||||||
|
unregister-tenant-handler 1 vlan 1000
|
||||||
|
|
||||||
|
The registration of tenant and tenant handlers can be done on a
|
||||||
|
running engine.
|
@ -0,0 +1,276 @@
|
|||||||
|
Snort.conf to Suricata.yaml
|
||||||
|
===========================
|
||||||
|
|
||||||
|
This guide is meant for those who are familiar with Snort and the
|
||||||
|
snort.conf configuration format. This guide will provide a 1:1 mapping
|
||||||
|
between Snort and Suricata configuration wherever possible.
|
||||||
|
|
||||||
|
Variables
|
||||||
|
---------
|
||||||
|
|
||||||
|
snort.conf
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
ipvar HOME_NET any
|
||||||
|
ipvar EXTERNAL_NET any
|
||||||
|
...
|
||||||
|
|
||||||
|
portvar HTTP_PORTS [80,81,311,591,593,901,1220,1414,1741,1830,2301,2381,2809,3128,3702,4343,4848,5250,7001,7145,7510,7777,7779,8000,8008,8014,8028,8080,8088,8090,8118,8123,8180,8181,8243,8280,8800,8888,8899,9000,9080,9090,9091,9443,9999,11371,55555]
|
||||||
|
portvar SHELLCODE_PORTS !80
|
||||||
|
...
|
||||||
|
|
||||||
|
suricata.yaml
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
vars:
|
||||||
|
address-groups:
|
||||||
|
|
||||||
|
HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"
|
||||||
|
EXTERNAL_NET: "!$HOME_NET"
|
||||||
|
|
||||||
|
port-groups:
|
||||||
|
HTTP_PORTS: "80"
|
||||||
|
SHELLCODE_PORTS: "!80"
|
||||||
|
|
||||||
|
Note that Suricata can automatically detect HTTP traffic regardless of
|
||||||
|
the port it uses. So the HTTP_PORTS variable is not nearly as
|
||||||
|
important as it is with Snort, **if** you use a Suricata enabled
|
||||||
|
ruleset.
|
||||||
|
|
||||||
|
Decoder alerts
|
||||||
|
--------------
|
||||||
|
|
||||||
|
snort.conf
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Stop generic decode events:
|
||||||
|
config disable_decode_alerts
|
||||||
|
|
||||||
|
# Stop Alerts on experimental TCP options
|
||||||
|
config disable_tcpopt_experimental_alerts
|
||||||
|
|
||||||
|
# Stop Alerts on obsolete TCP options
|
||||||
|
config disable_tcpopt_obsolete_alerts
|
||||||
|
|
||||||
|
# Stop Alerts on T/TCP alerts
|
||||||
|
config disable_tcpopt_ttcp_alerts
|
||||||
|
|
||||||
|
# Stop Alerts on all other TCPOption type events:
|
||||||
|
config disable_tcpopt_alerts
|
||||||
|
|
||||||
|
# Stop Alerts on invalid ip options
|
||||||
|
config disable_ipopt_alerts
|
||||||
|
|
||||||
|
suricata.yaml
|
||||||
|
|
||||||
|
Suricata has no specific decoder options. All decoder related alerts
|
||||||
|
are controlled by rules. See #Rules below.
|
||||||
|
|
||||||
|
Checksum handling
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
snort.conf
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
config checksum_mode: all
|
||||||
|
|
||||||
|
suricata.yaml
|
||||||
|
|
||||||
|
Suricata's checksum handling works _on-demand_. The stream engine
|
||||||
|
checks TCP and IP checksum by default:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
stream:
|
||||||
|
checksum-validation: yes # reject wrong csums
|
||||||
|
|
||||||
|
Alerting on bad checksums can be done with normal rules. See #Rules,
|
||||||
|
decoder-events.rules specifically.
|
||||||
|
|
||||||
|
Various configs
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Active response
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
snort.conf
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Configure active response for non inline operation. For more information, see REAMDE.active
|
||||||
|
# config response: eth0 attempts 2
|
||||||
|
|
||||||
|
suricata.yaml
|
||||||
|
|
||||||
|
Active responses are handled automatically w/o config if rules with
|
||||||
|
the "reject" action are used.
|
||||||
|
|
||||||
|
Dropping privileges
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
snort.conf
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
# Configure specific UID and GID to run snort as after dropping privs. For more information see snort -h command line options
|
||||||
|
#
|
||||||
|
# config set_gid:
|
||||||
|
# config set_uid:
|
||||||
|
|
||||||
|
Suricata
|
||||||
|
|
||||||
|
To set the user and group use the --user <username> and --group
|
||||||
|
<groupname> commandline options.
|
||||||
|
|
||||||
|
Snaplen
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
snort.conf
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Configure default snaplen. Snort defaults to MTU of in use interface. For more information see README
|
||||||
|
#
|
||||||
|
# config snaplen:
|
||||||
|
#
|
||||||
|
|
||||||
|
Suricata always works at full snap length to provide full traffic visibility.
|
||||||
|
|
||||||
|
Bpf
|
||||||
|
~~~
|
||||||
|
|
||||||
|
snort.conf
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Configure default bpf_file to use for filtering what traffic reaches snort. For more information see snort -h command line options (-F)
|
||||||
|
#
|
||||||
|
# config bpf_file:
|
||||||
|
#
|
||||||
|
|
||||||
|
suricata.yaml
|
||||||
|
|
||||||
|
BPF filters can be set per packet acquisition method, with the "bpf-filter: <file>" yaml option and in a file using the -F command line option.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
pcap:
|
||||||
|
- interface: eth0
|
||||||
|
#buffer-size: 16777216
|
||||||
|
#bpf-filter: "tcp and port 25"
|
||||||
|
#checksum-checks: auto
|
||||||
|
#threads: 16
|
||||||
|
#promisc: no
|
||||||
|
#snaplen: 1518
|
||||||
|
|
||||||
|
Log directory
|
||||||
|
-------------
|
||||||
|
|
||||||
|
snort.conf
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Configure default log directory for snort to log to. For more information see snort -h command line options (-l)
|
||||||
|
#
|
||||||
|
# config logdir:
|
||||||
|
|
||||||
|
suricata.yaml
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
default-log-dir: /var/log/suricata/
|
||||||
|
|
||||||
|
This value is overridden by the -l commandline option.
|
||||||
|
|
||||||
|
Packet acquisition
|
||||||
|
------------------
|
||||||
|
|
||||||
|
snort.conf
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Configure DAQ related options for inline operation. For more information, see README.daq
|
||||||
|
#
|
||||||
|
# config daq: <type>
|
||||||
|
# config daq_dir: <dir>
|
||||||
|
# config daq_mode: <mode>
|
||||||
|
# config daq_var: <var>
|
||||||
|
#
|
||||||
|
# <type> ::= pcap | afpacket | dump | nfq | ipq | ipfw
|
||||||
|
# <mode> ::= read-file | passive | inline
|
||||||
|
# <var> ::= arbitrary <name>=<value passed to DAQ
|
||||||
|
# <dir> ::= path as to where to look for DAQ module so's
|
||||||
|
|
||||||
|
suricata.yaml
|
||||||
|
|
||||||
|
Suricata has all packet acquisition support built-in. It's
|
||||||
|
configuration format is very verbose.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
pcap:
|
||||||
|
- interface: eth0
|
||||||
|
#buffer-size: 16777216
|
||||||
|
#bpf-filter: "tcp and port 25"
|
||||||
|
#checksum-checks: auto
|
||||||
|
#threads: 16
|
||||||
|
#promisc: no
|
||||||
|
#snaplen: 1518
|
||||||
|
pfring:
|
||||||
|
afpacket:
|
||||||
|
nfq:
|
||||||
|
ipfw:
|
||||||
|
|
||||||
|
Passive vs inline vs reading files is determined by how Suricata is
|
||||||
|
invoked on the command line.
|
||||||
|
|
||||||
|
Rules
|
||||||
|
-----
|
||||||
|
|
||||||
|
snort.conf:
|
||||||
|
|
||||||
|
In snort.conf a RULE_PATH variable is set, as well as variables for
|
||||||
|
shared object (SO) rules and preprocessor rules.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
var RULE_PATH ../rules
|
||||||
|
var SO_RULE_PATH ../so_rules
|
||||||
|
var PREPROC_RULE_PATH ../preproc_rules
|
||||||
|
|
||||||
|
include $RULE_PATH/local.rules
|
||||||
|
include $RULE_PATH/emerging-activex.rules
|
||||||
|
...
|
||||||
|
|
||||||
|
suricata.yaml:
|
||||||
|
|
||||||
|
In the suricata.yaml the default rule path is set followed by a list
|
||||||
|
of rule files. Suricata does not have a concept of shared object rules
|
||||||
|
or preprocessor rules. Instead of preprocessor rules, Suricata has
|
||||||
|
several rule files for events set by the decoders, stream engine, http
|
||||||
|
parser etc.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
default-rule-path: /etc/suricata/rules
|
||||||
|
rule-files:
|
||||||
|
- local.rules
|
||||||
|
- emerging-activex.rules
|
||||||
|
|
||||||
|
The equivalent of preprocessor rules are loaded like normal rule files:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
rule-files:
|
||||||
|
- decoder-events.rules
|
||||||
|
- stream-events.rules
|
||||||
|
- http-events.rules
|
||||||
|
- smtp-events.rules
|
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 17 KiB |