CoreDNSマニュアル

CoreDNSの入手と実行のあらゆる側面を網羅したマニュアル。

このマニュアルは*作業中です*!ご協力をお願いします!ご協力いただける場合は、このマニュアルのソースをご覧ください。プルリクエストを送信するか、Issueに、ここで対処してほしい内容、不足しているコンテンツ、または単に分かりにくい部分などを具体的に記入してください。

– CoreDNS作成者

目次

 

変更日:

CoreDNSとは?

CoreDNSはDNSサーバーです。Goで記述されています。

CoreDNSは、(すべて優れた)BINDKnotPowerDNSUnbound(厳密にはリゾルバーですが、それでも言及する価値があります)などの他のDNSサーバーとは異なり、非常に柔軟性があり、ほぼすべての機能がプラグインにアウトソースされています。

プラグインはスタンドアロンでも、「DNS機能」を実行するために連携して動作することもできます。

では、「DNS機能」とは何でしょうか?CoreDNSの目的のために、CoreDNSプラグインAPIを実装するソフトウェアの一部として定義します。実装される機能は大きく異なる可能性があります。メトリクスキャッシュなど、それ自体では応答を生成しないが、機能を追加するプラグインがあります。次に、*実際に*応答を生成するプラグインがあります。これらも何でもできます。サービスディスカバリーを提供するためにKubernetesと通信するプラグイン、ファイルまたはデータベースからデータを読み取るプラグインなどがあります。

現在、デフォルトのCoreDNSインストールには約30個のプラグインが含まれていますが、CoreDNSにコンパイルして機能を拡張できる外部プラグインも多数あります。

CoreDNSはプラグインによって動作します。

新しいプラグインの作成は十分に簡単である必要がありますが、Goの知識とDNSの仕組みについての洞察が必要です。CoreDNSはDNSの多くの詳細を抽象化するため、必要なプラグイン機能の作成に集中できます。

 

変更日:

インストール

CoreDNSはGoで記述されていますが、プラグインを開発したり、CoreDNSを自分でコンパイルしたりしない限り、おそらく気にしないでしょう。以下のセクションでは、CoreDNSバイナリを入手する方法、またはソースからインストールする方法について詳しく説明します。

バイナリ

すべてのCoreDNSリリースについて、さまざまなオペレーティングシステム用のプリコンパイル済みバイナリを提供しています。Linuxの場合、ARM、PowerPC、およびその他のアーキテクチャ用のクロスコンパイル済みバイナリも提供しています。

Docker

すべてのリリースをDockerイメージとしてもプッシュします。CoreDNS組織のパブリックDockerハブにあります。このDockerイメージは基本的に*scratch* + CoreDNS + TLS証明書(DoT、DoH、およびgRPC用)です。

ソース

CoreDNSをコンパイルするには、動作するGoセットアップがあることを前提としています。設定されていない場合は、さまざまなチュートリアルをご覧ください。CoreDNSは依存関係管理にGoモジュールを使用しています。

コンパイル方法に関する最新のドキュメントは、corednsソースに保持されています。

テスト

`coredns`バイナリを入手したら、 `-plugins`フラグを使用して、コンパイルされたすべてのプラグインを一覧表示できます。 `Corefile`(設定を参照)がない場合、CoreDNSはクライアントのIPアドレスとポートで応答する*whoami*プラグインを読み込みます。そのため、テストするために、CoreDNSをポート1053で実行するように開始し、 `dig`を使用してクエリを送信します

$ ./coredns -dns.port=1053
.:1053
2018/02/20 10:40:44 [INFO] CoreDNS-1.0.5
2018/02/20 10:40:44 [INFO] linux/amd64, go1.10,
CoreDNS-1.0.5
linux/amd64, go1.10,

別の端末ウィンドウから、 `dig`は次のようなものを返します

$ dig @localhost -p 1053 a whoami.example.org

;; QUESTION SECTION:
;whoami.example.org.		IN	A

;; ADDITIONAL SECTION:
whoami.example.org.	0	IN	AAAA	::1
_udp.whoami.example.org. 0	IN	SRV	0 0 39368 .

次のセクションでは、より興味深いプラグインを有効にする方法を示します。

 

変更日:

プラグイン

