リライト

ソース

rewrite は、内部的なメッセージのリライトを実行します。

説明

リライトはクライアントには見えません。単純なリライト(高速)と複雑なリライト(低速)がありますが、ほとんどの動的なバックエンドアプリケーションに対応できるほど強力です。

構文

rewrite の簡略化された/理解しやすい構文は次のとおりです...

rewrite [continue|stop] FIELD [TYPE] [(FROM TO)|TTL] [OPTIONS]
  • FIELD は、リライトされるリクエスト/レスポンスのどの部分を示します。

    • type - リクエストのタイプフィールドがリライトされます。FROM/TO は DNS レコードタイプ (AMX など) である必要があります。例えば、ANY クエリを HINFO にリライトするには、rewrite type ANY HINFO を使用します。
    • name - リクエスト内のクエリ名がリライトされます。デフォルトでは、これは名前の完全一致です。例えば、rewrite name example.net example.org のようにします。他のマッチタイプもサポートされています。以下の 名前フィールドのリライト セクションを参照してください。
    • class - メッセージのクラスがリライトされます。FROM/TO は DNS クラスタイプ (INCH、または HS) である必要があります。例えば、CH クエリを IN にリライトするには、rewrite class CH IN を使用します。
    • edns0 - EDNS0 オプションは、以下の EDNS0 オプション セクションで説明するように、リクエストに追加できます。
    • ttl - レスポンス内の TTL 値がリライトされます。
    • cname - レスポンスに CNAME レコードがある場合の CNAME ターゲット
  • TYPE このオプション要素は、name または ttl フィールドに対して指定できます。指定しない場合は、exact タイプが想定されます。オプションを指定する場合は、タイプを指定する必要があります。

  • FROM は、一致する名前 (完全一致、サフィックス、プレフィックス、サブストリング、または正規表現) またはタイプです。

  • TO は、リライト先の宛先名またはタイプです。

  • TTL は、TTL 値を設定する秒数です (ttl フィールドの場合のみ)

  • オプション

    フィールド name では、レスポンスのリライトを制御するための追加オプションが可能です。すべての名前マッチングタイプは、次のオプションをサポートしています。

    • answer auto - レスポンス内の名前が、ベストエフォート方式でリライトされます。
    • answer name FROM TO - レスポンス内のクエリ名が、FROM 正規表現パターンに一致するようにリライトされます。
    • answer value FROM TO - レスポンス内の名前が、FROM 正規表現パターンに一致するようにリライトされます。

    詳細については、以下の レスポンスのリライト セクションを参照してください。

複数のルールを指定し、着信クエリが複数のルールに一致する場合、リライトは次のように動作します

  • continue は、ルールリストの次のルールの適用を継続します。
  • stop は、現在のルールを最後のルールとみなし、継続しません。デフォルトの動作は stop です。

名前フィールドのリライト

rewrite プラグインは、DNS リクエストの質問セクションで名前をマッチングする機能を提供します。マッチは、完全一致、サブストリング一致、またはプレフィックス、サフィックス、または正規表現に基づく可能性があります。新しく使用される名前が有効なドメイン名でない場合、プラグインはクライアントにエラーを返します。

名前のリライトの構文は次のとおりです

rewrite [continue|stop] name [exact|prefix|suffix|substring|regex] STRING STRING [OPTIONS]

マッチタイプ(例:exactsubstring など)がリライトをトリガーします

  • exact (デフォルト): リクエストの質問セクションの名前が完全に一致する場合
  • substring: リクエストの質問セクションの名前が部分的に一致する場合
  • prefix: 名前がマッチング文字列で始まる場合
  • suffix: 名前がマッチング文字列で終わる場合
  • regex: リクエストの質問セクションの名前が正規表現に一致する場合

マッチタイプが省略されている場合、exact マッチタイプが想定されます。オプションを指定する場合は、タイプを指定する必要があります。

次の命令により、サブストリング service.us-west-1.example.org を含むクエリの名前のリライトが可能になります。

rewrite name substring service.us-west-1.example.org service.us-west-1.consul

したがって

  • 着信リクエスト名: ftp.service.us-west-1.example.org
  • リライトされたリクエスト名: ftp.service.us-west-1.consul

