ドキュメント
プロジェクト

reverse_proxy

設定可能なトランスポート、負荷分散、ヘルスチェック、リクエスト操作、およびバッファリングオプションを使用して、リクエストを1つ以上のバックエンドにプロキシします。

構文

reverse_proxy [<matcher>] [<upstreams...>] {
	# backends
	to      <upstreams...>
	dynamic <module> ...

	# load balancing
	lb_policy       <name> [<options...>]
	lb_retries      <retries>
	lb_try_duration <duration>
	lb_try_interval <interval>
	lb_retry_match  <request-matcher>

	# active health checking
	health_uri      <uri>
	health_port     <port>
	health_interval <interval>
	health_timeout  <duration>
	health_status   <status>
	health_body     <regexp>
	health_headers {
		<field> [<values...>]
	}

	# passive health checking
	fail_duration     <duration>
	max_fails         <num>
	unhealthy_status  <status>
	unhealthy_latency <duration>
	unhealthy_request_count <num>

	# streaming
	flush_interval     <duration>
	request_buffers    <size>
	response_buffers   <size>
	stream_timeout     <duration>
	stream_close_delay <duration>

	# request/header manipulation
	trusted_proxies [private_ranges] <ranges...>
	header_up   [+|-]<field> [<value|regexp> [<replacement>]]
	header_down [+|-]<field> [<value|regexp> [<replacement>]]
	method <method>
	rewrite <to>

	# round trip
	transport <name> {
		...
	}

	# optionally intercept responses from upstream
	@name {
		status <code...>
		header <field> [<value>]
	}
	replace_status [<matcher>] <status_code>
	handle_response [<matcher>] {
		<directives...>

		# special directives only available in handle_response
		copy_response [<matcher>] [<status>] {
			status <status>
		}
		copy_response_headers [<matcher>] {
			include <fields...>
			exclude <fields...>
		}
	}
}

アップストリーム

  • <upstreams...> は、プロキシ先のアップストリーム(バックエンド)のリストです。
  • to は、アップストリームのリストを1行に1つ(または複数)指定する別の方法です。
  • dynamic は、*動的アップストリーム*モジュールを設定します。これにより、リクエストごとにアップストリームのリストを動的に取得できます。標準の動的アップストリームモジュールの説明については、以下の動的アップストリームを参照してください。動的アップストリームは、すべてのリバースプロキシループの反復(つまり、負荷分散の再試行が有効になっている場合は、リクエストごとに複数回)で取得され、静的アップストリームよりも優先されます。エラーが発生した場合、プロキシは静的に設定されたアップストリームの使用にフォールバックします。

アップストリームアドレス

静的アップストリームアドレスは、スキームとホスト/ポートのみを含むURL、または従来のCaddyネットワークアドレスの形式を取ることができます。有効な例

  • localhost:4000
  • 127.0.0.1:4000
  • http://localhost:4000
  • https://example.com
  • h2c://127.0.0.1
  • example.com
  • unix//var/php.sock
  • unix+h2c//var/grpc.sock
  • localhost:8001-8006

デフォルトでは、接続はプレーンテキストHTTPを介してアップストリームに対して行われます。URLフォームを使用する場合、スキームを使用して、いくつかのtransportのデフォルトを省略形として設定できます。

  • スキームとしてhttps://を使用すると、httpトランスポートtls有効で使用されます。

    さらに、サーバーがルーティングと証明書の選択に使用するTLS SNI値と一致するように、Hostヘッダーをオーバーライドする必要がある場合があります。詳細については、以下のHTTPSセクションを参照してください。

  • スキームとしてh2c://を使用すると、httpトランスポートHTTPバージョン設定でクリアテキストHTTP/2接続を許可するように設定されます。

  • スキームとして`http://`を使用することは、HTTPがすでにデフォルトであるため、スキームを省略することと同じです。この構文は、他のスキームの省略形との対称性のために含まれています。

スキームは、共通のトランスポート設定を変更するため、混在させることはできません(TLS対応のトランスポートは、HTTPSとプレーンテキストHTTPの両方を伝送できません)。明示的なトランスポート設定は上書きされず、スキームを省略したり他のポートを使用したりしても、特定のトランスポートが想定されることはありません。

ネットワークアドレスフォームを使用する場合、ネットワークタイプはアップストリームアドレスのプレフィックスとして指定されます。これは、URLスキームと組み合わせることはできません。特別な場合として、`unix+h2c/`は`unix/`ネットワークのショートカットとして、`h2c://`スキームと同じ効果を持ちます。ポート範囲はショートカットとしてサポートされており、同じホストを持つ複数のアップストリームに展開されます。

アップストリームアドレスには、パスまたはクエリ文字列を含めることはできません。これは、プロキシ中にリクエストを同時に書き換えることを意味しますが、この動作は定義またはサポートされていません。この必要がある場合は、rewriteディレクティブを使用できます。

アドレスがURLでない場合(つまり、スキームがない場合)、プレースホルダーを使用できますが、これによりアップストリームは*動的に静的*になります。つまり、ヘルスチェックと負荷分散の観点からは、潜在的に多くの異なるバックエンドが単一の静的アップストリームとして機能します。可能であれば、代わりに動的アップストリームモジュールを使用することをお勧めします。プレースホルダーを使用する場合、ポートは**必須**です(プレースホルダーの置換、またはアドレスへの静的サフィックスのいずれか)。