CoreDNSが起動し、設定を解析すると、サーバーを実行します。各サーバーは、サービスを提供するゾーンとポートによって定義されます。各サーバーには独自のプラグインチェーンがあります。

CoreDNSによってクエリが処理されると、次の手順が実行されます

  1. クエリされたポートでリッスンする複数のサーバーが設定されている場合、このクエリに最も具体的なゾーンを持つサーバー(最長サフィックス一致)を確認します。たとえば、 `example.org`のサーバーと `a.example.org`のサーバーの2つがあり、クエリが `www.a.example.org`の場合、後者にルーティングされます。

  2. サーバーが見つかると、そのサーバーに設定されているプラグインチェーンを介してルーティングされます。これは常に同じ順序で発生します。この(静的)順序付けは、 `plugin.cfg`で定義されています。

  3. 各プラグインはクエリを検査し、処理する必要があるかどうかを判断します(一部のプラグインでは、クエリ名またはその他の属性でさらにフィルタリングできます)。ここでいくつかのことが起こる可能性があります

    1. クエリはこのプラグインによって処理されます。
    2. クエリはこのプラグインによって処理され*ません*。
    3. クエリはこのプラグインによって処理されますが、途中でチェーン内の次のプラグインを呼び出したいと判断します。これを有効にするキーワードにちなんで、*フォールスルー*と呼びます。
    4. クエリはこのプラグインによって処理され、「ヒント」が追加され、次のプラグインが呼び出されます。このヒントは、(最終的な)応答を「見て」行動する方法を提供します。

クエリを処理するということは、プラグインがクライアントに応答で応答することを意味します。

プラグインは上記のリストから自由に逸脱できることに注意してください。ただし、現在、CoreDNSに付属しているすべてのプラグインは、これら4つのグループのいずれかに分類されます。このブログ投稿も、クエリルーティングの背景を提供していることに注意してください。

クエリが処理されました

プラグインはクエリを処理します。応答を検索(または生成、またはプラグインの作成者がこのプラグインの動作を決定したもの)し、クライアントに送り返します。クエリの処理はここで停止し、次のプラグインは呼び出されません。このように動作する(単純な)プラグインは、*whoami*です。

クエリが処理されていません

プラグインがクエリを処理しないと判断した場合、チェーン内の次のプラグインを呼び出すだけです。チェーンの最後のプラグインがクエリを処理しないと判断した場合、CoreDNSはSERVFAILをクライアントに返します。

クエリがフォールスルーで処理されました

この状況では、プラグインはクエリを処理しますが、バックエンドから受け取った応答(つまり、NXDOMAINを受け取った可能性があります)は、チェーン内の他のプラグインにも見てほしいと考えています。*フォールスルー*が提供され(有効になっている場合)、次のプラグインが呼び出されます。このように動作するプラグインは、*hosts*プラグインです。最初に、ホストテーブル( `/etc/hosts`)で検索が試行され、回答が見つかった場合はそれを返します。そうでない場合、他のプラグインがクライアントに何かを返すことを期待して、*フォールスルー*します。

ヒント付きでクエリが処理されました

この種のプラグインはクエリを処理し、*常に*次のプラグインを呼び出します。ただし、クライアントに書き込まれる応答を確認できるヒントを提供します。これを行うプラグインは、*prometheus*です。期間(とりわけ)を測定しますが、実際にはDNSリクエストに対して何も行いません。渡して、戻りパスでいくつかのメタデータを検査するだけです。

未登録のプラグイン

DNSデータをまったく処理しないが、CoreDNSの動作に他の方法で影響を与える特別なクラスのプラグインがもう1つあります。たとえば、CoreDNSがどのインターフェースにバインドする必要があるかを制御する*bind*プラグインを考えてみましょう。次のプラグインはこのカテゴリに分類されます

  • *bind* - 前述のように、バインドするインターフェースを制御します。
  • *root* - CoreDNSプラグインがファイルを探すルートディレクトリを設定します。
  • *health* - HTTPヘルスチェックエンドポイントを有効にします。
  • *ready* - プラグインのレディネスレポートをサポートします。

プラグインの構造

プラグインは、セットアップ、登録、およびハンドラーの部分で構成されます。

セットアップは、設定とプラグインのディレクティブ(これらはプラグインのREADMEに記載されている必要があります)を解析します。

ハンドラーは、クエリを処理し、すべてのロジックを実装するコードです。

