GithubHelp home page GithubHelp logo

dnstap / golang-dnstap Goto Github PK

View Code? Open in Web Editor NEW
126.0 11.0 49.0 147 KB

flexible, structured event replication format for DNS servers (command-line tool and Golang package)

License: Apache License 2.0

Go 92.15% Roff 6.98% Shell 0.87%

golang-dnstap's Introduction

dnstap: flexible, structured event replication format for DNS servers
---------------------------------------------------------------------

dnstap implements an encoding format for DNS server events. It uses a
lightweight framing on top of event payloads encoded using Protocol Buffers and
is transport neutral.

dnstap can represent internal state inside a DNS server that is difficult to
obtain using techniques based on traditional packet capture or unstructured
textual format logging.

This repository contains a command-line tool named "dnstap" developed in the
Go programming language. It can be installed with the following command:

    go get -u github.com/dnstap/golang-dnstap/dnstap

golang-dnstap's People

Contributors

arthepsy avatar cmikk avatar cpu avatar edmonds avatar masahitoshinoda avatar pforemski avatar reedjc avatar varyoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

golang-dnstap's Issues

Issues installing

When trying to install the golang-dnstap utility I receive the following error

package code.google.com/p/goprotobuf/proto: unable to detect version control system for code.google.com/ path

Any help with this would be greatly appreciated.

Inability to unpack dnstap message to a Msg structure

I've noticed that some dnstap responses from unbound are unable to be parsed. dig also complains in this case, so I'm unsure if the problem is in the DNS response itself, Unbound handling it, or this dnstap library.

This is the query/response:

โฏ dig +short AAAA vstbrasil.com.
;; Warning: Message parser reports malformed message packet.

This is the output of dnstap:

16:45:28.364170 CQ 127.0.0.1 UDP 42b "vstbrasil.com." IN AAAA
16:45:28.968713 CR 127.0.0.1 UDP 58b X

The error occurs on msg.Unpack: "overflow unpacking aaaa"

release

Hello,

tags/v0.1.0 is not a good way to name your release, just v0.1.0 is OK

Buffer does not get flushed if remote write target is unreachable for a long time

if the remote is unreachable that socket writer is trying to connect to as per : https://github.com/dnstap/golang-dnstap/blob/master/SocketWriter.go#L202 it just continues, leaving the buffer full

2022/08/17 21:12:14 127.0.0.1:6000: open failed: dial tcp 127.0.0.1:6000: connect: connection refused < = failed write
E0817 21:12:17.800245  476695 logger.go:259] Failed to enqueue dnstap message type:CLIENT_QUERY  socket_family:INET6  socket_protocol:UDP  query_address:"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"  response_address:"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"  query_port:50564  response_port:8053  query_time_sec:1660767137  query_time_nsec:799106776  query_message:"\xd2U\x81\x05\x00\x01\x00\x00\x00\x00\x00\x01\x06github\x03com\x00\x00\x1c\x00\x01\x00\x00)\x10\x00\x00\x00\x00\x00\x00\x0c\x00\n\x00\x08y.5\x0f\x93~\xdb\xef" for sending, buffer is full
::1::11660767137AAAAgi <= failed subsequent enque attempt

Replacing google.golang.org/protobuf with github.com/protocolbuffers/protobuf-go

Hi there,

I am trying to package this repository to MacPorts (a package manager for macOS). Apparently, the tarballs from the domain google.golang.org/protobuf are not deterministic, so MacPorts doesn't support specifying dependencies with it. Can you replace google.golang.org/protobuf v1.23.0 with github.com/protocolbuffers/protobuf-go v1.23.0?

It would be extra awesome if you could cut a release after that, so that I have a release tag to pin.

... and Merry Christmas! ๐ŸŽ„

Could you make release?

Hello!

I'm going to use your tool for production purposes and I'm looking for some fixed version for building packages.

Code feels pretty stable and it's working well for me. What's your thinking about making release tag/branch? I think 1.0.0 is looking pretty nice :)

Breaking changes since last tagged release

Since the last release in November 2018, there have been a number of breaking changes in this project for those of us that pull it in as a library used in our own code.

Could a new release tag be created to make it cleaner to pin to this version when using the new default versioned module dependency support in golang 1.13?

Add ability to stop Input

Currently this is not very usable as a library since FrameStreamSockInputs ReadInto runs forever, leaking the goroutine. Consider a Close on the input interface (I may submit a PR if I end up using this as a library).