動的アップストリーム

Caddyのリバースプロキシには、いくつかの動的アップストリームモジュールが標準で付属しています。動的アップストリームを使用すると、特定のポリシー設定に応じて、負荷分散とヘルスチェックに影響が及ぶことに注意してください。アクティブヘルスチェックは動的アップストリームに対して実行されません。負荷分散とパッシブヘルスチェックは、アップストリームのリストが比較的安定していて一貫している場合(特にラウンドロビンを使用する場合)に最適です。理想的には、動的アップストリームモジュールは、正常で使えるバックエンドのみを返します。

SRV

SRV DNSレコードからアップストリームを取得します。

	dynamic srv [<full_name>] {
		service   <service>
		proto     <proto>
		name      <name>
		refresh   <interval>
		resolvers <ip...>
		dial_timeout        <duration>
		dial_fallback_delay <duration>
	}
  • <full_name> は、検索するレコードの完全ドメイン名です(つまり、`_service._proto.name`)。
  • service は、完全ドメイン名のサービスコンポーネントです。
  • proto は、完全ドメイン名のプロトコルコンポーネントです。`tcp`または`udp`のいずれかです。
  • name は、名前コンポーネントです。または、`service`と`proto`が空の場合、クエリする完全ドメイン名です。
  • **refresh** は、キャッシュされた結果を更新する頻度です。デフォルト:`1m`
  • **resolvers** は、システムリゾルバーをオーバーライドするDNSリゾルバーのリストです。
  • **dial_timeout** は、クエリをダイヤルするためのタイムアウトです。
  • **dial_fallback_delay** は、RFC 6555高速フォールバック接続を生成するまでの待機時間です。デフォルト:`300ms`
A/AAAA

A/AAAA DNSレコードからアップストリームを取得します。

	dynamic a [<name> <port>] {
		name      <name>
		port      <port>
		refresh   <interval>
		resolvers <ip...>
		dial_timeout        <duration>
		dial_fallback_delay <duration>
		versions ipv4|ipv6
	}
  • **name** は、クエリするドメイン名です。
  • **port** は、バックエンドに使用するポートです。
  • **refresh** は、キャッシュされた結果を更新する頻度です。デフォルト:`1m`
  • **resolvers** は、システムリゾルバーをオーバーライドするDNSリゾルバーのリストです。
  • **dial_timeout** は、クエリをダイヤルするためのタイムアウトです。
  • **dial_fallback_delay** は、RFC 6555高速フォールバック接続を生成するまでの待機時間です。デフォルト:`300ms`
  • **versions** は、解決するIPバージョンのリストです。デフォルト:`ipv4 ipv6`。それぞれAレコードとAAAAレコードに対応します。
マルチ

複数の動的アップストリームモジュールの結果を追加します。冗長なアップストリームソースが必要な場合に便利です。たとえば、セカンダリSRVクラスタによってバックアップされたプライマリSRVクラスタなどです。

	dynamic multi {
		<source> [...]
	}
  • <source> は、動的アップストリームのモジュールの名前とその設定です。複数指定できます。

負荷分散

負荷分散は、通常、複数のアップストリーム間でトラフィックを分割するために使用されます。再試行を有効にすることで、1つ以上のアップストリームで使用して、正常なアップストリームが選択されるまでリクエストを保留することもできます(たとえば、アップストリームの再起動または再デプロイ中にエラーを待機して軽減するため)。