登録部分は、CoreDNSにプラグインを登録します。これは、CoreDNSがコンパイルされるときに発生します。登録されているすべてのプラグインは、サーバーで使用できます。各サーバーでどのプラグインが設定されるかの決定は実行時に行われ、CoreDNSの設定ファイルであるCorefileで行われます。

プラグインのドキュメント

各プラグインには、設定方法を詳述した独自のREADMEがあります。このREADMEには、例と、ユーザーが注意すべきその他の点が含まれています。これらのREADMEはそれぞれhttps://coredns.dokyumento.jp/pluginsに掲載され、マニュアルページにもコンパイルされます。

 

変更日:

設定

CoreDNSでは、さまざまな部分を構成できます。1つ目は、CoreDNSにコンパイルするプラグインを決定することです。提供するバイナリには、 `plugin.cfg`にリストされているすべてのプラグインがコンパイルされています。追加または削除は簡単ですが、CoreDNSの再コンパイルが必要です。

そのため、ほとんどのユーザーは*Corefile*を使用してCoreDNSを設定します。CoreDNSが起動し、 `-conf`フラグが指定されていない場合、現在のディレクトリに `Corefile`という名前のファイルを探します。そのファイルは、1つ以上のサーバーブロックで構成されています。各サーバーブロックは、1つ以上のプラグインをリストします。これらのプラグインは、ディレクティブでさらに構成できます。

Corefile内のプラグインの順序は、プラグインチェーンの順序を*決定しません*。プラグインが実行される順序は、 `plugin.cfg`の順序によって決まります。

Corefileのコメントは `#`で始まります。行の残りはコメントと見なされます。

環境変数

CoreDNSは、設定ファイル内で環境変数の置換をサポートしています。環境変数はCorefile内のどこにでも使用できます。構文は{$ENV_VAR}です(よりWindowsライクな構文{%ENV_VAR%}もサポートされています)。CoreDNSは、Corefileの解析中に変数の内容を置換します。

他のファイルのインポート

importプラグインを参照してください。このプラグインは、Corefile内のどこにでも使用できるという点で少し特殊です。

再利用可能なスニペット

ファイルインポートの特殊なケースとして、_スニペット_があります。スニペットは、特別な構文でブロックに名前を付けることで定義されます。名前は括弧で囲む必要があります:(name)。その後、_import_プラグインを使用して、設定の他の部分に含めることができます。

# define a snippet
(snip) {
    prometheus
    log
    errors
}

. {
    whoami
    import snip
}

サーバーブロック

各サーバーブロックは、サーバーが権限を持つゾーンから始まります。ゾーン名またはゾーン名のリスト(スペースで区切られています)の後、サーバーブロックは開き波括弧で開かれます。サーバーブロックは閉じ波括弧で閉じられます。次のサーバーブロックは、ルートゾーン以下のすべてのゾーンを担当するサーバーを指定します:.。基本的に、このサーバーはすべての可能なクエリを処理する必要があります。

. {
    # Plugins defined here.
}

サーバーブロックは、オプションでリッスンするポート番号を指定できます。デフォルトはポート53(DNSの標準ポート)です。ポートの指定は、ゾーンの後にコロンで区切ってポートを列挙することで行います。このCorefileは、CoreDNSにポート1053でリッスンするサーバーを作成するように指示します。

.:1053 {
    # Plugins defined here.
}

注意:サーバーのリスニングポートを明示的に定義した場合、-dns.portオプションでオーバーライドすることは_できません_。

既にサーバーに割り当てられているゾーンを持つサーバーブロックを指定し、_かつ_同じポートで実行するとエラーになります。このCorefileは起動時にエラーを生成します。

.:1054 {

}

.:1054 {

}

2番目のポート番号を1055に変更すると、これらのサーバーブロックは2つの異なるサーバーになります。 bindプラグインを使用する場合、_異なる_インターフェースまたはIPアドレスにバインドされている限り、_同じ_ポートでリッスンする同じゾーンを持つことができます。ここで使用されている構文は、CoreDNS 1.8.4以降でサポートされています。

.:1054 {
    bind lo
    whoami
}

.:1054 {
    bind eth0
    whoami
}

起動時に次のようなものが表示されます。

.:1054 on ::1
.:1054 on 192.168.86.22
.:1054 on 127.0.0.1

