input { beats { port => 5141 type => "logs" tags => ["pihole","5141"] } } filter { if "pihole" in [tags]{ grok { patterns_dir => ["/etc/logstash/patterns/"] match => { "message" => [ # request - query type "^%{DNSMASQPREFIX} query\[%{WORD:query_type}\] %{FQDN:domain_request} from %{IP:request_from}$", # reponse domain to ip "^%{DNSMASQPREFIX} reply %{FQDN:domain_request} is %{IP:ip_response}$", # response domain is NXDOMAIN "^%{DNSMASQPREFIX} reply %{FQDN:domain_request} is NXDOMAIN$", # response config domain is NXDOMAIN "^%{DNSMASQPREFIX} config %{FQDN:domain_request} is NXDOMAIN$", # response config domain is no-DATA "^%{DNSMASQPREFIX} config %{FQDN:domain_request} is NODATA-IPv[4,6]$", # reponse domain to ip cname "^%{DNSMASQPREFIX} reply %{FQDN:domain_request} is \<CNAME\>$", # respone ip to domain "^%{DNSMASQPREFIX} reply %{IP:ip_request} is %{FQDN:domain_response}$", # piholed "^%{DNSMASQPREFIX} \/etc\/pihole\/gravity\.list %{FQDN:blocked_domain} is %{IP:pihole}$", # piholed local "^%{DNSMASQPREFIX} \/etc\/pihole\/local\.list %{FQDN:blocked_domain} is %{IP:pihole}$", # blacklist "^%{DNSMASQPREFIX} \/etc\/pihole\/black\.list %{FQDN:blocked_domain} is %{IP:pihole}$", # reverse response etc hosts ip to domain "^%{DNSMASQPREFIX} \/etc\/hosts %{IP:ip_request} is %{FQDN:domain_response}$", # reverse response etc hosts domain to ip "^%{DNSMASQPREFIX} \/etc\/hosts %{FQDN:domain_request} is %{IP:ip_response}$", # forward dns to "^%{DNSMASQPREFIX} forwarded %{FQDN:domain_request} to %{IP:dns_forward_to}$", # cached domain to ip "^%{DNSMASQPREFIX} cached %{FQDN:domain_request} is %{IP:ip_response}$", # cached ip to domain "^%{DNSMASQPREFIX} cached %{IP:ip_request} is %{FQDN:domain_response}$", # cached domain to ip cname "^%{DNSMASQPREFIX} cached %{FQDN:domain_request} is \<CNAME\>$", # cached domain is NXDOMAIN "^%{DNSMASQPREFIX} cached %{FQDN:domain_request} is NXDOMAIN$", # cached domain is no-DATA "^%{DNSMASQPREFIX} cached %{FQDN:domain_request} is NODATA-IPv[4,6]$", # domain is no-DATA "^%{DNSMASQPREFIX} reply %{FQDN:domain_request} is NODATA-IPv[4,6]$", # SRV "^%{DNSMASQPREFIX} query\[%{WORD:query_type}\] %{HOSTNAMEPTR:request} from %{IP:request_from}$", # SRV forwarded "^%{DNSMASQPREFIX} forwarded %{HOSTNAMEPTR:request} to %{IP:dns_forward_to}$" ] } } # to do cached and cached reverse if [request_from] { mutate { add_tag => [ "request and query type" ] } } else if [ip_response] { mutate { add_tag => [ "response domain to ip" ] } } else if [message] =~ "CNAME" and [message] =~ "reply" { mutate { add_tag => [ "response domain to ip CNAME" ] } } else if [domain_response] and [message] =~ "reply" { mutate { add_tag => [ "response ip to domain" ] } } else if [blocked_domain] { mutate { add_tag => [ "piholed" ] } } else if [message] =~ "\/etc\/hosts" { mutate { add_tag => [ "reverse hostsfile" ] } } else if [dns_forward_to] { mutate { add_tag => [ "dns forward" ] } } else if [ip_request] and [message] =~ "cached" { mutate { add_tag => [ "cached ip to domain" ] } } else if [domain_request] and [message] =~ "cached" { mutate { add_tag => [ "cached domain to ip" ] } } else if [message] =~ "cached" and [message] =~ "CNAME" { mutate { add_tag => [ "cached domain to ip cname" ] } } else if [message] =~ "cached" and [message] =~ "NXDOMAIN" { mutate { add_tag => [ "cached NXDOMAIN" ] } } else if [NODATA-IPv4] { mutate { add_tag => [ "NODATA" ] } } else if [NODATA-IPv6] { mutate { add_tag => [ "NODATA" ] } } reverse => [ "source_fqdn" ] action => "replace" add_tag => [ "dns_lookup" ] mutate { add_field => { "[source_fqdn]" => "%{source_host}" } } dns { reverse => ["source_fqdn"] action => "replace" nameserver => ["localhost"] hit_cache_size => 4096 hit_cache_ttl => 900 failed_cache_size => 512 failed_cache_ttl => 900 } } } output { if "pihole" in [tags]{ elasticsearch { # ELASTICSEARCHHOST:PORT hosts => ["127.0.0.1:9200"] manage_template => false index => "logstash-syslog-dns-%{+YYYY.MM}" } } }