これはデフォルトで有効になっており、`random`ポリシーが使用されます。再試行はデフォルトで無効になっています。

  • **lb_policy** は、負荷分散ポリシーの名前とそのオプションです。デフォルト:`random`。

    ハッシュを含むポリシーの場合、最高ランダム重み(HRW)アルゴリズムを使用して、アップストリームのリストが変更された場合でも、同じハッシュキーを持つクライアントまたはリクエストが同じアップストリームにマップされるようにします。

    一部のポリシーは、注記されている場合、フォールバックをオプションとしてサポートしています。その場合、別の負荷分散ポリシーを取る`fallback <policy>`を含むブロックを取ります。これらのポリシーでは、デフォルトのフォールバックは`random`です。フォールバックを設定すると、プライマリで選択されない場合にセカンダリポリシーを使用できるため、強力な組み合わせが可能になります。フォールバックは、必要に応じて複数回ネストできます。

    たとえば、`header`をプライマリとして使用して、開発者が特定のアップストリームを選択できるようにし、プライマリ/セカンダリフェイルオーバーを実装するために他のすべての接続のフォールバックとして`first`を使用できます。

    lb_policy header X-Upstream {
    	fallback first
    }
    
    • random ランダムにアップストリームを選択します

    • random_choose <n> ランダムに2つ以上のアップストリームを選択し、負荷が最も少ないアップストリームを選択します(`n`は通常2です)

    • first 設定で定義されている順序で、最初に利用可能なアップストリームを選択します。これにより、プライマリ/セカンダリフェイルオーバーが可能になります。これと一緒にヘルスチェックを有効にすることを忘れないでください。そうでないと、フェイルオーバーは発生しません

    • round_robin 各アップストリームを順番に反復処理します

    • weighted_round_robin <weights...> 提供された重みを考慮して、各アップストリームを順番に反復処理します。重み引数の量は、設定されているアップストリームの量と一致する必要があります。重みはゼロ以外の正の整数にする必要があります。たとえば、2つのアップストリームと重み`5 1`を使用すると、最初のアップストリームは2番目のアップストリームが1回選択される前に5回連続して選択され、その後サイクルが繰り返されます。

    • least_conn 現在のリクエスト数が最も少ないアップストリームを選択します。複数のホストのリクエスト数が最も少ない場合は、それらのホストのいずれかがランダムに選択されます

    • ip_hash リモートIP(直接ピア)をスティッキーアップストリームにマップします

    • client_ip_hash クライアントIPをスティッキーアップストリームにマップします。これは、実際のクライアントIP解析を有効にするservers > trusted_proxiesグローバルオプションと組み合わせるのが最適です。そうでない場合は、`ip_hash`と同じように動作します

    • uri_hash リクエストURI(パスとクエリ)をスティッキーアップストリームにマップします

    • query [key] クエリ値をハッシュすることにより、リクエストクエリをスティッキーアップストリームにマップします。指定されたキーが存在しない場合、フォールバックポリシーを使用してアップストリームが選択されます(デフォルトは`random`)

    • header [field] は、リクエストヘッダーの値をハッシュ化することで、リクエストヘッダーをスティッキーなアップストリームにマッピングします。指定されたヘッダーフィールドが存在しない場合、フォールバックポリシー(デフォルトはrandom)を使用してアップストリームが選択されます。

    • cookie [<name> [<secret>]] クライアントからの最初のリクエスト(クッキーがない場合)では、フォールバックポリシー(デフォルトはrandom)を使用してアップストリームが選択され、Set-Cookieヘッダーがレスポンスに追加されます(クッキー名が指定されていない場合、デフォルトのクッキー名はlbです)。クッキー値は、選択されたアップストリームのダイヤルアドレスをHMAC-SHA256でハッシュ化したものです(共有秘密として<secret>を使用、指定されていない場合は空文字列)。

      後続のリクエストでクッキーが存在する場合、クッキー値は利用可能な場合は同じアップストリームにマッピングされます。利用できないか見つからない場合は、フォールバックポリシーで新しいアップストリームが選択され、クッキーがレスポンスに追加されます。

      デバッグのために特定のアップストリームを使用したい場合は、アップストリームアドレスを秘密鍵でハッシュ化し、HTTPクライアント(ブラウザなど)でクッキーを設定できます。たとえば、PHPでは、次のコードを実行してクッキー値を計算できます。ここで、10.1.0.10:8080はアップストリームの1つのアドレス、secretは設定された秘密鍵です。

      echo hash_hmac('sha256', '10.1.0.10:8080', 'secret');
      // cdd96966817dd14a99f47ee17451464f29998da170814a16b483e4c1ff4c48cf
      

      Javascriptコンソールを使用してブラウザでクッキーを設定できます。たとえば、lbという名前のクッキーを設定するには、次のようにします。

      document.cookie = "lb=cdd96966817dd14a99f47ee17451464f29998da170814a16b483e4c1ff4c48cf";
      
  • lb_retries は、次に利用可能なホストがダウンしている場合、各リクエストに対して利用可能なバックエンドの選択を再試行する回数です。デフォルトでは、再試行は無効になっています(ゼロ)。

    lb_try_duration も設定されている場合、期間に達すると再試行が早期に停止する場合があります。つまり、再試行期間は再試行回数よりも優先されます。

  • lb_try_duration は、次に利用可能なホストがダウンしている場合、各リクエストに対して利用可能なバックエンドの選択を試行する期間を定義する期間値です。デフォルトでは、再試行は無効になっています(期間ゼロ)。

    ロードバランサーが利用可能なアップストリームホストを見つけようとしている間、クライアントはこの期間まで待機します。HTTPトランスポートのデフォルトのダイヤルタイムアウトは3sであるため、最初の選択されたアップストリームに到達できない場合に少なくとも1回の再試行を許可するため、妥当な開始点は5sです。ただし、ユースケースに適したバランスを見つけるために自由に試してみてください。

  • lb_try_interval は、プールから次のホストを選択するまでの待機時間を定義する期間値です。デフォルトは250msです。アップストリームホストへのリクエストが失敗した場合にのみ関連します。これを0に設定し、lb_try_durationをゼロ以外に設定すると、すべてのバックエンドがダウンしていてレイテンシが非常に低い場合にCPUがスピンする可能性があることに注意してください。

  • lb_retry_match 再試行が許可されるリクエストを制限します。アップストリームへの接続は成功したが、後続のラウンドトリップが失敗した場合、リクエストはこの条件に一致する必要があります。アップストリームへの接続が失敗した場合、再試行は常に許可されます。デフォルトでは、GETリクエストのみが再試行されます。

    このオプションの構文は、名前付きリクエストマッチャーと同じですが、@nameはありません。単一のマッチャーのみが必要な場合は、同じ行に設定できます。複数のマッチャーの場合は、ブロックが必要です。