プロトコルの指定

現在、CoreDNSは4つの異なるプロトコルを受け入れます:DNS、DNS over TLS(DoT)、DNS over HTTP/2(DoH)、およびDNS over gRPC。サーバーがサーバー設定で受け入れるものを、ゾーン名の前にスキームを付けることで指定できます。

  • プレーンDNSの場合はdns://(スキームが指定されていない場合はデフォルト)。
  • DNS over TLSの場合はtls://RFC 7858を参照してください。
  • DNS over HTTPSの場合はhttps://RFC 8484を参照してください。
  • DNS over gRPCの場合はgrpc://

プラグイン

各サーバーブロックは、この特定のサーバーに対してチェーンされるべきプラグインの数を指定します。最も単純な形式では、サーバーブロックでプラグインの名前を使用するだけでプラグインを追加できます。

. {
    chaos
}

_chaos_プラグインは、CoreDNSがCHクラスでクエリに応答するようにします。これは、サーバーを識別するのに役立ちます。上記の設定では、CoreDNSはリクエストを受け取るとバージョンで応答します。

$ dig @localhost -p 1053 CH version.bind TXT
...
;; ANSWER SECTION:
version.bind.		0	CH	TXT	"CoreDNS-1.0.5"
...

ほとんどのプラグインは、ディレクティブを使用してより多くの設定を許可します。 chaosプラグインの場合、構文に示されているように、VERSIONAUTHORSを指定できます。

構文

  chaos [VERSION] [AUTHORS...]
  • **VERSION**は、返すバージョンです。設定されていない場合、デフォルトはCoreDNS-<version>です。
  • **AUTHORS**は、返す作成者です。デフォルトは、OWNERファイルで指定されているすべての人です。

そのため、_chaos_プラグインにいくつかのディレクティブを追加すると、CoreDNSはバージョンとしてCoreDNS-001で応答します。

. {
    chaos CoreDNS-001 info@coredns.io
}

より多くの設定オプションを持つ他のプラグインには、サーバーブロックと同様に、開き波括弧と閉じ波括弧で囲まれたプラグインブロックがあります。

. {
    plugin {
       # Plugin Block
    }
}

これらをすべて組み合わせることで、2つの異なるポートで4つのゾーンを設定する次のCorefileを作成できます。

coredns.io:5300 {
    file db.coredns.io
}

example.io:53 {
    log
    errors
    file db.example.io
}

example.net:53 {
    file db.example.net
}

.:53 {
    kubernetes
    forward . 8.8.8.8
    log
    errors
    cache
}

CoreDNSによって解析されると、これは次の設定になります。

CoreDNS: Zones, plugins and query routing

外部プラグイン

外部プラグインは、デフォルトのCoreDNSにコンパイルされていないプラグインです。簡単に有効にすることができますが、CoreDNSを自分でコンパイルする必要があります。

考えられるエラー

healthプラグインのドキュメントには、「このプラグインは一度だけ有効にする必要があります」と記載されています。これは、これが有効なCorefileであると考えるかもしれません。

health

. {
    whoami
}

しかし、これは機能せず、やや不可解なエラーが発生します。

"Corefile:3 - Error during parsing: Unknown directive '.'".

何が起こったのでしょうか? healthはゾーン(およびサーバーブロックの開始)と見なされます。パーサーはプラグイン名(cacheetcdなど)が表示されることを期待していますが、代わりに次のトークンは.であり、これはプラグインではありません。 Corefileは次のように構成する必要があります。

. {
    whoami
    health
}

_health_プラグインのドキュメントのその行は、_health_が一度指定されると、1つのサーバーにのみ指定した場合でも、CoreDNSプロセス全体でグローバルになることを意味します。

 

変更日:

セットアップ

ここでは、CoreDNSの構成を多数見つけることができます。すべてのセットアップは、ルートユーザーではなく、したがってポート53でリッスンを開始できないことを前提としています。代わりに、-dns.portフラグを使用してポート1053を使用します。すべてのセットアップで、使用される設定ファイルはCoreDNSのデフォルトである`Corefile`です。これは、`-conf`フラグで設定ファイルを指定する_必要がない_ことを意味します。言い換えれば、`./coredns -dns.port=1053 -conf Corefile`でCoreDNSを起動します。これは`./coredns -dns.port=1053`と省略できます。