次の命令は正規表現を使用します。正規表現 (.*)-(us-west-1)\.example\.org に一致するリクエスト内の名前は、{1}.service.{2}.consul に置き換えられます。ここで、{1} および {2} は正規表現マッチグループです。

rewrite name regex (.*)-(us-west-1)\.example\.org {1}.service.{2}.consul

したがって

  • 着信リクエスト名: ftp-us-west-1.example.org
  • リライトされたリクエスト名: ftp.service.us-west-1.consul

次の例では、schmoogle.com サフィックスを google.com にリライトします。

rewrite name suffix .schmoogle.com. .google.com.

レスポンスのリライト

着信 DNS リクエストの名前 (フィールド name) をリライトする場合、CoreDNS はリクエストの QUESTION SECTION セクションをリライトします。QUESTION SECTIONANSWER SECTION の不一致を中間者攻撃 (MITM) として扱う DNS リゾルバがあるため、リクエストの ANSWER SECTION をリライトする必要がある場合があります。

たとえば、ユーザーが ftp-us-west-1.coredns.rocks を解決しようとします。CoreDNS 設定ファイルには次のルールがあります

rewrite name regex (.*)-(us-west-1)\.coredns\.rocks {1}.service.{2}.consul

CoreDNS は、リクエストを ftp-us-west-1.coredns.rocks から ftp.service.us-west-1.consul にリライトし、最終的に 3 つのレコードに解決しました。以下の ANSWER SECTION の解決されたレコードは、coredns.rocks ではなく、service.us-west-1.consul からのものでした。

$ dig @10.1.1.1 ftp-us-west-1.coredns.rocks

;; QUESTION SECTION:
;ftp-us-west-1.coredns.rocks. IN A

;; ANSWER SECTION:
ftp.service.us-west-1.consul. 0    IN A    10.10.10.10
ftp.service.us-west-1.consul. 0    IN A    10.20.20.20
ftp.service.us-west-1.consul. 0    IN A    10.30.30.30

上記は、質問された内容と提供された回答の不一致です。

応答のリライトを指定するには、3 つの可能性があります。

  • リライトは、オプション answer auto を追加することにより、ベストエフォートの応答のリライトを要求できます。
  • リライトは、answer name FROM TO オプションを使用して、専用の正規表現ベースの応答名のリライトを指定できます。
  • CNAMESRVなどのレコード値の正規表現ベースのリライトは、answer value FROM TO オプションでリクエストできます。

ここで、FROM/TO は regex 名前リライト構文のルールに従います。

自動応答名のリライト

次の設定スニペットでは、QUESTION SECTION のリライトに従って ANSWER SECTION のリライトを可能にします。

    rewrite stop {
        name suffix .coredns.rocks .service.consul answer auto
    }

回答内のリライトされた質問のすべての出現箇所は、リライト前の元の値にマップバックされます。

exact タイプのルールをリライトするための回答は常にリライトされることに注意してください。suffix 名前ルールの場合、auto はリバースサフィックス応答リライトにつながり、リライトリクエストの FROM と TO を交換します。

明示的な応答名のリライト

次の設定スニペットでは、QUESTION SECTION がリライトされた場合、ANSWER SECTION のリライトを可能にします

    rewrite stop {
        name regex (.*)-(us-west-1)\.coredns\.rocks {1}.service.{2}.consul
        answer name (.*)\.service\.(us-west-1)\.consul {1}-{2}.coredns.rocks
    }

これで、ANSWER SECTIONQUESTION SECTION に一致します

$ dig @10.1.1.1 ftp-us-west-1.coredns.rocks

;; QUESTION SECTION:
;ftp-us-west-1.coredns.rocks. IN A

;; ANSWER SECTION:
ftp-us-west-1.coredns.rocks. 0    IN A    10.10.10.10
ftp-us-west-1.coredns.rocks. 0    IN A    10.20.20.20
ftp-us-west-1.coredns.rocks. 0    IN A    10.30.30.30

その他の応答値のリライト

DNS レスポンスレコードで返される他の値 (たとえば、SRV および MX レコードで返されるサーバー名) をリライトすることもできます。これは、以下に示すように、answer value FROM TO オプションを名前ルールに追加することで有効にできます。answer value は、正規表現とリライト名をパラメーターとして受け取り、answer name ルールと同じように機能します。