アクティブヘルスチェック

アクティブヘルスチェックは、タイマーでバックグラウンドでヘルスチェックを実行します。これを有効にするには、health_uriまたはhealth_portが必要です。

  • health_uri は、アクティブヘルスチェックのURIパス(およびオプションのクエリ)です。

  • health_port は、アクティブヘルスチェックに使用するポートです(アップストリームのポートと異なる場合)。

  • health_interval は、アクティブヘルスチェックを実行する頻度を定義する期間値です。デフォルト:30s

  • health_timeout は、バックエンドをダウンとしてマークする前に応答を待つ時間を定義する期間値です。デフォルト:5s

  • health_status は、正常なバックエンドから予期されるHTTPステータスコードです。3桁のステータスコード、またはxxで終わるステータスクラスコードを指定できます。例:200(デフォルト)、または2xx

  • health_body は、アクティブヘルスチェックのレスポンス本文と一致させる部分文字列または正規表現です。バックエンドが一致する本文を返さない場合、ダウンとしてマークされます。

  • health_headers アクティブヘルスチェックリクエストに設定するヘッダーを指定できます。これは、Hostヘッダーを変更する必要がある場合、またはヘルスチェックの一部としてバックエンドに認証を提供する必要がある場合に役立ちます。

パッシブヘルスチェック

パッシブヘルスチェックは、実際にプロキシされたリクエストとインラインで発生します。これを有効にするには、fail_durationが必要です。

  • fail_duration は、失敗したリクエストを記憶する期間を定義する期間値です。期間> 0はパッシブヘルスチェックを有効にします。デフォルトは0(オフ)です。正常でないアップストリームをオンラインに戻す際のエラー率と応答性をバランスさせるための妥当な開始点は30sです。ただし、ユースケースに適したバランスを見つけるために自由に試してみてください。

  • max_fails は、バックエンドをダウンしていると見なすために必要な、fail_duration内の失敗したリクエストの最大数です。 1以上でなければなりません。デフォルトは1です。

  • unhealthy_status レスポンスがこれらのステータスコードのいずれかで返された場合、リクエストは失敗としてカウントされます。3桁のステータスコードまたはxxで終わるステータスクラスコードを指定できます。例:404または5xx

  • unhealthy_latency は、レスポンスの取得にこれだけの時間がかかった場合にリクエストを失敗としてカウントする期間値です。

  • unhealthy_request_count は、バックエンドをダウンとしてマークする前に許可される、バックエンドへの同時リクエスト数です。つまり、特定のバックエンドが現在これだけのリクエストを処理している場合、「過負荷」と見なされ、代わりに他のバックエンドが優先されます。

    これは、かなり大きな数にする必要があります。これを設定すると、プロキシの同時リクエストの合計制限がunhealthy_request_count × upstreams_countになり、そのポイントを超えるリクエストは、利用可能なアップストリームがないためにエラーが発生します。

イベント

アップストリームが正常から異常、またはその逆に遷移すると、イベントが発行されます。これらのイベントを使用して、通知の送信やメッセージのログ記録などの他のアクションをトリガーできます。イベントは次のとおりです。

  • healthy は、以前に異常だったアップストリームが正常としてマークされたときに発行されます
  • unhealthy は、以前に正常だったアップストリームが異常としてマークされたときに発行されます

どちらの場合も、状態が変化したアップストリームを識別するために、hostがイベントにメタデータとして含まれています。たとえば、execイベントハンドラでプレースホルダーとして{event.data.host}と一緒に使用できます。

ストリーミング

デフォルトでは、プロキシはワイヤ効率のためにレスポンスを部分的にバッファリングします。