すべてのDNSクエリは、DNSデバッグのゴールドスタンダードであるdigツールで生成されます。ここで使用する_完全な_コマンドラインは次のとおりです。

$ dig -p 1053 @localhost +noall +answer <name> <type>

ただし、以下のセットアップでは短縮されているため、dig www.example.org Aは実際にはdig -p 1053 @localhost +noall +answer www.example.org Aです。

ファイルからの権限のある配信

このセットアップでは、fileプラグインを使用します。外部のredisプラグインは、Redisデータベースからの権限のある配信を有効にします。 _file_を使用したセットアップを続けましょう。

ここで作成するファイルはDNSゾーンファイルであり、任意の名前を付けることができます(_file_プラグインは気にしません)。ファイルに入れているデータは、ゾーン`example.org.`用です。

現在のディレクトリに、`db.example.org`という名前のファイルを作成し、次の内容を書き込みます。

$ORIGIN example.org.
@	3600 IN	SOA sns.dns.icann.org. noc.dns.icann.org. (
				2017042745 ; serial
				7200       ; refresh (2 hours)
				3600       ; retry (1 hour)
				1209600    ; expire (2 weeks)
				3600       ; minimum (1 hour)
				)

	3600 IN NS a.iana-servers.net.
	3600 IN NS b.iana-servers.net.

www     IN A     127.0.0.1
        IN AAAA  ::1

最後の2行は、2つのアドレス127.0.0.1と(IPv6の):: 1を持つ名前`www.example.org.`を定義しています。

次に、このドメインのクエリを処理し、クエリロギングを有効にするためにlogプラグインを追加する、この最小限の`Corefile`を作成します。

example.org {
    file db.example.org
    log
}

CoreDNSを起動し、`dig`でクエリを実行します。

$ dig www.example.org AAAA

www.example.org.    3600    IN  AAAA    ::1

動作します。 _log_プラグインのため、ログに記録されているクエリも表示されるはずです。

[INFO] [::1]:44390 - 63751 "AAAA IN www.example.org. udp 45 false 4096" NOERROR qr,aa,rd,ra 121 0.000106009s

上記のログは、CoreDNSが応答したアドレス(`::1`)と応答した日時を示しています。さらに、クエリタイプ、クエリクラス、クエリ名、使用されたプロトコル(`udp`)、受信リクエストのバイト単位のサイズ、DOビットの状態、およびアドバタイズされたUDPバッファサイズをログに記録します。これは、受信クエリからのデータです。 `NOERROR`は応答の開始を示します。これは、返信された応答コードであり、その後に返信のフラグのセットが続きます:`qr,aa,rd,ra`、バイト単位の返信のサイズ(121)、および取得にかかった時間です。返信。

転送

CoreDNSは、forwardを使用して、トラフィックをリカーサーに転送するように構成できます。ここでは、_forward_を使用し、最も基本的な設定、つまりGoogle Public DNS(8.8.8.8)とQuad9 DNS(9.9.9.9)への転送に焦点を当てます。

必要な構成のCorefile以外は何も作成する必要はありません。この場合、CoreDNSに到達する_すべて_のクエリを8.8.8.8または9.9.9.9に転送します。

. {
    forward . 8.8.8.8 9.9.9.9
    log
}

_forward_では、アップストリームに送信する名前を微調整できることに注意してください。ここでは、すべての名前(`.`)を選択しました。たとえば、`forward example.com 8.8.8.8 9.9.9.9`は、`example.com.`ドメイン内の名前のみを転送します。

CoreDNSを起動し、`dig`でテストします。

$ dig www.example.org AAAA
www.example.org.	25837	IN	AAAA	2606:2800:220:1:248:1893:25c8:194

ドメインを異なるアップストリームに転送する

よく遭遇するシナリオは、`example.org`のクエリは8.8.8.8に送信する必要があり、残りは`/etc/resolv.conf`のネームサーバー経由で解決する必要があることです。 Corefileで実装できる方法は2つあります。

  1. 単一のサーバーブロック内でforwardプラグインの複数の宣言を使用します。
. {
    forward example.org 8.8.8.8
    forward . /etc/resolv.conf
    log
}
  1. ルーティングするドメインごとに1つずつ、複数のサーバーブロックを使用します。
