dnstap tls support (#5917)
Signed-off-by: dmachard <5562930+dmachard@users.noreply.github.com>
This commit is contained in:
parent
66df12d980
commit
83fc3bb5da
4 changed files with 52 additions and 6 deletions
|
@ -18,6 +18,7 @@ Every message is sent to the socket as soon as it comes in, the *dnstap* plugin
|
||||||
dnstap SOCKET [full] {
|
dnstap SOCKET [full] {
|
||||||
[identity IDENTITY]
|
[identity IDENTITY]
|
||||||
[version VERSION]
|
[version VERSION]
|
||||||
|
[skipverify]
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ dnstap SOCKET [full] {
|
||||||
* `full` to include the wire-format DNS message.
|
* `full` to include the wire-format DNS message.
|
||||||
* **IDENTITY** to override the identity of the server. Defaults to the hostname.
|
* **IDENTITY** to override the identity of the server. Defaults to the hostname.
|
||||||
* **VERSION** to override the version field. Defaults to the CoreDNS version.
|
* **VERSION** to override the version field. Defaults to the CoreDNS version.
|
||||||
|
* `skipverify` to skip tls verification during connection. Default to be secure
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
@ -61,6 +63,14 @@ dnstap /tmp/dnstap.sock {
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
Log to a remote TLS endpoint.
|
||||||
|
|
||||||
|
~~~ txt
|
||||||
|
dnstap tls://127.0.0.1:6000 full {
|
||||||
|
skipverify
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
You can use _dnstap_ more than once to define multiple taps. The following logs information including the
|
You can use _dnstap_ more than once to define multiple taps. The following logs information including the
|
||||||
wire-format DNS message about client requests and responses to */tmp/dnstap.sock*,
|
wire-format DNS message about client requests and responses to */tmp/dnstap.sock*,
|
||||||
and also sends client requests and responses without wire-format DNS messages to a remote FQDN.
|
and also sends client requests and responses without wire-format DNS messages to a remote FQDN.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dnstap
|
package dnstap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"net"
|
"net"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
@ -14,6 +15,8 @@ const (
|
||||||
|
|
||||||
tcpTimeout = 4 * time.Second
|
tcpTimeout = 4 * time.Second
|
||||||
flushTimeout = 1 * time.Second
|
flushTimeout = 1 * time.Second
|
||||||
|
|
||||||
|
skipVerify = false // by default, every tls connection is verified to be secure
|
||||||
)
|
)
|
||||||
|
|
||||||
// tapper interface is used in testing to mock the Dnstap method.
|
// tapper interface is used in testing to mock the Dnstap method.
|
||||||
|
@ -31,6 +34,7 @@ type dio struct {
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
flushTimeout time.Duration
|
flushTimeout time.Duration
|
||||||
tcpTimeout time.Duration
|
tcpTimeout time.Duration
|
||||||
|
skipVerify bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// newIO returns a new and initialized pointer to a dio.
|
// newIO returns a new and initialized pointer to a dio.
|
||||||
|
@ -42,14 +46,32 @@ func newIO(proto, endpoint string) *dio {
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
flushTimeout: flushTimeout,
|
flushTimeout: flushTimeout,
|
||||||
tcpTimeout: tcpTimeout,
|
tcpTimeout: tcpTimeout,
|
||||||
|
skipVerify: skipVerify,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dio) dial() error {
|
func (d *dio) dial() error {
|
||||||
conn, err := net.DialTimeout(d.proto, d.endpoint, d.tcpTimeout)
|
var conn net.Conn
|
||||||
if err != nil {
|
var err error
|
||||||
return err
|
|
||||||
|
if d.proto == "tls" {
|
||||||
|
config := &tls.Config{
|
||||||
|
InsecureSkipVerify: d.skipVerify,
|
||||||
|
}
|
||||||
|
dialer := &net.Dialer{
|
||||||
|
Timeout: d.tcpTimeout,
|
||||||
|
}
|
||||||
|
conn, err = tls.DialWithDialer(dialer, "tcp", d.endpoint, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
conn, err = net.DialTimeout(d.proto, d.endpoint, d.tcpTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcpConn, ok := conn.(*net.TCPConn); ok {
|
if tcpConn, ok := conn.(*net.TCPConn); ok {
|
||||||
tcpConn.SetWriteBuffer(tcpWriteBufSize)
|
tcpConn.SetWriteBuffer(tcpWriteBufSize)
|
||||||
tcpConn.SetNoDelay(false)
|
tcpConn.SetNoDelay(false)
|
||||||
|
|
|
@ -30,17 +30,26 @@ func parseConfig(c *caddy.Controller) ([]*Dnstap, error) {
|
||||||
|
|
||||||
endpoint = args[0]
|
endpoint = args[0]
|
||||||
|
|
||||||
if strings.HasPrefix(endpoint, "tcp://") {
|
var dio *dio
|
||||||
|
if strings.HasPrefix(endpoint, "tls://") {
|
||||||
// remote network endpoint
|
// remote network endpoint
|
||||||
endpointURL, err := url.Parse(endpoint)
|
endpointURL, err := url.Parse(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, c.ArgErr()
|
return nil, c.ArgErr()
|
||||||
}
|
}
|
||||||
dio := newIO("tcp", endpointURL.Host)
|
dio = newIO("tls", endpointURL.Host)
|
||||||
|
d = Dnstap{io: dio}
|
||||||
|
} else if strings.HasPrefix(endpoint, "tcp://") {
|
||||||
|
// remote network endpoint
|
||||||
|
endpointURL, err := url.Parse(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
dio = newIO("tcp", endpointURL.Host)
|
||||||
d = Dnstap{io: dio}
|
d = Dnstap{io: dio}
|
||||||
} else {
|
} else {
|
||||||
endpoint = strings.TrimPrefix(endpoint, "unix://")
|
endpoint = strings.TrimPrefix(endpoint, "unix://")
|
||||||
dio := newIO("unix", endpoint)
|
dio = newIO("unix", endpoint)
|
||||||
d = Dnstap{io: dio}
|
d = Dnstap{io: dio}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +61,10 @@ func parseConfig(c *caddy.Controller) ([]*Dnstap, error) {
|
||||||
|
|
||||||
for c.NextBlock() {
|
for c.NextBlock() {
|
||||||
switch c.Val() {
|
switch c.Val() {
|
||||||
|
case "skipverify":
|
||||||
|
{
|
||||||
|
dio.skipVerify = true
|
||||||
|
}
|
||||||
case "identity":
|
case "identity":
|
||||||
{
|
{
|
||||||
if !c.NextArg() {
|
if !c.NextArg() {
|
||||||
|
|
|
@ -44,6 +44,7 @@ func TestConfig(t *testing.T) {
|
||||||
{"dnstap.sock", true, "unix", []byte("NAME"), []byte("VER")},
|
{"dnstap.sock", true, "unix", []byte("NAME"), []byte("VER")},
|
||||||
{"127.0.0.1:6000", false, "tcp", []byte("NAME2"), []byte("VER2")},
|
{"127.0.0.1:6000", false, "tcp", []byte("NAME2"), []byte("VER2")},
|
||||||
}},
|
}},
|
||||||
|
{"dnstap tls://127.0.0.1:6000", false, []results{{"127.0.0.1:6000", false, "tls", []byte(hostname), []byte("-")}}},
|
||||||
}
|
}
|
||||||
for i, tc := range tests {
|
for i, tc := range tests {
|
||||||
c := caddy.NewTestController("dns", tc.in)
|
c := caddy.NewTestController("dns", tc.in)
|
||||||
|
|
Loading…
Add table
Reference in a new issue