プロキシはWebSocket接続もサポートしており、HTTPアップグレードリクエストを実行してから接続を双方向トンネルに移行します。

  • flush_interval は、Caddyがレスポンスバッファをクライアントにフラッシュする頻度を調整する期間値です。デフォルトでは、定期的なフラッシュは行われません。負の値(通常は-1)は、「低レイテンシモード」を示唆しており、レスポンスバッファリングを完全に無効にし、クライアントへの書き込みごとにすぐにフラッシュし、クライアントが早期に切断した場合でもバックエンドへのリクエストをキャンセルしません。このオプションは無視され、レスポンスから次のいずれかが適用される場合、レスポンスはすぐにクライアントにフラッシュされます。

    • Content-Type: text/event-stream
    • Content-Lengthが不明
    • プロキシの両側でHTTP/2、Content-Lengthが不明、およびAccept-Encodingが設定されていないか「identity」である
  • request_buffers プロキシがリクエスト本文から最大<size>バイトをバッファに読み込んでからアップストリームに送信するようにします。これは非常に非効率的であり、アップストリームが遅延なくリクエスト本文の読み取りを必要とする場合にのみ行う必要があります(これはアップストリームアプリケーションが修正する必要があるものです)。これは、go-humanizeでサポートされているすべてのサイズ形式を受け入れます。

  • response_buffers プロキシがレスポンス本文から最大<size>バイトをバッファに読み込んでからクライアントに返すようにします。パフォーマンス上の理由から、これは可能な限り避ける必要がありますが、バックエンドのメモリ制約が厳しい場合は役立つ可能性があります。これは、go-humanizeでサポートされているすべてのサイズ形式を受け入れます。

  • stream_timeout は、WebSocketsなどのストリーミングリクエストがタイムアウトの終わりに強制的に閉じられる期間値です。これは、接続が長時間開いたままになっている場合に、基本的に接続をキャンセルします。1日より古い接続を削除するための妥当な開始点は24hです。デフォルト:タイムアウトなし。

  • stream_close_delay は、設定がアンロードされたときにWebSocketsなどのストリーミングリクエストが強制的に閉じられるのを遅らせる期間値です。代わりに、ストリームは遅延が完了するまで開いたままになります。つまり、これを有効にすると、Caddyの設定がリロードされたときにストリームがすぐに閉じることがなくなります。これを有効にすると、以前の設定の終了によって接続が閉じられたクライアントの再接続の激しい集中を回避できるため、良い考えかもしれません。設定のリロード後、ユーザーが自然にページを離れることができるように、妥当な開始点は5mなどです。デフォルト:遅延なし。

ヘッダー

プロキシは、自身とバックエンドの間で**ヘッダーを操作**できます

  • header_up バックエンドへのアップストリームに向かうリクエストヘッダーで、設定、追加(+プレフィックス付き)、削除(-プレフィックス付き)、または置換(2つの引数、検索と置換を使用)を実行します。

  • header_down バックエンドからのダウンストリームに向かうレスポンスヘッダーで、設定、追加(+プレフィックス付き)、削除(-プレフィックス付き)、または置換(2つの引数、検索と置換を使用)を実行します。

たとえば、既存の値を上書きしてリクエストヘッダーを設定するには、次のようにします。

header_up Some-Header "the value"

レスポンスヘッダーを追加するには、次のようにします。ヘッダーフィールドには複数の値を指定できることに注意してください。

header_down +Some-Header "first value"
header_down +Some-Header "second value"

リクエストヘッダーを削除して、バックエンドに到達しないようにするには、次のようにします。

header_up -Some-Header

サフィックスマッチを使用して、一致するすべてのリクエストヘッダーを削除するには、次のようにします。

header_up -Some-*

必要なヘッダーを個別に追加できるように、*すべて*のリクエストヘッダーを削除するには、次のようにします(推奨されません)。

header_up -*

リクエストヘッダーで正規表現置換を実行するには、次のようにします。

header_up Some-Header "^prefix-([A-Za-z0-9]*)$" "replaced-$1-suffix"

使用される正規表現言語は、Goに含まれるRE2です。RE2構文リファレンスGo正規表現構文の概要を参照してください。置換文字列は展開され、キャプチャされた値を使用できます。たとえば、$1は最初のキャプチャグループです。

デフォルト

デフォルトでは、Caddyは、3つの例外を除いて、Hostを含む受信ヘッダーをバックエンドに変更を加えずにパススルーします。

  • X-Forwarded-Forヘッダーフィールドを設定または拡張します。
  • X-Forwarded-Protoヘッダーフィールドを設定します。
  • X-Forwarded-Hostヘッダーフィールドを設定します。

これらのX-Forwarded-*ヘッダーについては、デフォルトでは、プロキシは受信リクエストからの値を無視して、スプーフィングを防止します。

Caddyがクライアントが最初に接続するサーバーではない場合(たとえば、CDNがCaddyの前にある場合)、trusted_proxiesに、これらのヘッダーの良い値を送信したと信頼できる受信リクエストのIP範囲(CIDR)のリストを設定できます。

サーバー内のすべてのプロキシハンドラーに適用されるように、プロキシではなくservers > trusted_proxiesグローバルオプションを介してこれを設定することを強くお勧めします。これには、クライアントIP解析を有効にするという利点があります。

さらに、httpトランスポートを使用する場合、クライアントからのリクエストに欠落している場合、Accept-Encoding: gzipヘッダーが設定されます。これにより、アップストリームは圧縮されたコンテンツを提供できます。この動作は、トランスポートでcompression offを使用して無効にすることができます。

HTTPS

(ほとんどの)ヘッダーはプロキシされるときに元の値を保持するため、HTTPSにプロキシする場合、HostヘッダーがTLS ServerName値と一致するように、Hostヘッダーを設定済みのアップストリームアドレスで上書きすることがよくあります。

reverse_proxy https://example.com {
	header_up Host {upstream_hostport}
}

X-Forwarded-Hostヘッダーはデフォルトで渡されるため、アップストリームは元のHostヘッダー値を知る必要がある場合、引き続きそれを使用できます。

リライト

デフォルトでは、Caddyは、reverse_proxyに到達する前にミドルウェアチェーンで書き換えが実行されない限り、受信リクエストと同じHTTPメソッドとURIを使用してアップストリームリクエストを実行します。

