Grok patterns for BIND DNS server

Does anyone have a set of good grok patterns for the BIND DNS server query logs?

The messages I'm interested in look like this:
Apr 22 15:40:26 ns.example.com named[1351]: queries: info: client 192.0.2.215#53591: query: www.example.com IN A -ED (198.51.100.70)

Most of it is easy, but the second to last field is a bunch of flags that I'm not sure how to parse.

Most of it is easy, but the second to last field is a bunch of flags that I'm not sure how to parse.

Something like [+-][SETDC]+ should work.

That lets the pattern match, but doesn't seem to quite quite get me where I want to be. I'm thinking maybe something with translate filter to make the output easier to search later might work?

Well, you didn't tell us what result you desired. I'm not sure the translate filter will help you here. I'd probably use a ruby filter.

ruby {
  code => "
    event['signed'] = event['flags'].include? 'S'
    event['tcp'] = event['flags'].include? 'T'
    ...
  "
}

Sorry. You're right. I wasn't clear about my goal. I want to be able to easily access the individual flags, so I can do things like graph UDP vs. TCP transport.

I did manage to make it work with translate, but your suggestion is probably cleaner. Thank you for the suggestion.

grok {
    keep_empty_captures => true
    match => {
        "message" => "queries: info: client %{IP:clientip}#%{INT:port}: query: %{DATA:query} %{WORD:class} %{WORD:querytype} (?<recursive>[-+])((?<signed>S)?)((?<edns>E)?)((?<transport>T)?)((?<dnssec>D)?)((?<cd>C)?) \(%{IP:serverip}\)"
    }
}
translate {
    field => "recursive"
    destination => "[dns_flags][recursive]"
    remove_field => [ "recursive" ]
    dictionary => [ "+", "Yes", "-", "No" ]
}
translate {
    field => "signed"
    destination => "[dns_flags][signed]"
    remove_field => [ "signed" ]
    fallback => "No"
    dictionary => [ "S", "Yes" ]
}
translate {
    field => "edns"
    destination => "[dns_flags][edns]"
    remove_field => [ "edns" ]
    fallback => "No"
    dictionary => [ "E", "Yes" ]
}
translate {
    field => "transport"
    destination => "[dns_flags][transport]"
    remove_field => [ "transport" ]
    fallback => "UDP"
    dictionary => [ "T", "TCP" ]
}
translate {
    field => "dnssec"
    destination => "[dns_flags][dnssec]"
    remove_field => [ "dnssec" ]
    fallback => "No"
    dictionary => [ "D", "Yes" ]
}
translate {
    field => "cd"
    destination => "[dns_flags][cd]"
    remove_field => [ "cd" ]
    fallback => "No"
    dictionary => [ "C", "Yes" ]
}
2 Likes