example.org {
    forward . 8.8.8.8
    log
}

. {
    forward . /etc/resolv.conf
    log
}

これにより、ドメインルーティングはCoreDNSに任され、DSクエリなどの特殊なケースも処理されます。 1つではなく2つの小さなサーバーブロックを使用しても、Corefileがわずかに長くなることを除けば、悪影響はありません。スニペットやimportなどが役立ちます。

再帰リゾルバー

CoreDNSにはネイティブ(つまりGoで記述された)の再帰リゾルバーはありませんが、libunboundを利用する(外部)プラグインがあります。このセットアップを機能させるには、最初にCoreDNSを再コンパイルし、_unbound_プラグインを有効にする必要があります。ここでは非常に簡単な入門書です(CoreDNSのソースがインストールされている必要があります)。

  • `unbound:github.com/coredns/unbound`を`plugin.cfg`に追加します。
  • `go generate`を実行し、続いて`make`を実行します。

注:_unbound_プラグインをコンパイルするにはcgoが必要です。これは、corednsバイナリがlibunboundにリンクされており、静的バイナリではなくなったことも意味します。

これがうまくいったと仮定すると、次のCorefileで_unbound_を有効にできます。

. {
    unbound
    cache
    log
}

cacheが含まれています。これは、キャッシュのメトリックが通常どおり機能するように、_unbound_からの(内部)キャッシュが無効になっているためです。

 

変更日:

プラグインの作成

このマニュアルですでに述べたように、プラグインはCoreDNSを動かすものです。 前のセクションで多くの構成を見てきましたが、独自のプラグインをどのように記述できますか?

このテーマに関する古い投稿については、CoreDNSのプラグインの作成を参照してください。 CoreDNSのソースで文書化されているplugin.mdにも、いくつかの背景があり、README.mdのスタイルについて説明しています。

標準的なサンプルプラグインは、_example_プラグインです。そのgithubリポジトリは、プラグインを作成するために必要な最小限のコード(テスト付き!)を示しています。

これには以下が含まれています。

  1. Corefileからの構成の解析を実装する`setup.go`と`setup_test.go`。(通常は名前が付けられた)`setup`関数は、Corefileパーサーがプラグインの名前(この場合は「example」)を検出するたびに呼び出されます。
  2. クエリの処理ロジックを含む`example.go`(通常は`<plugin_name>.go`という名前)と、プラグインが機能するかどうかを確認するための基本的なユニットテストを含む`example_test.go`。
  3. このプラグインの構成方法をUnixマニュアルスタイルで説明する`README.md`。
  4. LICENSEファイル。 CoreDNSに含めるには、APLのようなライセンスが必要です。

コードには広範なコメントもあります。自由にフォークして、プラグインの基礎としてください。

プラグインの呼び出し方法

CoreDNSがプラグインを使用する場合、`ServeDNS`メソッドを呼び出します。 `ServeDNS`には3つのパラメーターがあります。

  • `context.Context`;
  • 基本的にクライアントの接続である`dns.ResponseWriter`;
  • クライアントからのリクエストである`*dns.Msg`。

`ServeDNS`は、(応答)コードとエラーの2つの値を返します。 errorsがこのサーバーで使用されている場合、エラーがログに記録されます。

このコードは、_プラグインチェーンによって返信が書き込まれたかどうか_をCoreDNSに伝えます。後者の場合、CoreDNSがそれを処理します。コードの値については、dnsパッケージからのDNSリターンコード(rcode)を_再利用_します。

CoreDNSは以下を特別扱いします。

  • SERVFAIL (dns.RcodeServerFailure)
  • REFUSED (dns.RcodeRefused)
  • FORMERR (dns.RcodeFormatError)
  • NOTIMP (dns.RcodeNotImplemented)

そして、クライアントに_何も_書き込まれていないと想定します。他のすべての場合、クライアントに(プラグインによって)何かが書き込まれたと想定します。

プラグインを使用してCoreDNSをコンパイルする方法については、この記事を参照してください。

プラグインからのロギング

プラグインにロギングを追加するには、logパッケージを使用します。あなたはそれを以下で初期化します。

var log = clog.NewWithPlugin("example")

標準出力に`[INFO] plugin/example`というプレフィックスを付けて何かを出力するには、`log.Infof("...")`を使用できます。レベルは`INFO`、`WARNING`、または`ERROR`です。