プロキシする前に、リクエストは複製されます。これにより、ハンドラー中にリクエストに加えられた変更が他のハンドラーにリークしないことが保証されます。これは、プロキシの後で処理を続行する必要がある状況で役立ちます。

ヘッダー操作に加えて、リクエストのメソッドとURIはアップストリームに送信される前に変更される場合があります。

  • method は、複製されたリクエストのHTTPメソッドを変更します。メソッドがGETまたはHEADに変更された場合、受信リクエストの本文はこのハンドラーによってアップストリームに送信され*ません*。これは、別のハンドラーにリクエスト本文を使用させたい場合に役立ちます。
  • rewrite は、複製されたリクエストのURI(パスとクエリ)を変更します。これはrewriteディレクティブに似ていますが、このハンドラーのスコープを超えて書き換えを永続化しない点が異なります。

これらの書き換えは、「事前チェックリクエスト」のようなパターンで役立つことがよくあります。このパターンでは、リクエストが別のサーバーに送信され、現在のリクエストの処理方法を決定するのに役立ちます。

たとえば、リクエストを認証ゲートウェイに送信して、リクエストが認証されたユーザーからのものであるかどうか(たとえば、リクエストにセッションCookieがある)と続行する必要があるか、ログインページにリダイレクトする必要があるかを決定できます。このパターンの場合、Caddyはショートカットディレクティブforward_authを提供して、ほとんどの設定ボイラープレートをスキップします。

トランスポート

Caddyのプロキシトランスポートはプラグイン可能です。

  • transport は、バックエンドとの通信方法を定義します。デフォルトはhttpです。

httpトランスポート

transport http {
	read_buffer             <size>
	write_buffer            <size>
	max_response_header     <size>
	proxy_protocol          v1|v2
	dial_timeout            <duration>
	dial_fallback_delay     <duration>
	response_header_timeout <duration>
	expect_continue_timeout <duration>
	resolvers <ip...>
	tls
	tls_client_auth <automate_name> | <cert_file> <key_file>
	tls_insecure_skip_verify
	tls_timeout <duration>
	tls_trusted_ca_certs <pem_files...>
	tls_server_name <server_name>
	tls_renegotiation <level>
	tls_except_ports <ports...>
	keepalive [off|<duration>]
	keepalive_interval <interval>
	keepalive_idle_conns <max_count>
	keepalive_idle_conns_per_host <count>
	versions <versions...>
	compression off
	max_conns_per_host <count>
}
  • read_buffer は、読み取りバッファのサイズ(バイト単位)です。go-humanizeでサポートされているすべての形式を受け入れます。デフォルト:4KiB

  • write_buffer は、書き込みバッファのサイズ(バイト単位)です。go-humanizeでサポートされているすべての形式を受け入れます。デフォルト:4KiB

  • max_response_header は、レスポンスヘッダーから読み取る最大バイト数です。go-humanizeでサポートされているすべての形式を受け入れます。デフォルト:10MiB

  • proxy_protocol は、アップストリームへの接続でPROXYプロトコル(HAProxyで普及)を有効にし、実際のクライアントIPデータを付加します。Caddyが別のプロキシの背後にある場合、これはservers > trusted_proxiesグローバルオプションと組み合わせるのが最適です。バージョンv1v2がサポートされています。これは、アップストリームサーバーがPROXYプロトコルを解析できることがわかっている場合にのみ使用する必要があります。デフォルトでは、これは無効になっています。

  • dial_timeout は、アップストリームソケットに接続するときに待つ最大期間です。デフォルト:3s

  • dial_fallback_delay は、RFC 6555高速フォールバック接続を生成する前に待つ最大期間です。負の値はこれを無効にします。デフォルト:300ms

  • response_header_timeout は、アップストリームからのレスポンスヘッダーの読み取りを待つ最大期間です。デフォルト:タイムアウトなし。

  • expect_continue_timeout は、リクエストにヘッダーExpect: 100-continueがある場合、リクエストヘッダーを完全に書き込んだ後にアップストリームの最初のレスポンスヘッダーを待つ最大期間です。デフォルト:タイムアウトなし。

  • read_timeout は、バックエンドからの次の読み取りを待つ最大期間です。デフォルト:タイムアウトなし。

  • write_timeout は、バックエンドへの次の書き込みを待つ最大期間です。デフォルト:タイムアウトなし。

  • resolvers は、システムリゾルバーをオーバーライドするDNSリゾルバーのリストです。

  • tls は、バックエンドでHTTPSを使用します。これは、https://スキームまたはポート:443を使用してバックエンドを指定した場合、または以下のtls_*オプションのいずれかが設定されている場合に自動的に有効になります。

  • tls_client_auth は、TLSクライアント認証を2つの方法のいずれかで有効にします。(1)Caddyが証明書を取得して更新し続けるドメイン名を指定するか、(2)バックエンドとのTLSクライアント認証に提示する証明書とキーファイルを指定します。

  • tls_insecure_skip_verify は、TLSハンドシェイク検証をオフにし、接続を安全でなくなり、中間者攻撃に対して脆弱にします。*本番環境では使用しないでください。*

  • tls_timeout は、TLSハンドシェイクの完了を待つ最大期間です。デフォルト:タイムアウトなし。

  • tls_trusted_ca_certs は、バックエンドに接続するときに信頼するCA公開鍵を指定するPEMファイルのリストです。

  • tls_server_name は、TLSハンドシェイクで受信した証明書を検証するときに使用されるサーバー名を設定します。デフォルトでは、これはアップストリームアドレスのホスト部分を使用します。

    アップストリームアドレスがアップストリームが使用する可能性のある証明書と一致しない場合にのみ、これをオーバーライドする必要があります。たとえば、アップストリームアドレスがIPアドレスの場合、これをアップストリームサーバーによって提供されているホスト名に設定する必要があります。

    リクエストプレースホルダーを使用できます。その場合、HTTPトランスポート設定のクローンがすべてのリクエストで使用され、パフォーマンスが低下する可能性があります。

  • tls_renegotiation は、TLS再ネゴシエーションレベルを設定します。TLS再ネゴシエーションとは、最初のハンドシェイクの後に行われる後続のハンドシェイクを実行することです。レベルは次のいずれかです。

    • never(デフォルト)は再ネゴシエーションを無効にします。
    • onceは、リモートサーバーが接続ごとに1回再ネゴシエーションをリクエストできるようにします。
    • freelyは、リモートサーバーが繰り返し再ネゴシエーションをリクエストできるようにします。
  • tls_except_ports TLSが有効になっている場合、アップストリームターゲットが指定されたポートのいずれかを使用している場合、これらの接続ではTLSが無効になります。これは、一部のアップストリームがHTTPを期待し、他のアップストリームがHTTPSリクエストを期待する動的アップストリームを設定する場合に役立ちます。

  • keepalive は、offまたは接続を維持する期間(タイムアウト)を指定する期間値です。デフォルト:2m

  • keepalive_interval は、livenessプローブ間の期間です。デフォルト:30s

  • keepalive_idle_conns は、キープアライブする最大接続数を定義します。デフォルト:制限なし。

  • keepalive_idle_conns_per_host ゼロ以外の場合、ホストごとに維持する最大アイドル(キープアライブ)接続数を制御します。デフォルト:32

  • versions は、サポートするHTTPのバージョンをカスタマイズできます。特殊なケースとして、「h2c」は、アップストリームへのクリアテキストHTTP / 2接続を有効にする有効な値です(ただし、これはGoのデフォルトHTTPトランスポートを使用しない非標準機能であるため、他の機能とは排他的です。変更または削除される可能性があります)。デフォルト:1.1 2、またはスキームがh2c://の場合はh2c 2

  • compression は、offに設定することにより、バックエンドへの圧縮を無効にするために使用できます。

  • max_conns_per_host は、必要に応じて、ダイヤル中、アクティブ、およびアイドル状態の接続を含む、ホストごとの合計接続数を制限します。デフォルト:制限なし。

