dnstap

原始碼

dnstap 啟用 dnstap 的日誌記錄功能。

描述

dnstap 是一種彈性的、結構化的 DNS 軟體二進位日誌格式;請參閱 https://dnstap.info。透過此外掛程式,您可以讓 CoreDNS 輸出 dnstap 日誌。

每個訊息一收到就會立即傳送到 socket,dnstap 外掛程式有一個 10000 個訊息的緩衝區,超過這個數量,dnstap 訊息將會被丟棄(這會被記錄)。

語法

dnstap SOCKET [full] {
  [identity IDENTITY]
  [version VERSION]
  [extra EXTRA]
  [skipverify]
}
  • SOCKET 是提供給 dnstap 命令列工具的 socket(路徑)。
  • full 用於包含 wire-format DNS 訊息。
  • IDENTITY 用於覆寫伺服器的身分。預設為主機名稱。
  • VERSION 用於覆寫版本欄位。預設為 CoreDNS 版本。
  • EXTRA 用於定義 dnstap 酬載中的「額外」欄位,metadata 替換功能在此可用。
  • skipverify 用於在連線期間跳過 TLS 驗證。預設為安全。

範例

將有關用戶端請求和回應的資訊記錄到 /tmp/dnstap.sock

dnstap /tmp/dnstap.sock

將包含 wire-format DNS 訊息的有關用戶端請求和回應的資訊記錄到 /tmp/dnstap.sock

dnstap unix:///tmp/dnstap.sock full

記錄到遠端端點。

dnstap tcp://127.0.0.1:6000 full

透過 FQDN 記錄到遠端端點。

dnstap tcp://example.com:6000 full

記錄到 socket,覆寫預設的身分和版本。

dnstap /tmp/dnstap.sock {
  identity my-dns-server1
  version MyDNSServer-1.2.3
}

記錄到 socket,自訂 dnstap 酬載中的「額外」欄位。您可以使用其他外掛程式在額外欄位中提供的 metadata。

forward . 8.8.8.8
metadata
dnstap /tmp/dnstap.sock {
  extra "upstream: {/forward/upstream}"
}

記錄到遠端 TLS 端點。

dnstap tls://127.0.0.1:6000 full {
  skipverify
}

您可以多次使用 dnstap 來定義多個監聽點。以下範例會將包含 wire-format DNS 訊息的有關用戶端請求和回應的資訊記錄到 /tmp/dnstap.sock,並將不包含 wire-format DNS 訊息的用戶端請求和回應傳送到遠端 FQDN。

dnstap /tmp/dnstap.sock full
dnstap tcp://example.com:6000

命令列工具

Dnstap 有一個命令列工具可以用來檢查日誌。該工具可以在 Github 上找到:https://github.com/dnstap/golang-dnstap。它是用 Go 語言編寫的。

以下命令會監聽指定的 socket 並將訊息解碼到 stdout。

$ dnstap -u /tmp/dnstap.sock

以下命令會監聽指定的 socket 並將訊息酬載儲存到二進位 dnstap 格式的日誌檔案中。

$ dnstap -u /tmp/dnstap.sock -w /tmp/test.dnstap

監聽 6000 埠上的 dnstap 訊息。

$ dnstap -l 127.0.0.1:6000

在您的外掛程式中使用 Dnstap

在您的設定函式中,收集並儲存配置中載入的所有 dnstap 外掛程式的清單

x :=  &ExamplePlugin{}

c.OnStartup(func() error {
    if taph := dnsserver.GetConfig(c).Handler("dnstap"); taph != nil {
        for tapPlugin, ok := taph.(*dnstap.Dnstap); ok; tapPlugin, ok = tapPlugin.Next.(*dnstap.Dnstap) {
            x.tapPlugins = append(x.tapPlugins, tapPlugin)
        }
    }
    return nil
})

然後在您的外掛程式中

import (
  "github.com/coredns/coredns/plugin/dnstap/msg"
  "github.com/coredns/coredns/request"

  tap "github.com/dnstap/golang-dnstap"
)

func (x ExamplePlugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
    for _, tapPlugin := range x.tapPlugins {
        q := new(msg.Msg)
        msg.SetQueryTime(q, time.Now())
        msg.SetQueryAddress(q, w.RemoteAddr())
        if tapPlugin.IncludeRawMessage {
            buf, _ := r.Pack() // r has been seen packed/unpacked before, this should not fail
            q.QueryMessage = buf
        }
        msg.SetType(q, tap.Message_CLIENT_QUERY)
        
        // if no metadata interpretation is needed, just send the message
        tapPlugin.TapMessage(q)

        // OR: to interpret the metadata in "extra" field, give more context info
        tapPlugin.TapMessageWithMetadata(ctx, q, request.Request{W: w, Req: query})
    }
    // ...
}

參見

網站 dnstap.info 提供了有關 dnstap 協定的資訊。forward 外掛程式的 dnstap.go 使用 dnstap 來監聽傳送到上游的訊息。