From 92b4403ba3e8992ba2ccfada15f333b49acc6cc6 Mon Sep 17 00:00:00 2001 From: Chris Mikkelson Date: Mon, 18 Aug 2025 14:47:16 -0500 Subject: [PATCH] Add support for tcp input with -input tcp:: Allow unix: to support paths with colons. --- config.go | 4 ++-- dnstap-sensor.8 | 21 ++++++++++++++------- input.go | 19 +++++++++++++++++-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/config.go b/config.go index 2f9f868..735b53b 100644 --- a/config.go +++ b/config.go @@ -63,7 +63,7 @@ func parseConfig(args []string) (conf *Config, err error) { fs.StringVar(&configFilename, "config", "", "Location of client config file") fs.StringVar(&inputSocket, "input", "", - "Path to dnstap input socket") + "[unix:] to OR tcp:: for dnstap input socket") fs.Var(&statsInterval, "stats_interval", "statistics logging interval (default 15m)") fs.Var(&heartBeat, "heartbeat", "heartbeat interval (default 30s)") fs.Var(&retry, "retry", "connection retry interval (default 30s)") @@ -73,7 +73,7 @@ func parseConfig(args []string) (conf *Config, err error) { fs.UintVar(&channel, "channel", 0, "channel to upload dnstap data") fs.IntVar(&mtu, "mtu", nmsg.EtherContainerSize, "UDP output buffer size") fs.BoolVar(&trace, "trace", false, "log activity (verbose, recommended for debugging only)") - fs.Var(&udpOutputAddr, "udp_output", "send NMSG UDP output to addr udp::host") + fs.Var(&udpOutputAddr, "udp_output", "send NMSG UDP output to addr udp::") fs.Parse(args) conf = new(Config) diff --git a/dnstap-sensor.8 b/dnstap-sensor.8 index 94fbf3a..935ed26 100644 --- a/dnstap-sensor.8 +++ b/dnstap-sensor.8 @@ -8,7 +8,7 @@ dnstap-sensor \- Convert dnstap data to NMSG for UDP output or SIE upload .B dnstap-sensor --apikey (\fIkey\fB|\fIkeyfile-path\fB) .br -.B " --channel \fInumber\fB --input \fIsocket-path\fB [--trace]" +.B " --channel \fInumber\fB --input (\fIsocket-path\fB|tcp[4|6]:\fIhost:port\fB) [--trace]" .br .B " [--filter_qname \fIdomain\fR ... ]" .br @@ -18,7 +18,7 @@ dnstap-sensor \- Convert dnstap data to NMSG for UDP output or SIE upload .br .B " \fIserver-uri\fB [ \fIserver-uri ...\fB ]" -.B dnstap-sensor --input \fIsocket-path\fB [--trace] +.B dnstap-sensor --input (\fIsocket-path\fB|tcp[4|6]:\fIhost:port\fB) [--trace] .br .B " --udp_output udp:\fIaddr\fB:\fIport\fB [-mtu \fIsize\fB]" .br @@ -56,11 +56,18 @@ option or the optional configuration file if any upload \fIserver-uri\fRs are configured. .TP -.B --input \fIsocket-path\fB -Collect dnstap input from the UNIX domain socket at \fIsocket-path\fR. -\fBdnstap-sensor\fR will create this socket and accept connections -from the DNS server. Note that this requires \fBdnstap-sensor\fR be -invoked as the same user as the DNS server. +.B --input ([unix:]\fIsocket-path\fB|tcp[4|6]:\fIhost:port\fB) +Specify the dnstap input socket. + +If the \fI--input\fR argument is prefaced with \fIunix:\fR or does +not contain a colon (\fI:\fR) character, it is treated as the path +to a UNIX domain socket. \fBdnstap-sensor\fR will create this socket +and accept connections from the DNS server. Note that this requires +\fBdnstap-sensor\fR be invoked as the same user as the DNS server. + +If prefaced with \fItcp:\fR, \fItcp4:\fR, or \fItcp6:\fR, the argument +specifies a TCP listening address, with \fItcp4\fR and \fItcp6\fR useful +for specifying the socket by hostname on dual-stack hosts. An input must be specified on the command line or in the optional configuration file. diff --git a/input.go b/input.go index fe66371..e1cf455 100644 --- a/input.go +++ b/input.go @@ -10,10 +10,13 @@ package main import ( "log" + "net" + "strings" - "github.com/dnstap/golang-dnstap" + dnstap "github.com/dnstap/golang-dnstap" "github.com/golang/protobuf/proto" + "github.com/farsightsec/go-config" "github.com/farsightsec/go-nmsg" "github.com/farsightsec/go-nmsg/nmsg_base" ) @@ -21,11 +24,23 @@ import ( type dnstapInput string func (i dnstapInput) run(ctx *Context) { + var fsinput dnstap.Input + var err error traceMsg(ctx, "Opening dnstap socket input at %s", i) - fsinput, err := dnstap.NewFrameStreamSockInputFromPath(string(i)) + var addr config.Addr + if strings.Contains(string(i), ":") { + err = addr.Set(string(i)) + } else { + err = addr.Set("unix:" + string(i)) + } + if err != nil { + log.Fatalf("Invalid input address '%s'", string(i)) + } + listener, err := net.Listen(addr.Network(), addr.String()) if err != nil { log.Fatalf("Could not listen on %s: %s", i, err.Error()) } + fsinput = dnstap.NewFrameStreamSockInput(listener) ch := make(chan []byte, 100) go i.publish(ctx, ch) fsinput.ReadInto(ch)