fastcgiトランスポート

transport fastcgi {
	root  <path>
	split <at>
	env   <key> <value>
	resolve_root_symlink
	dial_timeout  <duration>
	read_timeout  <duration>
	write_timeout <duration>
	capture_stderr
}
  • root は、サイトのルートです. デフォルト: {http.vars.root} または現在の作業ディレクトリ.

  • split は、URIの末尾にPATH_INFOを取得するためにパスを分割する場所です.

  • env は、追加の環境変数を指定された値に設定します. 複数の環境変数に対して複数回指定できます.

  • resolve_root_symlink は、シンボリックリンクが存在する場合、シンボリックリンクを評価することにより、root ディレクトリを実際の値に解決することを有効にします.

  • dial_timeout は、アップストリームソケットへの接続時に待機する時間です。期間値を受け入れます。デフォルト: 3s

  • read_timeout は、FastCGIサーバーからの読み取り時に待機する時間です。期間値を受け入れます。デフォルト:タイムアウトなし。

  • write_timeout は、FastCGIサーバーへの送信時に待機する時間です。期間値を受け入れます。デフォルト:タイムアウトなし。

  • capture_stderr は、アップストリームのfastcgiサーバーがstderrに送信したメッセージのキャプチャとロギングを有効にします。ロギングはデフォルトでWARNレベルで行われます。レスポンスのステータスが4xxまたは5xxの場合、代わりにERRORレベルが使用されます。デフォルトでは、stderrは無視されます。

レスポンスのインターセプト

リバースプロキシは、バックエンドからのレスポンスをインターセプトするように設定できます。これを容易にするために、レスポンスマッチャーを定義できます(リクエストマッチャーの構文と同様)。最初に一致するhandle_responseルートが呼び出されます。

レスポンスハンドラーが呼び出されると、バックエンドからのレスポンスはクライアントに書き込まれず、設定されたhandle_responseルートが代わりに実行されます。レスポンスを書き込むのはそのルート次第です。ルートがレスポンスを書き込ま*ない*場合、リクエスト処理は、このreverse_proxy後に順序付けられたハンドラーで続行されます。

  • @name は、レスポンスマッチャーの名前です。各レスポンスマッチャーに一意の名前が付けられている限り、複数のマッチャーを定義できます。レスポンスは、ステータスコードとレスポンスヘッダーの有無または値で照合できます。
  • replace_status は、指定されたマッチャーによって一致した場合に、レスポンスのステータスコードを単純に変更します。
  • handle_response は、指定されたマッチャー(または、マッチャーが省略されている場合はすべてのレスポンス)と一致した場合に実行するルートを定義します。最初に一致するブロックが適用されます。handle_responseブロック内では、他のディレクティブを使用できます。

