Executing scripts on log events

By setting up syslog-ng, as well as syslog translation on the MITIGATOR side, you can execute arbitrary scripts: blocking scripts, protection switching, BGP route switching, and so on. Syslog record format.

Syslog-ng setup

The configuration is written to /etc/syslog-ng/conf.d/mitigator.conf.

Parameters for receiving messages (protocol, port) must match the settings in the MITIGATOR web interface. The expect-hostname option is required because the hostname is specified in the messages.

source s_udp {
    syslog(transport("udp") flags(expect-hostname));
};

All MITIGATOR messages have the same program name, by which you can filter them:

filter f_mitigator {
    program("BIFIT_Mitigator");
};

The event description is in JSON format. To simplify the script, you can parse messages and select only those you need using syslog-ng. In the example, events of incoming traffic exceeding the thresholds to any policy are selected, the Policy.InputPps predicate is chosen in the interface. A description of the message format (types of events and their properties) can be obtained from technical support.

parser p_json {
    json-parser(prefix(".json."));
};

filter f_autodetect {
    "${.json.type_id}" eq "autodetect_alert_up" and "${.json.custom.autodetect_alert_flow}" eq "input.total.pps";
};

Finally, the script call is configured for the selected events (the script must be created and made executable):

destination d_prog {
    program("/srv/mitigator/script.sh");
};

log {
    source(s_udp);
    filter(f_mitigator);
    parser(p_json);
    filter(f_autodetect);
    destination(d_prog);
};

To apply a configuration:

systemctl reload syslog-ng

Processing messages with a script

The script receives message texts - JSON - on standard input, one message per line.

It is recommended that the script read the lines in an endless loop without long operations. However, syslog-ng can also restart the script on every message, which is handy when debugging the script.

If you take advantage of the fact that syslog-ng already parses JSON, you can immediately pass the necessary fields to the script, for example:

destination d_prog {
    program(
        "/srv/mitigator/script.sh"
        template(
            "${HOST} ${.json.type_id} ${.json.custom.autodetect_alert_flow}\n"
        ));
};

In this case, the script can read them like this:

#!/usr/bin/env sh
read host event metric
echo "Host:   $host"
echo "Event:  $event"
echo "Metric: $metric"

More flexibility at the cost of a more complex script can be achieved by removing JSON parsing and filtering using syslog-ng, and parsing JSON and selecting messages in a script.