AUTHORITY SECTION および ADDITIONAL SECTION の名前も、指定されたルールに従ってリライトされることに注意してください。次のレコードタイプによって返される名前: CNAMEDNAMESOASRVMXNAPTRNSPTR は、answer value ルールが指定されている場合にリライトされます。

DNS リクエストとレスポンスのリライトの構文は次のとおりです

rewrite [continue|stop] {
    name regex STRING STRING
    answer name STRING STRING
    [answer value STRING STRING]
}

上記の構文は厳密であることに注意してください。応答のリライトの場合、質問セクションに一致できるのは name ルールのみです。応答のリライトは、構文例のように、名前の後に続く必要があります。

例: PTR 応答値のリライト

元の応答には、ANSWER SECTIONVALUE 部分にドメイン service.consul. が含まれています

$ dig @10.1.1.1 30.30.30.10.in-addr.arpa PTR

;; QUESTION SECTION:
;30.30.30.10.in-addr.arpa. IN PTR

;; ANSWER SECTION:
30.30.30.10.in-addr.arpa. 60    IN PTR    ftp-us-west-1.service.consul.

次の設定スニペットでは、ANSWER SECTION の値のリライトを可能にします

    rewrite stop {
        name suffix .arpa .arpa
        answer name auto
        answer value (.*)\.service\.consul\. {1}.coredns.rocks.
    }

これで、ANSWER SECTIONVALUE は、ドメイン部分で上書きされました

$ dig @10.1.1.1 30.30.30.10.in-addr.arpa PTR

;; QUESTION SECTION:
;30.30.30.10.in-addr.arpa. IN PTR

;; ANSWER SECTION:
30.30.30.10.in-addr.arpa. 60    IN PTR    ftp-us-west-1.coredns.rocks.

複数の応答のリライト

name および value リライトは、複数の応答リライトオプションを追加することで連結できます。最初以外のすべての出現箇所で、キーワード answer を省略できます。

answer (auto | (name|value FROM TO)) { [answer] (auto | (name|value FROM TO)) }

rewrite [continue|stop] name regex FROM TO answer name FROM TO [answer] value FROM TO

exact 名前リライトルールを使用する場合、回答は自動的にリライトされるため、answer name auto を定義する必要はありません。ただし、追加の answer value および answer value オプションを定義することは可能です。

次のルールでは、リクエストの名前を RED から BLUE にリライトし、その後、対応する応答の名前を BLUE から RED にリライトします。リクエスト内のクライアントには、RED のみが表示され、BLUE は表示されません。

rewrite [continue|stop] name exact RED BLUE

TTL フィールドのリライト

TTL 値をリライトする必要がある場合があります。たとえば、DNS サーバーは、TTL がゼロ (0) のレコードをキャッシュしない場合があります。管理者は、TTL を 15 秒に増やすなどして、キャッシュされるように TTL を増やしたい場合があります。

以下の例では、coredns.rocks ドメインの応答の TTL が 15 に設定されています

    rewrite continue {
        ttl regex (.*)\.coredns\.rocks 15
    }

同様に、管理者はこの機能を使用して、TTL 値を非常に低く設定することで、キャッシュを防止または制限できます。

TTL リライトルールの構文は次のとおりです。exact|prefix|suffix|substring|regex の意味は、名前リライトルールと同じです。省略されたタイプは、デフォルトで exact になります。

rewrite [continue|stop] ttl [exact|prefix|suffix|substring|regex] STRING [SECONDS|MIN-MAX]

単一の値の代わりに、SECONDS パラメーターで TTL 値の範囲を指定できます。範囲が指定されている場合、TTL 値が下回っている場合は MIN に設定され、上回っている場合は MAX に設定されます。TTL 値がすでに指定された範囲内にある場合は、変更されません。範囲は、どちらの側でも境界がない場合があります。

範囲を持つ TTL の例

# rewrite TTL to be between 30s and 300s
rewrite ttl example.com. 30-300

# cap TTL at 30s
rewrite ttl example.com. -30 # equivalent to rewrite ttl example.com. 0-30

# increase TTL to a minimum of 30s
rewrite ttl example.com. 30-

# set TTL to 30s
rewrite ttl example.com. 30 # equivalent to rewrite ttl example.com. 30-30

