Key takeaways
- Keep the main ISC BIND TA parser in the standard named-program format.
- Route documented BIND categories to Splunk_TA_isc-bind sourcetypes.
- Add authorized dynamic update observability as a separate optional parser and Splunk knowledge component.
- Preserve raw BIND messages with t_msg_only so Splunk search-time extraction remains reliable.
Keep The TA Parser Clean And Maintainable
The main SC4S parser for Splunk_TA_isc-bind should stay focused on the categories and sourcetypes the add-on already understands. That means matching program("named") and routing queries, query-errors, network, notify, transfer, and lame-servers events to the TA sourcetypes.
Authorized dynamic DNS update events are a little different in this environment. They arrive from a helper program such as dns-txt-transfer-bind, not from named, and Splunk_TA_isc-bind 2.0.0 does not ship an isc:bind:update stanza. For that reason, dynamic update observability is kept as a separate optional component.
Responsible Use And Scope
This parser guide is for approved Splunk and SC4S administration. It focuses on classification, field extraction, and log quality for legitimate ISC BIND operations. Use the optional update parser only when those helper-program logs are part of an authorized DNS workflow.
Parser changes should be tested in a non-production SC4S instance first, then promoted through the normal change process for your SIEM environment.
Component Layout
| Component | File | Install target | Purpose |
|---|---|---|---|
| Main TA parser | app-isc_bind_ta.conf | /opt/sc4s/local/config/app_parsers/syslog/app-isc_bind_ta.conf | Routes standard named BIND logs to TA sourcetypes |
| Optional update parser | app-isc_bind_update.conf | /opt/sc4s/local/config/app_parsers/syslog/app-isc_bind_update.conf | Routes dns-* dynamic update logs to isc:bind:update |
| Update props | splunk_props_isc_bind_update.conf | $SPLUNK_HOME/etc/apps/Splunk_TA_isc-bind/local/props.conf | Adds local Splunk props for isc:bind:update |
| Update transforms | splunk_transforms_isc_bind_update.conf | $SPLUNK_HOME/etc/apps/Splunk_TA_isc-bind/local/transforms.conf | Extracts update fields |
| Test generator | generate_isc_bind_ta_logs.sh | Any Linux test host | Generates standard and update test logs |
Sourcetype Map
| BIND signal | Sourcetype | Component |
|---|---|---|
queries: with query: | isc:bind:query | Main TA parser |
query-errors: or query failed | isc:bind:queryerror | Main TA parser |
lame-servers: or resolver lame-server text | isc:bind:lameserver | Main TA parser |
notify:, xfer-in:, xfer-out:, transfer: | isc:bind:transfer | Main TA parser |
network: or listening state messages | isc:bind:network | Main TA parser |
other named events | isc:bind | Main TA parser fallback |
dns-* program with update: and updating zone | isc:bind:update | Optional update parser |
Why update logs were in fallback
The fallback events looked like this:
-- dns-txt-transfer-bind -- -22-Apr-2026 16:07:11.331 update: info: client @0x7fa988011e18 192.168.52.129#40041/key text-transfer-key: updating zone 'text.example.local/IN': adding an RR at 'inbox.text.example.local' TXT "Splunk forwarding fixed"The main TA parser correctly matches program("named"), but this event uses program=dns-txt-transfer-bind. The optional update parser matches program("dns-" flags(prefix)), classifies those events as isc:bind:update, and leaves the main TA parser unchanged.
Install On SC4S
Install the main TA parser:
sudo cp app-isc_bind_ta.conf /opt/sc4s/local/config/app_parsers/syslog/app-isc_bind_ta.conf
sudo systemctl restart sc4sInstall the optional dynamic update observability parser only if you have dns-* update logs:
sudo cp app-isc_bind_update.conf /opt/sc4s/local/config/app_parsers/syslog/app-isc_bind_update.conf
sudo systemctl restart sc4sIf SC4S fails to start, inspect the generated syslog-ng configuration inside the container:
sudo podman exec -it SC4S /bin/bash
cd /opt/syslog-ng/etcUse docker instead of podman if that is how your SC4S host runs containers.
Install In Splunk
The standard sourcetypes are handled by Splunk_TA_isc-bind. The custom isc:bind:update sourcetype needs local Splunk knowledge objects.
Append or copy this into:
$SPLUNK_HOME/etc/apps/Splunk_TA_isc-bind/local/props.conf[isc:bind:update]
KV_MODE = none
SHOULD_LINEMERGE = false
EVENT_BREAKER_ENABLE = true
REPORT-1_extract_field = isc_bind_update_extract_field_0
EVAL-message_type = "Update"
EVAL-vendor_product = "ISC:Bind"
EVAL-query_count = 1
FIELDALIAS-src_ip = src as src_ip
FIELDALIAS-query_type = record_type as query_typeAppend or copy this into:
$SPLUNK_HOME/etc/apps/Splunk_TA_isc-bind/local/transforms.conf[isc_bind_update_extract_field_0]
REGEX = (?:\s+update:)?(?:\s+([^:]+):)?\s+client(?:\s+\S+)?\s+([^#]+)#(\d{1,5})/key\s+([^:]+):\s+(updating\s+zone)\s+'([^/]+)/([^']+)':\s+(adding\s+an\s+RR\s+at|deleting\s+an\s+RR\s+at|approved)\s+'?([^']*?)'?\s+([^\s]+)?(?:\s+(.*))?$
FORMAT = vendor_severity::$1 src::$2 src_port::$3 key_name::$4 vendor_action::$5 dest_zone::$6 record_class::$7 update_action::$8 query::$9 record_type::$10 record_value::$11Restart Splunk or reload knowledge objects using your deployment process.
BIND Logging Requirements
The BIND logs should include time, category, and severity:
print-time yes;
print-category yes;
print-severity yes;
severity dynamic;Recommended categories:
category notify { notify_channel; };
category network { network_channel; };
category queries { queries_channel; };
category query-errors { query-errors_channel; };
category lame-servers { lame-servers_channel; };
category update { update_channel; };
Main TA Parser Code
Save as /opt/sc4s/local/config/app_parsers/syslog/app-isc_bind_ta.conf:
# /opt/sc4s/local/config/app_parsers/syslog/app-isc_bind_ta.conf
#
# ISC BIND routing for Splunk_TA_isc-bind.
# BIND messages commonly arrive as:
# -21-Apr-2026 14:03:21.297 queries: info: client ...
# so the category is not always at the start of $MESSAGE. Use substring checks.
# Query logs
block parser bind_query-parser() {
channel {
parser(vendor_product_by_source);
rewrite {
r_set_splunk_dest_default(
source("isc:bind:query")
sourcetype("isc:bind:query")
vendor("isc")
product("bind")
template("t_msg_only")
);
};
};
};
application bind_query[sc4s-network-source] {
filter {
program("named" type(string))
and message("queries:" type(string) flags(substring))
and message(" query: " type(string) flags(substring))
;
};
parser { bind_query-parser(); };
};
# Query error logs
block parser bind_queryerror-parser() {
channel {
parser(vendor_product_by_source);
rewrite {
r_set_splunk_dest_default(
source("isc:bind:queryerror")
sourcetype("isc:bind:queryerror")
vendor("isc")
product("bind")
template("t_msg_only")
);
};
};
};
application bind_queryerror[sc4s-network-source] {
filter {
program("named" type(string))
and (
message("query-errors:" type(string) flags(substring))
or message(" query failed " type(string) flags(substring))
or message(" query failed (" type(string) flags(substring))
)
;
};
parser { bind_queryerror-parser(); };
};
# Network logs
block parser bind_network-parser() {
channel {
parser(vendor_product_by_source);
rewrite {
r_set_splunk_dest_default(
source("isc:bind:network")
sourcetype("isc:bind:network")
vendor("isc")
product("bind")
template("t_msg_only")
);
};
};
};
application bind_network[sc4s-network-source] {
filter {
program("named" type(string))
and (
message("network:" type(string) flags(substring))
or message("no longer listening on " type(string) flags(substring))
or message("not listening on any interfaces" type(string) flags(substring))
or message("listening on " type(string) flags(substring))
)
;
};
parser { bind_network-parser(); };
};
# Transfer-related logs
# Covers notify/xfer-in/xfer-out categories and maps them to the TA transfer sourcetype.
block parser bind_transfer-parser() {
channel {
parser(vendor_product_by_source);
rewrite {
r_set_splunk_dest_default(
source("isc:bind:transfer")
sourcetype("isc:bind:transfer")
vendor("isc")
product("bind")
template("t_msg_only")
);
};
};
};
application bind_transfer[sc4s-network-source] {
filter {
program("named" type(string))
and (
message("notify:" type(string) flags(substring))
or message("xfer-in:" type(string) flags(substring))
or message("xfer-out:" type(string) flags(substring))
or message("transfer:" type(string) flags(substring))
or message(": sending notifies " type(string) flags(substring))
or message(": sending notify to " type(string) flags(substring))
or message(": notify to " type(string) flags(substring))
or message(": notify response from " type(string) flags(substring))
)
;
};
parser { bind_transfer-parser(); };
};
# Lame server logs
block parser bind_lameserver-parser() {
channel {
parser(vendor_product_by_source);
rewrite {
r_set_splunk_dest_default(
source("isc:bind:lameserver")
sourcetype("isc:bind:lameserver")
vendor("isc")
product("bind")
template("t_msg_only")
);
};
};
};
application bind_lameserver[sc4s-network-source] {
filter {
program("named" type(string))
and (
message("lame-servers:" type(string) flags(substring))
or message(" resolving '" type(string) flags(substring))
)
;
};
parser { bind_lameserver-parser(); };
};
# Fallback for other named logs that do not match the TA-specific buckets.
block parser bind_generic-parser() {
channel {
parser(vendor_product_by_source);
rewrite {
r_set_splunk_dest_default(
source("isc:bind")
sourcetype("isc:bind")
vendor("isc")
product("bind")
template("t_msg_only")
);
};
};
};
application bind_generic[sc4s-network-source] {
filter {
program("named" type(string))
and not (
message("queries:" type(string) flags(substring))
or message("query-errors:" type(string) flags(substring))
or message(" query failed " type(string) flags(substring))
or message("lame-servers:" type(string) flags(substring))
or message(" resolving '" type(string) flags(substring))
or message("network:" type(string) flags(substring))
or message("no longer listening on " type(string) flags(substring))
or message("not listening on any interfaces" type(string) flags(substring))
or message("listening on " type(string) flags(substring))
or message("notify:" type(string) flags(substring))
or message("xfer-in:" type(string) flags(substring))
or message("xfer-out:" type(string) flags(substring))
or message("transfer:" type(string) flags(substring))
)
;
};
parser { bind_generic-parser(); };
};
Optional Update Parser Code
Save as /opt/sc4s/local/config/app_parsers/syslog/app-isc_bind_update.conf:
# /opt/sc4s/local/config/app_parsers/syslog/app-isc_bind_update.conf
#
# Optional custom ISC BIND dynamic update routing.
# Use this alongside app-isc_bind_ta.conf when dynamic update events arrive
# from helper programs such as dns-txt-transfer-bind and would otherwise land
# in fallback/nix:syslog.
block parser bind_update-parser() {
channel {
parser(vendor_product_by_source);
rewrite {
r_set_splunk_dest_default(
source("isc:bind:update")
sourcetype("isc:bind:update")
vendor("isc")
product("bind")
template("t_msg_only")
);
};
};
};
application bind_update[sc4s-network-source] {
filter {
program("dns-" type(string) flags(prefix))
and message("update:" type(string) flags(substring))
and message(" updating zone " type(string) flags(substring))
;
};
parser { bind_update-parser(); };
};
Generate Test Logs
Print samples locally:
bash ./generate_isc_bind_ta_logs.sh --stdoutSend samples to SC4S over UDP:
bash ./generate_isc_bind_ta_logs.sh --send 192.168.115.103 --port 514 --transport udpSend repeated traffic:
bash ./generate_isc_bind_ta_logs.sh --send 192.168.115.103 --repeat 5 --sleep 1
Validate In Splunk
Confirm standard sourcetype routing:
sourcetype=isc:bind:*
| stats count by sourcetypeValidate standard TA fields:
sourcetype=isc:bind:*
| table _time sourcetype src src_port query record_type record_class response_code reply_code dest dest_port vendor_action action severityValidate dynamic update fields:
sourcetype=isc:bind:update
| table _time src src_port key_name vendor_action dest_zone record_class update_action query record_type record_value vendor_severityExpected update extraction:
| Field | Example |
|---|---|
src | 192.168.52.129 |
src_port | 40041 |
key_name | text-transfer-key |
vendor_action | updating zone |
dest_zone | text.example.local |
record_class | IN |
update_action | adding an RR at |
query | inbox.text.example.local |
record_type | TXT |
record_value | "Splunk forwarding fixed" |
Local Checks
PowerShell:
.\test_isc_bind_parser.ps1 -SampleFile .\generated_isc_bind_ta_samples.log | Format-Table -AutoSizeBash:
bash ./test_isc_bind_parser.sh generated_isc_bind_ta_samples.log