Also, in general this code logs errors silently among other practices that are poor for library use. If adapting the code for use as a library is not a goal, please at least add caveats via comments to warn other potential users.

Feature request: netflow like rate limiting

I'm using dnstap in a reasonable busy setup (avg. 16K, max. 19K queries/second) and my processing / storage setup (Graylog+Elasticsearch) can barely cope.
Since we are using this for statistical analysis only, we would love to have a feature with which we can say from the command line "send on only 1 in x queries".
Somthing like:
-L 1:1000
I hope you can consider implementing this feature.
Thanks for your efforts and keep up the good work.

v0.2.x loses events on both unix socket and TCP

Hi there,

So I've been using DNSTAP on Debian stretch for 2 years now and have been pretty happy with it - but i saw that json output was added in version v0.2.x so i decided i would upgrade.

Unfortunately i do see a lot of lost events when using this new version of DNSTAP - and I've done some extensive testing to figure out whats going on:

Resperf(8999 queries over 60 seconds) ---> CoreDNS(DNSTAP) --- TCP ---> DNSTAPv1: 8999 CQ events received.
Resperf(8999 queries over 60 seconds) ---> CoreDNS(DNSTAP) --- TCP ---> DNSTAPv2: 3223 CQ events received.
Resperf(8999 queries over 60 seconds) ---> CoreDNS(DNSTAP) --- SOCKET ---> DNSTAPv1: 8999 CQ events received.
Resperf(8999 queries over 60 seconds) ---> CoreDNS(DNSTAP) --- SOCKET ---> DNSTAPv2: 3324 CQ events received.

If i put the rate to about 10 queries pr. second DNSTAPv2 does seem to be able to keep up.

I find it hard to believe this hasn't been caught before - but nevertheless its what im facing right now.

I'm willing to spend time debugging and troubleshooting anytime you like.

-w always leave empty files

dnstpa works fine for output on the screen but -w always leave me with empty files.

I tried to SIGHUP the program, to stop it with Control-C, send thousands of requests to get a buffer flush, and in all cases, the output file is created but it is empty.

Add the ability to ship text logs into a remote syslog service

Currently the -T option allow me to ship only the dnstap paylads into tcp/ip address.
I want to be able to send the text logs to a remote TCP service.
Currently what I am doing is piping the text output to a second command which forward the incoming lines to the remote server.

No query_time in DNSTAP Response message

Hi there,

I would love to be able to keep track of the performance of queries and responses going through my CoreDNS instances, and as you know i have the DNSTAP Plugin configured to point to binaries of this goland-dnstap project.

However - I think we might have missed a key part of the implementation of response messages here.

Reading through this article about response logging with DNSTAP from 2017: https://jpmens.net/2017/09/11/dns-query-response-logging-with-dnstap

It seems like we are suppose to have a query_time in our response_messages along with the response_time - so that we can diff those two and get the query/response performance.

The example from Jan-Piet Mens article:

message:
type: TOOL_RESPONSE
query_time: !!timestamp 1970-01-01 04:22:23.659631
response_time: !!timestamp 1970-01-01 04:22:23.725209
socket_family: INET
socket_protocol: UDP
query_address: 0.0.0.0
response_address: 192.168.1.81
query_port: 54370
response_port: 53
response_message: |
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 53652
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 0

Been trying to poke the binary to give similar query_time on the response_messages but so far without luck - so i think the implementation of the response_message might have missed this?

Best regards

Decode() silently ignoring too large frames

Hello,

I have been using this library to parse dnstap files via NewDecoder() and Decode(). I noticed Decode() is documented like so:

Decode silently discards data frames larger than the Decoder's configured maxSize.

Is there a reason it was designed like that? It seems to me silently ignoring things means I can not trust that I decoded all of the dnstap entries in a file. Should I check for this some other way?

High memory usage issue

Hi

I have encountered an issue with high memory usage by the lib. It seems to be caused by the buffer that is being allocated using the max payload size https://github.com/farsightsec/golang-framestream/blob/master/framestream.go#L24

What is the ideal max payload size as the default is using up lots of mem.

(pprof) top
Showing nodes accounting for 1.16MB, 100% of 1.16MB total
      flat  flat%   sum%        cum   cum%
    1.16MB   100%   100%     1.16MB   100%  git.home.topdog-software.com/baruwa-infra/nambari/vendor/github.com/farsightsec/golang-framestream.NewDecoder
         0     0%   100%     1.16MB   100%  git.home.topdog-software.com/baruwa-infra/nambari/vendor/github.com/dnstap/golang-dnstap.(*FrameStreamSockInput).ReadInto
         0     0%   100%     1.16MB   100%  git.home.topdog-software.com/baruwa-infra/nambari/vendor/github.com/dnstap/golang-dnstap.NewFrameStreamInput
         0     0%   100%     1.16MB   100%  main.main
         0     0%   100%     1.16MB   100%  runtime.main
