概要
dnstap は DNS ソフトウェア向けの柔軟な構造化バイナリログの形式です。 https://dnstap.info を参照してください。このプラグインは、CoreDNS に dnstap ログの出力をさせます。
メッセージはすべて受信されるとすぐにソケットに送信され、dnstap プラグインには 10000 個のメッセージのバッファがあり、その数を超えると dnstap メッセージはドロップされます(これはログに記録されます)。
構文
dnstap SOCKET [full] {
[identity IDENTITY]
[version VERSION]
[extra EXTRA]
[skipverify]
}
- SOCKET は dnstap コマンドラインツールに提供されるソケット(パス)です。
full
はワイヤー形式の DNS メッセージを含めるかどうかを表します。- IDENTITY はサーバの ID を上書きします。デフォルトでは、ホスト名が使用されます。
- VERSION はバージョンフィールドを上書きします。デフォルトでは、CoreDNS のバージョンが使用されます。
- EXTRA は dnstap ペイロードの「追加」フィールドを定義し、メタデータ の置き換えが使用できます。
skipverify
は接続中の TLS 検証をスキップします。デフォルトでは、安全になります。
例
クライアントからのリクエストと応答に関する情報を /tmp/dnstap.sock に記録します。
dnstap /tmp/dnstap.sock
クライアントからのリクエストと応答に関するワイヤー形式の 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
ソケットに記録し、デフォルトの ID とバージョンを上書きします。
dnstap /tmp/dnstap.sock {
identity my-dns-server1
version MyDNSServer-1.2.3
}
ソケットに記録し、dnstap ペイロードの「追加」フィールドをカスタマイズします。他のプラグインが提供するメタデータを追加のフィールドで使用できます。
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 を繰り返し使用します。次の例は、クライアントからのリクエストと応答に関するワイヤー形式の DNS メッセージを含む情報を /tmp/dnstap.sock に記録し、さらに、ワイヤー形式の DNS メッセージなしでクライアントからのリクエストと応答をリモート FQDN に送信します。
dnstap /tmp/dnstap.sock full
dnstap tcp://example.com:6000
コマンドラインツール
Dnstap には、ログを検査するために使用できるコマンドラインツールがあります。このツールは GitHub: https://github.com/dnstap/golang-dnstap にあります。Go で記述されています。
次のコマンドは、指定されたソケットでリッスンし、メッセージをデコードして stdout に送信します。
$ dnstap -u /tmp/dnstap.sock
次のコマンドは、指定されたソケットでリッスンし、メッセージのペイロードをバイナリ 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 Web サイトに dnstap プロトコルの情報があります。forward プラグインの dnstap.go
は dnstap を使用してアップストリームに送信されるメッセージをタップします。