さらに、handle_response内では、2つの特別なハンドラーディレクティブを使用できます。

  • copy_response は、バックエンドから受信したレスポンス本文をクライアントにコピーして返します。必要に応じて、レスポンスのステータスコードを変更することもできます。このディレクティブは、respond前に順序付けられています
  • copy_response_headers は、バックエンドからクライアントにレスポンスヘッダーをコピーします。オプションで、ヘッダーフィールドのリストを含める*または*除外することができます(includeexcludeの両方を指定することはできません)。このディレクティブは、header後に順序付けられています

handle_responseルート内では、3つのプレースホルダーが使用可能になります。

  • {rp.status_code} バックエンドのレスポンスからのステータスコード。
  • {rp.status_text} バックエンドのレスポンスからのステータステキスト。
  • {rp.header.*} バックエンドのレスポンスからのヘッダー。

レスポンスマッチャー

レスポンスマッチャーを使用して、特定の基準でレスポンスをフィルタリング(または分類)できます。

status
status <code...>

HTTPステータスコード別。

  • <code...> は、HTTPステータスコードのリストです。特殊なケースは、2xx3xxなどの文字列で、それぞれ200299および300399の範囲のすべてのステータスコードと一致します。

サポートされている構文については、headerリクエストマッチャーを参照してください。

すべてのリクエストをローカルバックエンドにリバースプロキシする

example.com {
	reverse_proxy localhost:9005
}

すべてのリクエストを3つのバックエンド間で負荷分散する

example.com {
	reverse_proxy node1:80 node2:80 node3:80
}

上記と同じですが、/api内のリクエストのみをcookieポリシーを使用してスティッキーにする

example.com {
	reverse_proxy /api/* node1:80 node2:80 node3:80 {
		lb_policy cookie api_sticky
	}
}

アクティブヘルスチェックを使用して、どのバックエンドが正常であるかを判断し、失敗した接続で再試行を有効にして、正常なバックエンドが見つかるまでリクエストを保持する

example.com {
	reverse_proxy node1:80 node2:80 node3:80 {
		health_uri /healthz
		lb_try_duration 5s
	}
}

いくつかのトランスポートオプションを設定する

example.com {
	reverse_proxy localhost:8080 {
		transport http {
			dial_timeout 2s
			response_header_timeout 30s
		}
	}
}

HTTPSアップストリームへのリバースプロキシ

example.com {
	reverse_proxy https://example.com {
		header_up Host {upstream_hostport}
	}
}

HTTPSアップストリームへのリバースプロキシですが、⚠️TLS検証を無効にします。これは、HTTPSが提供するすべてのセキュリティチェックが無効になるため、推奨されません。プライベートネットワークでは、誤った安心感を避けるため、可能な場合はHTTP経由のプロキシが推奨されます。

example.com {
	reverse_proxy 10.0.0.1:443 {
		transport http {
			tls_insecure_skip_verify
		}
	}
}

代わりに、アップストリームの証明書を明示的に信頼し、(オプションで)TLS-SNIをアップストリームの証明書のホスト名と一致するように設定することにより、アップストリームとの信頼を確立できます。

example.com {
	reverse_proxy 10.0.0.1:443 {
		transport http {
			tls_trusted_ca_certs /path/to/cert.pem
			tls_server_name app.example.com
		}
	}
}

プロキシする前にパスプレフィックスを削除します。ただし、サブフォルダーの問題 に注意してください。

example.com {
	handle_path /prefix/* {
		reverse_proxy localhost:9000
	}
}

rewriteを使用して、プロキシする前にパスプレフィックスを置き換えます。

example.com {
	handle_path /old-prefix/* {
		rewrite * /new-prefix{path}
		reverse_proxy localhost:9000
	}
}

レスポンスをインターセプトすることにより、リクエストされた静的ファイルを提供するX-Accel-Redirectサポート

example.com {
	reverse_proxy localhost:8080 {
		@accel header X-Accel-Redirect *
		handle_response @accel {
			root    * /path/to/private/files
			rewrite * {rp.header.X-Accel-Redirect}
			method  * GET
			file_server
		}
	}
}

ステータスコードでエラーレスポンスをインターセプトすることにより、アップストリームからのエラーのカスタムエラーページ

example.com {
	reverse_proxy localhost:8080 {
		@error status 500 503
		handle_response @error {
			root    * /path/to/error/pages
			rewrite * /{rp.status_code}.html
			file_server
		}
	}
}

A/AAAAレコードDNSクエリから動的にバックエンドを取得する

example.com {
	reverse_proxy {
		dynamic a example.com 9000
	}
}

SRVレコードDNSクエリから動的にバックエンドを取得する

example.com {
	reverse_proxy {
		dynamic srv _api._tcp.example.com
	}
}