描述
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 來監聽傳送到上游的訊息。