EDNS0 オプション

FIELD edns0 を使用すると、リクエストで特定の EDNS0 オプションを設定、追加、または置換できます。

  • replace は、「一致する」オプションを指定されたオプションで変更します。「一致」の基準は、EDNS0 タイプによって異なります。
  • append は、一致するオプションが存在しない場合にのみオプションを追加します
  • set は、一致するオプションを変更するか、一致するオプションがない場合は追加します

現在サポートされているのは、EDNS0_LOCALEDNS0_NSID、および EDNS0_SUBNET です。

EDNS0_LOCAL

これには、コードとデータの2つのフィールドがあります。一致とは、同じコードを持つことと定義されます。データは、文字列または変数の場合があります。

  • 文字列データは、0xで始まる場合、16進数として扱われます。例:
. {
    rewrite edns0 local set 0xffee 0x61626364
    whoami
}

は、コードが0xffeeの最初のローカルオプションを書き換え、データを「abcd」に設定します。これは、以下と同等です。

. {
    rewrite edns0 local set 0xffee abcd
}
  • 変数データは、波括弧{}のペアで指定されます。サポートされている変数は、{qname}、{qtype}、{client_ip}、{client_port}、{protocol}、{server_ip}、{server_port}です。

  • メタデータプラグインが有効な場合、ラベルが波括弧内に存在する場合は、変数としてサポートされます。変数データは、そのラベルに関連付けられた値に置き換えられます。そのラベルが提供されていない場合、変数は空の文字列で黙って置き換えられます。

rewrite edns0 local set 0xffee {client_ip}

次の例では、メタデータと、メタデータ情報として「some-label」を提供する架空の「some-plugin」を使用しています。

metadata
some-plugin
rewrite edns0 local set 0xffee {some-plugin/some-label}

EDNS0_NSID

これにはフィールドはありません。NSIDオプションに空の文字列でNSIDを追加します。オプションがすでに存在し、アクションがreplaceまたはsetの場合、オプションのNSIDは空の文字列に設定されます。

EDNS0_SUBNET

これには、IPv4ビットマスク長とIPv6ビットマスク長の2つのフィールドがあります。ビットマスク長は、クエリ内の送信元IPアドレスからクライアントサブネットを抽出するために使用されます。

例:

rewrite edns0 subnet set 24 56
  • クエリの送信元IPアドレスがIPv4アドレスの場合、IPの最初の24ビットがネットワークサブネットになります。
  • クエリの送信元IPアドレスがIPv6アドレスの場合、IPの最初の56ビットがネットワークサブネットになります。

CNAMEフィールドの書き換え

応答のCNAMEターゲットを書き換えたいシナリオがあるかもしれません。これは、CNAMEフィールドの書き換えを使用することで実行できます。これにより、新しいCNAMEターゲットに従って新しい応答レコードが生成されます。

CNAME書き換えルールの構文は次のとおりです。exact|prefix|suffix|substring|regexの意味は、名前書き換えルールと同じです。省略されたタイプは、デフォルトでexactになります。

rewrite [continue|stop] cname [exact|prefix|suffix|substring|regex] FROM TO

正規表現タイプを使用した次のCNAME書き換えルールを検討してください。

rewrite cname regex (.*).cdn.example.net. {1}.other.cdn.com.

上記のルールなしで次のDNSリクエストを送信した場合、応答例は次のようになります。

$ dig @10.1.1.1 my-app.com

;; QUESTION SECTION:
;my-app.com. IN A

;; ANSWER SECTION:
my-app.com.                  200  IN  CNAME  my-app.com.cdn.example.net.
my-app.com.cdn.example.net.  300  IN  A      20.2.0.1
my-app.com.cdn.example.net.  300  IN  A      20.2.0.2

上記の設定で同じDNSリクエストを送信した場合、応答例は次のようになります。

$ dig @10.1.1.1 my-app.com

;; QUESTION SECTION:
;my-app.com. IN A

;; ANSWER SECTION:
my-app.com.                  200  IN  CNAME  my-app.com.other.cdn.com.
my-app.com.other.cdn.com.    100  IN  A      30.3.1.2

回答は、CNAMEターゲットを書き換えた後、完全に異なる一連の応答レコードを含むことに注意してください。