一般的に、エラーを返す場合は、ロギングは上位レイヤーに任せるべきです。ただし、エラーを処理する必要があるものの、ユーザーに通知する理由がある場合は、プラグインでロギングを行うことは許容されます。

メトリクス

メトリクスをエクスポートする場合、_名前空間_は`plugin.Namespace`(="coredns")で、_サブシステム_はプラグインの名前である必要があります。プラグインのREADME.mdには、メトリクスの詳細を説明する_メトリクス_セクションも含まれている必要があります。プラグインが準備完了レポートをサポートしている場合は、それを詳細に説明する_準備完了_セクションも必要です。

ドキュメント

各プラグインには、プラグインの機能と設定方法を説明するREADME.mdが必要です。ファイルには、次のレイアウトが必要です。

  • タイトル:プラグインの名前を使用します
  • `<プラグイン名> - <一行の説明>。`で「名前付き」というタイトルのサブセクション。つまり、名前、ダッシュ、説明、ピリオドです。
  • より長い説明とプラグインがサポートするすべてのオプションを含む「説明」というタイトルのサブセクション。
  • 構文とサポートされているディレクティブを詳細に説明する「構文」というタイトルのサブセクション。
  • 「例」というタイトルのサブセクション。
  • IETF RFCなどの外部ドキュメントを参照する、オプションの「関連項目」というタイトルのサブセクション。
  • まだ機能していないものをリストする、オプションの「バグ」というタイトルのサブセクション。

もちろん、さらにセクションを追加することも可能です。

スタイル

Unixのマニュアルページスタイルを使用します

  • 実行テキスト内のプラグインの名前はイタリック体にする必要があります:`*plugin*`。
  • 実行テキスト参照内のすべての大文字のユーザー指定引数は、太字を使用します:`**EXAMPLE**`。
  • オプションのテキストはブロック引用符で囲みます:`[optional]`(オプション)。
  • 3つのドットを使用して、複数のオプションが許可されていることを示します:`arg...`。
  • アイテムはリテラルを使用しました:`literal`。

ドメイン名の例

提供する例やテストでは、必ず`example.org`または`example.net`を使用してください。これらは、この目的のために作成された標準のドメイン名です。使用しない場合、空想上のドメイン名が誰かに登録され、実際にWebコンテンツを提供する可能性があります(好むかどうかにかかわらず)。

フォールスルー

理想的な世界では、プラグインには次のことが当てはまります。「ゾーンを担当するかどうか」。答えが「いいえ」の場合、プラグインはチェーン内の次のプラグインを呼び出す必要があります。「はい」の場合、そのゾーンとその下の_すべて_の名前を処理する必要があります。つまり、ドメイン全体とすべてのサブドメインを処理する必要があります。`fallthrough`が有効な場合のクエリの処理方法については、こちらをご覧ください

. {
    file example.org db.example
}

この例では、_file_プラグインは`example.org`以下の(およびを含む)すべての名前を処理しています。`example.org`のサブドメインではない(または等しくない)クエリが着信した場合、次のプラグインが呼び出されます。

しかし、世界は完璧ではなく、次のミドルウェアに「フォールスルー」する正当な理由があります。つまり、プラグインはゾーン内の名前の_サブセット_のみを担当します。最初に登場したのは_reverse_プラグインで、現在はさまざまな応答を合成できる汎用化された_template_プラグインに置き換えられています。

_template_プラグインの性質上、指定されたレコードTYPEのみを処理し、それも名前のサブセットに対してのみ処理する場合があります。理想的には、_file_や_auto_などの別のプラグインの**前に**_template_をレイヤー化したいと思うでしょう。これは、_template_がいくつかの特別な逆引きケースを処理し、**他のすべて**のリクエストはバッキングプラグインによって処理されることを意味します。これはまさに「フォールスルー」が行うことです。物事を明確にするために、このような動作を実装するプラグインは`fallthrough`キーワードを実装する必要があるという選択をしました。

`fallthrough`ディレクティブは、オプションでゾーンのリストを受け入れる必要があります。これらのゾーンのいずれかのレコードに対するクエリのみがフォールスルーを許可される必要があります。

メインリポジトリの資格

要件については、このドキュメントをご覧ください。