(pprof) list git.home.topdog-software.com/baruwa-infra/nambari/vendor/github.com/farsightsec/golang-framestream.NewDecoder
Total: 1.16MB
ROUTINE ======================== git.home.topdog-software.com/baruwa-infra/nambari/vendor/github.com/farsightsec/golang-framestream.NewDecoder in /Users/andrew/Documents/devel/go/path/src/git.home.topdog-software.com/baruwa-infra/nambari/vendor/github.com/farsightsec/golang-framestream/Decoder.go
    1.16MB     1.16MB (flat, cum)   100% of Total
         .          .     42:   }
         .          .     43:   if opt.MaxPayloadSize == 0 {
         .          .     44:       opt.MaxPayloadSize = DEFAULT_MAX_PAYLOAD_SIZE
         .          .     45:   }
         .          .     46:   dec = &Decoder{
    1.16MB     1.16MB     47:       buf:    make([]byte, opt.MaxPayloadSize),
         .          .     48:       opt:    *opt,
         .          .     49:       reader: bufio.NewReader(r),
         .          .     50:       writer: nil,
         .          .     51:   }
         .          .     52:

-y output is fine, -q is not

Input file:

19528 -rw-rw-r-- 1 dns dns 19995623 Jan 8 19:43 dnstap.20160108-194222.fs

This runs just fine:

[root@k tmp]# time /opt/unbound/sbin/dnstap -r dnstap.20160108-194222.fs -y -w koe.yaml
dnstap: opened input file dnstap.20160108-194222.fs

real 0m6.900s
user 0m6.614s
sys 0m1.071s

But this not, with the same input file:

[root@k tmp]# time /opt/unbound/sbin/dnstap -r dnstap.20160108-194222.fs -q -w koe.txt
dnstap: opened input file dnstap.20160108-194222.fs
panic: runtime error: index out of range

goroutine 6 [running]:
github.com/dnstap/golang-dnstap.textConvertMessage(0xc8203890a0, 0xc8202a4770)
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/QuietTextFormat.go:147 +0x5b2
github.com/dnstap/golang-dnstap.TextFormat(0xc82009e000, 0x0, 0x0, 0x0, 0xc82009e000)
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/QuietTextFormat.go:159 +0x67
github.com/dnstap/golang-dnstap.(*TextOutput).RunOutputLoop(0xc82000e480)
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/TextOutput.go:67 +0x286
created by main.main
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/dnstap/main.go:97 +0x409

goroutine 1 [chan receive]:
github.com/dnstap/golang-dnstap.(*FrameStreamInput).Wait(0xc820010bc0)
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/FrameStreamInput.go:69 +0x39
main.main()
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/dnstap/main.go:129 +0x813

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/home/sjm/go/src/runtime/asm_amd64.s:1721 +0x1

goroutine 5 [syscall]:
os/signal.loop()
/home/sjm/go/src/os/signal/signal_unix.go:22 +0x18
created by os/signal.init.1
/home/sjm/go/src/os/signal/signal_unix.go:28 +0x37

goroutine 7 [select, locked to thread]:
runtime.gopark(0x7c4e70, 0xc820024f28, 0x747988, 0x6, 0x42d518, 0x2)
/home/sjm/go/src/runtime/proc.go:185 +0x163
runtime.selectgoImpl(0xc820024f28, 0x0, 0x18)
/home/sjm/go/src/runtime/select.go:392 +0xa64
runtime.selectgo(0xc820024f28)
/home/sjm/go/src/runtime/select.go:212 +0x12
runtime.ensureSigM.func1()
/home/sjm/go/src/runtime/signal1_unix.go:227 +0x353
runtime.goexit()
/home/sjm/go/src/runtime/asm_amd64.s:1721 +0x1

goroutine 8 [chan receive]:
main.main.func1(0xc82000a540, 0x7f4d4c82f568, 0xc82000e480)
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/dnstap/main.go:103 +0x4d
created by main.main
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/dnstap/main.go:107 +0x4f5

goroutine 9 [runnable]:
syscall.Syscall(0x0, 0x4, 0xc82009d000, 0x1000, 0x1000, 0x1000, 0x0)
/home/sjm/go/src/syscall/asm_linux_amd64.s:18 +0x5
syscall.read(0x4, 0xc82009d000, 0x1000, 0x1000, 0x4, 0x0, 0x0)
/home/sjm/go/src/syscall/zsyscall_linux_amd64.go:783 +0x5f
syscall.Read(0x4, 0xc82009d000, 0x1000, 0x1000, 0x1000, 0x0, 0x0)
/home/sjm/go/src/syscall/syscall_unix.go:160 +0x4d
os.(_File).read(0xc820026038, 0xc82009d000, 0x1000, 0x1000, 0x1000, 0x0, 0x0)
/home/sjm/go/src/os/file_unix.go:211 +0x53
os.(_File).Read(0xc820026038, 0xc82009d000, 0x1000, 0x1000, 0x1000, 0x0, 0x0)
/home/sjm/go/src/os/file.go:95 +0x8a
bufio.(_Reader).fill(0xc82000a6c0)
/home/sjm/go/src/bufio/bufio.go:97 +0x1e9
bufio.(_Reader).Read(0xc82000a6c0, 0xc8200a2018, 0xc8, 0xfffe8, 0x18, 0x0, 0x0)
/home/sjm/go/src/bufio/bufio.go:207 +0x260
io.ReadAtLeast(0x7f4d4c82f698, 0xc82000a6c0, 0xc8200a2000, 0xe0, 0x100000, 0xe0, 0x18, 0x0, 0x0)
/home/sjm/go/src/io/io.go:298 +0xe6
io.ReadFull(0x7f4d4c82f698, 0xc82000a6c0, 0xc8200a2000, 0xe0, 0x100000, 0x0, 0x0, 0x0)
/home/sjm/go/src/io/io.go:316 +0x62
github.com/farsightsec/golang-framestream.(_Decoder).readFrame(0xc820084120, 0xe0, 0x0, 0x0)
/home/sjm/gocode/src/github.com/farsightsec/golang-framestream/Decoder.go:177 +0xcb
github.com/farsightsec/golang-framestream.(_Decoder).Decode(0xc820084120, 0x0, 0x0, 0x0, 0x0, 0x0)
/home/sjm/gocode/src/github.com/farsightsec/golang-framestream/Decoder.go:210 +0x1d7
github.com/dnstap/golang-dnstap.(*FrameStreamInput).ReadInto(0xc820010bc0, 0xc82000a480)
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/FrameStreamInput.go:54 +0x40
created by main.main
/home/sjm/gocode/src/github.com/dnstap/golang-dnstap/dnstap/main.go:126 +0x7ff

real 0m0.403s
user 0m0.301s
sys 0m0.131s

[root@k tmp]# ls -las koe.*
628 -rw-r----- 1 root dns 643050 Jan 8 19:49 koe.txt
79580 -rw-r----- 1 root dns 81486794 Jan 8 19:48 koe.yaml

dnstap log file not populating for every entry even if repeated.

Not sure if this belongs here or somewhere else, so let me know if my question / problem needs to be redirected.

When running dnstap I noticed the binary log only populates when new entries are requested from the named server. Is this expected?

Trouble shooting:

  • On bind server make sure dnstap is running, then start the named service.
  • Can see the dnstap log gets created, and populated properly on named start up.
  • Perform a dig request from a remote client for an entry in the zone db (test.domain.internal). I am performing a watch ls -l on the dnstap file, and see the file increase in size.
  • Also monitoring the bind.log file, I see the request come through.
  • Perform the same exact dig request (test.domain.internal) from the same remote client to the same named server running dnstap. The bind.log populates with the request, the dnstap log does not increase in size.
  • Perform a new request with a different domain (www.internet.com). I see the bind.log populate, then the dnstap log increases in size.
  • I use dnstap-read (memory flag) on the file, and can see the CQ entries for the original request (test.domain.internal), the duplicate request (test.domain.internal again), and then the external domain request (www.internet.com).

I was thinking the log would populate for every request no matter how frequent or similar they are. Was there a reason this was disabled? Too much overhead?

Is there a way to enable this feature?

a quick way to add timestamp for coredns(only use linux cli)

i find that dnstap cannot support date, only show hours and minutes, so i find a easy(maybe simple&stupid way) to log coredns,

here is the solution:

/usr/bin/coredns -conf /etc/storage/csc/coredns/Corefile 2>&1 | stdbuf -oL awk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' | stdbuf -oL tee -a log7.log

result:
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.