これはセクションの複数ページ印刷用ビューです。 .
HAProxy 3.4.6-66ドキュメント
- 1: 負荷分散の基礎
- 2: HAProxyの役割と動作の仕組み
- 3: 基本機能
- 4: 標準機能
- 5: 高度な機能
- 6: サイジングと性能
- 7: リリース、パッケージ、アップグレード
- 8: 補完製品と代替製品
- 9: ドキュメントとコミュニティ
- 10: 1. HTTPの基礎を振り返る
- 11: 2. HAProxyの設定
- 12: 3. globalセクション
- 13: 4. プロキシ
- 14: 5. bindとserverのオプション
- 15: 6. キャッシュ
- 16: 7. ACLとサンプル取得
- 17: 8. ログ
- 18: 9. 対応するフィルター
- 19: 10. FastCGIアプリケーション
- 20: 11. スティックテーブルとピア
- 21: 12. その他のセクション
- 22: 1. 前提条件
- 23: 2. HAProxyのアーキテクチャ
- 24: 3. HAProxyの起動
- 25: 4. HAProxyの停止と再起動
- 26: 5. ファイル記述子の制限
- 27: 6. メモリ管理
- 28: 7. CPU使用率
- 29: 8. ログ
- 30: 9. 統計情報とモニタリング
- 31: 10. 設定管理を容易にする方法
- 32: 11. 回避すべき既知の落とし穴
- 33: 12. デバッグと性能の問題
- 34: 13. セキュリティに関する考慮事項
HAProxyは、高可用性、TCPとHTTPの負荷分散、アプリケーショントラフィックの管理を実現する、無料で高速かつ信頼性の高いリバースプロキシです。このコンポーネントでは、HAProxy 3.4の主要な3つのマニュアルの日本語訳全文を、OINK用に階層のない一連のMarkdownページへ再構成しています。
この版は、公式英語マニュアルのメンテナンスブランチのスナップショット3.4.6-66に対応しています。最新の安定版リリースは3.4.6(v3.4.6)です。このスナップショットには、そのリリース後のドキュメントの変更も含まれます。正確なソースはコミット16acce1dac1d
です。
マニュアルの選択
- 入門ガイド — 負荷分散の概念、HAProxyのアーキテクチャ、機能、サイジング、リリース、エコシステムに関する9つのトピック。
- 設定マニュアル — プロキシ、ACL、サンプル、ログ、フィルター、すべてのオプション群を網羅した12章。
- 管理ガイド — 起動、リロード、リソース、ログ、統計、ランタイムCLI、デバッグ、セキュリティに関する13章。
収録範囲
| マニュアル | アップストリームの原文 | このサイトでの構成 |
|---|---|---|
| 入門ガイド | 1,695行 | 同一階層の9トピックページ |
| 設定マニュアル | 33,216行 | 同一階層の12章ページ |
| 管理ガイド | 5,305行 | 同一階層の13章ページ |
本文34ページはいずれもHAProxyコンポーネントのルート直下に配置しています。リンクを持たない3つの区切り用プレースホルダーで各マニュアルを区分し、ディレクトリ階層やページ送りの経由先を増やさずにサイドバーへ表示しています。
固定バージョンの完全な入力データとSHA-256チェックサムはsources/haproxy/に保持しています。アップストリームのライセンス通知
とGPLv2の本文
も、マニュアルとともに公開しています。各ページには、レビュー済みの簡体字中国語版も用意されています。
1 - 負荷分散の基礎
このドキュメントは、HAProxyを知らない方と、古いバージョンを知っていて改めて理解したい方のための入門です。主な目的は、HAProxyが探している製品かどうかを判断するために必要な情報を提供することです。上級ユーザーにも、知らなかった新機能によって、考えていた構想の実現につながる情報が見つかるかもしれません。サイジングに関する情報、製品のライフサイクルの説明、一部の機能が重なる製品との比較も提供します。
このドキュメントには設定方法の説明やヒントはありませんが、関連ドキュメントの場所を説明します。ガイドは、HAProxyのサイドバーで、トピックごとのページを単一階層で順に並べています。
負荷分散とは、複数のコンポーネントをまとめ、エンドユーザーの介入なしに、拡張可能な方法で、各コンポーネント単体を上回る総処理能力を得ることです。これにより、1つのコンポーネントが1つの操作を実行する時間内に、より多くの操作を同時に実行できます。ただし、個々の操作は依然として一度に1つのコンポーネントで処理されるため、負荷分散なしの場合より速くはなりません。すべてのコンポーネントを活用して負荷分散の利点を十分に得るには、少なくとも利用可能なコンポーネント数と同じ数の操作と、効率的な負荷分散の仕組みが常に必要です。よい例が高速道路の車線数です。個々の車の速度を上げなくても、同じ時間内に通過できる車の数を増やせます。
負荷分散の例:
- マルチプロセッサーシステムのプロセススケジューリング
- リンクの負荷分散(EtherChannel、Bondingなど)
- IPアドレスの負荷分散(ECMP、DNSラウンドロビンなど)
- サーバーの負荷分散(ロードバランサーによるもの)
負荷分散を行う仕組みやコンポーネントをロードバランサーと呼びます。Web環境では「ネットワークロードバランサー」と呼ばれますが、この用途が負荷分散として最も広く知られているため、単に「ロードバランサー」と呼ぶほうが一般的です。
ロードバランサーは、次のレベルで動作できます。
-
リンクレベル:リンクの負荷分散と呼び、パケットを送るネットワークリンクを選択します。
-
ネットワークレベル:ネットワークの負荷分散と呼び、一連のパケットが通る経路を選択します。
-
サーバーレベル:サーバーの負荷分散と呼び、接続やリクエストを処理するサーバーを決定します。
異なるニーズに対応する2つの技術があり、一部は重なります。どちらの場合も、負荷分散はトラフィックを本来の流れから別の経路へ振り向ける操作であり、すべてのルーティング判断の間で必要な整合性を保つため、常に最低限の注意が必要であることを忘れないでください。
第1の技術はパケットレベルで動作し、パケットをおおむね個別に処理します。入力パケットと出力パケットは1対1で対応するため、通常のネットワークスニファーでロードバランサーの両側のトラフィックを追跡できます。この技術は非常に低コストかつ極めて高速にできます。ECMPを行うスイッチのように、通常はハードウェア(ASIC)で実装され、回線速度に達する性能を得られます。一般にはステートレスですが、パケットが属するセッションを考慮するステートフルな実装もあり、layer4-LBまたはL4と呼ばれます。パケットを変更していなければ、DSR(direct server return、戻りのトラフィックがLBを再び通過しない方式)をサポートする場合もありますが、内容はほぼ認識できません。この技術はネットワークレベルの負荷分散に非常に適していますが、高速でごく基本的なサーバーの負荷分散にも使われることがあります。
第2の技術はセッションの内容を扱います。入力ストリームを再構築し、全体として処理する必要があります。内容を変更することもでき、出力ストリームは新しいパケットへと分割されます。このため、通常はプロキシが処理を行い、レイヤー7ロードバランサー、またはL7と呼ばれることがよくあります。両側に別々の接続が存在し、入力パケットと出力パケットの大きさや個数には対応関係がありません。クライアントとサーバーが同じプロトコルを使う必要もありません(IPv4とIPv6、平文とSSLなど)。処理は常にステートフルで、戻りのトラフィックはロードバランサーを通過しなければなりません。追加処理にはコストがかかるため、特に小さなパケットでは、常に回線速度を達成できるとは限りません。一方、幅広い機能を実現でき、ハードウェアアプライアンスに組み込まれていても、一般には純粋なソフトウェアで実装されます。この技術はサーバーの負荷分散に非常に適しています。
パケットベースのロードバランサーは通常、カットスルーモードで配置されます。つまり、通常のトラフィック経路上に設置し、設定に従ってトラフィックを振り分けます。戻りのトラフィックは、必ずしもロードバランサーを通る必要はありません。正しい宛先へ送るために、ネットワークの宛先アドレスを変更する場合があります。この場合、戻りのトラフィックは必ずロードバランサーを通過しなければなりません。経路の都合でそれができない場合、ロードバランサーはパケットの送信元アドレスも自身のアドレスに置き換え、戻りのトラフィックを強制的に自身へ通すことができます。
プロキシベースのロードバランサーは、独自のIPアドレスとポートを持つサーバーとして、構成の変更なしに配置されます。クライアントがサーバーへ直接接続せず、ロードバランサーのIPアドレスへ正しく接続するように、アプリケーションの調整が必要な場合もあります。そのために、ロードバランサーがサーバーのレスポンスの一部を調整する必要がある場合もあります(HTTPリダイレクトで使われるHTTPのLocationヘッダーフィールドなど)。プロキシベースのロードバランサーの中には、自身が所有しないアドレス宛てのトラフィックを捕捉し、サーバーへの接続時にクライアントのアドレスを送信元として使えるものがあります。これにより、パケットベースのロードバランサーとよく似たカットスルーモードで、通常のルーターやファイアウォールのように配置できます。パケットモードとプロキシモードを併せ持つ製品では、特に重宝されます。ただし、この場合もDSRは不可能であり、戻りのトラフィックはロードバランサーへ戻す必要があります。
拡張性の高い階層構成としては、前段のルーターが負荷分散された複数のリンクからトラフィックを受け取り、ECMPで第1層にある複数のステートフルなパケットベースのロードバランサー(L4)へ分散する方法があります。これらのL4ロードバランサーは、さらに多数のプロキシベースのロードバランサー(L7)へトラフィックを渡します。これらは内容を解析し、最終的にどのサーバーが受信するかを決定する必要があります。
コンポーネント数とトラフィックの経路の選択肢が増えるほど、障害のリスクは高まります。非常に大きな環境では、故障したいくつかのコンポーネントを常に修理・交換していることさえ普通です。スタック全体の健全性を把握せずに負荷分散を行うと、可用性は大きく低下します。そのため、適切なロードバランサーは、トラフィックを送ろうとするコンポーネントが稼働中で到達可能かを確認し、故障したものへの送信を停止します。これを実現するには、いくつかの方法があります。
最も一般的なのは、定期的にプローブを送信して、コンポーネントが動作していることを確認する方法です。このプローブを「ヘルスチェック」と呼びます。チェックは、対処したい種類の障害を検出できるものでなければなりません。たとえば、pingによるチェックでは、Webサーバーがクラッシュしてポートでリッスンしなくなっても検出できません。ポートへの接続なら検出でき、さらに高度なリクエストであれば、サーバーが正常に動作し、依存するデータベースにも到達できることを確認できます。ヘルスチェックでは、偶発的な測定誤差を考慮して数回の再試行を行うことがよくあります。チェック間隔は、エラー発生後に故障したコンポーネントが長時間使われないよう、十分短くしなければなりません。
別の方法は、宛先へ送った本番トラフィックをサンプリングし、正しく処理されるかを観測して、不適切なレスポンスを返すコンポーネントを除外することです。ただし、本番トラフィックの一部を犠牲にする必要があり、常に許容されるわけではありません。この2つを組み合わせると、障害の検出には両方を使い、復旧の検出にはヘルスチェックだけを使うことで、それぞれの利点を得られます。最後の方法は、集中的な状態報告です。中央の監視エージェントが、すべてのコンポーネントの状態をすべてのロードバランサーへ定期的に通知します。これにより、各コンポーネントはインフラストラクチャーの全体像を把握できますが、精度や応答性が低くなる場合もあります。ロードバランサーとサーバーの両方が多い環境に最も適しています。
レイヤー7ロードバランサーには、スティッキネス、または永続性と呼ばれる別の課題もあります。基本となる要件は、同じ送信元(エンドユーザーなど)からの連続した複数のリクエストや接続を、同じ宛先へ送ることです。最もよく知られた例がオンラインストアのショッピングカートです。クリックのたびに新しい接続が作られる場合でも、ユーザーは常に自分のカートを保持するサーバーへ送られなければなりません。内容を認識できれば、リクエスト内の要素から送信先サーバーを特定しやすくなりますが、それだけでは十分でない場合があります。たとえば、送信元アドレスをサーバー選択のキーに使う場合、ハッシュ方式を採用し、アドレスを利用可能なサーバー数で割った結果に基づいて、特定のIPアドレスを常に同じサーバーへ送ることができます。しかし、1台のサーバーが故障すると結果が変わり、すべてのユーザーが突然別のサーバーへ送られてカートを失います。この問題の解決策は、選択した宛先を記憶しておき、同じ訪問者が現れたら、利用可能なサーバー数にかかわらず同じサーバーへ送ることです。情報はロードバランサーのメモリに保存でき、ロードバランサーが複数ある場合はほかのロードバランサーへの複製が必要になることもあります。また、クライアントがリクエストごとにその情報を返せるなら、さまざまな方法でクライアントのメモリに保存することもできます(Cookieの挿入、サブドメインへのリダイレクトなど)。この仕組みには、送信元IPアドレスのように不安定で分布に偏りがある情報に依存せずに済むという利点もあります。実際、これがレイヤー4ではなくレイヤー7のロードバランサーを採用する最も大きな理由です。
Cookie、Hostヘッダーフィールド、URLなどの情報を取り出すため、ロードバランサーはSSL/TLSトラフィックを復号し、場合によってはサーバーへ渡す際に再暗号化する必要があります。この処理は高コストなため、トラフィックの多いインフラストラクチャーでは、ロードバランサーを多数配置する場合があります。
レイヤー7ロードバランサーは、復号、解析、変更、Cookieの照合、送信先サーバーの決定など、トラフィックに複雑な操作をいくつも行うため、実際に問題の原因となる可能性があります。また、単に問題を表面化させただけでも、原因として疑われることがよくあります。調べてみると、サーバーが不安定で定期的に稼働・停止を繰り返していたり、Webページに埋め込まれた固定リンクによってクライアントがロードバランサーを通らず特定のサーバーへ直接接続していたり、高負荷時に応答が極端に遅くなってタイムアウトしていたりすることがよくあります。そのため、ログはレイヤー7の負荷分散で極めて重要です。問題が報告されたら、ロードバランサーが誤った判断をしたか、そうであればなぜかを調べ、再発を防ぐことが重要です。
2 - HAProxyの役割と動作の仕組み
製品を指す場合は"HAProxy"、実行可能プログラム、ソフトウェアパッケージ、プロセスを指す場合は"haproxy"と表記します。ただし、実際にはどちらの表記も両方の意味でよく使われ、H-A-Proxyと発音します。ごく初期には、“haproxy"は"high availability proxy"の略で、名前も2語に分けて書かれていましたが、現在は単に"HAProxy"という名前です。
3.1. HAProxyが担う役割と担わない役割
HAProxyは、次の役割を担います。
-
TCPプロキシ:リッスンソケットでTCP接続を受け付け、サーバーに接続し、両方のソケットを結び付けて双方向にトラフィックを流せます。どちら側でもIPv4、IPv6、さらにUNIXソケットをサポートするため、異なるアドレスファミリー間の変換を簡単に実現できます。
-
HTTPリバースプロキシ(HTTPの用語では「ゲートウェイ」):自身をサーバーとして公開し、リッスン中のTCPソケットで受け付けた接続を通じてHTTPリクエストを受信し、別の接続を使ってサーバーへ渡します。両側でHTTP/1.xとHTTP/2を任意に組み合わせられ、TLS上でALPNを使う場合は、それぞれの側のプロトコルを自動検出することもできます。
-
SSLの終端・開始・オフロード:クライアントからの接続、サーバーへの接続、またはその両方でSSL/TLSを使えます。多くの設定を名前(SNI)ごとに適用でき、再起動せずに実行時に更新できます。この構成は極めて拡張性が高く、数万から数十万の証明書を扱う導入例が報告されています。
-
TCPの正規化:接続はOSによってローカルで終端され、両側に対応関係がないため、不正なパケット、フラグの組み合わせ、ウィンドウ広告、シーケンス番号、不完全な接続(SYNフラッド)などの異常なトラフィックは反対側へ渡されません。これにより、脆弱なTCPスタックをプロトコル攻撃から保護でき、サーバーのTCPスタック設定を変更せずに、クライアントとの接続パラメーターを最適化することもできます。
-
HTTPの正規化:HTTPトラフィックを処理する設定では、正しく完全なリクエストだけを通します。これにより、多くのプロトコルベースの攻撃を防げます。また、仕様上許容されるプロトコルの逸脱(複数行のヘッダーなど)を修正し、サーバーで問題を起こさないようにします。
-
HTTPの修正:URLや任意のリクエスト・レスポンスヘッダーを変更、修正、追加、削除、書き換えできます。複雑な環境での相互運用性の問題を解決するのに役立ちます。
-
内容に基づく振り分け:リクエストの任意の要素を使って、リクエストや接続を渡すサーバーを決められます。そのため、同じポートで複数のプロトコル(HTTP、HTTPS、SSHなど)を扱えます。
-
サーバーの負荷分散:TCP接続とHTTPリクエストを負荷分散できます。TCPモードでは接続全体に対して、HTTPモードではリクエストごとに振り分け先を決定します。
-
トラフィックの調整:さまざまな箇所でレートを制限し、サーバーを過負荷から保護し、内容に応じてトラフィックの優先順位を調整できます。また、パケットにマークを付けることで、その情報を下位層や外部のネットワークコンポーネントへ渡すこともできます。
-
DDoSやサービスの不正利用からの保護:IPアドレス、URL、Cookieなどごとに多くの統計を保持し、不正利用の発生を検出して対処できます(攻撃元の速度制限、ブロック、古い内容への誘導など)。
-
ネットワークのトラブルシューティングの観測点:ログに記録される情報が正確なため、ネットワークに関する問題を絞り込むためによく使われます。
-
HTTP圧縮のオフロード:サーバーが圧縮しなかったレスポンスを圧縮でき、接続品質が低いクライアントや、レイテンシーの高いモバイルネットワークを使うクライアントのページ読み込み時間を短縮します。
-
キャッシュプロキシ:レスポンスをRAMにキャッシュでき、同じオブジェクトへの後続リクエストでは、そのオブジェクトが存在して有効な間、サーバーから再度ネットワーク転送するコストを避けられます。ただし、永続ストレージにはオブジェクトを保存しません。このキャッシュ機能はメンテナンス不要となるよう設計されており、サーバーのリソースではなく、haproxyの貴重なリソースの節約だけを目的としています。サーバーを最適化するためのキャッシュには、はるかに多くの調整と柔軟性が必要です。そのような高度なキャッシュが必要な場合は、Varnish Cacheを使ってください。特にいずれかの側でSSL/TLSが必要な場合、haproxyと非常によく連携します。
-
FastCGIゲートウェイ:FastCGIはHTTPの別の表現と見なせるため、HAProxyは、任意の組み合わせのFastCGIアプリケーションサーバーから成るサーバーファームを、その間に別のゲートウェイ層を挟まずに直接負荷分散できます。これにより、リソースを節約し、保守コストを削減できます。
HAProxyは、次の役割は担いません。
-
明示的なHTTPプロキシ、つまりブラウザーがインターネットに到達するために使うプロキシ。この用途には、Squidなどの優れた専用オープンソースソフトウェアがあります。ただし、そのようなプロキシの前段にHAProxyを配置して、負荷分散と高可用性を提供できます。
-
データの加工:リクエストやレスポンスのボディーは変更しません。
-
静的Webサーバー:起動時にchroot jail内に自身を隔離して権限を落とすため、起動後はファイルシステムへ一切アクセスしません。そのため、静的Webサーバーにはできません(ただし、動的サーバーはFastCGI経由でサポートします)。この用途にはApacheやNginxなどの優れたオープンソースソフトウェアがあり、その前段にHAProxyを簡単に配置して、負荷分散、高可用性、高速化を提供できます。
-
パケットベースのロードバランサー:IPパケットやUDPデータグラムを扱わず、NATもDSRも行いません。これらは下位層の仕事です。IPVS(Linux Virtual Server)などのカーネルベースのコンポーネントがすでにこれらを十分に実現しており、HAProxyと非常によく補完し合います。
3.2. HAProxyの動作の仕組み
HAProxyは、非常に高速なI/O層と、優先順位に基づくマルチスレッドスケジューラーを組み合わせた、イベント駆動のノンブロッキングエンジンです。データ転送を目的に設計されているため、最小限の操作で、できるだけ速くデータを移動できるようアーキテクチャーを最適化しています。接続を可能な限り同じCPUに割り当て続けることで、CPUキャッシュの効率を高めることに重点を置いています。そのため、各層にバイパス機構を備えた階層モデルを実装し、必要な場合以外はデータが上位層へ進まないようにしています。処理の大半はカーネルで行われ、HAProxyはヒントを与えたり、後でまとめられると判断した操作を避けたりして、カーネルができるだけ速く処理できるよう支援します。その結果、典型的には、TCPまたはHTTPのcloseモードでは処理時間の15%がHAProxy、85%がカーネルで費やされ、HTTPのkeep-aliveモードでは約30%がHAProxy、70%がカーネルで費やされます。
1つのプロセスで多数のプロキシインスタンスを動かせます。1プロセス内に300000個もの個別のプロキシを設定しても、正常に動作した例が報告されています。99%を超えるユーザーにとって、1コア・1 CPUの構成で十分以上です。そのため、コンテナーや仮想マシンを使う場合は、運用コストを抑え、トラブルシューティングを容易にするため、入手できる最小のイメージを使うことを推奨します。ただし、HAProxyが動作するマシンは決してスワップしてはなりません。また、そのCPUに人為的な制限をかけたり(ハイパーバイザーでCPUの一部だけを割り当てるなど)、コンテキストスイッチのレイテンシーを大きくする計算負荷の高いプロセスとCPUを共有したりしてはなりません。
スレッドを使うと、CPUコアごとに1スレッドを割り当てて、利用可能な処理能力をすべて活用できます。これは主にSSLや、40 Gbpsを超えるデータ転送速度が必要な場合に有効です。この場合、複数の物理CPU間での通信を避けることが極めて重要です。ネットワークスタックとHAProxy自体の両方で、大きなボトルネックになり得るためです。直感に反すると思う方もいるかもしれませんが、性能上の問題が発生した際、最初に行うべきことは、HAProxyが使うCPUの数を減らすことである場合がよくあります。
HAProxyの実行に必要なのは、haproxyの実行可能ファイルと設定ファイルだけです。ログについては、syslogデーモンを正しく設定し、ログローテーションを用意することを強く推奨します。ログはstdout/stderrにも送信でき、コンテナー内では便利な場合があります。起動前に設定ファイルを解析し、すべてのリッスンソケットへのバインドを試み、何かに失敗すれば起動を拒否します。この段階を過ぎれば、失敗することはありません。つまり、実行時の失敗はなく、起動できれば停止されるまで動作し続けます。
起動後、HAProxyが行うことは、次の3つだけです。
-
着信接続を処理する。
-
サーバーの状態を定期的に確認する(ヘルスチェック)。
-
ほかのhaproxyノードと情報を交換する。
着信接続の処理は、多くの設定によって動作が変わるため、最も複雑なタスクです。ただし、次の9つの手順にまとめられます。
-
1つ以上のリッスンアドレスを参照する"frontend"という設定要素に属するリッスンソケットで、着信接続を受け付ける。
-
これらの接続に、フロントエンド固有の処理ルールを適用する。接続のブロック、ヘッダーの変更、統計ページやCLIなどの内部アプレットを実行するための捕捉が行われる場合がある。
-
接続を、サーバーファームを表す"backend"という別の設定要素へ渡す。この要素には、サーバーのリストと、そのサーバーファームの負荷分散方式が含まれる。
-
これらの接続に、バックエンド固有の処理ルールを適用する。
-
負荷分散方式に従って、接続を転送するサーバーを決定する。
-
レスポンスデータに、バックエンド固有の処理ルールを適用する。
-
レスポンスデータに、フロントエンド固有の処理ルールを適用する。
-
起きたことを詳しく記録するログを出力する。
-
HTTPでは2番目の手順に戻って次のリクエストを待ち、それ以外では接続を閉じる。
フロントエンドとバックエンドは、エンドツーエンド接続の片側だけを見るため、ハーフプロキシと考えられることがあります。フロントエンドはクライアント側だけ、バックエンドはサーバー側だけを扱います。HAProxyは、フロントエンドとバックエンドをそのまま合わせたフルプロキシもサポートします。HTTPを処理する場合は、一般に設定をフロントエンドとバックエンドに分けます。任意のフロントエンドから任意のバックエンドへ接続を渡せるため、多くの構成が可能になるからです。TCP専用のプロキシでは、フロントエンドとバックエンドに分ける利点は少なく、フルプロキシのほうが設定を読みやすくできる場合があります。
3 - 基本機能
このセクションでは、HAProxyが実装する機能をいくつか紹介します。現代のロードバランサーなら一般に備えていることが期待されるものもあれば、HAProxyのアーキテクチャーから直接得られる利点もあります。より高度な機能は、次のセクションで詳しく説明します。
3.3.1. 基本機能:プロキシ
プロキシ処理とは、独立した二つの接続を介して、クライアントとサーバーの間でデータを転送することです。プロキシ処理と接続管理について、HAProxyは次の基本機能をサポートします。
-
サーバーに正常な接続を提供し、クライアント側の不具合や攻撃から保護する。
-
複数のIPアドレスやポート、さらにはポート範囲でリッスンする。
-
透過的な受け付け:ローカルシステムに属していないものも含め、任意のIPアドレス宛てのトラフィックを捕捉する。
-
サーバーのポートはリッスンポートと対応する必要がなく、固定オフセットで変換することもできる(ポート範囲を使う場合に便利)。
-
透過的な接続:必要に応じて、サーバーへの接続時にクライアントのIPアドレス、または任意のIPアドレスを送信元として使う。
-
複数拠点のLBで、サーバーに信頼できる戻り先IPアドレスを提供する。
-
バッファーと、必要に応じて短時間の接続を使い、サーバーの同時接続数とメモリ使用量を減らして負荷を軽減する。
-
TCPスタック(SACKなど)と輻輳制御を最適化し、RTTの影響を減らす。
-
両側で異なるプロトコルファミリーをサポートする(IPv4/IPv6/Unixなど)。
-
タイムアウトの適用:接続の段階に応じた複数のタイムアウトをサポートし、停止したクライアントやサーバー、攻撃者が長時間リソースを占有できないようにする。
-
プロトコルの検証:HTTP、SSL、ペイロードを検査し、明示的に受け入れるよう指示されていない限り、不正なプロトコル要素を拒否する。
-
ポリシーの適用:許可されたものだけが転送されるようにする。
-
受信接続と送信接続の両方を特定のネットワーク名前空間に制限できる(Linuxのみ)。これにより、コンテナーをまたぐマルチテナントのロードバランサーを簡単に構築できる。
-
PROXYプロトコルにより、HTTP以外のトラフィックでもクライアントのIPアドレスをサーバーへ伝える。これはHAProxyの拡張機能で、現在では多くのサードパーティー製品に採用されている。執筆時点では、少なくとも次の製品が対応している。
- クライアント:haproxy、stud、stunnel、exaproxy、ELB、squid
- サーバー:haproxy、stud、postfix、exim、nginx、squid、node.js、varnish
3.3.2. 基本機能:SSL
HAProxyのSSLスタックは、Googleのエンジニアから、最も機能が豊富なものの一つと評価されています(http://istlsfastyet.com/ )。特に幅広い対応を支える、よく使われる機能は次のとおりです。
-
サイト数に制限がなく、性能を重視したSNIベースのマルチホスティング。それぞれの証明書を持つ50000ドメインを稼働させている導入例が、少なくとも一つ知られています。
-
ワイルドカード証明書をサポートし、多数の証明書を用意する必要性を減らします。
-
証明書によるクライアント認証。有効な証明書を提示できなかった場合のポリシーを設定できます。たとえば、クライアント証明書を再生成するための別のサーバーファームを提示できます。
-
バックエンドサーバーの認証により、接続先が中間者ではなく、本物のバックエンドサーバーであることを確認します。
-
バックエンドサーバーに対する認証により、接続しているのが期待されたhaproxyノードであることを、バックエンドサーバーへ証明します。
-
TLSのNPN拡張とALPN拡張により、SPDY/HTTP2接続を確実にオフロードし、平文でバックエンドサーバーへ渡せます。
-
OCSP staplingにより、クライアントがCertificate Status Requestを送った場合に、OCSPレスポンスを同時に渡し、最初のページの読み込み時間をさらに短縮します。
-
動的なレコードサイズ調整により、高性能と低レイテンシーを両立します。パケットがまだ転送中でもブラウザーが新しいオブジェクトの取得を始められるため、ページ読み込み時間を大きく短縮します。
-
ログ、アクセス制御、レポートなどのために、SSL/TLS層の関連情報へ常にアクセスできます。HTTPヘッダーやPROXYプロトコルの拡張にこれらの情報を埋め込むこともでき、オフロード先サーバーは、自身でSSLを終端した場合に得られたはずの情報をすべて取得できます。
-
OpenSSLの特定のバージョンに影響するHeartbleedのような既知の攻撃を、脆弱なSSLライブラリを使っている場合でも検出、記録、ブロックできます。
-
ステートレスなセッション再開をサポートします(RFC 5077のTLS Ticket拡張)。TLSチケットはCLIから更新できるため、頻繁にローテーションしてPerfect Forward Secrecyを実現できます。
3.3.3. 基本機能:監視
HAProxyは可用性を重視しています。そのため、サーバーの状態の確認と、自身の状態をほかのネットワークコンポーネントへ報告することに力を入れています。
-
サーバーごとのパラメーターで、その状態を継続的に監視します。これにより、通常のトラフィックが通るサーバーへの経路が機能していることを確認します。
-
ヘルスチェックには、稼働状態と停止状態への遷移それぞれにヒステリシスがあり、状態が頻繁に切り替わるのを防ぎます。
-
チェックは別のアドレス、ポート、プロトコルへ送れます。たとえば、HTTP+HTTPSサーバーのHTTPSポートのように、複数のサービスを代表すると見なせる単一のサービスを簡単にチェックできます。
-
サーバーはほかのサーバーの状態を追跡し、同時に停止状態へ移行できます。これにより、複数のサービスを提供するサーバーを一括して停止扱いにし、一部だけが故障したサーバーへ利用者を送らずに済みます。
-
サーバーにエージェントを配置して、負荷と健全性を監視できます。サーバー側から、ヘルスチェックでは見えない負荷、稼働状態、管理上の状態を報告したい場合があります。単純なエージェントを動かすことで、経路全体を検証するヘルスチェックに加え、サーバー自身が認識する健全性も判断に使えます。
-
TCP接続、HTTPリクエスト、SMTP hello、SSL hello、LDAP、SQL、Redis、send/expectスクリプトなど、さまざまなチェック方法を利用できます。すべてSSLの有無を選べます。
-
状態の変化は、障害の理由(検出時に受信したHTTPレスポンスなど)とともに、ログと統計ページに通知されます。変化が起きた際、設定したアドレスへメールを送ることもできます。
-
サーバーの状態は統計インターフェースにも表示され、ルーティングの判断に利用できます。サーバーファームの規模や健全性に応じて、別のファームへトラフィックを送れます(データセンター間リンクが失われた場合など)。
-
HAProxyはヘルスチェックリクエストを使い、サーバー名、重み、ファーム内のほかのサーバーの数などをサーバーへ伝えられます。サーバーは、その情報に基づいてレスポンスや判断を調整できます(利用可能なCPUを多く残すため、バックアップを延期するなど)。
-
サーバーはヘルスチェックで、単なる稼働・停止より詳しい状態を報告できます(停止したいため、新規訪問者の送信を止めてほしい、など)。
-
HAProxy自身も、ルーターやほかのロードバランサーなどの外部コンポーネントへ状態を報告でき、非常に充実した複数経路・複数層のインフラストラクチャーを構築できます。
3.3.4. 基本機能:高可用性
HAProxyは、本格的なロードバランサーと同様に、サービス全体をできるだけ継続させるため、可用性を非常に重視しています。
-
有効なサーバーだけを使い、それ以外は負荷分散先のファームから自動的に除外します。ただし、一定の条件では強制的に使うこともできます。
-
グレースフルシャットダウンをサポートし、接続に影響を与えずにサーバーをファームから外せます。
-
稼働系サーバーが停止すると、バックアップサーバーが自動的に代わりに使われ、可能な限りセッションが失われないようにします。同じサーバーへ到達する複数の経路(複数のインターフェースなど)も構築できます。
-
多数のサーバーが停止した場合、ファーム全体が障害状態であると報告できます。監視機能と組み合わせることで、上流のコンポーネントは、そのサービスに別のLBノードを選べます。
-
ステートレスな設計により、クラスターを簡単に構築できます。HAProxyは、障害時に失われる可能性のある情報を保存せず、サービスの継続性をできるだけ高めるよう設計されています。そのため、引き継ぎを可能な限り滑らかに行えます。
-
標準的なVRRPデーモンであるkeepalivedとよく連携します。HAProxyは自身の状態をkeepalivedへ簡単に伝えられ、フローティング仮想IPアドレスも適切に扱えます。注意:クラスター方式のソリューション(Heartbeatなど)ではなく、IP冗長化プロトコル(VRRP/CARP)だけを使ってください。最も速く、円滑で、信頼性の高いスイッチオーバーを実現するためです。
3.3.5. 基本機能:負荷分散
HAProxyは非常に充実した負荷分散機能を提供します。その多くは、残念ながら他の多くの負荷分散製品では利用できません。
-
10種類以上の負荷分散アルゴリズムをサポートします。入力データを使うものもあり、用途は無限に広がります。代表的なのは、round-robin(短い接続向け。各サーバーを順番に選ぶ)、leastconn(長い接続向け。接続数が最小のサーバー群のうち、最後に使われてから最も時間がたったものを選ぶ)、source(SSLやターミナルサーバーのファーム向け。クライアントの送信元アドレスでサーバーが直接決まる)、URI(HTTPキャッシュ向け。HTTP URIでサーバーが直接決まる)、hdr(特定のHTTPヘッダーフィールドの内容でサーバーが直接決まる)、first(短期間だけ稼働する仮想マシン向け。できるだけ少数のサーバーへ接続を集め、未使用のサーバーを停止できるようにする)です。
-
上記のすべてのアルゴリズムは、サーバーごとの重みをサポートします。ファーム内に世代の異なるサーバーを混在させたり、一部のトラフィックだけを特定のサーバー(デバッグモードや次期バージョンのソフトウェアを実行しているものなど)へ送ったりできます。
-
round-robin、leastconn、コンシステントハッシュでは、動的な重みをサポートします。CLIや、サーバーで動作するエージェントから、稼働中にサーバーの重みを変更できます。
-
動的な重みをサポートする場合は、常にslow-startも使えます。これにより、サーバーが受け持つトラフィックを段階的に増やせます。実行時にクラスをコンパイルする必要がある繊細なアプリケーションサーバーや、最大負荷をかける前にデータを蓄える必要のあるコールドキャッシュにとって、重要な機能です。
-
ハッシュには、クライアントの送信元アドレス、URLの要素、クエリー文字列の要素、ヘッダーフィールドの値、POSTパラメーター、RDP Cookieなど、さまざまな要素を使えます。
-
コンシステントハッシュは、ファームへのサーバー追加・削除時の大規模な再分配を防ぎます。大規模なキャッシュファームでは非常に重要で、slow-startを使ってコールドキャッシュにデータを蓄えられます。
-
サーバーごと・バックエンドごとの接続数、バックエンドの空き接続枠の数など、多数の内部メトリクスを使い、非常に高度な負荷分散方式を構築できます。
3.3.6. 基本機能:スティッキネス
スティッキネスがなければ、アプリケーションの負荷分散は役に立ちません。HAProxyは、サーバーの追加・削除、停止・復旧などが起きても、訪問者を同じサーバーに割り当て続けるための幅広い手段を提供します。一部の方式は複製を必要としないため、複数の負荷分散ノード間に距離があっても影響を受けにくい設計です。
-
必要に応じて、異なる場所からスティッキネス情報を個別に照合・学習できます。たとえば、JSESSIONID CookieをCookieとURLの両方で照合できます。最大8つの情報源を同時に学習でき、それぞれで異なるスティックテーブルを参照できます。
-
スティッキネス情報には、送信元アドレス、TCPペイロードのオフセットと長さ、HTTPクエリー文字列の要素、ヘッダーフィールドの値、Cookieなど、リクエストやレスポンス内で確認できるあらゆるものを使えます。
-
スティックテーブルは、マルチマスター方式ですべてのノード間に複製されます。
-
SSL-IDや、TSEファームで使うRDP Cookieなど、よく使われる要素には直接アクセスでき、簡単に操作できます。
-
すべてのスティッキー処理ルールには、ACLによる動的な条件を付けられます。
-
バックアップサーバーなど、特定のサーバーには固定しないようにできます。これにより、通常使うサーバーが復旧すると、自動的に負荷が戻ります。複数経路の環境でよく使われます。
-
HTTPでは、何も学習せずに、スティッキネス専用のCookieを操作する方式が好まれることがよくあります。Cookieを検出、書き換え、挿入したり、接頭辞を付けたりして、割り当てられたサーバーをクライアントに記憶させられます。
-
サーバーはログアウト時にスティッキネスCookieを変更・削除でき、離脱した訪問者は自動的にサーバーとの対応付けが解除されます。
-
ACLに基づくルールで、サーバーの状態にかかわらず、選択的にスティッキネスを無視したり強制したりできます。高度なヘルスチェックと組み合わせると、管理者は、導入中のサーバーが正常に動作することを一般公開前に確認できます。
-
Cookieに最大アイドル時間と有効期間を設定する独自の仕組みにより、スマートフォン、テレビ、家電など、閉じられることのない端末でも、永続ストレージに保存することなく、スティッキネスを円滑に終了できます。
-
複数のサーバーエントリーで同じスティッキネスキーを共有できます。複数経路の環境で一つの経路が停止しても、スティッキネスを維持できます。
-
ソフト停止では、スティッキネス情報を持つユーザーだけが割り当て済みのサーバーへ到達し続け、新しいユーザーはそこへ送られません。
3.3.7. 基本機能:ログ
ログは、ロードバランサーにとって極めて重要な機能です。第一に、ロードバランサーは単に表面化させた問題の原因として誤って疑われることがよくあります。第二に、インフラストラクチャーの重要な位置に置かれるため、正常・異常を問わずすべての動作を分析し、ほかのコンポーネントと突き合わせる必要があります。
HAProxyは非常に詳しいログを提供します。ミリ秒精度で、接続を受け付けた正確な時刻が含まれ、ファイアウォールのログで照合できます(NATとの対応付けなど)。デフォルトのTCPログとHTTPログは十分に詳細で、トラブルシューティングに必要な情報をすべて含みます。送信元IPアドレスとポート、フロントエンド、バックエンド、サーバー、タイマー(リクエスト受信時間、キュー待機時間、接続確立時間、レスポンスヘッダー受信時間、データ転送時間)、プロセス全体の状態、接続数、キューの状態、再試行回数、スティッキネス処理と切断理由の詳細、安全にエンコードされた取得ヘッダーなどです。この形式を拡張・置換して、任意のサンプルデータ、変数、取得値を含めることで、さらに詳しい情報を記録できます。たとえば、クライアントの累積リクエスト数や、訪問した異なるURLの数を記録できます。
標準のACLを使って、リクエストごとにログレベルを調整できます。不要なノイズと見なすログを自動的に抑え、その一方で、トラフィックの一部に異常な動作(特定の送信元アドレスのURL数やHTTPエラーが多すぎるなど)が見られた場合に警告を出せます。サーバーの停止や復旧などを知らせる管理ログも、独自のレベルで出力されます。
各フロントエンドとバックエンドは、複数の独立したログ出力先を持てるため、マルチテナント運用が容易になります。ログはUDPで送るのが望ましく、JSON形式でエンコードすることもできます。配送を保証するため、設定可能な行長で切り詰められます。stdout/stderr、任意のファイル記述子、またはクライアントが購読して取得できるリングバッファーへ送ることもできます。
3.3.8. 基本機能:統計
HAProxyは、認証、セキュリティレベル、スコープを備えたWebベースの統計表示インターフェースを提供します。ホスティングの顧客ごとに、その顧客のインスタンスだけを表示する専用ページを提供できます。通常のWebサイトの非公開URLに置けるため、新しいポートを開く必要はありません。ほかのHAProxyノードの稼働状況も表示でき、すべてが期待どおりに動作しているかを一目で確認できます。全体を簡潔に表示しながら、エラーの原因、最後のアクセスや変更からの経過時間など、多くの詳細にもアクセスできます。これらの情報はCSV表でも取得でき、ほかのツールに取り込んでグラフを作成できます。ページを自動更新して、大型ディスプレイ上の監視画面として使うこともできます。管理モードでは、保守作業を容易にするため、ページからサーバーの状態も変更できます。
Prometheusエクスポーターも用意されており、導入構成に応じて別の形式で統計を利用できます。
4 - 標準機能
このセクションでは、HAProxyで非常によく使われるものの、ほかのロードバランサーに必ずしも備わっているとは限らない機能を紹介します。
3.4.1. 標準機能:情報の取得と変換
HAProxyは、多数の「サンプル取得関数」による情報の取得をサポートします。サンプルと呼ばれる個々の情報を取り出し、その場で利用する仕組みです。スティッキネス、条件の構築、ログ情報の生成、HTTPヘッダーへの情報追加などに使われます。
サンプルは、さまざまな情報源から取得できます。
-
定数:整数、文字列、IPアドレス、バイナリブロック。
-
プロセス:日付、環境変数、サーバー・フロントエンド・バックエンド・プロセスの状態、バイト数・接続数とそのレート、キューの長さ、乱数生成器など。
-
変数:セッションごと、リクエストごと、レスポンスごとの変数。
-
クライアント接続:送信元・宛先のアドレスとポート、および関連するすべての統計カウンター。
-
SSLクライアントセッション:プロトコル、バージョン、アルゴリズム、暗号方式、鍵の長さ、セッションID、クライアント・サーバー証明書のすべてのフィールド、証明書のシリアル番号、SNI、ALPN、NPN、特定の拡張に対するクライアントの対応状況。
-
リクエスト・レスポンスバッファーの内容:オフセットと長さで指定した任意のペイロード、データ長、RDP Cookie、SSL helloの種類のデコード、TLS SNIのデコード。
-
HTTP(リクエストとレスポンス):メソッド、URI、パス、クエリー文字列の引数、ステータスコード、ヘッダーの値、位置を指定したヘッダーの値、Cookie、取得値、認証、ボディーの要素。
取得したサンプルは、「コンバーター」と呼ばれる一連の演算子を通して変換できます。コンバーターはサンプルを受け取り、新しいサンプルを返します。型がまったく異なることもあります。たとえば、入力文字列の長さだけを整数として返したり、文字列を大文字に変換したりできます。最終的に使う前に、任意の数のコンバーターを順に適用できます。利用可能なサンプルコンバーターのうち、よく使われるものは次のとおりです。
-
算術・論理演算子:比率や百分率の計算、単位変換など、入力データに対する高度な計算ができます。
-
IPアドレスマスク:アドレスをより大きなネットワーク単位でまとめたい場合に便利です。
-
データ表現:URLデコード、base64、16進数、JSON文字列、ハッシュ。
-
文字列変換:固定位置・固定長の部分文字列の抽出、特定の区切り文字で分けられたフィールドの抽出、特定の単語の抽出、大文字・小文字の変換、正規表現による置換。
-
日付変換:HTTP日付形式への変換、ローカル時刻とUTCの相互変換、オフセットの加減算。
-
スティックテーブルのエントリーを検索し、統計や割り当てられたサーバーを取得する。
-
ファイルを使った、マップによるキーから値への変換(主に位置情報の判定に使われます)。
3.4.2. 標準機能:マップ
マップは強力なコンバーターの一種です。起動時に二列のファイルをメモリへ読み込み、入力サンプルを一列目で検索し、見つかれば二列目の対応するパターンを、見つからなければデフォルト値を返します。出力もサンプルなので、さらに別のマップ検索を含む変換を適用できます。マップはネットワークアドレスの最長一致をサポートするため、クライアントのIPアドレスをAS番号や国コードへ変換する用途が最も一般的ですが、ほかにもさまざまな用途に使えます。
強みの一つは、CLIや、ほかのサンプルを使う特定のアクションから、稼働中に更新できることです。これにより、アクセス間で情報を保存・取得できます。もう一つは、二分木による索引で、数十万件のエントリーがあっても極めて高速に検索できることです。位置情報の判定を低コストで簡単に導入できます。
3.4.3. 標準機能:ACLと条件
HAProxyのほとんどの操作には、条件を付けられます。条件は、複数のACLを論理演算子(AND、OR、NOT)で組み合わせて構築します。各ACLは、次の要素に基づく一連のテストです。
-
テスト対象の要素を取得するサンプル取得メソッド。
-
要素を変換する、任意の一連のコンバーター。
-
照合するパターンのリスト。
-
パターンとサンプルの比較方法を指定する照合メソッド。
たとえば、HTTPの"Host"ヘッダーからサンプルを取得し、小文字に変換してから、正規表現による照合メソッドで複数の正規表現パターンと比較できます。
技術的には、ACLはマップと同じ基盤で構築されており、内部構造、パターン照合メソッド、性能はまったく同じです。実質的な違いは、サンプルを返す代わりに、「見つかった」か「見つからなかった」だけを返すことです。使い方の面では、ACLパターンは設定ファイル内に直接記述でき、専用のファイルは不要です。使いやすさや設定の分かりやすさのために、ACLに名前を付けることもできます。名前付きACLは複数回定義でき、どれかに一致するまで、すべての定義を順に評価します。
IPアドレスマスク、整数範囲、部分文字列、正規表現など、約13種類のパターン照合メソッドがあります。関数のように動作し、プログラミング言語と同様に、必要なものだけを評価します。そのため、ORを含む条件がすでに真なら後続は評価せず、ANDを含む条件がすでに偽なら残りの条件を評価しません。
定義できるACLの数に実用上の制限はなく、よく使うものがいくつかあらかじめ用意されています。ただし経験上、名前付きACLを多用する構成はトラブルシューティングがかなり難しく、場合によっては、匿名ACLをその場に記述したほうが簡単です。調べている範囲の外を参照する回数を減らせるためです。
3.4.4. 標準機能:内容に基づく振り分け
HAProxyは、内容に基づく振り分けの仕組みを実装しています。接続やリクエストがフロントエンドへ届くと、それに含まれる情報を処理します。その情報を使うACL条件を記述して、リクエストを処理するバックエンドを決められます。つまり、リクエストの内容に応じて、いずれかのバックエンドへトラフィックを送ります。最も一般的な例は、Hostヘッダーやパスの要素(サブディレクトリやファイル拡張子)から、HTTPリクエストの対象が静的オブジェクトかアプリケーションかを判断するものです。静的オブジェクトへのトラフィックは高速で軽量なサーバー群のバックエンドへ、それ以外はより複雑なアプリケーションサーバーへ送り、きめ細かな仮想ホスティングを実現します。複数の技術を全体的なソリューションとして共存させるのに便利です。
別の用途は、さまざまな条件に応じて異なる負荷分散アルゴリズムを使うことです。キャッシュにはURIハッシュを使い、アプリケーションにはラウンドロビンを使う、といった構成が可能です。
また、バックエンドごと、つまり顧客ごとに接続数を制限することで、複数の顧客が共通のリソースを少しずつ利用できるようにします。
内容に基づく振り分けルールは非常によく拡張できますが、性能は使用するACLの数や複雑さに左右される場合があります。ACLを一切使わず、サンプル値を直接バックエンド名に変換する動的な振り分けルールも記述できます。このような構成は、本番環境で少なくとも300000のバックエンドを扱い、正常に動作したと報告されています。
3.4.5. 標準機能:スティックテーブル
スティックテーブルは、通常、スティッキネス情報の保存に使われます。つまり、特定の訪問者が送られたサーバーへの参照を保持します。キーは訪問者に関連する識別子(送信元アドレス、接続のSSL ID、HTTPまたはRDP Cookie、URLやペイロードから抽出した顧客番号など)で、保存する値はサーバーの識別子です。
スティックテーブルのキーには、整数、文字列、アドレスの3種類のサンプルを使えます。一つのプロキシで参照できるスティックテーブルは一つだけで、どこでもプロキシ名で指定します。最大8個のキーを並行して追跡できます。キーとサーバーの両方が判明した時点で、リクエストまたはレスポンスの処理中にサーバー識別子を確定します。
スティックテーブルの内容は、“peers"と呼ばれるほかのHAProxyノードへアクティブ・アクティブ方式で複製でき、リロード時の新しいプロセスにも引き継げます。これにより、すべての負荷分散ノードで同じ情報を共有し、クライアントのリクエストが複数ノードに分散しても、同じルーティング判断ができます。
スティックテーブルは、クライアントを識別できる情報をキーにするため、クライアントごとの統計など、追加情報の保存にもよく使われます。追加の統計には余分な領域が必要で、明示的に宣言しなければなりません。保存できる統計には、入出力帯域幅、同時接続数、一定期間の接続レートと件数、エラーの数と頻度、特定のタグやカウンターなどがあります。特定のサーバーへ固定せずにこれらの情報を保持できるよう、特別な「追跡」機能を実装しています。スティッキー処理ルールに関係なく、異なるテーブルの最大3個のキーを同時に追跡できます。保存した各統計は、CLIから検索、ダンプ、クリアでき、稼働中のトラブルシューティングに役立ちます。
この仕組みは、再訪問者を優遇したり、利用者の行動の良し悪しに応じてサービス品質を調整したりするためにも使えますが、主な用途はサービスの不正利用や、より広くDDoSへの対策です。特定の不正な行動を高速に検出する複雑なモデルを構築できます。
3.4.6. 標準機能:書式付き文字列
HAProxyでは、ログ、リダイレクト、ヘッダーの追加など、さまざまな箇所で文字列を操作します。柔軟性を最大限に高めるため、書式付き文字列という概念を導入しました。当初はログ用に導入されたため、今でも"log-format"と呼ばれています。これらの文字列にはエスケープ文字が含まれ、変数やサンプル取得式など、さまざまな動的データを埋め込めます。また、結果を文字列に変換する際に、引用符を付けるなど、エンコード方法を調整することもできます。ヘッダーの内容、レスポンスデータ、レスポンステンプレートの構築や、ログ行のカスタマイズに使える強力な仕組みです。さらに、よく使う文字列を簡単に組み立てられるよう、ログで頻繁に使う情報の省略表現として、約50個の特別なタグを提供しています。
3.4.7. 標準機能:HTTPの書き換えとリダイレクト
ロードバランサーを前提に設計されていないアプリケーションの前段へロードバランサーを配置することは、適切なツールがなければ難しい作業です。この場合によく求められるのは、リクエストとレスポンスのヘッダーを調整し、ロードバランサーをオリジンサーバーとして見せ、固定された情報を修正することです。これには、リクエストのパスの変更(強く非推奨)、Hostヘッダーフィールドの変更、リダイレクト用のLocationレスポンスヘッダーフィールドの変更、Cookieのpath属性・domain属性の変更などが含まれます。また、サーバーによってはレスポンスで過剰な情報を公開し、標的型の攻撃に対して脆弱になることがあります。理論的には、これを取り除くのはロードバランサーの役割ではありませんが、実際には、すべてを確実に取り除くのに最も適した位置にあります。
同様に、ロードバランサーが一部のリクエストを捕捉し、新しい宛先URLへのリダイレクトで応答する必要がある場合もあります。リダイレクトと書き換えは混同されがちですが、まったく異なる概念です。書き換えではクライアントとサーバーが異なるものを見ることになり、訪問中のページの場所について認識が食い違います。一方、リダイレクトではクライアントに新しいURLへのアクセスを求めるため、サーバーと同じ場所を見ることになります。
このために、HAProxyはさまざまな書き換え・リダイレクト機能をサポートします。
-
正規表現による、リクエスト・レスポンス内のURLとヘッダーの書き換え。正規表現は扱いやすく、よく理解されているため、ヘッダー値の変更に最もよく使われる手段です。
-
書式付き文字列に基づくヘッダーの追加、削除、置換。たとえば、クライアント側のTLSアルゴリズムや暗号方式などの情報をヘッダーで渡せます。
-
任意の3xxコードを使った、相対URI、絶対URI、完全に動的なURI(書式付き文字列)へのHTTPリダイレクト。
-
特定のCookieの設定・削除、クエリー文字列の除去、末尾にスラッシュがない場合の追加など、HTTPリダイレクトの追加オプション。
-
強力な"return"ディレクティブ。動的な内容やテンプレートファイルを使い、ステータス、ヘッダー、ボディーなど、レスポンスのすべての部分をカスタマイズできます。
-
すべての操作で、ACLによる条件をサポートします。
3.4.8. 標準機能:サーバー保護
HAProxyは、サービスの可用性を最大化するため、サーバーを過負荷や攻撃から保護することに力を入れています。まず最も重要なのは、完全で正しいリクエストだけをサーバーへ転送することです。第一の理由は、バイトストリームとの同期を保つために必要なプロトコル要素を、HAProxyが見つける必要があるためです。第二の理由は、リクエストが完成するまで、その意味を変える要素が含まれるか分からないためです。直接の利点は、サーバーが不正・不完全なリクエストにさらされないことです。これはslowloris攻撃に非常に有効で、この攻撃はHAProxyにほとんど影響を与えません。
もう一つ重要なのは、HAProxyがリクエストとレスポンスを保存するバッファーを備えていることです。リクエストが完全になってからサーバーへ送り、ローカルネットワークからレスポンス全体を素早く読み取るため、サーバー側の接続を使う時間が非常に短くなり、サーバーのリソースをできるだけ節約できます。
この延長として、HAProxyはサーバーへの同時接続数や未完了のリクエスト数に制限をかけられます。トラフィックの急増時に処理能力の100%で動き続けても、サーバーが過負荷にならないことを保証します。超過したリクエストはキューに入り、空き枠ができたときに処理されます。この大きなリソース節約により、サーバーのレスポンス時間が十分に改善し、結果として過負荷にした場合より速くなることがほとんどです。キュー内のリクエストは、ほかのサーバーへ再配分でき、クライアントが中断した場合はキュー内で中断することもできます。これにより、「再読み込みの影響」からもサーバーを保護します。読み込みの遅いページで訪問者が「再読み込み」を押すたびに、通常は新しいリクエストが発生し、サーバーの過負荷状態が続いてしまう現象です。
slow-startの仕組みは、再起動中のサーバーがまだ起動処理を終えていなかったり、クラスをコンパイルしていたりする間に、大量のトラフィックが届くことも防ぎます。
プロトコルレベルの保護では、HTTPパーサーの制約を緩め、標準に準拠していなくても無害なリクエストやレスポンスを受け入れ、修正することもできます。これにより、修正の開発中も、不具合のあるアプリケーションを利用できます。同時に、問題のあるメッセージは詳細なレポートとともに完全に取得され、開発者がアプリケーションの問題を見つけるのに役立ちます。最も危険なプロトコル違反は、適切に検出し、対処・修正します。たとえば、Content-lengthヘッダーが二つある不正なリクエストやレスポンスは、値が完全に同じなら修正し、異なるならセキュリティ上の問題となるため拒否します。プロトコル検査はHTTPに限らず、TLSやRDPなどにも利用できます。
プロトコル違反や攻撃を検出した際の応答には、一般的な"HTTP 400 bad request"を返す、TCPリセットで接続を閉じる、長く待たせてからエラーを返したように見せて攻撃者を混乱させる(“tarpit”)など、さまざまな選択肢があります。いずれも、攻撃の継続コストを高めて攻撃元のクライアントに断念させ、サーバーの保護に役立ちます。
HAProxyは、偶発的なデータ漏えいやセッションの混在を防ぐ、さらに高度なオプションも提供します。疑わしいサーバーレスポンスを記録するだけでなく、訪問者の機密性に影響し得るレスポンスを記録し、必要に応じてブロックします。その一例が、キャッシュ可能なレスポンスにキャッシュ可能なCookieが含まれる場合です。中間キャッシュが別の訪問者へそれを渡してしまい、意図せずセッションが共有される可能性があります。
5 - 高度な機能
3.5.1. 高度な機能:管理
HAProxyは、通常の本番環境で極めて安定し、安全に管理できるよう設計されています。インストール作業を必要としない単一の実行可能ファイルとして提供されます。複数のバージョンを簡単に共存させられるため、すべてのインスタンスを一度に移行する代わりに、重要度の順に段階的にアップグレードできます(この方法を推奨します)。設定ファイルは容易にバージョン管理できます。設定のチェックはオフラインで行うため、失敗するかもしれないサービスを再起動する必要はありません。設定チェックでは、別のルールを隠してしまうルールや、機能しないスティッキー処理など、見つけにくい誤りも検出でき、修正のための詳しい警告や設定のヒントが提示されます。設定ファイルの後方互換性は非常に長い期間に及び、バージョン1.5は13年前に書かれたバージョン1.1の設定を完全にサポートしていました。1.6でも、別の方法で実現できる、ほとんど使われていない古いキーワードのサポートを削除しただけです。設定とソフトウェアのアップグレードは円滑で処理を中断せず、古いプロセスと新しいプロセスをシステム上で共存させ、それぞれの接続を処理させられます。システムの状態、ビルドオプション、ライブラリの互換性は起動時に報告されます。
高度な機能の一部を使うと、アプリケーション管理者は、サーバーを穏やかに停止へ移行させ、処理がなくなったことを検出してからオフラインにし、停止、アップグレードを行い、その間はトラフィックを受け取らないようにできます。その後、一般公開せずに通常の経路を通じて再度テストできます。これらはすべてHAProxyに一切手を加えずに行えます。そのため、複雑な本番運用作業でも、技術要員を十分確保できる営業時間中に実施できます。
プロセスは可能な限りリソースを節約しようとします。メモリプールで割り当て時間を削減し、メモリ断片化を抑え、ペイロードバッファーは内容の送信後すぐに解放します。また、厳格なメモリ上限を適用でき、上限を超えた場合は、追加のメモリを割り当てる代わりに、接続を利用可能なバッファーができるまで待機させます。この仕組みは、制約の厳しい環境でメモリ使用量を保証するのに役立ちます。
コマンドラインインターフェース(CLI)をUNIXまたはTCPソケットで利用でき、さまざまな操作やトラブルシューティング情報の取得を行えます。このソケットで行う操作はすべて設定変更を必要としないため、主に一時的な変更に使われます。このインターフェースでは、サーバーのアドレス、重み、状態の変更、統計の参照とカウンターのクリア、スティックテーブルのダンプとクリア(必要に応じてキー条件で選択)、クライアント側・サーバー側の接続のダンプと強制終了、取得したエラーとその正確な原因・発生箇所の詳細分析のダンプ、ACLやマップのエントリーのダンプ・追加・削除、TLS共有シークレットの更新、任意のフロントエンドへの接続数制限やレート制限の即時適用(共用ホスティング環境で便利です)、特定のフロントエンドの無効化によるリッスンポートの解放(日中の運用作業が禁止されているものの、修正が必要な場合に便利です)が可能です。証明書とその設定を稼働中に更新したり、トラフィック処理の各段階のトレースを有効化・参照したりすることもできます。
SNMPが必須の環境向けには、少なくとも2つのエージェントがあります。1つはHAProxyのソースに付属し、Net-SNMPのPerlモジュールに依存します。もう1つは商用パッケージに付属し、Perlを必要としません。対応範囲はほぼ同等です。
HAProxyを配置するマシンには、次の4つのユーティリティのインストールがよく推奨されます。
-
socat:CLIに接続するために使います。netcatの一部の派生版でも、ある程度は代用できます。
-
最新のHAProxyバージョンに付属するhalog:ログ解析ツールです。ネイティブのTCPログとHTTPログを極めて高速(毎秒1〜2 GB)に解析し、URL別・送信元アドレス別のリクエスト数、レスポンス時間やエラー率で並べたURL、終了コードなど、有用な情報と統計を抽出します。稼働中の問題を調査するために本番サーバーへ配置することを想定して設計されているため、すぐ使える状態で用意しておく必要があります。
-
tcpdump:ログで明らかになった問題の調査に必要なネットワークトレースを取得するため、強く推奨します。アプリケーション側とhaproxy側の分析が食い違う局面では、どちらが正しいかを判断する唯一の方法がネットワークトレースになります。また、tcpdumpによってネットワークスタックやハイパーバイザーのバグが見つかることもよくあります。
-
strace:tcpdumpと組み合わせて使うツールです。HAProxyが実際に何を見ているかを報告し、OSに原因がある問題とHAProxyに原因がある問題を切り分けるのに役立ちます。HAProxyのバグが疑われる場合、straceの結果を求められることがよくあります。
3.5.2. 高度な機能:システム固有の機能
HAProxyを配置するOSによっては、追加の機能が利用できる場合や必要となる場合があります。HAProxyは多数のプラットフォームをサポートしていますが、主にLinux上で開発されているため、一部の機能はLinuxでしか利用できません。
透過的なバインドと接続、特定のネットワークインターフェースへの接続のバインド、複数のプロセスを同じIPアドレスとポートにバインドする機能は、LinuxとBSDシステムでのみ利用できます。ただし、利用可能なプロセス間で受信リクエストをカーネル側で負荷分散するのはLinuxだけです。
Linuxには、このほかにも多くの追加機能と最適化があります。HAProxyをすべてのコンテナー間のゲートウェイとして動作させられるネットワーク名前空間(「コンテナー」とも呼ばれます)、クライアント側接続のMSS・Netfilterマーク・IP TOSフィールドの設定、リッスン側のTCP FastOpen、設定されたタイムアウトよりも前にクライアントの消失を検出した場合にカーネルが接続を素早く終了できるTCPユーザータイムアウト、カーネルに接続の両側間でデータを転送させて複数回のメモリコピーを避けるTCP splicing、カーネルバッファーにデータが届いてから着信接続の通知を受ける"defer-accept"バインドオプション、接続の確認ACKとともにリクエストを送信する機能(“piggy-back"とも呼ばれ、“tcp-smart-connect"オプションで有効になります)などです。Linuxでは、ネットワーク上のパケットをできるだけ節約するため、HAProxyはTCPの遅延ACKの扱いにも細心の注意を払っています。
システムによっては、時刻が過去や未来へ飛ぶ、信頼性の低い時計を持つものがあります。以前は、複数のプロセッサーが厳密に同じ時刻を参照しない一部のNUMAシステムで発生していました。最近では、仮想時計が実時計と無関係に動作する仮想化環境でより一般的になり、大きな時刻の飛び(最大30秒に達する例も観測されています)が起きています。これにより、一般にタイムアウトの適用で多くの問題が生じます。このようなシステムの欠陥に対処するため、HAProxyはシステム時計に基づきながら、そのずれを測定・補正する独自の単調時計を維持しています。その結果、システム時計が非常に不正確でも、タイマーは十分な精度を保ち、タイムアウトも機能し続けます。この問題はHAProxy固有ではなく、そのシステム上で動作するすべてのソフトウェアに影響します。典型的な症状は、不意のタイムアウトやアプリケーションのフリーズです。したがって、この動作がシステムで検出された場合は、HAProxyが自衛しているかどうかにかかわらず、必ず修正しなければなりません。
Linuxでは、新しく起動するプロセスが既存のプロセスと通信し、リッスン用のファイル記述子を再利用できるため、プロセスを置き換える間もリッスンソケットが中断されません。
3.5.3. 高度な機能:スクリプト
HAProxyは組み込み言語Luaをサポートする構成でビルドでき、リクエストやレスポンスの複雑な操作、ルーティングの判断、統計処理など、幅広い新たな用途が可能になります。Luaを使うと、ほかのサーバーに並列に接続して情報を交換することもできます。これにより、たとえば認証システムの開発も可能になります(ただし複雑です)。Luaの使い方の詳細は、“doc/lua-api/index.rst"のドキュメントを参照してください。
3.5.4. 高度な機能:トレース
管理者はいつでもCLIで接続し、さまざまな内部サブシステムのトレースを有効にできます。複数の詳細レベルが標準で用意されており、実際にはリクエストごとに1行から500行までの情報を取得できます。フィルターと、自動的な取得開始・停止・一時停止の仕組みも利用できるため、特定のイベントを待ち、その詳細を観察できます。不具合のあるサーバーやクライアントによるプロトコル違反、サービス拒否攻撃の診断に非常に便利です。
6 - サイジングと性能
一般的なCPU使用率を見ると、TCPモードまたはHTTP closeモードでは、処理時間の15% をHAProxyが、85% をカーネルが使用します。HTTP keep-aliveモードでは、HAProxyが約30%、カーネルが約70% を使用します。つまり、オペレーティングシステムとそのチューニングは、全体の性能に大きく影響します。
利用形態はユーザーによって大きく異なります。帯域幅を重視する場合もあれば、リクエストレート、同時接続数、SSL性能を重視する場合もあります。このセクションでは、サイジングの判断に役立つ要素をいくつか紹介します。
どの処理にもコストがかかることを忘れないでください。個々の処理のオーバーヘッドは他の処理に上乗せされます。ある条件では無視できても、別の条件では支配的になることがあります。
接続からのリクエストを処理する際には、次の関係が成り立ちます。
-
データの転送は、リクエストヘッダーやレスポンスヘッダーの解析より低コストです。
-
リクエストヘッダーやレスポンスヘッダーの解析は、サーバーへの接続を確立して切断するより低コストです。
-
接続の確立と切断は、TLSの再開より低コストです。
-
TLSの再開は、鍵計算を伴う完全なTLSハンドシェイクより低コストです。
-
アイドル状態の接続は、バッファーにデータを保持している接続よりCPUコストが小さくなります。
-
TLSコンテキストは、データを保持している接続よりさらに多くのメモリを消費します。
実際には、ペイロードのバイト列を処理するほうが、ヘッダーのバイト列を処理するより低コストです。そのため、単位データ量あたりのリクエスト数が多い小さなオブジェクトよりも、リクエスト数が少ない大きなオブジェクトのほうが、高いネットワーク帯域幅を実現しやすくなります。最大帯域幅を常に大きなオブジェクトで測定し、リクエストレートや接続レートを小さなオブジェクトで測定するのはこのためです。
複数のCPUに分散した複数のプロセスでよくスケールする処理もあれば、そうでない処理もあります。大きなオブジェクトではCPUがボトルネックになることはまれで、主にネットワーク帯域幅とネットワークインターフェースに至るデータバスが制約となるため、ネットワーク帯域幅はあまりスケールしません。接続レートは、ローカルポートテーブルを扱う際のシステム内のロックの影響で、複数プロセッサーではうまくスケールしません。持続的接続上のリクエストレートは、メモリやネットワーク帯域幅をあまり使用せず、ロックされた構造へのアクセスも不要なため、非常によくスケールします。TLSの鍵計算は完全にCPUに制約されるため、非常によくスケールします。TLSの再開もある程度スケールしますが、共有テーブルへのアクセスのオーバーヘッドが処理能力の増加による小さな利得を相殺するため、約4プロセスで限界に達します。
十分にチューニングしたシステムで期待できる性能は、次に示す範囲です。これらは桁の目安として捉えてください。プロセッサー、IRQ設定、メモリの種類、ネットワークインターフェースの種類、オペレーティングシステムのチューニングなどにより、上下どちらにも大きく変動します。
次の数値は、デュアルポートの10 Gbps NICを備えた3.7 GHzのCore i7上で、Linuxカーネル3.10、HAProxy 1.6、OpenSSL 1.0.2を実行して測定したものです。HAProxyは専用の単一CPUコア上で単一プロセスとして動作し、さらに二つのコアをネットワーク割り込み専用に割り当てました。
-
平文での最大ネットワーク帯域幅は、256 kB以上のオブジェクトで20 Gbps、41kB以上で10 Gbps。
-
大きなオブジェクトとAES256-GCM暗号を使用したTLSトラフィックは4.6 Gbps。
-
クライアントからサーバーへのTCP接続は毎秒83000。
-
クライアントからサーバーへのHTTP接続は毎秒82000。
-
server-closeモードでは毎秒97000のHTTPリクエスト。クライアント側はkeep-alive、サーバー側はcloseとします。
-
エンドツーエンドのkeep-aliveモードでは毎秒243000のHTTPリクエスト。
-
フィルタリングされるTCP接続は毎秒300000(DDoS対策)。
-
持続的なTLS接続のkeep-aliveモードでは毎秒160000のHTTPSリクエスト。
-
再開されたTLS接続では毎秒13100のHTTPSリクエスト。
-
RSA2048で再ネゴシエーションされるTLS接続では毎秒1300のHTTPS接続。
-
RAMのGBあたり、帯域を使い切る同時接続を20000処理できます。システムバッファーに必要なメモリも含みます。入念にチューニングすればさらに改善できますが、この結果は容易に達成できます。
-
RAMのGBあたり、約8000の同時TLS接続(クライアント側のみ)。システムバッファーに必要なメモリも含みます。
-
RAMのGBあたり、約5000の同時エンドツーエンドTLS接続(両側)。システムバッファーに必要なメモリも含みます。
より新しいベンチマークでは、AWSの64コアARM Graviton2プロセッサー上でマルチスレッドを有効にしたHAProxy 2.4が、ミリ秒未満の応答時間で毎秒200万のHTTPSリクエストと、100Gbpsのトラフィックを達成しました。
覚えておくと便利な目安は、TLS keep-aliveからTLS再開へ、またTLS再開からTLS再ネゴシエーションへ切り替えると、リクエストレートがそれぞれ10分の一になることです。一方、HTTP keep-aliveからHTTP closeへの切り替えでは3分の一になるだけです。また、AES命令を備えた高クロックのコアでは、コアあたり約20 GbpsのAES-GCM処理が可能です。
同じサーバーを使う場合、HAProxyはおおむね次の台数を飽和させられると考えるのも、有用な目安です。
-
約5-10台の静的ファイルサーバーまたはキャッシュプロキシ。
-
約100台のアンチウイルスプロキシ。
-
使用する技術に応じて、約100-1000台のアプリケーションサーバー。
7 - リリース、パッケージ、アップグレード
HAProxyはGPLv2ライセンスのオープンソースプロジェクトです。要求に応じてソースへアクセスできるようにすることを条件に、誰でも再配布できます。変更を加えた場合は、特にこの条件が重要です。
HAProxyは、“master"または"mainline"と呼ばれる主開発ブランチで開発が進み、コードが安定したと判断されると、そこから新しいブランチが分岐します。プロジェクトへの参加や最新機能の利用を目的として、多くのWebサイトが自発的に開発ブランチを本番環境で動かしています。そのフィードバックは、バグの修正や開発中バージョンの全体的な品質・安定性の判断に非常に役立ちます。
コードが十分安定した時点で作られる新しいブランチが安定版となり、通常は数年間保守されます。そのため、最新版でなくても、新しいブランチへ急いで移行する必要はありません。安定版ブランチの公開後は、バグ修正だけが取り込まれ、ごくまれに、ユーザーの利便性を高める小さな機能更新が加わります。安定版ブランチに取り込まれる修正は、必ずmasterブランチに由来します。これにより、アップグレード後に修正が失われないことを保証します。そのため、バグを修正する場合は、安定版ブランチではなくmasterブランチに対するパッチを作成してください。すでに修正済みだと分かることもあります。この手順によって安定版ブランチのリグレッションも極めてまれになるため、現在のブランチの最新版へ更新しない理由はありません。
ブランチは、“1.6"のようにドットで区切られた2つの数値で表します。1.9以降、2番目の数値が奇数のブランチは、主に影響の大きい技術的な更新を扱い、ほかのブランチよりバグが発生しやすいため、上級ユーザー向けの性格が強くなっています。保守期間は約1年に限られ、緊急時にロールバックできない場所には配置してはなりません。完全なバージョンには、修正の段階を示す1つまたは2つのサブバージョン番号が含まれます。たとえば、バージョン1.5.14は、1.5.0の公開後にブランチ1.5で行われた14番目の修正リリースです。個別のバグに対する126件の修正、24件のドキュメント更新、75件のその他のバックポートが含まれ、その多くは前述の126件のバグ修正に必要なものでした。同じブランチ内でのアップグレードが常に安全であることを保証するため、安定版ブランチでは既存の機能を変更・削除してはなりません。
HAProxyは複数の入手元から提供され、それぞれリリースの頻度が異なります。
-
公式コミュニティサイト:http://www.haproxy.org/ 。最新の開発リリース、すべての安定版リリース、各ブランチのナイトリースナップショットのソースを提供します。リリースサイクルは速くなく、安定版リリース間、または開発スナップショット間には数か月かかります。非常に古いバージョンも引き続きサポートしています。提供されるのはソースだけなので、ここから入手したものはビルドやパッケージ化が必要です。
-
GitHub:https://github.com/haproxy/haproxy/ 。開発ブランチだけのミラーで、課題管理、継続的インテグレーション、コードカバレッジのツールと連携しています。コントリビューター専用です。
-
LinuxディストリビューションやBSD portsなどのOS。通常、長期保守されるバージョンを提供します。公式版の修正がすべて含まれるとは限りませんが、少なくとも重要な修正は含まれます。高度な設定は必要なく、更新を簡単に保ちたい多くのユーザーにとって、よい選択肢になることがよくあります。
-
http://www.haproxy.com/ の商用版。最新の安定版に基づき、需要の高い次期リリースの機能をいくつかバックポートした、サポート付きの業務用パッケージです。各種OS向けのパッケージやアプライアンスとして提供されます。安定版ブランチの信頼性と最新機能を両立したい場合、バグ修正への最速の対応を求める場合、またはオープンソース製品にサポート契約を付けたい場合に最適です。
使っているバージョンが、そのブランチの最新版であることを確かめるには、次のように進めます。
-
実行中のHAProxy実行可能ファイルを確認します。システムに標準で付属するものとは別に、管理者が別の場所に自分のバージョンをインストールしている場合があります。起動スクリプトで、どれを使っているか確認することが重要です。
-
HAProxyの入手元を特定します。通常は"haproxy -v"を実行すれば十分です。開発バージョンは、次のようにブランチ番号の後に"dev"と表示されます。
安定版は次のように表示されます。OSベンダーが提供する、変更されていない安定版も
同じ形式です。
安定版のナイトリースナップショットは、次のようにバージョンの後に16進数の列が付き、
リリース日ではなくスナップショットの
日付が表示されます。
これ以外の形式は、独自のパッチを含むシステム固有のパッケージを示す場合があります。
たとえば、HAProxy Enterpriseのバージョンは
次の形式(<branch>-<latest commit>-<revision>)で表示されます。
歴史的には、2.4より前のバージョンでは、プロセス名の"HA"と"Proxy"の間にハイフンが
入っていたことに注意してください。上の例も該当しますが、正しい形式を示すために調整しています。
そのため、スクリプトではこの語を無視するか、緩い条件で照合するほうがよいでしょう。
また、最近のバージョンでは、プロジェクトのホームページへのURLが追加されています。
最後に、バージョン2.1以降には"Status"行があり、そのバージョンが本番環境で安全に
使えるかどうか、安全に使える場合はいつまでかを示します。また、そのバージョンに
影響する既知のバグの一覧へのリンクも含まれます。
- システム固有のパッケージでは、ベンダーのパッケージリポジトリや更新システムで、使っているシステムが引き続きサポートされ、そのブランチに修正が提供されていることを確認する必要があります。haproxy.orgから入手したコミュニティ版では、サイトでブランチの状態を確認し、最新版と手元のバージョンを比較するだけで、最新版かどうかが分かります。最新版でなければ更新できます。ブランチがすでに保守されていない場合は、更新が大幅に遅れているため、より新しいブランチへのアップグレードを検討する必要があります(その際はREADMEを注意深く読んでください)。
HAProxyは、その入手元に応じた方法で更新する必要があります。通常は、システムベンダーのパッケージ更新方法に従います。ソースから導入した場合は、ソースを展開した後、ソースディレクトリのREADMEを読み、利用するOS向けの手順に従ってください。
8 - 補完製品と代替製品
HAProxyは、以下に挙げる製品の一部と非常にうまく連携します。そのため、HAProxyに直接関連しないものもここで紹介します。
4.1. Apache HTTPサーバー
Apacheは、事実上の標準となっているHTTPサーバーです。非常に充実したモジュール構成のプロジェクトで、ファイル配信と動的コンテンツの両方をサポートします。一部のアプリケーションサーバーのフロントエンドとしても使用でき、リクエストのプロキシやレスポンスのキャッシュも行えます。いずれの用途でも、通常は前段にロードバランサーが必要です。Apacheにはさまざまな動作モードがあり、モードによって負荷が異なります。一部のモジュールでは、依然として負荷の大きいpreforkモデルが必要なため、接続数が増えるとうまくスケールできません。この場合、HAProxyでサーバーごとの同時接続数を安全な値に制限すると、大きな効果があります。サーバーを大幅に高速化し、そのリソースを確保してアプリケーションで有効に利用できます。
Apacheは “mod_rpaf” 拡張を使い、X-Forwarded-Forヘッダーからクライアントのアドレスを取得できます。HAProxyの設定に “option forwardfor” を指定すると、このヘッダーを自動的に付加します。HAProxyはさまざまなDoS攻撃への耐性が高いため、インターネットに公開するApacheの保護にも役立ちます。
4.2. NGINX
NGINXは、もう一つの事実上の標準HTTPサーバーです。Apacheと同様、幅広い機能を備えています。HAProxyに似たモデルで構築されており、数万の同時接続を問題なく処理できます。付属のPHP FPMを使用する場合など、アプリケーションへのゲートウェイとして使用するときは、前段で接続数を制限してPHPアプリケーションの負荷を軽減すると効果的なことがよくあります。この場合、HAProxyは通常のロードバランサーとしてだけでなく、トラフィックを調整してPHPの混雑を解消し、高速化する役割でも有用です。また、どちらもイベント駆動型のアーキテクチャによりCPU使用量が非常に小さいため、同じシステムに両方を配置することも容易です。NGINXはHAProxyのPROXYプロトコルを実装しているため、HAProxyからNGINXへクライアントの接続情報を簡単に渡し、アプリケーションに必要な情報をすべて提供できます。大きな静的ファイルの配信では、NGINXの前段にあるHAProxyでコンシステントハッシュを使用すると、OSのキャッシュヒット率が改善することを示すベンチマークもあります。実質的に、サーバーノード数に応じた倍率で改善します。
4.3. Varnish
Varnishは、高度なキャッシュ機能を持つリバースプロキシです。Webアプリケーションアクセラレーターと呼ぶのが最も適切でしょう。SSL/TLSは実装せず、自身が最も得意とする処理にすべてのCPUサイクルを使うことを目指しています。VarnishもHAProxyのPROXYプロトコルを実装しているため、HAProxyをVarnishの前段に簡単に配置し、SSLオフロードと負荷分散を行いながら、必要なクライアント情報をすべて渡せます。また、Varnishはサーバーから圧縮済みのオブジェクトを受け取った場合、キャッシュからの配信時に展開できますが、圧縮は行いません。バックエンドサーバーが圧縮に対応していなければ、HAProxyで送信データを圧縮できます。ただし、トラフィックが少ない場合を除き、ロードバランサーでの圧縮はあまり勧められません。
複数ノードで大規模なキャッシュ群を構築する場合、HAProxyはURLのコンシステントハッシュでキャッシュノードに負荷を適切に分散し、キャッシュの重複を避けられます。結果として、全キャッシュノードの合計に相当するキャッシュ容量を得られます。また、処理の不要な非常に小さいオブジェクトをHAProxyで短時間キャッシュすると、ネットワークの往復を減らし、HAProxyとVarnishの両ノードのCPU負荷を軽減できることがあります。これはVarnishがそれらのオブジェクトに処理を加えない場合に限られます。一般に「faviconキャッシュ」と呼ばれる考え方で、不要な下流へのリクエストを相当な割合で減らせることがあります。ただし、他のキャッシュの前段でHAProxyのキャッシュを長時間、具体的には数秒を超えて有効にしないでください。大きな節約効果を得られないまま、トラブルシューティングが大幅に複雑になります。
4.4. 代替製品
Linux Virtual Server(LVSまたはIPVS)は、Linuxカーネルに含まれるレイヤー4のロードバランサーです。パケット単位で動作し、TCPとUDPを処理します。レイヤー7の知識をまったく持たないため、多くの場合、代替というより補完する製品です。
Poundもよく知られたロードバランサーです。HAProxyより大幅に簡素で機能も少ないものの、非常に基本的な構成であればどちらも利用できます。作者は常にコードの監査しやすさを最優先し、機能数を少なく保つ方針をとっています。スレッドベースのアーキテクチャのため、多数の接続ではスケーラビリティに劣りますが、優れた製品です。
Penは比較的軽量なロードバランサーです。SSLをサポートし、クライアントのIPアドレスを格納する固定サイズのテーブルで接続先を固定します。パケット指向のモードも備え、Direct Server ReturnやUDPにもある程度対応します。接続先固定用のテーブルは2048エントリーしかなく、小さな負荷を想定しています。
NGINXにもある程度の負荷分散機能がありますが、明らかに主要な機能ではありません。実際のトラフィックを使ってサーバー障害を検出し、負荷分散アルゴリズムも限られ、接続先固定の機能も非常に限定的です。それでも、すでにNGINXを使用している単純な構成では、有用な場合があります。HAProxyと非常によく連携するため、限界に達してからHAProxyを追加しても問題ありません。
Varnishもバックエンドサーバーの負荷分散を行い、実際のヘルスチェックにも対応します。ただし、接続先固定は実装していません。そのため、NGINXと同様、接続先固定が不要であれば、最初はそれだけで十分な場合があります。HAProxyとVarnishは非常によく連携するので、後からHAProxyを追加して機能を補うのも容易です。
9 - ドキュメントとコミュニティ
1. 利用可能なドキュメント
HAProxyのドキュメント一式は、次の文書に収録されています。時間を節約し、必要な情報を正確に得るために、該当するドキュメントを必ず参照してください。これらの文書に回答がある質問は、メーリングリストに送らないでください。
-
intro.txt(このドキュメント):負荷分散の基本、製品としてのHAProxy、できることとできないこと、回避すべき既知の落とし穴、OS固有の制限、入手方法、開発の進め方、既知の修正をすべて含む版を稼働させる方法、更新方法、補完製品と代替製品について説明します。 -
management.txt:haproxyの起動方法、実行中の管理方法、複数ノードでの管理方法、サービスを中断せずにアップグレードする方法を説明します。 -
configuration.txt:すべての設定キーワードとそのオプションを詳しく説明するリファレンスマニュアルです。設定変更が必要なときに参照します。 -
coding-style.txt:プロジェクトにコードを提案する開発者向けに、コーディングスタイルを説明します。それほど厳格ではなく、コード全体が完全に従っているわけでもありませんが、大きく逸脱したコードの提供は受け付けられません。
-
proxy-protocol.txt:HAProxyと多くのサードパーティ製品が実装するPROXYプロトコルの事実上の仕様です。
-
security.txt:セキュリティ上の問題の報告方法と、脆弱性に該当するもの、該当しないものを説明します。
-
README:ソースからHAProxyをビルドする方法。
5. 連絡先
開発者やコミュニティのメンバーに連絡するには、通常、メーリングリストのhaproxy@formilux.org にメッセージを送るのが最適です。このリストとアーカイブは公開されているため、機密情報は開示しないようにしてください。さまざまな経験を持つ約千人のユーザーが参加しており、非常に複雑な質問にも、通常は比較的早く適切な回答が得られます。提案も歓迎します。メールの利用が難しい場合は、http://discourse.haproxy.org/ のDiscourseを利用できます。ただし、こちらで質問を読む人は少なく、大半の質問にごく少人数のチームで対応しています。いずれの場合も、余暇を使って支援している人々に敬意を払い、辛抱強く対応してください。
バグと思われる問題が見つかっても確信が持てない場合は、メーリングリストで報告するのがよいでしょう。バグだと確信しており、使用中のバージョンがそのブランチの最新版で、GitHubアカウントを持っている場合は、https://github.com/haproxy/haproxy/ に直接アクセスし、把握している詳細をすべて記載してissueを登録できます。こちらも公開されるため、後で後悔するような情報を投稿しないよう注意してください。issueは長いスレッドとして表示されるため、数百行以上の長いダンプは貼り付けず、ファイルとして添付してください。
セキュリティ上の問題が見つかったと思われる場合は、doc/security.txtを参照してください。HAProxyの脆弱性に該当するもの、該当しないものと、実際の脆弱性を非公開で報告する方法を説明しています。疑わしい問題の大半は通常のバグと判明するため、その場合は上記の方法で報告するのが適切です。
このサイトのマニュアル一式
この版の出典
- バージョン: HAProxy 3.4.6-66、メンテナンスブランチのドキュメントスナップショット
- 最新の安定版リリース: HAProxy 3.4.6、タグ
v3.4.6 - ソースコミット:
16acce1dac1d - アップストリームの公開版: docs.haproxy.org/3.4/
- このサイトに保存したライセンス: HAProxyのライセンス通知 とGPLv2
10 - 1. HTTPの基礎を振り返る
この文書は、上記バージョンに実装されている設定言語を扱います。ヒント、例、助言は提供しません。そのような文書については、リファレンスマニュアルまたはアーキテクチャマニュアルを参照してください。番号付きの章は、直接移動できるようにHAProxyのフラットなサイドバーに順番に並んでいます。
HAProxyをHTTPモードで実行すると、リクエストとレスポンスの両方を完全に解析してインデックスを作成するため、その内容に含まれるほぼあらゆる要素についてマッチ条件を組み立てられます。
ただし、HTTPのリクエストとレスポンスがどのように構成され、HAProxyがそれらをどのように分解するかを理解することが重要です。これを理解すれば、正しいルールの記述や既存設定のデバッグが容易になります。
まず、HTTPは一連のRFCで標準化されており、HAProxyはそれらにできる限り忠実に従います。
- RFC 9110: HTTP Semantics(プロトコル要素の意味を説明)
- RFC 9111: HTTP Caching(HTTPキャッシュが従うべきルールを説明)
- RFC 9112: HTTP/1.1(表現、相互運用性のルール、セキュリティ)
- RFC 9113: HTTP/2(表現、相互運用性のルール、セキュリティ)
- RFC 9114: HTTP/3(表現、相互運用性のルール、セキュリティ)
これらに加えて、RFC 8999から9002は、HTTP/3プロトコルが使用するQUICトランスポート層を規定しています。
1.1. HTTPトランザクションモデル
HTTPプロトコルはトランザクションに基づきます。つまり、各リクエストに対してレスポンスは必ず一つだけ返されます。当初のプロトコルバージョン1.0では、接続ごとにリクエストは一つでした。クライアントからサーバーへTCP接続を確立し、クライアントがその接続を通じてリクエストを送り、サーバーが応答すると、接続を閉じます。したがって、新しいリクエストには新しい接続が必要です。
このモードはしばしば"HTTP close"モードと呼ばれ、HTTPトランザクションの数だけ接続が確立されます。レスポンスの後にサーバーが接続を閉じるので、クライアントはコンテンツ長を知る必要がなく、接続が閉じられた時点でレスポンスが完了したと判断します。これは、ネットワークエラーによってレスポンスの一部が切り詰められた場合でも、クライアントがレスポンスを完全だと誤認しうることを意味します。かつてはこのため、途中までしかない画像が画面に表示されることがありました。
プロトコルがトランザクションを単位としていることを利用し、連続する二つのトランザクションの間で接続を閉じないように改良できました。ただし、このモードではクライアントが無期限に待ち続けないよう、サーバーは各レスポンスのコンテンツ長を必ず示さなければなりません。そのために、特別なヘッダー"Content-length"を使用します。このモードは"keep-alive"モードと呼ばれ、HTTP/1.1で登場しました(一部のHTTP/1.0エージェントも対応しています)。複数のリクエストで再利用される接続は「持続的接続」と呼ばれます。
このモードの利点は、トランザクション間の遅延を減らせること、サーバー側で必要な処理能力が少なくなること、切り詰められたレスポンスを検出できることです。通常はcloseモードより高速ですが、常にそうとは限りません。一部のクライアントは同時接続数を少なく制限することが多く、その分、ネットワーク接続の悪さを補いにくくなるためです。また、一部のサーバーは次のリクエストが来る可能性を考えて長時間接続を維持する必要があり、接続数の多さからメモリ使用量が増えることがあります。一方、早く閉じすぎると、ちょうど接続を閉じた時点で到着したリクエストが失敗することがあります。
このモードではレスポンスのサイズを事前に知る必要があるため、動的に生成したコンテンツや圧縮したコンテンツでは常に利用できるわけではありません。このため、別のモードとして"chunked mode"が実装されました。送信側は全体のサイズを一度に通知する代わりに、すでにバッファーにあるレスポンスの次の「チャンク」のサイズだけを通知し、サイズがゼロのチャンクを使って任意の時点で終了できます。このモードではContent-Lengthヘッダーを使用しません。
通信に関するもう一つの改良はパイプラインモードです。引き続きkeep-aliveを使用しますが、クライアントは最初のレスポンスを待たずに二番目のリクエストを送信します。これは、ページを構成する多数の画像を取得する場合に役立ちます。
連続するリクエスト間のネットワーク遅延をなくせるため、性能に非常に大きな利点をもたらすことは明らかです。しかし、HTTPではレスポンスを対応するリクエストに関連付ける方法がないため、多くのHTTPエージェントはパイプラインを正しくサポートしていません。このため、サーバーはリクエストを受信した順序とまったく同じ順序で応答しなければなりません。実際には、さまざまなクライアントが何度か導入を試みた後、一部のサーバーでの信頼性の低さから完全に使われなくなりました。ただし、サーバーにはこの機能のサポートが義務付けられています。
次の改良は、HTTP/2とHTTP/3に実装されている多重化モードです。このモードでは、複数のトランザクション(リクエストとレスポンスの組)を単一の接続上で並列に送信し、それぞれが互いに独立して自身の速度で進行します。多重化プロトコルでは、同じ接続上で並行して行われる通信を表すため、「ストリーム」という新しい概念が導入されました。通常、各ストリームには接続内で一意の識別子を割り当て、両端がこれを使ってデータの受け渡し先を判断します。クライアントが同じ接続上で多数(最大100、場合によってはそれ以上)のストリームを並行して開始し、サーバーに処理を振り分けさせ、準備できたレスポンスから任意の順序で応答させることはよくあります。多重化モードの主な利点は、ラウンドトリップ数を大幅に減らし、遅延の大きいネットワークでページの読み込み時間を短縮することです。多数の画像を使うサイトで、すべての画像が並行して読み込まれるように見えることがあります。
これらのプロトコルは、回線上のバイト数を減らすためにヘッダーフィールドを圧縮する仕組みを採用し、効率も高めています。そのため、適切なツールなしでは、HTTP/1のように手で操作したり目で読んだりすることは現実的ではありません。この理由により、文献(この文書を含む)にあるHTTPメッセージの各種例では、新しいバージョンのプロトコルでも引き続きHTTP/1の構文を使って表現しています。
HTTP/2にはいくつかの設計上の制約があります。たとえば、パケットの損失がすべてのストリームに同時に影響します。また、クライアントがオブジェクトの取得に時間をかけすぎると(たとえばディスクへの保存が必要な場合)、その取得が遅くなり、その間は後ろで待機するデータにアクセスできなくなることがあります。これは"head of line blocking"、“HoL blocking”、または単に"HoL"と呼ばれます。
HTTP/3はQUIC上に実装され、QUIC自体はUDP上に実装されています。QUICはストリームを独立して処理することで、トランスポート層のhead of line blockingを解決します。実際、損失が発生しても、影響を受けたストリームが他のストリームに影響することはなく、すべてに並行してアクセスできます。QUICは接続マイグレーションもサポートしますが、現在haproxyはこれをサポートしていません。
HAProxyは、持続的接続についてデフォルトでkeep-aliveモードで動作します。接続ごとに各リクエストとレスポンスを処理し、レスポンスの終了から新しいリクエストの開始までの間、両側の接続をアイドル状態に保ちます。クライアントからHTTP/2接続を受け取ると、すべてのリクエストを並行して処理し、keep-aliveのHTTP接続と同じように、接続をアイドル状態にして新しいリクエストを待ちます。
HAProxyは基本的に3つの接続モードをサポートします。
-
keep alive:すべてのリクエストとレスポンスを処理し、クライアント側とサーバー側の接続を新しいリクエストに備えて維持します。これがデフォルトで、現在のWebとプロトコル(HTTP/2およびHTTP/3)に適しています。
-
server close:レスポンスの後にサーバー側の接続を閉じます。
-
close:レスポンスの終了後、両側の接続を能動的に閉じます。
これに加えて、HTTPプロトコル仕様で要求されるとおり、デフォルトでは、サーバー側の接続はどのクライアントのどのリクエストでも再利用できます。そのため、特定のクライアントに関する情報が必要な場合は、各リクエストと一緒に渡さなければなりません(クライアントの送信元アドレスなど)。サーバーとの通信でHTTP/2を使用する場合、HAProxyはデフォルトでその接続を同じクライアント専用にし、クライアント間でhead of line blockingが起こる危険を避けます。
1.2. 用語
HAProxy内の用語は、HTTPプロトコルとその用途の変化に合わせ、長年の間に少し変化してきました。当初は接続、セッション、ストリーム、トランザクションに大きな違いはありませんでしたが、現代のHTTPプロトコルに存在するものに近づけるよう、徐々に明確になりました。ただし、過去との互換性を保つため、一部の用語は設定やコマンドラインインターフェースに残っています。
以下は現在のHAProxyバージョンに適用される定義です。
-
connection(接続):接続は、リモートエージェント(クライアントまたはサーバー)とhaproxyの間にある、可能な限り低い層の単一の双方向通信チャネルです。通常は、IPとポートの組の間で確立されたTCPソケットに相当します。クライアント側では、クライアントがhaproxyに接続したときに最初に作成されるエンティティが接続であり、接続レベルのルールが最も早い段階で適用されます。
-
session(セッション):セッションは、接続に関連するコンテキスト情報を加えます。これには、トランスポート層固有の情報(TLSキーなど)や変数が含まれます。この用語はHAProxy内で長く、両端間のエンドツーエンドのHTTP/1.0通信を指すために使われてきました。そのため、現在はストリームを表していても、一部のCLIコマンドや統計の名前にはこの用語が残っていますが、ヘルプメッセージや説明では曖昧にならないようにしています。ネットワークレベルの用語(OS内のTCPセッションや、ファイアウォールを通過するTCPセッションなど)や、HTTP以外のユーザーレベルのアプリケーション(telnetセッションやSSHセッションなど)では、今でも適切な用語です。Cookieにユーザーの完全なコンテキストを保存し、同じサーバーへ送信する必要がある「アプリケーションセッション」と混同してはいけません。
-
stream(ストリーム):ストリームは、解析や変換を適用できるアプリケーションレベルのエンドツーエンドの双方向通信に厳密に対応します。HTTPでは、一つのリクエストと対応するレスポンスを含み、リクエストの到着時に作成され、レスポンスの配信終了時に完了します。この文脈では、このストリームと多重化プロトコルのストリームの間には1:1の関係があります。TCP通信では、接続ごとにストリームは一つです。
-
transaction(トランザクション):トランザクションは、リクエストとそれに対応するレスポンスの組だけを指します。ストリーム以前はセッションと組み合わせて使われていましたが、現在はトランザクションとストリームの間に1:1の関係があります。主に変数のスコープ"txn"に現れ、このスコープはトランザクション全体、したがってストリーム全体で有効です。
-
request(リクエスト):クライアントからサーバーへ流れるトラフィックを指します。主にHTTPで、操作を行う場所を示すために使います。この用語はTCPの操作でも、データを処理する場所を示すために使われます。リクエストは、トラフィックや活動の単位としてカウンターによく現れます。常にレスポンスを伴うとは限りませんが(エラーなどのため)、リクエストなしにレスポンスが自発的に発生することはないため、全体の活動を示す指標として有用です。TCPでは、リクエストの数は接続数と同じです。
-
response(レスポンス):サーバーからクライアントへ流れるトラフィックを指します。HAProxy自身がレスポンスを生成する場合(HTTPリダイレクトなど)には、HAProxyからクライアントへ流れるトラフィックを指すこともあります。
-
service(サービス):通常、統計ページ、キャッシュ、小さなアプリケーションを実装するLuaコードなど、サーバーを必要としないHAProxy内部の処理を指します。サービスは通常、リクエストを読み取り、何らかの操作を行い、レスポンスを生成します。
1.3. HTTPリクエスト
まず、このHTTPリクエストを考えます。
1.3.1. リクエスト行
1行目が「リクエスト行」です。常に3つのフィールドで構成されます。
- METHOD:GET
- URI:/serv/login.php?lang=en&profile=2
- バージョンタグ:HTTP/1.1
これらはすべて、標準でLWS(linear white spaces)と呼ばれる文字で区切ります。通常はスペースですが、タブ、または改行/復帰の後にスペース/タブが続くものでも構いません。メソッド自体にコロン(’:’)を含めることはできず、英字だけに制限されます。こうしたさまざまな組み合わせがあるため、複雑な、あるいは不正確な正規表現をユーザーに書かせるより、HAProxy自身で分割することが望まれます。
URI自体にはいくつかの形式があります。
- 「相対URI」:
- 「絶対URI」、別名「URL」:
-
アスタリスク(’*’):この形式はOPTIONSメソッドと組み合わせた場合にのみ受け入れられ、中継できません。次のホップの機能を問い合わせるために使います。
-
アドレス:ポートの組み合わせ:192.168.0.12:80。これはCONNECTメソッドで使います。このメソッドはHTTPプロキシ経由でTCPトンネルを確立するためのもので、通常はHTTPSに使いますが、他のプロトコルに使うこともあります。
相対URIには二つの部分があります。疑問符の前の部分を「パス」と呼びます。通常、サーバー上の静的オブジェクトへの相対パスです。疑問符の後の部分を「クエリ文字列」と呼びます。主に動的なスクリプトへ送るGETリクエストで使われ、使用する言語、フレームワーク、アプリケーションに大きく依存します。
HTTP/2とHTTP/3はリクエストにバージョン情報を含めないため、バージョンは下位のプロトコルと同じもの(つまり"HTTP/2")とみなします。また、これらのプロトコルはリクエスト行をひとまとまりで送信せず、名前がコロンで始まる「疑似ヘッダー」と呼ばれる個々のフィールドに分割します。HAProxyは、扱いやすいようにこれらを同等のリクエスト行へ再構成します。このため、ログ内のリクエスト行はHTTP/1.xとHTTP/2またはHTTP/3で少し異なる場合があります。
1.3.2. リクエストヘッダー
ヘッダーは二行目から始まります。行頭の名前と、その直後のコロン(’:’)で構成されます。慣例ではコロンの後にLWSを置きますが、必須ではありません。その後に値が続きます。同じヘッダーが複数ある場合は、値の順序を保つ限り、カンマで区切って一行にまとめられます。これは"Cookie:“フィールドでよく見られます。後続行がLWSで始まる場合、ヘッダーを複数行にまたがらせることもできます。1.3の例では、4行目と5行目が"Accept:“ヘッダーの合計3つの値を定義しています。最後に、仕様どおり、ヘッダーの先頭または末尾にあるLWSはすべて無視され、値には含まれません。
よくある誤解とは異なり、ヘッダー名は大文字と小文字を区別しません。他のヘッダー名を参照する値(“Connection:“ヘッダーなど)も同様です。HTTP/2とHTTP/3では、デバッグモードで実行すると確認できるように、ヘッダー名は常に小文字で送信されます。内部ではすべてのヘッダー名を小文字に正規化し、HTTP/1.xとHTTP/2またはHTTP/3でまったく同じ表現を使用し、反対側にはそのまま送信します。このため、キャメルケースで入力したHTTP/1.xリクエストも小文字で届きます。
ヘッダーの終わりは、最初の空行で示します。よく二重改行と呼ばれますが、二重改行は空行の有効な形式の一つにすぎず、厳密な表現ではありません。
幸い、HAProxyはヘッダーのインデックス作成、値の検査、個数のカウントの際に、これらの複雑な組み合わせをすべて処理します。そのため、どのような書き方ができるかを心配する必要はありません。ただし、珍しくても正当な動作をするアプリケーションを、バグがあると決めつけないことが重要です。
重要な注意:
1.4. HTTPレスポンス
HTTPレスポンスはHTTPリクエストと非常によく似ています。どちらもHTTPメッセージと呼びます。このHTTPレスポンスを考えます。
特別なケースとして、HTTPはステータスコード1xxの、いわゆる「情報レスポンス」をサポートします。これらはレスポンスの内容を一切運ばず、たとえばクライアントにリクエストの送信継続を求める、一種の通知メッセージとしてのみ使われる点が特殊です。ステータス100のレスポンスの場合、要求された情報は、その情報レスポンスの後に続く、次の100以外のレスポンスメッセージで運ばれます。つまり、一つのリクエストに複数のレスポンスを送信でき、これはkeep-aliveを有効にした場合にのみ機能します(1xxメッセージはHTTP/1.1で登場しました)。HAProxyはこれらのメッセージを処理し、正しく転送して読み飛ばし、次の100以外のレスポンスだけを処理できます。そのため、明示的に別の指定がない限り、これらのメッセージはログに記録されず、変換もされません。ステータス101のメッセージは、同じ接続上でプロトコルが変わり、CONNECTが発生した場合と同じようにHAProxyがトンネルモードへ切り替える必要があることを示します。この場合、Upgradeヘッダーには切り替え先のプロトコルの種類に関する追加情報が含まれます。
1.4.1. レスポンス行
1行目が「レスポンス行」です。常に3つのフィールドで構成されます。
- バージョンタグ:HTTP/1.1
- ステータスコード:200
- 理由:OK
ステータスコードは常に3桁です。最初の桁は全般的な状態を示します。
- 1xx = 読み飛ばす情報メッセージ(例:100、101)
- 2xx = OK、後にコンテンツが続く(例:200、206)
- 3xx = OK、後にコンテンツは続かない(例:302、304)
- 4xx = クライアントに起因するエラー(例:401、403、404)
- 5xx = サーバーに起因するエラー(例:500、502、503)
一部のエージェントが内部状態を報告するためにログへ出力することはありますが、通信では599を超えるステータスコードを送信してはいけません。各コードの詳しい意味はRFC9110を参照してください。HTTP/2以降にはバージョンタグがなく、":status"疑似ヘッダーでステータスコードを伝えます。
“reason"フィールドは単なる手掛かりであり、クライアントは解析しません。何が入っていても構いませんが、広く定着したメッセージに従うのが一般的です。“OK”、“Found”、“Authentication Required"など、一語または複数の語で構成できます。HTTP/2以降には存在せず、送信されません。HTTP/2以降のレスポンスをHTTP/1クライアントに送信する場合、HAProxyはステータスコードに対応する、このような一般的なreasonフィールドを生成します。
HAProxy自身が出力することのあるステータスコードは次のとおりです。
上記のエラーコード4xxと5xxはカスタマイズできます(セクション4.2 の"errorloc"を参照)。特定のアクションによって、別のステータスコードを意図的に出力することもできます(たとえば、セクション4.3 の"deny”、“return”、“redirect"アクションを参照)。
1.4.2. レスポンスヘッダー
レスポンスヘッダーはリクエストヘッダーとまったく同じように機能するため、HAProxyは両方に同じ解析関数を使います。詳しくは1.3.2を参照してください。
11 - 2. HAProxyの設定
2.1. 設定ファイルの形式
HAProxyの設定では、主に3つのパラメーター源を使います。
- コマンドライン引数。常に優先されます。
- 設定ファイル。その形式をここで説明します。
- 実行中のプロセスの環境。環境変数を明示的に参照した場合に使います。
設定ファイルは、いくつかの基本規則に従う、比較的単純な階層形式です。
単純で信頼できる設定生成器を書くには、これだけ知っていれば十分です。ただし、あらゆる設定を確実に解析したり、特殊なケースへの対処方法を判断したりするには不十分です。
まず、上記の規則からいくつかのことが導かれます。規則6と7から、新しいセクションを定義するキーワードはどこでも有効であり、特定のセクション内で別の意味を持つことはできません。これらのキーワードは、複数の語の並びではなく、常に単一の語です。慣例として、その後に続くセクションも同じ名前で呼びます。たとえば「globalセクション」とは、“global"キーワードに続く設定のセクションを指します。この呼び方は、修正が必要な箇所を見つけやすくするため、エラーメッセージで頻繁に使います。
多くのセクションは、他のものと区別する必要がある内部オブジェクトや設定空間を作成します。その場合は、そのセクションの名前を設定する追加の語を取ります。セクションによっては名前が必須です。たとえば"frontend foo"は、“frontend"型で"foo"という名前の新しいセクションを作成します。通常、名前はセクションの型ごとに扱われるため、異なる型の二つのセクションで同じ名前を使えます。ただし、設定管理が複雑になりがちなので推奨しません。
規則7から直接導かれるのは、複数のファイルを一度に読み込む場合、各ファイルは新しいセクションで始めなければならず、各ファイルの末尾でセクションが終わるということです。ファイルにサブセクションを含めることはできず、既存のセクションを終わらせて新しいセクションを始めることもできません。
規則1では、順序が重要であると述べました。実際、一部のキーワードは、繰り返し指定することで、一定の順序で適用するルールの並びを作るディレクティブを生成します。たとえば"tcp-request"では、さまざまな条件の"accept"ルールと"reject"ルールを交互に並べられます。したがって、設定ファイルを処理するプログラムは、編集時にセクション内の順序を必ず維持しなければなりません。通常、セクション同士の順序は重要ではありませんが、globalセクションだけは他のセクションより前に置く必要があります。必要ならglobalセクションを繰り返すことはできます。また、作成するオブジェクト(プロキシなど)の一部には識別子が自動的に割り当てられるため、セクションの順序を変えると識別子も変わります。これらは統計などに現れます。したがって、次の設定では"foo"に"bar"より小さいIDを割り当てます。二つのセクションを逆にすると、IDの大小も逆になります。
もう一つ重要なのは、上記の規則2と3により、空行、空白、タブ、保護されていない”#“の後のコメントは、区切りとして使うだけで、設定そのものには含まれないことです。つまり、次の設定は厳密に同等です。
および:
一般的には、新しいセクションを開始するキーワードだけを左端に置き、他のすべてのキーワードはインデントします(タブまたはいくつかの空白を先頭に付けます)。これにより、同じセクションに属することがすぐ分かります(上記の二番目の例のように)。新しいセクションの前にコメントを置くと、読者が探しているセクションかどうかを判断しやすくなります。セクション末尾の空行も、編集時に終わりを視覚的に見つけやすくします。
タブはインデントに便利ですが、コピーと貼り付けがうまくいかない場合があります。代わりに空白を使う場合は、自動インデントに対応しない制約のあるエディターでも現場での編集が負担にならないよう、多くしすぎず2~4個にすることを推奨します。
初期には、ほとんどのキーワードが二つを超える引数を取らなかったため、引数を一定のタブ位置で揃える書き方が一般的でした。複雑な式を使う現在のバージョンには適さず、推奨しません。
2.2. 引用とエスケープ
現在の設定では、以前は単なる区切りとみなしていた文字を、引数内で使う必要があります。そのため、HAProxyは、対象文字の前にバックスラッシュ(’\’)を置く文字エスケープ、テキストを二重引用符("")で囲む弱い引用、単一引用符(’’)で囲む強い引用をサポートします。
これは多くのプログラミング言語の処理に似ており、Bourneシェルでよく見る動作に非常に近いものです。原則は次のとおりです。設定パーサーは行を語に分割しながら、引用符とバックスラッシュも考慮し、文字が区切りなのか、現在の語の中の文字そのものなのかを判断します。その後、エスケープ文字と引用符を除去し、残った語を、たとえばキーワードや引数としてそのまま使います。
語の中でバックスラッシュが必要な場合は、バックスラッシュ自身でエスケープする(二重のバックスラッシュにする)か、強い引用で囲まなければなりません。
引用符の外では、特殊文字の前にバックスラッシュ(’\’)を置いてエスケープします。
また、一部の表示できない文字は、通常のC言語表現で出力できます。
弱い引用では、保護する文字または文字列を二重引用符("")で囲みます。弱い引用は、次の解釈を防ぎます。
弱い引用の中では、ドル記号(’$’)を前に付けると環境変数を解釈できます(引用符の外では評価しません)。二重引用符の中でドル文字そのものが必要な場合は、バックスラッシュでエスケープしなければなりません。
強い引用では、保護する文字または文字列を単一引用符(’’)で囲みます。単一引用符の中では何も解釈しないため、正規表現を引用する効率的な方法です。
以上をまとめると、各文脈で特殊文字を入力する方法は次の表になります(表示できない文字は、山括弧で囲んだ名前で示します)。エスケープでしか表現できない一部の文字は、単一引用符の中では表現できないため、その欄は空です。
例:
二段階目の引用やエスケープが必要になる特殊なケースがあります。一部のキーワードは丸括弧内に引数を取り、ときにはカンマで区切ります。引数は通常、整数や定義済みの語ですが、任意の文字列である場合、引数に含まれる文字と、引数自体を区切る文字を区別するため、別の段階のエスケープが必要になることがあります。よくある例が"regsub"コンバーターです。引数に正規表現を取るため、その中に閉じ丸括弧が必要なら、それ自体を引用する必要があります。
キーワードの引数パーサーの引用処理は、最上位のパーサーとまったく同じですが、\#、\$、\xNNのエスケープは処理しません。ただし、内部で使う区切りを最上位で解決しないよう、まずエスケープまたは引用する必要があることは、必ずしも明らかではありません。
正規表現、置換文字列、フラグ集合という3つの引数を取る"regsub"コンバーターの例を見てみます。
ここでは特別な引用は不要でした。しかし、“foo"または"bar"を"blah"に置き換えるには、正規表現”(foo|bar)“が必要です。次のようには書けません。
文字列を次のように分割したいからです。
ところが、実際に渡されるのは、開き丸括弧と閉じ丸括弧の間の文字列と、その後の不要な文字列です。
明らかな解決策は閉じ丸括弧を引用することに見えますが、それだけでは動作しません。前述のとおり、この語を処理する前に、最上位のパーサーが引用符を処理して解決してしまうためです。
したがって、二段階目の引数パーサーにとっては何も変わりません。切り詰められた正規表現が唯一の引数となり、文字列末尾には不要な文字が残ります。引用符をエスケープすると、そのまま二段階目に渡せます。
別の方法は、文字列全体の外側に単一引用符、内側に二重引用符を使うことです(二重引用符が再び除去されないようにします)。
ただし、この場合、上位の文字列に埋め込まれた区切りは単なる文字となり、区切りではなくなることに注意が必要です。特に、カンマの前後の空白やタブは文字列の一部になります。次の例には複数の誤りがあります。
カンマの前後に空白を置くだけで、その空白がフィールド自体に含まれます。そのため、コンバーター名が空白で始まる” regsub"になり、見つからずエラーになります。さらに分かりにくい点として、置換文字列” blah"は出力に空白を挿入します。式の中に不要な空白を入れないことが、よい目安です。
正規表現を使う場合、式にドル文字(’$’)が現れたり、置換文字列にバックスラッシュ(’\’)を使ったりすることがあります。その場合、二重引用符の中でも処理されるため、単一引用符を推奨します(または二重にエスケープします)。例:
単一引用符の中ではバックスラッシュはエスケープ文字ではなく、上記の語全体は、すでに単一引用符でその処理から保護されていることを忘れないでください。逆に、式全体を二重引用符で囲むと、ドル文字とバックスラッシュが最上位で解決され、二段階目の引数内容が壊れます。
残念ながら、強い引用の中では単一引用符をエスケープできないため、引数に単一引用符を含めるには、二重にエスケープまたは引用する必要があります。いくつかの方法があります。
迷ったら、まずどこにも引用符を使わず、カンマや閉じ丸括弧を必要とする引数を単一引用符または二重引用符で囲んでください。文字列にドルやバックスラッシュを含むなら、その引用符をバックスラッシュでエスケープすることを検討します。これも、Bourneシェルで"eval"に渡すコマンドを二重にエスケープする方法とよく似ています。APIを作成する場合は、内容に関係なく、すべての引数をエスケープした引用符で囲む方法が最善でしょう。利用者にとっては、式全体を単一引用符、各引数を二重引用符で囲むと、設定が読みやすくなるでしょう。
2.3. 環境変数
HAProxyの設定は環境変数をサポートします。変数は二重引用符の中でのみ解釈し、設定の解析時に展開します。Bourneシェルと同様、変数名の前にはドル(”$")が必須で、任意で波括弧("{}")で囲めます。変数名には英数字と下線("_")を使えますが、数字で始めるべきではありません。変数に空白で区切った複数の値が入っている場合は、波括弧で囲み、閉じ波括弧の前に接尾辞’[*]‘を付けることで、個々の引数へ展開できます。また、変数名の後のダッシュ’-‘に続けて値を指定すると、変数が設定されていない場合のデフォルト値になります。デフォルト値で置き換えるのは存在しない変数だけであり、空の変数ではない点に注意してください。
例:
HAProxyが定義し、設定ファイルで使える変数もあります。次の表に示す変数は、四つのカテゴリーに分類します。
-
使用可能:設定からアクセスし、そのまま解決するか、条件ブロックや述語で設定の一部を有効・無効にするために使えます。セクション2.4 「条件ブロック」で説明します。
-
変更可能:設定の"setenv"/“unsetenv"キーワードで、再定義または解除できます。
-
表示:管理ガイドのセクション9.3 「Unixソケットコマンド」で説明するCLIの"show env"出力に表示されます。
さらに、下表でそれぞれ’M’と’W’で示す"master"と"worker"の二つの下位カテゴリーがあります。HAProxyをマスターワーカーモードで起動した場合の、二つのプロセスの違いを示します。
-
master:マスタープロセスで変数が設定され、アクセスできます。したがって、マスターCLIの"show env"出力に現れ、条件ブロックやディレクティブでマスター固有の設定を有効にするために使えます(セクション2.4 「条件ブロック」の例を参照)。
-
worker:ワーカープロセスで変数が設定され、アクセスできます。ワーカーCLIの"show env”(またはマスターCLIの"@1 show env")に現れ、ワーカープロセスのパラメーターを条件付きで設定するためにも使えます(セクション2.4 「条件ブロック」の例を参照)。
単独モード("-W"オプションも"master-worker"キーワードもない場合)では、プロセスはワーカーと同様に振る舞います。ただし、“HAPROXY_MASTER_CLI"と"HAPROXY_MWORKER"は定義しません。
一部の変数は、使用も変更もできないものとして示しています。
- HAPROXY_CFGFILES
- HAPROXY_MWORKER
- HAPROXY_CLI
- HAPROXY_MASTER_CLI
- HAPROXY_LOCALPEER
これらの値は設定解析時には未定義で、その後の初期化で設定します。したがって、条件ブロックで使わず、globalセクションの"setenv”/“resetenv”/“unsetenv"キーワードで参照しないことを推奨します。
各動作モードにおける変数の状態を次の表にまとめます。
対象の変数は次のとおりです。
-
HAPROXY_LOCALPEER:プロセスの起動時に定義し、ローカルピアの名前を保持します(管理ガイドの”-L"を参照)。
-
HAPROXY_CFGFILES:HAProxyが読み込んだ設定ファイルの一覧で、セミコロンで区切ります。ディレクトリーを指定した場合に便利です。
-
HAPROXY_HTTP_LOG_FMT:セクション8.2.3 「HTTPログ形式」で定義するデフォルトのHTTPログ形式の値を保持します。元の定義全体をコピーせずに、デフォルトのログ形式を上書きできます。
-
HAPROXY_HTTP_CLF_LOG_FMT:セクション8.2.3 「HTTPログ形式」で定義するデフォルトのHTTP CLFログ形式の値を保持します。元の定義全体をコピーせずに、デフォルトのログ形式を上書きできます。
例:
-
HAPROXY_HTTPS_LOG_FMT:HAPROXY_HTTP_LOG_FMTに似ていますが、セクション8.2.4 「HTTPSログ形式」で定義するHTTPSログ形式用です。
-
HAPROXY_TCP_LOG_FMT:HAPROXY_HTTP_LOG_FMTに似ていますが、セクション8.2.2 「TCPログ形式」で定義するTCPログ形式用です。
-
HAPROXY_TCP_CLF_LOG_FMT:HAPROXY_HTTP_CLF_LOG_FMTに似ていますが、セクション8.2.2 「TCPログ形式」で定義するTCP CLFログ形式用です。
-
HAPROXY_KEYLOG_FC_LOG_FMT:フロントエンド(クライアント側)のTLS接続のキーログ形式を保持します。キーのエントリーは改行で区切るため、syslogサーバーと互換性がない場合があります。“tune.ssl.keylog on"が必須です。
-
HAPROXY_KEYLOG_BC_LOG_FMT:HAPROXY_KEYLOG_FC_LOG_FMTに似ていますが、バックエンド(サーバー側)のTLS接続用です。キーのエントリーは改行で区切るため、syslogサーバーと互換性がない場合があります。“tune.ssl.keylog on"が必須です。
-
HAPROXY_MWORKER:マスターワーカーモードでは、値を1に設定します。
-
HAPROXY_CLI:各プロセスの統計ソケットに設定したリスナーのアドレスです。セミコロンで区切ります。
-
HAPROXY_MASTER_CLI:マスターワーカーモードにおけるマスターCLIのリスナーのアドレスです。セミコロンで区切ります。
-
HAPROXY_STARTUP_VERSION:起動に使ったバージョンを保持します。マスターワーカーモードでは、バイナリを更新してリロードした後も、マスターの起動に使ったバージョンです。
-
HAPROXY_BRANCH:HAProxyのブランチバージョン(“2.8"など)を保持します。完全なバージョン番号ではありません。マップや証明書などのリソースを、ブランチ番号を含むパスに置く場合、移行時に便利です。
さらに、一部の疑似変数は内部で解決し、通常の変数と同様に使えます。疑似変数は必ずドット(’.’)で始まり、ドットを使える唯一の変数です。現在の疑似変数は次のとおりです。
-
.FILE:現在解析中の設定ファイルの名前。
-
.LINE:現在解析中の設定ファイルの行番号。一から始まります。
-
.SECTION:現在解析中のセクションの名前。名前のないセクションでは型(“global"など)、最初のセクションより前では空文字列です。
これらの変数は、解析する場所で解決します。たとえば、defaultsセクション内の"log-format"ディレクティブで”.LINE"変数を使うと、“log-format"を解析・コンパイルする前に行番号を解決するため、その後のプロキシでは同じ行番号を再利用します。
この方法で、変数、ログ、エラーステータス、ヘルスチェック、ヘッダー値にルールの場所を示す情報を出力できます。行番号を使って、サーバーなどの設定オブジェクトに名前を付けることもできます。
2.4. 条件ブロック
設定の任意の部分を、条件に応じて有効・無効にできると便利な場合があります。たとえば、SSLや暗号を切り替える、設定を変更せずに本番前のリスナーを切り替える、移行時に異なる二つのHAProxyバージョンに対応するよう設定構文を調整する場合です。HAProxyには、テキストのブロックを取り込むか無視するかを指定する、入れ子にできるプリプロセッサー風のディレクティブがあります。これらは独立した行に置かなければならず、後に続く行に作用します。二つは式を取り、それ以外は別のブロックへ切り替えるか、現在の階層を終了するだけです。条件ブロックを構成する次の4つのディレクティブを定義しています。
- .if
<condition> - .elif
<condition> - .else
- .endif
“.if"は新しい階層を開始し、".elif"と”.else"は同じ階層にとどまり、".endif"は階層を閉じます。各”.if"は、対応する”.endif"で終えなければなりません。".elif"を置けるのは”.if"または”.elif"の後だけで、連続する".elif"の数に制限はありません。各".if"に置ける".else"は一つだけで、必ずそのブロックの".if"または最後の".elif"より後に置かなければなりません。
必要なら、同じ行の’#‘の後にコメントを置けます。コメントは無視します。これらのディレクティブも他の設定ディレクティブと同様にトークンへ分割するため、条件の中で環境変数を使えます。
条件は、起動時に-ccパラメーターで評価することもできます。管理ドキュメントの「3. HAProxyの起動」を参照してください。
条件は空文字列(偽を返します)、または次の要素を任意に組み合わせた式です。
- 整数のゼロ(‘0’)。常に"false"を返します。
- ゼロでない整数(‘1’など)。常に"true"を返します。
- 述語。任意で、丸括弧内に引数を続けます。
- 丸括弧’(‘と’)‘で囲んだ条件。
- 上記の空でない要素の前に置く感嘆符(’!’)。その真偽を反転します。
- 論理AND(’&&’)で結合した式。いずれかが偽を返すまで、左から右へ評価します。
- 論理OR(’||’)で結合した式。いずれかが真を返すまで、右から左へ評価します。
設定言語の他の部分と同じ行トークナイザーと引数パーサーを使います。引用されていない一つ以上の連続した空白やタブで語を分割し、評価の前に、単一の空白を区切りとして再結合します。利用者が行全体を引用しなくて済むようにするためです。ただし、これはカンマや丸括弧の前後の空白も確実に値の一部になることを意味し、必ずしも期待どおりではありません。たとえば、次の式は、
変数" HAPROXY_MWORKER “(空白を含む)の存在を確認します。また、次の式は、
環境変数"ENABLE_SSL"を値” 1"(先頭に空白一つ)と比較します。これは、まず行を次のように語へ分割するためです。
次に弱い引用を適用し、環境変数"$ENABLE_SSL"を解決します(たとえばENABLE_SSL=0とします)。最後に、語の間に単一の空白を置いて、一つの文字列に再結合します。
その後で初めて、単一の式として解析します。カンマと"1"の間に挿入した空白は、引数の値の一部として残り、この引数を" 1"にします。
ここから分かるように、ENABLE_SSLが"1"であっても、空白一つ分だけ文字列が異なるため、" 1"にはマッチしません。
注意:「2.2. 引用とエスケープ」で説明したとおり、式の中に不要な空白を入れないことが、よい目安です。
他の言語と同様、AND演算子はOR演算子より優先されるため、“A && B || C && D"は”(A && B) || (C && D)“として評価します。
現在サポートする述語は次のとおりです。
-
awslc_api_atleast(
<ver>):現在のawslc API番号が<ver>以上なら真、それ以外は偽を返します。例:awslc_api_atleast(35) -
awslc_api_before(
<ver>):現在のawslc API番号が<ver>より厳密に古ければ真、それ以外は偽を返します。例:awslc_api_before(26) -
defined(
<name>):環境変数<name>が存在すれば、内容に関係なく真を返します。 -
feature(
<name>):“haproxy -vv"が報告する機能一覧に、<name>が存在すると示されていれば(’+‘の後に<name>が現れれば)、真を返します。 -
openssl_version_atleast(
<ver>):現在のopensslバージョンが<ver>以上なら真、それ以外は偽を返します。LibreSSL、AWS-LC、WolfSSLなどのライブラリも、疑似OpenSSLバージョンを提供します。例:
-
openssl_version_before(
<ver>):現在のopensslバージョンが<ver>より厳密に古ければ真、それ以外は偽を返します。LibreSSL、AWS-LC、WolfSSLなどのライブラリも、疑似OpenSSLバージョンを提供します。例:openssl_version_before(3.5.0) -
ssllib_name_startswith(
<name>):HAProxyをリンクしたSSLライブラリ名が<name>で始まれば、真を返します。例:ssllib_name_startswith(wolfSSL) -
streq(
<str1>,<str2>):二つの文字列が等しい場合にのみ、真を返します。 -
strneq(
<str1>,<str2>):二つの文字列が異なる場合にのみ、真を返します。 -
strstr(
<str1>,<str2>):最初の文字列の中に二番目の文字列が見つかった場合にのみ、真を返します。 -
version_atleast(
<ver>):現在のhaproxyバージョンが<ver>以上なら真、それ以外は偽を返します。バージョン構文は"haproxy -v"の表示と同じで、省略された要素はゼロとみなします。 -
version_before(
<ver>):現在のhaproxyバージョンが<ver>より厳密に古ければ真、それ以外は偽を返します。バージョン構文は"haproxy -v"の表示と同じで、省略された要素はゼロとみなします。 -
enabled(
<opt>):実行時にオプション<opt>が有効なら、真を返します。一部のオプションだけをサポートします。
例:
状態を報告するため、さらに四つのディレクティブがあります。
- .diag “message”:診断モード(-dD)の場合にのみ、このメッセージを出力します。
- .notice “message”:このメッセージをNOTICEレベルで出力します。
- .warning “message”:このメッセージをWARNINGレベルで出力します。
- .alert “message”:このメッセージをALERTレベルで出力します。
WARNINGレベルのメッセージは、“zero-warning"が有効な場合、プロセスの起動を失敗させることがあります。ALERTレベルのメッセージは、常に致命的エラーを引き起こします。これらを使って、不適切な条件を検出し、利用者へ助言できます。
例:
2.5. 時間の形式
タイムアウトなど、一部のパラメーターは時間を表す値を取ります。明示的に別の指定がない限り、通常はミリ秒ですが、数値の後に単位を付けると、他の単位でも表せます。各キーワードの説明で繰り返さないので、この点に注意してください。次の単位をサポートします。
- us:マイクロ秒。1マイクロ秒 = 1/1000000秒
- ms:ミリ秒。1ミリ秒 = 1/1000秒。デフォルトです。
- s:秒。1s = 1000ms
- m:分。1m = 60s = 60000ms
- h:時間。1h = 60m = 3600s = 3600000ms
- d:日。1d = 24h = 1440m = 86400s = 86400000ms
2.6. サイズの形式
帯域制限など、一部のパラメーターはサイズを表す値を取ります。明示的に別の指定がない限り、通常はバイトですが、数値の後に単位を付けると、他の単位でも表せます。各キーワードの説明で繰り返さないので、この点に注意してください。次の単位をサポートし、大文字と小文字は区別しません。
- k:キロバイト。1キロバイト = 1024バイト
- m:メガバイト。1メガバイト = 1048576バイト
- g:ギガバイト。1ギガバイト = 1073741824バイト
時間とサイズのどちらの形式も整数が必須で、小数表記は使えません。
2.7. マップとACLの名前の形式
マップやACLには、パターンの一覧を使えます。パターン一覧は名前で識別し、設定のさまざまな場所で使えます。名前の形式により、三つのカテゴリーに分かれます。
-
通常ファイルに基づくパターン一覧:デフォルトの形式です。絶対パスまたは相対パスのファイル名を名前として使います。ファイルは存在しなければならず、なければエラーになりますが、空でも構いません。接頭辞"file@“も指定できますが、一覧を識別する名前の一部には含まれません。接頭辞の有無にかかわらず、同じファイル名は同じパターン一覧を参照します。
-
任意ファイルに基づくパターン一覧:ファイル名の前に接頭辞"opt@“が必須です。ファイルの存在は任意です。存在すれば内容を読み込みますが、存在しなくてもエラーを報告しません。接頭辞は、一覧を識別する名前の一部には含まれません。つまり、同じファイル名なら、任意ファイルと通常ファイルは同じパターン一覧を参照します。
-
仮想ファイルに基づくパターン一覧:名前は単なる識別子で、どのファイルも参照しません。接頭辞"virt@“が必須で、名前の一部になります。したがって、他の種類の一覧と混在させることはできません。
仮想ファイルは、パターンを完全に動的に管理し、起動時やリロード時にはパターンがない場合に便利です。任意ファイルも同じ条件で使えます。ただし、たとえばCLIの"show map"コマンドを使う外部スクリプトにより、パターンをファイルへ書き出せます。これにより、リロード時にもパターンを保持できます。
注意:まれなケースですが、“file@"、“opt@"、“virt@“で始まる通常ファイルを読み込むには、ファイル名の前に明示的に”./“を付ける必要があります(たとえば"file@./virt@map”)。
2.8. 変数
HAProxyの設定では、サンプル取得関数、コンバーター、ログ形式文字列、TCP/HTTPアクションで変数を使えます。プロセス全体の生存期間を通じてグローバルにアクセスできる、プロセス単位の変数を定義できます。それより寿命の短い変数もあります。変数はシェルスクリプトの変数と同様、メモリ領域に付けた記号名です。変数のサイズに制限はなく、動的に割り当てます。したがって、特に大量に使う場合は注意が必要です。ただし、globalパラメーター"tune.vars"を設定すると、変数が使うメモリ量の上限を制限できます。
変数は”<scope>.<name>“の形式で指定しなければなりません。<scope>は、変数の生存期間を示す単一の語です。スコープ内の<name>には、‘a-z’、‘A-Z’、‘0-9’、’_‘だけを使えます。同じスコープ内では一意ですが、異なるスコープでは同じ名前を使うことができ、それぞれ別の変数を参照します。次のスコープをサポートします。
-
proc:プロセスの生存期間全体で存在し、グローバルにアクセスできる変数です。“proc"変数は、CLIの"get var"と"set var"で操作できます。“global"セクションの"set-var"と"set-var-fmt"ディレクティブでも設定できます。
-
sess:セッションの生存期間全体で存在する変数です。“sess"変数はセッション専用で、外部から見えず、他のセッションと共有しません。
-
txn:トランザクションの生存期間全体で存在する変数です。“txn"変数はストリーム専用で、外部から見えず、他のストリームと共有しません。
-
req:特定のストリームのリクエスト処理中に存在する変数です。“req"変数は、ストリームの作成から最初のサーバー接続試行まで参照できます。ストリーム専用で、外部から見えず、他のストリームと共有しません。“req"変数と"res"変数の期間は、まったく重なりません。
-
res:特定のストリームのレスポンス処理中に存在する変数です。“res"変数は、最初のサーバー接続試行からストリームの破棄まで参照できます。ストリーム専用で、外部から見えず、他のストリームと共有しません。“req"変数と"res"変数の期間は、まったく重なりません。
-
check:ヘルスチェックの実行中に存在する変数です。“check"変数はヘルスチェック専用で、外部から見えず、他のヘルスチェックと共有しません。専用の"tcp-check"または"http-check"ディレクティブで設定できます。
文脈によっては、現在のストリームの親を参照する追加のスコープを使えます。
-
psess:“sess"と同じですが、親ストリームがあれば、そのセッションを使います。
-
ptxn:“txn"と同じですが、親ストリームがあれば、そのトランザクションを使います。
-
preq:“req"と同じですが、親ストリームがあれば、それを使います。“preq"変数へアクセスできるのは、親ストリームのリクエスト処理中だけです。
-
pres:“res"と同じですが、親ストリームがあれば、それを使います。“pres"変数へアクセスできるのは、親ストリームのレスポンス処理中だけです。
親ストリームを参照するスコープは、親を定義した時点から使えます。通常、親ストリームはありませんが、ある場合は明示的に記載します。現在は、親ストリームのスコープに定義した変数の値を取得することしかできず、設定や解除はできません。通常、子ストリームは特定の時点で親のために処理を行い、その操作が完了するまで親の進行を止めます。つまり、親はリクエスト処理やレスポンス処理の途中で停止する場合があります。そのため、子ストリームから利用できないスコープもあります。たとえば、子ストリームがリクエストを解析している場合、親はレスポンスを処理しておらず、“res"スコープの変数がないので、子は"pres"スコープに変数を見つけられません。
変数の内容はサンプル取得式を評価した結果で、その式の出力型を引き継ぎます。変数の型は用途と互換性がなければならないため、使用時にはこの点が重要です。たとえば、文字列を保持する変数を"add()“コンバーターで使うには、有効な整数へ変換できなければ成功しません。特に、変数を静的な値と比較する場合が該当します。正しいマッチング方法を使わなければなりません。
2.9. アドレスの形式
“bind”、“server”、“nameserver”、“log"などの文にはアドレスが必要です。
アドレスには、ホスト名、IPv4アドレス、IPv6アドレス、または’‘を指定できます。’‘は特殊アドレス"0.0.0.0"と同じで、“bind"や"dgram-bind"で、システムのすべてのIPv4アドレスを待ち受けるために使えます。IPv6で対応するものは’::‘です。
文によっては、IPアドレスの後にポートまたはポート範囲を続けます。‘bind’文では必須、‘server’では任意です。
アドレスはスラッシュ’/‘で始めることもできます。その場合は"unix"ファミリーとみなし、’/‘とそれ以降の文字でパスを表さなければなりません。
デフォルトのソケット型または転送方式が"datagram"か"stream"かは、そのアドレスを記載する設定文によります。‘bind’と’server’はデフォルトで"stream"ソケットを使い、’log’、’nameserver’、‘dgram-bind’は"datagram"を使います。
任意の接頭辞で、アドレスファミリー、ソケット型、転送方式の一部またはすべてを強制できます。
2.9.1. アドレスファミリーの接頭辞
‘abns@<name>’:続く<name>は抽象名前空間です(Linuxのみ)。
‘abnsz@<name>’:続く<name>はゼロ終端の抽象名前空間です(Linuxのみ)。
‘fd@<n>’:続くアドレスは、親から継承したファイルディスクリプター<n>です。fdはバインド済みでなければなりませんが、すでにリッスンしていても、していなくても構いません。
‘ip@<address>[:port1[-port2]]’:続く<address>は、構文に応じてIPv4またはIPv6アドレスとみなします。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。
‘ipv4@<address>[:port1[-port2]]’:続く<address>は、常にIPv4アドレスとみなします。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。
‘ipv6@<address>[:port1[-port2]]’:続く<address>は、常にIPv6アドレスとみなします。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。
‘sockpair@<n>’:続くアドレスは、接続済みunixソケットまたはsocketpairのファイルディスクリプターです。接続時、開始側は接続したソケットのペアを作り、その一方をFD経由で相手へ渡します。リスナーはunixソケットからFDを受け取るのを待ち、accept()が返したFDと同じように使います。慎重に使用してください。
不具合:macOSのsendmsg(2)実装の問題により、このプロトコルはmacOS上では信頼できないことが知られています。接続を正しく受け入れられない場合があります。
‘unix@<path>’:続く文字列は、UNIXソケットの<path>とみなします。スラッシュ’/‘で始まらないUNIXソケットパスを宣言するのに便利です。
2.9.2. ソケット型の接頭辞
上記の「アドレスファミリーの接頭辞」の前に、さらに接頭辞を付けて、ソケット型と転送方式を強制できます。デフォルトはアドレスを使う文によりますが、場合によっては別のものを強制できます。たとえば"log"文のデフォルトはUDP上のsyslogですが、TCP上のsyslogを強制できます。
これらの接頭辞は内部用途向けに設計したもので、利用者は代わりに、次の「2.9.3 プロトコルの接頭辞」にある別名を使うべきです。ただし、ファイルディスクリプター番号で指定する継承ソケットと組み合わせる場合などには便利です。その場合、アドレスファミリーは"fd"となり、ソケット型を宣言しなければなりません。
プロトコルの接頭辞では同じ設定を実現できず、目的の動作にこれらの接頭辞が必要な場合は、メンテナーへ報告してください。
‘stream+<family>@<address>’:ソケット型と転送方式を"stream"に強制します。
‘dgram+<family>@<address>’:ソケット型と転送方式を"datagram"に強制します。
‘quic+<family>@<address>’:ソケット型を"datagram”、転送方式を"stream"に強制します。
2.9.3. プロトコルの接頭辞
‘quic4@<address>[:port1[-port2]]’:続く<address>は常にIPv4アドレスとみなしますが、ソケット型を"datagram”、転送方式を"stream"に強制します。そのアドレスを使う文により、UDPポートまたはポート範囲の指定が任意または必須になります。“quic+ipv4@“と同じです。
‘quic6@<address>[:port1[-port2]]’:続く<address>は常にIPv6アドレスとみなしますが、ソケット型を"datagram”、転送方式を"stream"に強制します。そのアドレスを使う文により、UDPポートまたはポート範囲の指定が任意または必須になります。“quic+ipv6@“と同じです。
’tcp@<address>[:port1[-port2]]’:続く<address>は構文に応じてIPv4またはIPv6アドレスとみなしますが、ソケット型と転送方式を"stream"に強制します。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。‘stream+ip@‘の別名とみなします。
’tcp4@<address>[:port1[-port2]]’:続く<address>は常にIPv4アドレスとみなしますが、ソケット型と転送方式を"stream"に強制します。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。‘stream+ipv4@‘の別名とみなします。
’tcp6@<address>[:port1[-port2]]’:続く<address>は常にIPv6アドレスとみなしますが、ソケット型と転送方式を"stream"に強制します。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。‘stream+ipv6@‘の別名とみなします。
‘mptcp@<address>[:port1[-port2]]’:続く<address>は構文に応じてIPv4またはIPv6アドレスとみなしますが、MPTCPプロトコルで、ソケット型と転送方式を"stream"に強制します。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。
‘mptcp4@<address>[:port1[-port2]]’:続く<address>は常にIPv4アドレスとみなしますが、MPTCPプロトコルで、ソケット型と転送方式を"stream"に強制します。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。
‘mptcp6@<address>[:port1[-port2]]’:続く<address>は常にIPv6アドレスとみなしますが、MPTCPプロトコルで、ソケット型と転送方式を"stream"に強制します。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。
‘udp@<address>[:port1[-port2]]’:続く<address>は構文に応じてIPv4またはIPv6アドレスとみなしますが、ソケット型と転送方式を"datagram"に強制します。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。‘dgram+ip@‘の別名とみなします。
‘udp4@<address>[:port1[-port2]]’:続く<address>は常にIPv4アドレスとみなしますが、ソケット型と転送方式を"datagram"に強制します。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。‘dgram+ipv4@‘の別名とみなします。
‘udp6@<address>[:port1[-port2]]’:続く<address>は常にIPv6アドレスとみなしますが、ソケット型と転送方式を"datagram"に強制します。そのアドレスを使う文により、ポートまたはポート範囲の指定が任意または必須になります。‘dgram+ipv6@‘の別名とみなします。
‘uxdg@<path>’:続く文字列はunixソケットの<path>とみなしますが、転送方式を"datagram"に強制します。‘dgram+unix@‘の別名とみなします。
‘uxst@<path>’:続く文字列はunixソケットの<path>とみなしますが、転送方式を"stream"に強制します。‘stream+unix@‘の別名とみなします。
将来のバージョンでは、“datagram"型ソケット上にストリーム転送を提供するQUICなどのプロトコルを指定するため、他の接頭辞を使う可能性があります。
2.10. 例
haproxyが$PATH内にあるものとして、シェルで次のように設定をテストします。
12 - 3. globalセクション
“global” セクションのパラメーターはプロセス全体に適用され、多くはOSに依存します。通常は最初にまとめて設定し、正しく設定できれば変更する必要はありません。一部には対応するコマンドラインオプションがあります。
“global” セクションでは、次のキーワードを使用できます。
-
プロセス管理とセキュリティ
- 51degrees-allow-unmatched
- 51degrees-cache-size
- 51degrees-data-file
- 51degrees-difference
- 51degrees-drift
- 51degrees-property-name-list
- 51degrees-property-separator
- 51degrees-use-performance-graph
- 51degrees-use-predictive-graph
- ca-base
- chroot
- cluster-secret
- cpu-affinity
- cpu-map
- cpu-policy
- cpu-set
- crt-base
- daemon
- default-path
- description
- deviceatlas-json-file
- deviceatlas-log-level
- deviceatlas-properties-cookie
- deviceatlas-separator
- dns-accept-family
- expose-deprecated-directives
- expose-experimental-directives
- external-check
- fd-hard-limit
- gid
- grace
- group
- h1-accept-payload-with-any-method
- h1-case-adjust
- h1-case-adjust-file
- h1-do-not-close-on-insecure-transfer-encoding
- h2-workaround-bogus-websocket-clients
- hard-stop-after
- harden.reject-privileged-ports.tcp
- harden.reject-privileged-ports.quic
- insecure-fork-wanted
- insecure-setuid-wanted
- issuers-chain-path
- jwt.allow_none_alg
- jwt.decrypt_alg_list
- jwt.decrypt_enc_list
- key-base
- limited-quic
- localpeer
- log
- log-send-hostname
- log-tag
- lua-load
- lua-load-per-thread
- lua-prepend-path
- max-threads-per-group
- mworker-max-reloads
- nbthread
- node
- numa-cpu-mapping
- ocsp-update.disable
- ocsp-update.maxdelay
- ocsp-update.mindelay
- ocsp-update.httpproxy
- ocsp-update.mode
- pidfile
- pp2-never-send-local
- presetenv
- prealloc-fd
- resetenv
- set-dumpable
- set-var
- setenv
- ssl-default-bind-ciphers
- ssl-default-bind-ciphersuites
- ssl-default-bind-client-sigalgs
- ssl-default-bind-curves
- ssl-default-bind-options
- ssl-default-bind-sigalgs
- ssl-default-server-ciphers
- ssl-default-server-ciphersuites
- ssl-default-server-client-sigalgs
- ssl-default-server-curves
- ssl-default-server-options
- ssl-default-server-sigalgs
- ssl-dh-param-file
- ssl-propquery
- ssl-provider
- ssl-provider-path
- ssl-security-level
- ssl-server-verify
- ssl-skip-self-issued-ca
- stats
- stats-file
- strict-limits
- uid
- ulimit-n
- unix-bind
- unsetenv
- user
- wurfl-cache-size
- wurfl-data-file
- wurfl-information-list
- wurfl-information-list-separator
-
パフォーマンス調整
- busy-polling
- max-spread-checks
- maxcompcpuusage
- maxcomprate
- maxconn
- maxconnrate
- maxpipes
- maxsessrate
- maxsslconn
- maxsslrate
- maxzlibmem
- no-memory-trimming
- noepoll
- noevports
- nogetaddrinfo
- nokqueue
- noktls
- nopoll
- noreuseport
- nosplice
- profiling.memory
- profiling.tasks
- server-state-base
- server-state-file
- spread-checks
- ssl-engine
- ssl-mode-async
- tune.applet.zero-copy-forwarding
- tune.buffers.limit
- tune.buffers.reserve
- tune.bufsize
- tune.bufsize.large
- tune.bufsize.small
- tune.cli.max-payload-size
- tune.comp.maxlevel
- tune.defaults.purge
- tune.disable-fast-forward
- tune.disable-zero-copy-forwarding
- tune.epoll.mask-events
- tune.events.max-events-at-once
- tune.fail-alloc
- tune.fd.edge-triggered
- tune.h1.be.glitches-threshold
- tune.h1.fe.glitches-threshold
- tune.h1.zero-copy-fwd-recv
- tune.h1.zero-copy-fwd-send
- tune.h2.be.glitches-threshold
- tune.h2.be.initial-window-size
- tune.h2.be.max-concurrent-streams
- tune.h2.be.max-frames-at-once
- tune.h2.be.rxbuf
- tune.h2.fe.glitches-threshold
- tune.h2.fe.initial-window-size
- tune.h2.fe.max-concurrent-streams
- tune.h2.fe.max-frames-at-once
- tune.h2.fe.max-rst-at-once
- tune.h2.fe.max-total-streams
- tune.h2.fe.rxbuf
- tune.h2.header-table-size
- tune.h2.initial-window-size
- tune.h2.max-concurrent-streams
- tune.h2.max-frame-size
- tune.h2.zero-copy-fwd-send
- tune.http.cookielen
- tune.http.logurilen
- tune.http.maxhdr
- tune.idle-pool.shared
- tune.idletimer
- tune.lua.bool-sample-conversion
- tune.lua.burst-timeout
- tune.lua.forced-yield
- tune.lua.log.loggers
- tune.lua.log.stderr
- tune.lua.maxmem
- tune.lua.openlibs
- tune.lua.service-timeout
- tune.lua.session-timeout
- tune.lua.task-timeout
- tune.max-checks-per-thread
- tune.maxaccept
- tune.maxpollevents
- tune.maxrewrite
- tune.max-rules-at-once
- tune.memory.hot-size
- tune.pattern.cache-size
- tune.peers.max-updates-at-once
- tune.pipesize
- tune.pool-high-fd-ratio
- tune.pool-low-fd-ratio
- tune.pt.zero-copy-forwarding
- tune.quic.be.cc.cubic-min-losses
- tune.quic.be.cc.hystart
- tune.quic.be.cc.max-frame-loss
- tune.quic.be.cc.max-win-size
- tune.quic.be.cc.reorder-ratio
- tune.quic.be.max-idle-timeout
- tune.quic.be.sec.glitches-threshold
- tune.quic.be.stream.data-ratio
- tune.quic.be.stream.max-concurrent
- tune.quic.be.stream.rxbuf
- tune.quic.be.tx.pacing
- tune.quic.be.tx.udp-gso
- tune.quic.cc.cubic.min-losses (非推奨)
- tune.quic.cc-hystart (非推奨)
- tune.quic.disable-tx-pacing (非推奨)
- tune.quic.disable-udp-gso (非推奨)
- tune.quic.fe.cc.cubic-min-losses
- tune.quic.fe.cc.hystart
- tune.quic.fe.cc.max-frame-loss
- tune.quic.fe.cc.max-win-size
- tune.quic.fe.cc.reorder-ratio
- tune.quic.fe.max-idle-timeout
- tune.quic.fe.sec.glitches-threshold
- tune.quic.fe.sec.retry-threshold
- tune.quic.fe.sock-per-conn
- tune.quic.fe.stream.data-ratio
- tune.quic.fe.stream.max-concurrent
- tune.quic.fe.stream.max-total
- tune.quic.fe.stream.rxbuf
- tune.quic.fe.tx.pacing
- tune.quic.fe.tx.udp-gso
- tune.quic.frontend.max-data-size (非推奨)
- tune.quic.frontend.max-idle-timeout (非推奨)
- tune.quic.frontend.max-streams-bidi (非推奨)
- tune.quic.frontend.max-tx-mem (非推奨)
- tune.quic.frontend.stream-data-ratio (非推奨)
- tune.quic.frontend.default-max-window-size (非推奨)
- tune.quic.listen
- tune.quic.max-frame-loss (非推奨)
- tune.quic.mem.tx-max
- tune.quic.reorder-ratio (非推奨)
- tune.quic.retry-threshold (非推奨)
- tune.quic.socket-owner (非推奨)
- tune.quic.zero-copy-fwd-send
- tune.renice.runtime
- tune.renice.startup
- tune.rcvbuf.backend
- tune.rcvbuf.client
- tune.rcvbuf.frontend
- tune.rcvbuf.server
- tune.recv_enough
- tune.ring.queues
- tune.runqueue-depth
- tune.sched.low-latency
- tune.sndbuf.backend
- tune.sndbuf.client
- tune.sndbuf.frontend
- tune.sndbuf.server
- tune.streams-elasticity
- tune.stick-counters
- tune.ssl.cachesize
- tune.ssl.capture-buffer-size
- tune.ssl.capture-cipherlist-size (非推奨)
- tune.ssl.certificate-compression
- tune.ssl.default-dh-param
- tune.ssl.force-private-cache
- tune.ssl.hard-maxrecord
- tune.ssl.keylog
- tune.ssl.keyupdate-rate-limit
- tune.ssl.lifetime
- tune.ssl.maxrecord
- tune.ssl.ssl-ctx-cache-size
- tune.ssl.ocsp-update.maxdelay (非推奨)
- tune.ssl.ocsp-update.mindelay (非推奨)
- tune.takeover-other-tg-connections
- tune.vars.global-max-size
- tune.vars.proc-max-size
- tune.vars.reqres-max-size
- tune.vars.sess-max-size
- tune.vars.txn-max-size
- tune.zlib.memlevel
- tune.zlib.windowsize
-
デバッグ
- anonkey
- debug.counters
- force-cfg-parser-pause
- quiet
- warn-blocked-traffic-after
- zero-warning
-
HTTPClient
- httpclient.resolvers.disabled
- httpclient.resolvers.id
- httpclient.resolvers.prefer
- httpclient.retries
- httpclient.ssl.ca-file
- httpclient.ssl.verify
- httpclient.timeout.connect
3.1. プロセス管理とセキュリティ
51degrees-data-file <file path>
デバイス検出サービスを提供する51Degreesデータファイルのパスです。ファイルは解凍し、適切な権限でHAProxyからアクセスできる状態にしておくことを推奨します。
このオプションは、HAProxyをUSE_51DEGREES付きでコンパイルした場合にのみ使用できます。
51degrees-property-name-list [<string> ...]
データセットから読み込む51Degreesプロパティ名の一覧です。名前の完全な一覧は、51DegreesのWebサイトを参照してください。https://51degrees.com/resources/property-dictionary
このオプションは、HAProxyをUSE_51DEGREES付きでコンパイルした場合にのみ使用できます。
51degrees-property-separator <char>
51Degreesの結果を含むレスポンスヘッダーで、各プロパティ値の末尾に追加する文字です。未設定の場合は ‘,’ になります。
このオプションは、HAProxyをUSE_51DEGREES付きでコンパイルした場合にのみ使用できます。
51degrees-cache-size <number>
51Degreesコンバーターのキャッシュサイズを <number> エントリーに設定します。このLRUキャッシュは、過去のデバイス検出とその結果を記憶します。デフォルトでは、このキャッシュは無効です。
このオプションは、HAProxyをUSE_51DEGREES付きでコンパイルした場合にのみ使用できます。
51degrees-use-performance-graph { on | off }
検出処理でパフォーマンスグラフを使用するかどうかを、有効 (‘on’) または無効 (‘off’) に設定します。デフォルト値は51Degreesライブラリによって異なります。
このオプションは、HAProxyをUSE_51DEGREESおよび51DEGREES_VER=4付きでコンパイルした場合にのみ使用できます。
51degrees-use-predictive-graph { on | off }
検出処理で予測グラフを使用するかどうかを、有効 (‘on’) または無効 (‘off’) に設定します。デフォルト値は51Degreesライブラリによって異なります。
このオプションは、HAProxyをUSE_51DEGREESおよび51DEGREES_VER=4付きでコンパイルした場合にのみ使用できます。
51degrees-drift <number>
検出時に許容するドリフト値を設定します。
このオプションは、HAProxyをUSE_51DEGREESおよび51DEGREES_VER=4付きでコンパイルした場合にのみ使用できます。
51degrees-difference <number>
検出時に許容する差分値を設定します。
このオプションは、HAProxyをUSE_51DEGREESおよび51DEGREES_VER=4付きでコンパイルした場合にのみ使用できます。
51degrees-allow-unmatched { on | off }
検出処理で一致しないノードを使用するかどうかを、有効 (‘on’) または無効 (‘off’) に設定します。デフォルト値は51Degreesライブラリによって異なります。
このオプションは、HAProxyをUSE_51DEGREESおよび51DEGREES_VER=4付きでコンパイルした場合にのみ使用できます。
acme.scheduler { auto | off }
ACMEスケジューラーを有効または無効にします。
ACMEスケジューラーはHAProxyの起動時に開始されます。証明書を順に調べ、notAfter値が curtime + (notAfter - notBefore) / 12 を過ぎている場合、またはnotBeforeが定義されていない場合は7日を基準として、ACME更新タスクを開始します。その後、スケジューラーはスリープし、12時間後に起動します。
デフォルト値は “auto” です。
関連項目: acme
ca-base <dir>
“ca-file”、“ca-verify-file”、または “crl-file” ディレクティブに相対パスを指定した場合に、SSL CA証明書とCRLを取得するデフォルトディレクトリを指定します。“ca-file”、“ca-verify-file”、および “crl-file” に絶対パスを指定した場合は、そちらが優先され、“ca-base” は無視されます。
chroot { <jail dir> | auto }
権限を降格する前に、カレントディレクトリを <jail dir> に変更してそこでchroot()を実行します。未知の脆弱性を悪用された場合でも、攻撃者がシステムを悪用することを非常に困難にするため、セキュリティが向上します。<jail dir> が空であり、誰も書き込めないことを確認することが重要です。スーパーユーザー権限でプロセスを起動した場合は、chroot()を直接実行します。Linux上で権限を持たずに起動した場合、haproxyはunshare(CLONE_NEWUSER)で作成した新しいユーザー名前空間の内部から実行を試みます。この仕組みを利用できない場合、chroot()は通常のエラーで失敗します。
特別な指定として、<jail dir> を “auto” にできます。この場合、haproxyは名前のない一時ディレクトリを作成してリンクを削除し、その中にchrootします。作成された隔離先はファイルシステム上に名前を持たず、空で読み取り専用になるため、専用の隔離ディレクトリを用意する必要がありません。
スーパーユーザー権限で起動し、chrootを使用していない場合は、この仕組みを常に使用するよう促すため、警告を表示します。chrootを使用できないやむを得ない理由(たとえば、都合の悪いパスにあるUNIXソケット経由でサーバーにアクセスする場合)があるときは、明示的に “chroot /” を追加すれば警告を抑制できます。この方法には、その指定が設定上で確認できるという利点があります。
close-spread-time <time>
ソフト停止時に、アイドル接続とアクティブな接続の切断を分散させる時間枠を定義します。SIGUSR1を受信し、猶予期間があればその終了後、このオプションが未設定なら、アイドル接続はすべて一度に切断されます。アクティブなHTTPまたはHTTP2接続は、次のリクエストを受信した後、HTTPレスポンスに “Connection: close” 行を追加するか、HTTP2の場合はGOAWAYフレームを送信して終了します。このオプションを設定すると、接続の切断は指定した <time> にわたって分散されます。close-spread-timeを “infinite” に設定すると、ソフト停止時のアクティブな接続の切断が無効になります。HTTPレスポンスに “Connection: close” ヘッダー(HTTP2ではGOAWAY)が追加されなくなり、アイドル接続はタイムアウトに達したときにだけ切断されます(設定で指定した各種タイムアウトに基づきます)。
引数:
“hard-stop-after” オプションを使用する場合は、プロセスが停止する前にすべての接続が正常に終了できるよう、この設定値を “hard-stop-after” の値より小さくすることを推奨します。
関連項目: grace, hard-stop-after, idle-close-on-response
cluster-secret <secret>
同じクラスターに属する複数のノード間で共有する、ASCII文字列のシークレットを定義します。さまざまな用途に使用できます。少なくとも、このプロセスが生成するすべてのQUIC接続のステートレスリセットトークンの導出に使用されます。Retryトークンを暗号化するシークレットの導出にも使用されます。
このパラメーターを設定しない場合、プロセスの起動時にランダムな値が選ばれます。これにより、この値に依存する機能を、一定の制限付きで使用できます。
cpu-map [auto:]<thread-group>[/<thread-set>] <cpu-set>[,...] [...]
一部のOSでは、スレッドグループやスレッドを特定のCPUセットにバインドできます。これは、指定したスレッドがほかのCPUで実行されなくなることを意味します。“cpu-map” ディレクティブは、個々のスレッドまたはスレッドグループにCPUセットを指定します。最初の引数はスレッドグループの範囲で、必要に応じてその後にスレッドセットを指定します。範囲は次の形式で表します。
<number> は、マシンのワードサイズに応じて1から32または64までの数値でなければなりません。’thread-groups’ を超えるグループIDと、マシンのワードサイズを超えるスレッドIDは無視されます。スレッド番号はすべて、所属するグループ内での相対番号です。このような2つの数値をダッシュ (’-’) で区切って範囲を指定できます。“thread” bindディレクティブと同様に、“all” ですべてのスレッドをまとめて、“odd” で奇数番号だけを、“even” で偶数番号だけを指定することもできます。2番目以降の引数はCPUセットです。各CPUセットには、最初のCPUを0とする単一の番号、またはこのような2つの番号をダッシュ (’-’) で区切った範囲を指定します。CPU番号や範囲は、コンマで区切るか、同じ行に別の引数として追加の範囲を渡すことで、複数指定できます。LinuxおよびBSD以外のOSでは、CPUインデックスの最大値が31または63に制限されることがあります。複数の “cpu-map” ディレクティブを指定できますが、範囲が重なる場合は、後の “cpu-map” ディレクティブが前の指定を置き換えます。
範囲を部分的に定義し、上限を省略することもできます。この場合、マシンのワードサイズに応じた最大値である32または64が上限になります。
スレッドセットの前にプレフィックス “auto:” を付けると、HAProxyがスレッドとCPUセットを順に進めながら、スレッドの集合をCPUに自動でバインドします。有効な指定にするには、両方の集合の要素数が同じでなければなりません。CPUセットの宣言順序にかかわらず、下限から上限に向かってバインドされます。“auto:” プレフィックスとともにグループとスレッドの両方に範囲を指定することはできません。範囲を指定できるのは一方だけで、もう一方は固定の番号でなければなりません。
グループの範囲指定は、歴史的な理由からサポートされています。現在では、番号だけを指定するとスレッドグループを表し、thread-groupsを使用していない場合は1でなければなりません。また、スレッドグループを使用せずにスレッドの範囲や番号を指定する場合は、その前に “1/” を付ける必要があります。なお、“1” は “1/all” と完全に同じ意味で、グループ内のすべてのスレッドを表します。
例:
cpu-affinity <affinity>
スレッドをCPUにバインドする方法を定義します。現在、次の値を指定できます。
- per-core: 各スレッドを、1つのコアのすべてのハードウェアスレッドにバインドします。
- per-group: 各スレッドを、グループ内のすべてのハードウェアスレッドにバインドします。“cpu-policy” で “threads-per-core 1” を使用していない場合のデフォルトです。“per-group” には、CPUの割り当て方法を指定する任意の引数を追加できます。CPUの一覧がグループごとに許可される最大CPU数を超え、複数のグループに分割する必要がある場合、追加のオプションでグループをそれらのCPUにバインドする方法を選べます。
- auto: 各スレッドグループには、そのグループ専用でほかのグループとは共有しない、連続したCPUコアを公平に割り当てます。通常はより効率的なため、これがデフォルトです。
- loose: 各グループが、一覧内のどのCPUも引き続き使用できます。通常は競合が増えますが、同じCPUで動作するほかの負荷に、よりうまく対処できる場合があります。
- auto: “cpu-policy” で “threads-per-core 1” を使用している場合は “per-core”、それ以外の場合は “per-group” を使用します。これがデフォルトです。
- per-thread: 1つのスレッドを1つのハードウェアスレッドだけにバインドします。“cpu-policy” で “threads-per-core 1” を使用している場合、各スレッドはそれぞれ異なるコアの1つのハードウェアスレッドにバインドされます。
- per-ccx: 各スレッドを、1つのCCX内のすべてのハードウェアスレッドにバインドします。
cpu-policy <policy> [threads-per-core 1 | auto]
使用するCPU割り当てポリシーを選択します。
複数CPUのシステムでは、パフォーマンス、レイテンシー、コスト、システム全体のリソース管理など、利用可能なCPUコアをすべて使用しない理由や、別々のスレッドグループにまとめる理由が数多くあります。“cpu-set” ディレクティブで一部を除外できますが、その後、残りのCPUをスレッドとスレッドグループにどう割り当てるかを決める必要があります。
この対応付けは通常 “cpu-map” ディレクティブで行いますが、異なる種類のCPUが混在するシステムでは、保守が特に難しくなることがあります。
“cpu-policy” ディレクティブは、“cpu-map” を使用していない場合に、代わりに使用する割り当てポリシーをいくつかの候補から選びます。現在は次のポリシーをサポートしており、デフォルトは “performance” です。
-
none: 特別な追加選択は行いません。有効なCPUをすべて使用できます。スレッド数が未設定の場合は、利用可能なCPU数に設定しますが、スレッドグループごとに、32ビットシステムでは32、64ビットシステムでは64を超えないようにします。スレッドグループ数が未設定の場合は1に設定します。
-
efficiency: 後述の “group-by-ccx” と同じですが、性能がすぐ下の種類のコアより25%を超えて高いコアからなるCPUクラスターを除外します。通常は “big” コアや “performance” コアが該当します。つまり、複数の種類のCPUコアを検出した場合は、効率のよい種類だけを使用します。負荷が中程度で、最も高性能なコアをアプリケーションやセキュリティコンポーネントで使えるようにしておく必要がある場合に有効です。最近のCPUには、このような高効率のCPUコアを多数備え、消費電力を抑えながら、全体として十分な性能を発揮できるものがあります。
-
first-usable-node: 起動時にCPUがあらかじめ制限されておらず(たとえば “taskset” ユーティリティによる制限)、“nbthread” ディレクティブも未設定の場合、有効なCPUが存在する最初のNUMAノードを使用し、そのCPU数をスレッド数として使用します。システムに応じて32または64という上限の範囲内で、それらすべてを含む単一のスレッドグループを有効にします。
-
group-by-2-ccx: 後述の “group-by-ccx” と同じですが、2つのCCXごとにグループを作成します。コア数の少ないCCXを多数持つCPUで、グループが増えすぎるのを避けたり、全コアを使用しない場合の分布を少し均したりするのに役立つことがあります。CCX間の通信が遅い場合、性能に非常に悪い影響を与える可能性があります。一般には推奨しません。
-
group-by-2-clusters: “group-by-cluster” と同じですが、2つのクラスターごとにグループを作成します。コア数の少ないクラスターを多数持つCPUで、グループが増えすぎるのを避けたり、全コアを使用しない場合の分布を少し均したりするのに役立つことがあります。クラスター間の通信が遅い場合、性能に非常に悪い影響を与える可能性があります。一般には推奨しません。
-
group-by-3-ccx: 後述の “group-by-ccx” と同じですが、3つのCCXごとにグループを作成します。コア数の少ないCCXを多数持つCPUで、グループが増えすぎるのを避けたり、全コアを使用しない場合の分布を少し均したりするのに役立つことがあります。CCX間の通信が遅い場合、性能に非常に悪い影響を与える可能性があります。一般には推奨しません。
-
group-by-3-clusters: “group-by-cluster” と同じですが、3つのクラスターごとにグループを作成します。コア数の少ないクラスターを多数持つCPUで、グループが増えすぎるのを避けたり、全コアを使用しない場合の分布を少し均したりするのに役立つことがあります。クラスター間の通信が遅い場合、性能に非常に悪い影響を与える可能性があります。一般には推奨しません。
-
group-by-4-ccx: 後述の “group-by-ccx” と同じですが、4つのCCXごとにグループを作成します。コア数の少ないCCXを多数持つCPUで、グループが増えすぎるのを避けたり、全コアを使用しない場合の分布を少し均したりするのに役立つことがあります。CCX間の通信が遅い場合、性能に非常に悪い影響を与える可能性があります。一般には推奨しません。
-
group-by-4-clusters: “group-by-cluster” と同じですが、4つのクラスターごとにグループを作成します。コア数の少ないクラスターを多数持つCPUで、グループが増えすぎるのを避けたり、全コアを使用しない場合の分布を少し均したりするのに役立つことがあります。クラスター間の通信が遅い場合、性能に非常に悪い影響を与える可能性があります。一般には推奨しません。
-
group-by-ccx: “nbthread” と “nbtgroups” のどちらも未設定の場合、利用可能なCPUを持つCPUコアコンプレックス (“CCX”) ごとにスレッドグループを作成し、それぞれにCPU数と同じ数のスレッドを作成します。CCXは、最終レベルキャッシュ (“LLC”)、通常はL3キャッシュへのアクセスが同程度に速いCPUをまとめたものです。最近のほとんどのマシンでは、離れたCCXのCPUを同じスレッドグループに混在させないことが、性能上きわめて重要です。グループ内の全スレッドを、そのCCXのすべてのCPUにバインドすることで、バインドを厳密にしすぎずに、グループ内通信をCCX内に収めます。グループごとのスレッド数の上限とスレッドグループ数の上限は守られます。マルチソケットシステムやNUMAシステム、CCX間のレイテンシーが大きいCPUで推奨します。
-
group-by-cluster: “nbthread” と “nbtgroups” のどちらも未設定の場合、利用可能なCPUを持つCPUクラスターごとにスレッドグループを作成し、それぞれにCPU数と同じ数のスレッドを作成します。グループ内の全スレッドを、そのクラスターのすべてのCPUにバインドすることで、バインドを厳密にしすぎずに、グループ内通信をクラスター内に収めます。グループごとのスレッド数の上限とスレッドグループ数の上限は守られます。マルチソケットシステムやNUMAシステム、CCX間のレイテンシーが大きいCPUで推奨します。ほとんどのサーバーマシンではクラスターとCCXは同じですが、異種CPUが混在するマシン(“performance” と “efficiency”、または “big” と “little”)では、一般にクラスターはCCXの一部で、非常によく似たCPUだけ(種類が同じで、周波数差が最大 +/-5%)から構成されます。この違いは、開発者や管理者が構成を検証するために使用する最近のノートPCやデスクトップマシンで確認できます。
-
performance: 前述の “group-by-ccx” と同じですが、性能がすぐ上の種類のコアの80%未満であるコアからなるCPUクラスターを除外します。通常は “little” コアや “efficient” コアが該当し、これらを追加しても大きな改善は得られず、簡単に逆効果になることがあります(TLSハンドシェイクなど)。多くの場合、このようなコアはネットワーク処理などの別のタスクに残しておく方がはるかに効果的です。開発用システムでは、負荷生成ツールや監視ツールなどの補助ツールにも使用できます。これがデフォルトのポリシーです。
-
resource: 前述の “group-by-cluster” と同じですが、最も小さく効率のよいCPUクラスターだけを使用し、ほかはすべて無視します。十分な性能を維持しつつ、リソース使用量を必要最小限に抑えるために使用できます。たとえば、消費電力をさらに減らしたり、レンタルシステムのサイドカー構成で必要なコア数を最小限にして、システムをより容易に縮小したりする用途です。クラスターが1つしかない場合は、それをすべて使用します。
任意のキーワード “threads-per-core” を追加できます。指定できる値は “1” と “auto” の2つです。1に設定すると、コアのハードウェアスレッド数にかかわらず、コアごとに1つのスレッドだけを作成します。autoに設定すると、ハードウェアスレッドごとに1つのスレッドを作成します。アフィニティーが未指定でthreads-per-core 1を使用する場合、デフォルトのアフィニティーはper-coreになります。
関連項目: “cpu-map”, “cpu-set”, “nbthread”
cpu-set <directive>...
実行するCPUの集合を記号的に記述できます。このディレクティブは次のキーワードをサポートします。- reset: サービスマネージャーや “taskset” コマンドなどから継承した既存の制限をすべて解除します。- drop-cpu <set>: この集合に含まれるCPUにはバインドしません。- only-cpu <set>: この集合に含まれないCPUにはバインドしません。- drop-node <set>: このNUMAノードに属するCPUにはバインドしません。- only-node <set>: このNUMAノードに属さないCPUにはバインドしません。- drop-cluster <set>: このハードウェアクラスター番号のCPUにはバインドしません。- only-cluster <set>: ほかのハードウェアクラスター番号のCPUにはバインドしません。- drop-core <set>: このハードウェアコア番号のCPUにはバインドしません。- only-core <set>: ほかのハードウェアコア番号のCPUにはバインドしません。- drop-thread <set>: このハードウェアスレッド番号のCPUにはバインドしません。- only-thread <set>: ほかのハードウェアスレッド番号のCPUにはバインドしません。関連項目: “cpu-policy”
crt-base <dir>
“crtfile” または “crt” ディレクティブに相対パスを指定した場合に、SSL証明書を取得するデフォルトディレクトリを指定します。絶対パスを指定した場合は、そちらが優先され、“crt-base” は無視されます。
daemon
プロセスをforkしてバックグラウンドに移します。これが推奨される動作モードです。コマンドライン引数 “-D” と同じです。コマンドライン引数 “-db” で無効にできます。systemdモードでは、このオプションは無視されます。
default-path { current | config | parent | origin <path> }
デフォルトでは、HAProxyは相対パスで指定されたすべてのファイルを、プロセスを起動した場所から読み込みます。状況によっては、すべての相対パスの起点を別の場所に変更し、その場所でプロセスを起動したかのように扱いたいことがあります。このディレクティブはそのためのものです。内部的には、各設定ファイルの処理中に指定した場所へ一時的にchdir()し、各ファイルの処理後に元のディレクトリに戻ります。スラッシュ (’/’) で始まらないパスのファイルを読み込む際のポリシーを、引数で指定します。- “current” は、相対パスのファイルをすべて、プロセスを起動したディレクトリから読み込むことを示します。これがデフォルトです。
- "config" は、相対パスのファイルをすべて、設定ファイルがあるディレクトリから読み込むことを示します。具体的には、設定ファイルのパスにスラッシュ ('/') が含まれる場合、最後のスラッシュまでの最長の部分を移動先ディレクトリとして使用し、それ以外の場合はカレントディレクトリを使用します。このモードは、マップ、エラーファイル、証明書、Luaスクリプトを、移動可能なパッケージとしてまとめるのに便利です。複数の設定ファイルを読み込む場合は、それぞれについてディレクトリを更新します。
- "parent" は、相対パスのファイルをすべて、設定ファイルがあるディレクトリの親ディレクトリから読み込むことを示します。具体的には、設定ファイルのパスにスラッシュ ('/') が含まれる場合、最後のスラッシュまでの最長の部分に ".." を追加したものを移動先ディレクトリとして使用し、それ以外の場合は ".." を使用します。このモードは、マップ、エラーファイル、証明書、Luaスクリプトを移動可能なパッケージとしてまとめつつ、各要素を別々のサブディレクトリ("config/"、"certs/"、"maps/" など)に置く場合に便利です。
- "origin" は、相対パスのファイルをすべて、指定した必須のパスから読み込むことを示します。同じシステムで異なるHAProxyインスタンスを並行して実行し、インスタンスごとに異なるプレフィックスを使用しながら、ほかのセクションを容易に移動できるようにしている場合、管理を簡単にするために使用できます。
“default-path” ディレクティブは、直前までの指定をただちに置き換え、別のディレクトリへの移動を伴う場合があります。これによって常に意図した動作になるはずですが、複数のdefault-pathディレクティブを使用することは好ましい方法ではありません。使用する場合は、すべての設定ファイルでポリシーを統一するべきです。
警告: マップや証明書などの一部の設定要素は、設定したパスによって一意に識別されます。移動可能な配置にすると、複数の要素が同じ一意名を持つ可能性があり、実行時の更新が難しくなります。特に、異なるディレクトリから複数の設定ファイルを読み込む場合に問題になります。相対パスを採用する前に、衝突を起こさない厳密なファイル命名規則を守ることが不可欠です。堅牢な方法として、すべてのファイル名にそれぞれのサイト名をプレフィックスとして付けるか、ディレクトリ単位で同様にすることが考えられます。
description <text>
インスタンスを説明するテキストを追加します。
一部の文字(# など)はエスケープが必要です。また、このテキストはhtmlページに挿入されるため、"<" と “>” の使用は避けることを推奨します。
deviceatlas-json-file <path>
APIが読み込むDeviceAtlas JSONデータファイルのパスを設定します。パスは有効なJSONデータファイルを指し、HAProxyプロセスからアクセスできなければなりません。
deviceatlas-log-level <value>
APIが返す情報のレベルを設定します。このディレクティブは任意で、未設定の場合のデフォルトは0です。
deviceatlas-properties-cookie <name>
リクエストでDeviceAtlasのクライアント側コンポーネントを使用した場合に、検出に使うクライアントCookieの名前を設定します。このディレクティブは任意で、未設定の場合のデフォルトはDAPROPSです。
deviceatlas-separator <char>
APIのプロパティ結果に使う区切り文字を設定します。このディレクティブは任意で、未設定の場合のデフォルトは | です。
dns-accept-family <family>[,...]
デフォルトでは、DNSリゾルバーはIPv4とIPv6の両方のアドレスを受け入れます。server行の “resolve-prefer” キーワードや “do-resolve” アクションのfamily引数で優先度を変えられますが、これは優先度にすぎず、もう一方のファミリーしかない場合にその使用を禁止するものではありません。デュアルスタックを使用できない環境では、到達不能なIPv6だけのDNSレコードに遭遇すると、次のリクエストまで機能し続けた可能性のある従来のIPv4レコードが置き換えられるため、大きな問題を引き起こすことがあります。グローバルオプション “dns-accept-family” では、一方(または両方)のアドレスファミリーだけを使用するよう強制できます。引数は次の単語をコンマで区切った一覧です。- “ipv4”: IPv4アドレス(“A” レコード)を問い合わせ、受け入れます。- “ipv6”: IPv6アドレス(“AAAA” レコード)を問い合わせ、受け入れます。- “auto”: IPv4を使用し、IPv6については、システムにそのデフォルトゲートウェイがあれば使用します。最後の確認結果は30秒間キャッシュされます。
一方のファミリーだけを使用する場合、もう一方のファミリーについてリゾルバーにリクエストを送信せず、そのファミリーの応答はすべて無視します。3.3以降のデフォルト値は “auto” で、IPv6でルーティングできることを確認できた場合にだけ両方のファミリーを有効にし、それ以外の場合はIPv4だけを使用します。関連項目: “resolve-prefer”, “do-resolve”
expose-deprecated-directives
非推奨とされた一部のディレクティブを使用する前に、この文を記述しなければなりません。これにより、警告を抑制し、設定ファイルが拒否されないようにします。すべての非推奨ディレクティブが対象ではなく、代替手段がないものだけが対象です。
expose-experimental-directives
実験的とされたディレクティブを使用する前に、この文を記述しなければなりません。そうしないと設定ファイルは拒否されます。このオプションの対象となる機能は、正常な動作が保証されず、保守期間中に動作しなくなる可能性があります。開発者は次のバージョンの開発中、ベストエフォートで保守し、機能を壊さないよう合理的な努力を尽くしますが、保証はしません。このため、これらの機能は次のLTSリリースの公開後までサポートされることを想定していません。実験的な機能を試すユーザーは、その機能の改善を利用できるよう、速やかにアップグレードすることが期待されます。このディレクティブがまだ必要かどうかは簡単に確認できます。有効にしていても対象の機能で使用されていない場合は、無効にするよう勧める警告が出ます。したがって、警告がなければ、まだ必要であることを意味します。
external-check [preserve-env]
外部エージェントによるヘルスチェックを許可します。セキュリティ上の予防措置として、デフォルトでは無効です。有効にしても、“insecure-fork-wanted” も有効にしないと、チェックが失敗することがあります。起動したプログラムがsetuid実行ファイルを使用する場合(本来は使用すべきではありません)、globalセクションで “insecure-setuid-wanted” も設定する必要があるかもしれません。デフォルトでは、チェックは、backendセクションの “external-check” コマンドで定義した変数だけを含む、初期化された環境で開始します。ただし、複雑なスクリプトが追加のパスや情報を環境から取得する場合など、環境を保持したいこともあります。その場合は “preserve-env” キーワードを追加します。ただし、この場合はチェックプログラムが攻撃にさらされる可能性があるため、setuidでも特権ユーザーとしても実行しないことを強く推奨します。詳細は “option external-check”、“insecure-fork-wanted”、および “insecure-setuid-wanted” を参照してください。
fd-hard-limit <number>
システムの制限にかかわらず、プロセスが使用するファイルディスクリプター数の最大値に上限を設定します。“ulimit-n” と “maxconn” で値を強制できますが、それらが未設定の場合、プロセスは “ulimit -n -H” で報告されるRLIMIT_NOFILE設定のハードリミットに制限されます。しかし、最近のOSには、ここにきわめて大きな値(10億程度)を許容するものがあり、通常の用途ではRAMを消費しすぎてしまいます。fd-hard-limit設定は、この上限をより低く制限するために用意されています。つまり、システムが課す上限が <number> より低ければ常にそれに従い、システムの上限が高ければ指定した値を使用します。fd-hard-limitのデフォルト値は1048576です。このデフォルトは、コンパイル時変数DEFAULT_MAXFDで変更できます。RLIMIT_NOFILEのハードリミットがきわめて大きい場合、この値をシステム(カーネル)の最大上限として使用できます。globalセクションでfd-hard-limitを設定すると、ビルド時にDEFAULT_MAXFDで指定した値を一時的に上書きできます。次の例ではほかの設定を指定しておらず、maxconn値は “fd-hard-limit” とRLIMIT_NOFILEの上限のうち、小さい方に自動的に合わせられます。
関連項目: ulimit-n, maxconn
gid <number>
プロセスのグループIDを <number> に変更します。このグループIDは、HAProxy専用、または同種の少数のデーモンだけで使用することを推奨します。HAProxyは、このグループに属するユーザー、またはスーパーユーザー権限で起動しなければなりません。補助グループを持つユーザーからHAProxyを起動した場合、それらのグループを外せるのは、スーパーユーザー権限で起動した場合だけです。“group” と “uid” も参照してください。
grace <time>
SIGUSR1から実際のソフト停止までの遅延時間を定義します。
引数:
これは、haproxyプロセスを停止する必要がある一方、リスナーのバインドを解除する前に、外部コンポーネントが状態を検出する必要のある従来の環境との互換性のために使用します。内部の “stopping” 変数(“stopping” サンプル取得関数が報告する変数)をtrueにしますが、遅延時間が経過するまで、リスナーはそれまでどおり接続の受け入れを続けます。その後、通常のソフト停止を実行します。リロードされるプロセスで使用してはなりません。古いプロセスがバインドを解除できなくなり、新しいプロセスの起動を妨げたり、ほかの問題を引き起こしたりする可能性があるためです。
例:
より柔軟で長期的にも使える方法として、オーケストレーションシステムがCLIからグローバル変数を設定し、その変数を外部チェックへの応答に使用して、一定時間後にSIGUSR1シグナルを送信することが考えられます。
例:
関連項目: hard-stop-after, monitor
group <group name>
“gid” と同様ですが、/etc/groupにあるグループ名 <group name> のGIDを使用します。“gid” と “user” も参照してください。
h1-accept-payload-with-any-method
ペイロードを含むHTTP/1.0のGET/HEAD/DELETEリクエストを、HTTPレスポンス413 Payload Too Largeで拒否しないようにします。
HTTP/1.1では明示的に許可されていますが、HTTP/1.0ではこの点が明確ではなく、一部の古いサーバーはペイロードを想定せず、本文の長さを(Content-LengthやTransfer-Encodingヘッダーで)調べることもありません。そのため、HTTP/1.0のGET/HEAD/DELETEリクエストのペイロードを正しく処理する中継機器がある一方で、完全に無視するものもあります。これによりリクエストスマグリング攻撃が可能となり、セキュリティ上の問題につながることがあります。したがって、デフォルトでは、HAProxyはペイロードを含むHTTP/1.0のGET/HEAD/DELETEリクエストを拒否します。
ただし、一部の古いクライアントでは、それが問題になることがあります。その場合は、このグローバルオプションを設定できます。
h1-do-not-close-on-insecure-transfer-encoding
HTTP/1.1仕様(RFC9112#6.1)が規定するように、同じメッセージにTransfer-EncodingヘッダーフィールドとContent-Lengthヘッダーフィールドの両方がある場合、上流または下流の経路のどこかにHTTP/1.0エージェントが存在すると、コンテンツスマグリング攻撃を運んでしまう重大な危険があります。この場合、悪用を防ぐために、エージェントはレスポンス後に必ず接続を切断しなければなりません。しかし、一部の非常に古いクライアントでは、特にリクエストごとにTLS接続を再ネゴシエーションする必要がある場合、性能に影響することがあります。このオプションは、この規則の強制をHAProxyに行わせず、メッセージを適切に整えるだけにして、レスポンス後も接続を維持するためのものです。これを行えるのは、経路にHTTP/1.0エージェントが存在せず、HAProxyより前にあるすべての実装が、これらのヘッダーフィールドに適用される規則についてHTTP/1.1に完全に準拠していると確実に判断できる場合だけです。いずれの場合も、HAProxyは次のホップを混乱させないよう、余分なContent-Lengthヘッダーを引き続き無視して削除します。
古い不正なクライアントやサーバーを回避するためにこのオプションを有効にする場合、このオプションが必要かどうかにかかわらず、規則に違反するエージェントのメッセージには切り詰められる危険があることを理解することが重要です。古いエージェントがContent-Lengthを参照してTransfer-Encodingを無視すると、チャンクサイズを符号化した部分の累積長が計上されないためです。このように、上記の規則はセキュリティだけの問題ではなく、古いエージェントとの非互換性によって通信に支障が出る可能性のあるエージェントを排除するためのものでもあります。
h1-case-adjust <from> <to>
有効にした場合に、HTTP/1クライアントまたはサーバーへ送信する前に、ヘッダー名 <from> を <to> に変更する大文字・小文字の調整を定義します。<from> は小文字でなければならず、<from> と <to> は大文字・小文字以外に違いがあってはなりません。複数のヘッダー名を調整する場合は、繰り返し指定できます。重複するエントリーは許可されません。多数のヘッダー名を調整する場合は、“h1-case-adjust-file” の方が便利なことがあります。プロキシで “option h1-case-adjust-bogus-client” または “option h1-case-adjust-bogus-server” を指定しない限り、変換は適用されません。
RFC7230が規定するとおり、ヘッダー名は大文字・小文字を区別しないため、標準の表記はありません。したがって、アプリケーションは大文字・小文字を区別せずに処理しなければなりません。しかし、一部の不正なアプリケーションは標準に違反し、ブラウザーで最も一般的な大文字・小文字の使い方に誤って依存しています。HTTP/2では、すべてのヘッダー名を小文字で交換しなければならないため、この問題が深刻になります。HAProxyも同じ慣例に従い、HTTPバージョンにかかわらず、すべてのヘッダー名を小文字でクライアントとサーバーに送信します。
リクエストやレスポンスを正しく処理できないアプリケーションでは、修正が済むまでの間、送信されるヘッダー名を調整するこのような回避策を、一時的に使用する必要があるかもしれません。このような回避策を必要とするアプリケーションは、コンテンツスマグリング攻撃に対して脆弱である可能性があり、必ず修正しなければなりません。
例:
“h1-case-adjust-file”、“option h1-case-adjust-bogus-client”、および “option h1-case-adjust-bogus-server” を参照してください。
h1-case-adjust-file <hdrs-file>
HTTP/1クライアントまたはサーバーに送信する前に、一部のヘッダー名の大文字・小文字を調整するための、キーと値のペアの一覧を含むファイルを定義します。ファイル <hdrs-file> には、行ごとに2つのヘッダー名を記述しなければなりません。最初の名前は小文字で、両者は大文字・小文字以外に違いがあってはなりません。’#’ で始まる行は、空行と同様に無視されます。先頭と末尾のタブとスペースは取り除かれます。重複するエントリーは許可されません。プロキシで “option h1-case-adjust-bogus-client” または “option h1-case-adjust-bogus-server” を指定しない限り、変換は適用されません。
このディレクティブを繰り返し指定した場合、最後のものだけを処理します。多数のヘッダー名を調整する場合の、“h1-case-adjust” ディレクティブの代替です。使用に伴うリスクを確認してください。
“h1-case-adjust”、“option h1-case-adjust-bogus-client”、および “option h1-case-adjust-bogus-server” を参照してください。
h2-workaround-bogus-websocket-clients
h2のWebSocketサポートをクライアントに通知しないようにします。Firefox 88など、比較的新しいRFC8441の実装に問題のあるクライアントへの対処に使用できます。クライアントがWebSocketトンネルを自動的にhttp/1.1に切り替えられるようにするには、bind行で明示的な “proto” キーワードを使わずに、“alpn” でh2のサポートを指定してください。この文が以前に有効化されていた場合は、キーワードの前に “no” を付けることで無効にできます。
hard-stop-after <time>
正常なソフト停止に許容する最大時間を定義します。
引数:
ソフト停止中に接続が開いたままでも、インスタンスが確実に終了するようにするために使用できます(たとえば、tcpモードのプロキシに長いタイムアウトを設定している場合)。TCPモードとHTTPモードの両方に適用されます。
例:
関連項目: grace
harden.reject-privileged-ports.tcp { on | off }
送信元ポートに特権ポートを使用するクライアントとの通信を禁止する保護を、プロトコルごとに切り替えます。このポート範囲はRFC 6335に従って定義されます。QUICプロトコルでは、この動作は不審であり、なりすましやDNS/NTP増幅攻撃に使われる可能性があるため、デフォルトで保護が有効です。
http-err-codes [+-]<range>[,...] [...]
終了コードとスティックテーブルの “http_err_cnt” カウンターがエラーと見なすステータスコードの一覧を、置換、縮小、または拡張します。エラーのデフォルト範囲は400から499ですが、状況によっては、特にクライアントエラーを追跡するときに、特定のコードを除外したい場合があります(動的にコンテンツを生成するシステムの404など)。“http-fail-codes” と “http_err_cnt” も参照してください。
範囲を ‘+’ も ‘-’ も付けずに指定すると、既存の範囲を新しい範囲に置き換えます。’+’ で始まる範囲は、指定した範囲も含むように既存の範囲を拡張します。指定する範囲は、既存の範囲と重なっていてもいなくてもかまいません。’-’ で始まる範囲は、既存の範囲から指定した範囲を取り除きます。範囲は100から599までの数値で表し、必要に応じて、その後に “-” と、最初の数値以上の別の数値を指定して、範囲の上限を表します。同じ追加・削除・置換操作について、複数の範囲をコンマで区切れます。
例:
http-fail-codes [+-]<range>[,...] [...]
終了コードとスティックテーブルの “http_fail_cnt” カウンターが障害と見なすステータスコードの一覧を、置換、縮小、または拡張します。障害のデフォルト範囲は、クライアントによって発生しうる501と505を除く500から599で、通常はサーバーがリクエストを処理できなかったことを示します。特定の状況で関係がないと分かっているコードは、除外したい場合があります。たとえば、一部のSOAP環境では500はサーバーの障害を意味しません。構文は、前述のhttp-err-codesとまったく同じです。“http-err-codes” と “http_fail_cnt” も参照してください。
insecure-fork-wanted
デフォルトでは、HAProxyは起動後のスレッドやプロセスの作成を徹底して防ごうとします。これは、出所が不確かなLuaファイルを使用する場合や、悪用できるか不明なバグが残っている可能性のある開発版を試す場合に、特に重要です。また一般に、トラフィックによって予期しないバックグラウンド動作が引き起こされないようにすることは、適切な運用上の配慮です。しかし、この保護によって外部チェックが動作しなくなり、forkできることに明確に依存する一部の特殊なLuaスクリプトが壊れる可能性があります。このオプションは、その保護を無効にするためのものです。無効にするとライブラリやHAProxy自体の脆弱性を悪用しやすくなるため、無効化は望ましくありません。また、Luaなどからのforkは信頼できません。forkされたプロセスが、別のスレッドが保持するロックを偶然引き継ぎ、処理を完了できなくなる可能性があるためです。そのため、このオプションは決して使用せず、そのようなforkが必要な処理を見直して、より安全な方法(外部チェックではなくエージェントを使用するなど)に移すことを強く推奨します。このオプションは、無効にするための “no” プレフィックスをサポートします。haproxyのコマンドラインで “-dI” を指定して有効にすることもできます。
insecure-setuid-wanted
HAProxyは、外部チェックを使用する場合を除き、実行時に実行ファイルを呼び出す必要はありません(外部チェックは使用しないことを強く推奨します)。さらに、空のchroot内に自身を隔離することが想定されています。そのため、ユーザーがリスクを十分に理解しないままsetuid実行ファイルの呼び出しを許可する正当な理由は、基本的にありません。HAProxyが外部チェックを呼び出したり、chrootを無効にしたりする必要がある状況では、ライブラリやHAProxy自体の脆弱性が悪用されると、外部プログラムが実行される可能性があります。Linuxでは、プロセスを制限して、そのような実行ファイルに設定されたsetuidビットを無視させることができます。これにより、そのような状況での権限昇格のリスクが大幅に減ります。HAProxyはデフォルトでこの制限を行います。これが外部チェックで問題になる場合(“ping” コマンドを必要とする場合など)は、globalセクションにこのディレクティブを明示的に追加して、保護を無効にできます。有効にした後は、前に “no” キーワードを付けて再び無効にできます。
issuers-chain-path <dir>
発行者の補完に使う証明書チェーンを読み込むディレクトリを指定します。すべてのファイルはPEM形式でなければなりません。“crt” または “crt-list” で読み込んだ証明書について、PEMに証明書チェーン(一般に中間証明書とも呼ばれます)が含まれていない場合、証明書の発行者が “issuers-chain-path” で読み込んだチェーンの最初の証明書と一致すれば、HAProxyがチェーンを補完します。PrivateKey+Certificate+IntermediateCA2+IntermediateCA1を含む “crt” ファイルは、PrivateKey+Certificateに置き換えられます。“issuers-chain-path” ディレクトリにIntermediateCA2+IntermediateCA1を含むファイルがあれば、HAProxyがチェーンを補完します。同じ発行者を持つほかのすべての証明書は、メモリ内のチェーンを共有します。
OCSP機能は、.issuerを使用していない場合やPEMにチェーンが含まれていない場合に、補完されたチェーンを使用できます。
jwt.allow_none_alg
‘jwt_verify’コンバーターで"none"アルゴリズムのJWTトークンを許可します。このオプションを設定すると、これらのトークンは常に有効とみなされます。デフォルトでは、署名のないトークンは安全でないとみなして拒否します(RFC8725のセクション3.1 を参照)。
jwt.decrypt_alg_list <list>
jwt_decrypt_XXXコンバーターで許可するアルゴリズムの一覧を設定します。未サポートまたは無効なアルゴリズムを使用するJWTトークンは、決して復号されません。指定するアルゴリズムは、RFC7518の4.1節 と同じ形式で、コロンで区切らなければなりません。特別な名前 “ALL” を使用すると、サポートされるすべてのアルゴリズムを有効にできます(完全な一覧は “jwt_decrypt_jwk” コンバーターを参照してください)。アルゴリズム名に ‘!’ を追加すると、明示的に無効にできます。“ALL” を指定しない限り、このオプションを使用すると、指定した一覧に明記されていないアルゴリズムはすべて無効になります。
例:
jwt.decrypt_enc_list <list>
jwt_decrypt_XXXコンバーターで許可する暗号化アルゴリズムの一覧を設定します。未サポートまたは無効な暗号化アルゴリズムを使用するJWTトークンは、決して復号されません。指定するアルゴリズムは、RFC7518の5.1節 と同じ形式で、コロンで区切らなければなりません。特別な名前 “ALL” を使用すると、サポートされるすべてのアルゴリズムを有効にできます(完全な一覧は “jwt_decrypt_jwk” コンバーターを参照してください)。アルゴリズム名に ‘!’ を追加すると、明示的に無効にできます。“ALL” を指定しない限り、このオプションを使用すると、指定した一覧に明記されていないアルゴリズムはすべて無効になります。
例:
key-base <dir>
“key” ディレクティブに相対パスを指定した場合に、SSL秘密鍵を取得するデフォルトディレクトリを指定します。絶対パスを指定した場合は、そちらが優先され、“key-base” は無視されます。このオプションは、crt-storeのload行でのみ機能します。
limited-quic
QUICをサポートしないバージョンのOpenSSLでhaproxyをコンパイルした場合、QUICリスナーのバインドを明示的に有効にするには、この設定を使用しなければなりません。これにより、haproxy内部の互換レイヤーが有効になります。このレイヤーは、ビルド時にUSE_QUIC_OPENSSL_COMPAT=1で選択しておかなければなりません。この互換レイヤーは、必要なTLS操作の大部分をサポートしますが、QUIC 0-RTT機能はサポートしません。
この機能は主に、QUIC APIが未実装または一部しか実装されていない、バージョン3.5.2より前のOpenSSLを対象としています。3.5.2以降でも互換レイヤーを有効にできますが、おそらく不要です。
limited-quicを設定しても、ビルド時に互換レイヤーを選択していなかった場合、このオプションは通知なく無視され、QUICのTLS操作はTLSライブラリに依存します。
localpeer <name>
ローカルインスタンスのピア名を設定します。コマンドライン引数 “-L” を指定した場合、または “peers” セクションの定義より後に使用した場合は無視されます。その場合、設定の解析中に警告メッセージが出ます。
このオプションは、環境変数HAPROXY_LOCALPEERも設定します。管理ガイドの “-L” と、後述の “peers” セクションも参照してください。
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]
グローバルなsyslogサーバーを追加します。複数のグローバルサーバーを定義できます。これらは起動と終了のログに加え、“log global” を設定したプロキシからのすべてのログを受信します。詳細は、プロキシの “log” オプションを参照してください。
log-send-hostname [<string>]
syslogヘッダーのhostnameフィールドを設定します。任意の “string” パラメーターを指定した場合はその文字列の内容を、指定しなかった場合はシステムのホスト名を使用します。一般には、中間のsyslogサーバーを経由してログを中継しない場合や、ログに出力するホスト名を単に変更したい場合に使用します。
log-tag <string>
syslogヘッダーのtagフィールドを、この文字列に設定します。デフォルトはコマンドラインから起動した際のプログラム名で、通常は “haproxy” です。同じホストで動作する複数のプロセスを区別するのに便利な場合があります。プロキシごとの “log-tag” ディレクティブも参照してください。
lua-load <file> [ <arg1> [ <arg2> [ ... ] ] ]
このグローバルディレクティブは、すべてのスレッドから見える共有コンテキストにLuaファイルを読み込んで実行します。このコンテキストで設定した変数は、どのスレッドからも見えます。Luaプログラムを読み込む最も簡単な推奨方法ですが、グローバル状態で同時に実行できるのは1つのスレッドだけなので、Luaの呼び出しが多い場合はスケールしにくくなります。この方法で読み込んだプログラムでは、“core.thread” 変数は常に0になります。このディレクティブは複数回使用できます。
ファイル本体で次のコードを使用すると、Luaファイルから引数を参照できます。Lua配列のインデックスは1から始まることに注意してください。ファイル内で宣言した “local” 変数は、そのファイル全体で使用でき、ほかのファイルからは使用できません。
local args = table.pack(...)
lua-load-per-thread <file> [ <arg1> [ <arg2> [ ... ] ] ]
このグローバルディレクティブは、起動する各スレッドにLuaファイルを読み込んで実行します。グローバル変数もスレッド内でのみ見えるため、スレッドごとに異なる値が見えることがあります。このため、この方法で読み込むプログラムでは、グローバル変数を使用しないことを強く推奨します。各スレッドに独立したコピーを読み込んで初期化し、すべてをスレッド番号1からnbthreadの順に逐次実行します。一度だけ実行する必要のある処理がある場合、プログラムで “core.thread” 変数を調べ、どのスレッドを初期化しているかを確認することを推奨します。この方法で読み込んだプログラムはすべてのスレッドで並行して動作し、非常に高いスケーラビリティーを得られます。プログラムがグローバル変数に依存しないと確認できた場合、サンプル取得、コンバーター、アクション、サービスを登録する単純な関数を読み込むための推奨方法です。簡便さのため、使用するスレッドが1つだけの場合や、スレッドを無効にしている場合でも、このディレクティブを使用できます(後者の場合はlua-loadと同等です)。このディレクティブは複数回使用できます。
引数の使用方法はlua-loadを参照してください。
lua-prepend-path <string> [<type>]
指定した文字列の後にセミコロンを付け、Luaのpackage.<type> 変数の先頭に追加します。<type> は “path” または “cpath” のいずれかでなければなりません。<type> を省略した場合のデフォルトは “path” です。
Luaのパスは、require 関数がライブラリのソースファイルを探す方法を指定するパターンを、セミコロンで区切った一覧です。パターン内の疑問符 (?) は、モジュール名に置き換えられます。パスは左から右へ評価します。したがって、後から先頭に追加したパスほど、先に調べられます。
たとえば、次のパスを指定した場合:
require "example" を呼び出すと、Luaは最初に/usr/share/haproxy-lua/example.luaスクリプトの読み込みを試みます。そのファイルがなければ/usr/share/haproxy-lua/example/init.luaを、それもなければデフォルトのパスを試みます。
詳細は、Luaドキュメントの https://www.lua.org/pil/8.1.html を参照してください。
master-worker (deprecated)
マスターワーカーモードです。コマンドライン引数 “-W” と同じです。
このキーワードは非推奨です。"-W" または “-Ws” を使用してマスターワーカーモードで起動してください。
このモードでは “master” を起動し、設定を読み込んだ後に “worker” をforkしてトラフィックを処理します。マスターは、“workers” を監視するプロセスマネージャーとして機能します。
このモードでは、マスターにSIGUSR2シグナルを送信することで、HAProxyを直接リロードできます。リロード時にはマスターが設定を再び読み込み、新しいワーカーをforkします。以前のワーカーは、処理中の仕事が完了するまで維持されます。
マスターワーカーモードは、フォアグラウンドモードとデーモンモードのどちらとも併用できます。
デフォルトでは、たとえばセグメンテーション違反などでワーカーが異常な終了コードを返して終了すると、すべてのワーカーを強制終了し、マスターも終了します。この動作をsystemdのユニットファイルのRestart=on-failureと組み合わせると、プロセス全体を再起動できて便利です。この動作が不要な場合は、“no-exit-on-failure” キーワードを使用しなければなりません。
管理ガイドの “-W” も参照してください。
master-worker no-exit-on-failure
マスターワーカーモードでは、デフォルトで、たとえばセグメンテーション違反などでワーカーが異常な終了コードを返して終了すると、すべてのワーカーを強制終了し、マスターも終了します。この動作をsystemdのユニットファイルのRestart=on-failureと組み合わせると、プロセス全体を再起動できて便利です。
このキーワードは、ワーカーがクラッシュしたときに、すべてを強制終了する代わりに、残りのプロセスを生かしておけるようにします。デバッグのみを目的としたもので、マスタープロセスを異常な状態にする可能性があるため、注意して使用する必要があります。
max-threads-per-group <number>
スレッドグループ内の最大スレッド数を定義します。“thread-groups” ディレクティブでスレッドグループ数を固定していない限り、haproxyは要求されたスレッド数を満たすのに必要な数だけスレッドグループを作成します。最小値は1、最大値は64です(64ビットシステムの場合。32ビットシステムでは32です)。小さい値は、共有状態へのアトミック操作による競合を減らしますが、すべてのリスナーの作成や、アイドル状態のバックエンド接続の保持に必要なソケット数を増やすことがあります。大きい値はこれらのコストを減らしますが、競合時のCPU使用率が高まり、接続レートが低下します。デフォルト値は16です。これは、複数のベンダーのx86_64プロセッサーや大規模なArm64システムを含むさまざまなシステムで、ベアメタルとハイパーバイザーの両方について行った実験で、最もよいバランスが得られた値です。
mworker-max-reloads <number>
マスターワーカーモードで、ワーカーがリロード後も存続できる回数を制限します。リロード後にワーカーが終了せず、リロード回数がこの値を超えた場合、そのワーカーにSIGTERMを送信します。このオプションは、ワーカー数を制御するのに役立ちます。管理ガイドの “show proc” も参照してください。
この値のデフォルトは50です。
nbthread <number>
この設定は、スレッドのサポートを組み込んでビルドした場合にのみ使用できます。HAProxyを <number> 個のスレッドで実行します。“nbthread” は、HAProxyをフォアグラウンドで起動した場合にも機能します。CPUアフィニティーをサポートする一部のプラットフォームでは、デフォルトの “nbthread” 値を、起動時にプロセスがバインドされているCPUの数に自動設定します。そのため、呼び出し元プロセスから “taskset” や “cpuset” などのコマンドを使って、スレッド数を簡単に調整できます。それ以外の場合のデフォルト値は1です。デフォルト値は “haproxy -vv” の出力に表示されます。ここで設定した値や自動検出した値には、“thread-hard-limit” が設定されていれば、その上限が適用されます。
numa-cpu-mapping
NUMAを認識するプラットフォームで実行する場合、“cpu-policy” ディレクティブがトポロジーを調べ、使用する最適なCPUの集合と対応するスレッド数を決められるようにします。ただし、特定のアーキテクチャーで適用されたバインドが最適でない場合は、’no numa-cpu-mapping’ で無効にできます。この自動バインドは、設定に ’nbthread’ がある場合、‘cpu-map’ ディレクティブやtasksetユーティリティなどでプロセスのアフィニティーをすでに指定している場合、またはcpu-policyをほかの値に設定している場合にも適用されません。“cpu-map”、“cpu-policy”、および “cpu-set” も参照してください。
ocsp-update.disable [ on | off ]
HAProxyのocsp-updateを完全に無効にします。ocsp-updateに関する設定はすべて無視されます。デフォルトは “off” です。自動更新の仕組みについては、“ocsp-update” オプションを参照してください。
ocsp-update.httpproxy <address>[:port]
OCSPの更新にHTTPプロキシを使用できるようにします。HTTPでのみ機能し、HTTPSはサポートしません。このオプションにより、OCSP更新処理が、プロキシへのリクエストで絶対URIを送信できるようになります。
ocsp-update.maxdelay <number>
同じOCSPレスポンスに対する自動更新の最大間隔を設定します。時間は秒単位で指定し、デフォルトは3600(1時間)です。“ocsp-update.mindelay” より大きい値に設定しなければなりません。自動更新の仕組みについては、“ocsp-update” オプションを参照してください。
ocsp-update.mindelay <number>
同じOCSPレスポンスに対する自動更新の最小間隔を設定します。時間は秒単位で指定し、デフォルトは300(5分)です。明示的な有効期限がないOCSPレスポンスに特に有用です。“ocsp-update.maxdelay” より小さい値に設定しなければなりません。自動更新の仕組みについては、“ocsp-update” オプションを参照してください。
ocsp-update.mode [ on | off ]
設定で使用するすべての証明書について、デフォルトのocsp-updateモードを設定します。このグローバルオプションは、crt-listの “ocsp-update” オプションで上書きできます。デフォルトは “off” です。自動更新の仕組みについては、“ocsp-update” オプションを参照してください。
pidfile <pidfile>
デーモンモードではすべてのデーモンのPIDをファイル <pidfile> に書き込み、マスターワーカーモードではマスタープロセスのPIDをファイル <pidfile> に書き込みます。このオプションは、コマンドライン引数 “-p” と同じです。ファイルは、プロセスを起動するユーザーからアクセスできなければなりません。“daemon” と “master-worker” も参照してください。
pp2-never-send-local
HAProxyのバージョン2.1まで存在したPROXYプロトコルv2実装のバグにより、ヘルスチェックでLOCALコマンドの代わりにPROXYコマンドが送信されていました。これはごく軽微な問題ですが、一部のサーバーのログを混乱させます。残念ながら、このバグの発見が遅く、PROXYプロトコル実装をHAProxyに対してしか試験していなかった可能性のある一部のサーバーが、LOCALコマンドを正しく処理できず、HAProxyによるチェックで “down” のままになることが判明しました。その場合、影響を受けるコンポーネントのベンダーに連絡して修正されるまでの間、このグローバルオプションを有効にして、以前の誤った動作に戻せます。このオプションはデフォルトで無効で、“send-proxy-v2” を指定したすべてのサーバーに作用します。
presetenv <name> <value>
環境変数 <name> を値 <value> に設定します。変数がすでに存在する場合は、上書きしません。変更はただちに有効になり、設定ファイルの次の行から新しい値を参照できます。“setenv”、“resetenv”、および “unsetenv” も参照してください。
prealloc-fd
最大のファイルディスクリプターを一度だけ開き、カーネルのデータ構造を事前に割り当てます。これにより、nbthread>1の場合に、HAProxyがファイルディスクリプターを開くためにカーネルがデータ構造を拡張する際の短い停止を防ぎます。
resetenv [<name> ...]
引数で指定したものを除き、すべての環境変数を削除します。setenvやunsetenvで新しい値を設定する前に、整理された管理可能な環境にできます。時刻を操作する関数などの内部関数に加え、OpenSSLや外部チェックも、環境変数を使用することがある点に注意してください。使用には細心の注意を払い、十分に検証した後でなければなりません。変更はただちに有効になり、設定ファイルの次の行から新しい環境を参照できます。“setenv”、“presetenv”、および “unsetenv” も参照してください。
server-state-base <directory>
先頭が ‘/’ でないすべてのサーバー状態ファイル名に付ける、ディレクトリプレフィックスを指定します。“server-state-file”、“load-server-state-from-file”、および “server-state-file-name” も参照してください。
server-state-file <file>
サーバーの状態を含むファイルのパスを指定します。パスがスラッシュ (’/’) で始まる場合は絶対パスとして扱い、それ以外の場合は、“server-state-base” が設定されていればそのディレクトリ、未設定ならカレントディレクトリからの相対パスとして扱います。HAProxyをリロードする前に、statsコマンド “show servers state” でサーバーの現在の状態を保存できます。このコマンドの出力は、<file> が指すファイルに書き込まなければなりません。起動時には、トラフィックを処理する前に、ファイルに記載され、現在の稼働設定にも存在する各サーバーの状態を、HAProxyが読み込んで適用します。“server-state-base”、“show servers state”、“load-server-state-from-file”、および “server-state-file-name” も参照してください。
set-dumpable [ on | off | libs ]
プロセスがクラッシュしたときのコアダンプの動作を選択します。使用できるオプションは次のとおりです。
-
on: コアダンプが無効になっていた場合、プロセス単位で有効にします。
-
off: 有効になっているコアダンプを無効にします。
-
libs: デバッグに必要なバイナリーとライブラリのコピーを含めて、コアダンプを有効にします。開発者からこの設定を求められることがあります。この場合、haproxyは依存するライブラリをメモリに読み込み、そのまま保持しようとします。プロセスがクラッシュすると、それらもコアに出力されるため、ファイルシステムから取得する必要がなく、コアと一致しない危険もなくなります。追加で数メガバイトから数十メガバイトのRAMを使用するため、小規模なシステムでは使わない方がよいでしょう。
このオプションは通常は無効のままとし、開発者から求められた場合にだけ有効にすることを推奨します。デフォルトでは無効です。引数を付けずに指定した場合のデフォルトは “on” です。有効にした後でも、“no” キーワードを前に付けるか “off” を指定すれば、強制的に無効にできます。パフォーマンスや安定性には影響しませんが、ファイルサイズの制限 (ulimit -f)、コアサイズの制限 (ulimit -c)、UID/GID変更後のプロセスの “dumpability”(Linuxの/proc/sys/fs/suid_dumpableなど)によって無効になっていた可能性のあるコアダンプを、できる限り再度有効にしようとします。それでも、カレントディレクトリの権限(どのディレクトリから起動しているかを確認してください)、chroot先ディレクトリの権限(chrootディレクティブを一時的に無効にするか、専用の書き込み可能な場所に変更する必要がある場合があります)、その他のシステム固有の制約によって、コアダンプが制限されることがあります。たとえば、一部のLinuxでは、デフォルトのコアファイルを、システムにインストールされてすらいない実行ファイルへのパスに置き換えていることで知られています(/proc/sys/kernel/core_patternを確認してください)。多くの場合、単に “core”、“core.%p”、または “/var/log/core/core.%p” と書けば問題を解決できます。まれな問題が再発するのを待つためにこのオプションを有効にする場合は、最初にたとえば “haproxy” プロセスへ “kill -11” を実行してダンプの取得を試し、終了時に期待した場所へコアが残ることを確認しておくとよいでしょう。
set-var <var-name> <expr>
プロセス全体の変数 ‘<var-name>’ を、サンプル式 <expr> を評価した結果に設定します。変数 ‘<var-name>’ は、‘proc.’ プレフィックスを使うプロセス全体の変数でなければなりません。TCPルールやHTTPルールの ‘set-var’ アクションと同じように動作しますが、式は設定の解析時に評価され、変数はただちに設定されます。式で使用できるサンプル取得関数とコンバーターは、通常は ‘int(value)’ や ‘str(value)’ など、内部データを使用するものだけです。すでに確保された変数も参照できます。これらの変数は、その後、通常のルールセットから読み取ったり変更したりできます。
例:
set-var-fmt <var-name> <fmt>
プロセス全体の変数 ‘<var-name>’ を、ログ形式 <fmt> を評価して得られた文字列に設定します。変数 ‘<var-name>’ は、‘proc.’ プレフィックスを使うプロセス全体の変数でなければなりません。TCPルールやHTTPルールの ‘set-var-fmt’ アクションと同じように動作しますが、式は設定の解析時に評価され、変数はただちに設定されます。式で使用できるサンプル取得関数とコンバーターは、通常は ‘int(value)’ や ‘str(value)’ など、内部データを使用するものだけです。すでに確保された変数も参照できます。これらの変数は、その後、通常のルールセットから読み取ったり変更したりできます。カスタムログ形式の構文については、8.2.6節
を参照してください。
例:
setcap <name>[,<name>...]
root以外のユーザー (uid > 0) として起動・実行する場合、またはuid 0 (root) で起動してからroot以外のユーザーに切り替える場合に、保持しなければならないケーパビリティーの一覧を設定します。デフォルトでは、uidを切り替えるとすべての権限を失います。しかし、透過プロキシで別のアドレスを送信元としてサーバーに接続する場合や、1024未満のポートにバインドする場合、たとえば “tune.quic.fe.sock-per-conn default-on” を使用する場合には、一部の権限が必要になることが多く、全体をuid 0で実行する構成になってしまいます。ケーパビリティーの設定は、必要なものだけを保持するため、通常はより安全な代替手段です。この機能はOSに依存し、ビルド時にUSE_LINUX_CAP=1を設定したLinuxでのみ有効です。サポートするケーパビリティーの一覧もOSに依存し、無効な名前や空の名前を渡したときのエラーメッセージに列挙されます。複数のケーパビリティーをコンマで区切って指定できます。よく使われるものでは、“cap_net_raw” は別のアドレスへの透過的なバインドを許可し、“cap_net_bind_service” は特権ポートへのバインドを許可してQUICで使用できます。同じroot以外のユーザーでプロセスを起動・実行する場合は、このキーワードに加えて、setcapでhaproxyバイナリーファイルに必要なケーパビリティーを設定することを推奨します。haproxyバイナリーのケーパビリティー設定については、管理ガイドの13.1章「Linuxケーパビリティーのサポート」を参照してください。
例:
setenv <name> <value>
環境変数 <name> を値 <value> に設定します。変数がすでに存在する場合は、上書きします。変更はただちに有効になり、設定ファイルの次の行から新しい値を参照できます。“presetenv”、“resetenv”、および “unsetenv” も参照してください。
shm-stats-file <name>
このディレクティブを設定すると、統計カウンターの保存に共有メモリを使用するようになります。<name> はshm_open()の引数として使用し、一意の場所にある共有メモリを開きます。そのため、このディレクティブはshm_open()をサポートするシステムでのみ使用できます。統計にSHMを使用する場合、GUIDが設定されていることを条件に、フロントエンド、バックエンド、リスナー、サーバーの共有可能なカウンターをすべてSHMに保存します。haproxyをリロードすると、新しいプロセスはGUIDと型に基づいて、設定で定義したオブジェクトと関連付けられるオブジェクトをSHMから探します。これにより、リロード時に一部のカウンターの値を保持することを目指します。一方、haproxyを正常に停止すると、SHMオブジェクトを解放するため、カウンターは実際にリセットされます。新しいプロセスを起動する前にファイルを手動で削除し、強制的にリセットすることもできます。
“guid”、“guid-prefix”、および “shm-stats-file-max-objects” も参照してください。
shm-stats-file-max-objects <number>
共有カウンター用の共有メモリに保存できるオブジェクト数の、スレッドグループごとの上限を定義します。これはSHMの最大メモリサイズに直接関係し、実行時の再マッピングを避けるため、SHMを所定のサイズであらかじめマッピングするために使用します。デフォルトは2kで、ほとんどの構成で不適切なメモリ使用量になる危険を避けながら利用できるはずですが、必要に応じて簡単に変更できます。この値が小さすぎて、共有メモリに保存する予定のオブジェクトを登録できない場合、haproxyは起動時に問題を報告します。“shm-stats-file” を定義した場合にのみ意味があります。
“thread-groups” も参照してください。
ssl-default-bind-ciphers <ciphers>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。独自の指定を明示していないすべての “bind” 行について、TLSv1.2までのSSL/TLSハンドシェイクでネゴシエーションする暗号アルゴリズムの一覧(暗号スイート)を表す、デフォルトの文字列を設定します。文字列の形式は、OpenSSLのmanページの “man 1 ciphers” で定義されています。背景情報や推奨事項については、たとえば (https://wiki.mozilla.org/Security/Server_Side_TLS ) と (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ) を参照してください。TLSv1.3の暗号設定については、“ssl-default-bind-ciphersuites” キーワードを参照してください。詳細は “bind” キーワードを参照してください。
ssl-default-bind-ciphersuites <ciphersuites>
この設定は、OpenSSLのサポートを組み込み、OpenSSL 1.1.1以降を使ってHAProxyをビルドした場合にのみ使用できます。独自の指定を明示していないすべての “bind” 行について、TLSv1.3ハンドシェイクでネゴシエーションする暗号アルゴリズムの一覧(暗号スイート)を表す、デフォルトの文字列を設定します。文字列の形式は、OpenSSLのmanページ “man 1 ciphers” の “ciphersuites” 節で定義されています。TLSv1.2以前の暗号設定については、“ssl-default-bind-ciphers” キーワードを参照してください。この設定はTLSv1.2の暗号スイートを受け入れることもありますが、文書化されていない動作であり、一貫性がなかったりバグがあったりする可能性があるため、推奨しません。OpenSSLのデフォルトのTLSv1.3暗号スイートは次のとおりです。 “TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256”
TLSv1.3がサポートする暗号スイートは、次の5つだけです。
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256
詳細は “bind” キーワードを参照してください。
例:
ssl-default-bind-client-sigalgs <sigalgs>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。独自の指定を明示していないすべての “bind” 行について、クライアント認証に関する署名アルゴリズムの一覧を表す、デフォルトの文字列を設定します。形式は、署名アルゴリズムをコロンで区切った一覧です。各署名アルゴリズムは、TLS1.3の署名方式名 (“rsa_pss_rsae_sha256”)、または公開鍵アルゴリズム + ダイジェストの形式 (“ECDSA+SHA256”) のいずれかで指定できます。両方の形式を同じ一覧に含められます。形式の詳細は、SSL_CTX_set1_client_sigalgs(3)を参照してください。署名アルゴリズムの一覧は、RFC8446の4.2.3節 と、OpenSSLのssl/t1_lib.cファイルにもあります。TLSv1.1以前では、署名アルゴリズムを個別にネゴシエーションしないため、この設定は適用されません。中間装置との互換性が必要な場合を除き、この設定の変更は推奨しません。
ssl-default-bind-curves <curves>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。ECDHEを使うSSL/TLSハンドシェイクでネゴシエーションする楕円曲線アルゴリズムの一覧(曲線スイート)を表す、デフォルトの文字列を設定します。形式は、曲線名をコロンで区切った一覧です。詳細は “bind” キーワードを参照してください。
ssl-default-bind-options [<option>]...
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。すべての “bind” 行に強制するデフォルトのssl-optionsを設定します。使用できるオプションは、“bind” キーワードを参照してください。
例:
ssl-default-bind-sigalgs <sigalgs>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。独自の指定を明示していないすべての “bind” 行について、TLSv1.2とTLSv1.3のハンドシェイクでネゴシエーションする署名アルゴリズムの一覧を表す、デフォルトの文字列を設定します。形式は、署名アルゴリズムをコロンで区切った一覧です。各署名アルゴリズムは、TLS1.3の署名方式名 (“rsa_pss_rsae_sha256”)、または公開鍵アルゴリズム + ダイジェストの形式 (“ECDSA+SHA256”) のいずれかで指定できます。両方の形式を同じ一覧に含められます。形式の詳細は、SSL_CTX_set1_sigalgs(3)を参照してください。署名アルゴリズムの一覧は、RFC8446の4.2.3節 と、OpenSSLのssl/t1_lib.cファイルにもあります。TLSv1.1以前では、署名アルゴリズムを個別にネゴシエーションしないため、この設定は適用されません。中間装置との互換性が必要な場合を除き、この設定の変更は推奨しません。
ssl-default-server-ciphers <ciphers>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。独自の指定を明示していないすべての “server” 行について、TLSv1.2までのサーバーとのSSL/TLSハンドシェイクでネゴシエーションする暗号アルゴリズムの一覧を表す、デフォルトの文字列を設定します。文字列の形式は、OpenSSLのmanページの “man 1 ciphers” で定義されています。背景情報や推奨事項については、たとえば (https://wiki.mozilla.org/Security/Server_Side_TLS ) と (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ) を参照してください。TLSv1.3の暗号設定については、“ssl-default-server-ciphersuites” キーワードを参照してください。詳細は “server” キーワードを参照してください。
ssl-default-server-ciphersuites <ciphersuites>
この設定は、OpenSSLのサポートを組み込み、OpenSSL 1.1.1以降を使ってHAProxyをビルドした場合にのみ使用できます。独自の指定を明示していないすべての “server” 行について、サーバーとのTLSv1.3ハンドシェイクでネゴシエーションする暗号アルゴリズムの一覧を表す、デフォルトの文字列を設定します。文字列の形式は、OpenSSLのmanページ “man 1 ciphers” の “ciphersuites” 節で定義されています。TLSv1.2以前の暗号設定については、“ssl-default-server-ciphers” キーワードを参照してください。詳細は “server” キーワードを参照してください。
ssl-default-server-client-sigalgs <sigalgs>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。独自の指定を明示していないすべての “server” 行について、クライアント認証に関する署名アルゴリズムの一覧を表す、デフォルトの文字列を設定します。形式は、署名アルゴリズムをコロンで区切った一覧です。各署名アルゴリズムは、TLS1.3の署名方式名 (“rsa_pss_rsae_sha256”)、または公開鍵アルゴリズム + ダイジェストの形式 (“ECDSA+SHA256”) のいずれかで指定できます。両方の形式を同じ一覧に含められます。形式の詳細は、SSL_CTX_set1_client_sigalgs(3)を参照してください。署名アルゴリズムの一覧は、RFC8446の4.2.3節 と、OpenSSLのssl/t1_lib.cファイルにもあります。TLSv1.1以前では、署名アルゴリズムを個別にネゴシエーションしないため、この設定は適用されません。中間装置との互換性が必要な場合を除き、この設定の変更は推奨しません。
ssl-default-server-curves <curves>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。ECDHEを使うSSL/TLSハンドシェイクでネゴシエーションする楕円曲線アルゴリズムの一覧(曲線スイート)を表す、デフォルトの文字列を設定します。形式は、曲線名をコロンで区切った一覧です。詳細は “server” キーワードを参照してください。
ssl-default-server-options [<option>]...
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。すべての “server” 行に強制するデフォルトのssl-optionsを設定します。使用できるオプションは、“server” キーワードを参照してください。
ssl-default-server-sigalgs <sigalgs>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。独自の指定を明示していないすべての “server” 行について、TLSv1.2とTLSv1.3のハンドシェイクでネゴシエーションする署名アルゴリズムの一覧を表す、デフォルトの文字列を設定します。形式は、署名アルゴリズムをコロンで区切った一覧です。各署名アルゴリズムは、TLS1.3の署名方式名 (“rsa_pss_rsae_sha256”)、または公開鍵アルゴリズム + ダイジェストの形式 (“ECDSA+SHA256”) のいずれかで指定できます。両方の形式を同じ一覧に含められます。形式の詳細は、SSL_CTX_set1_sigalgs(3)を参照してください。署名アルゴリズムの一覧は、RFC8446の4.2.3節 と、OpenSSLのssl/t1_lib.cファイルにもあります。TLSv1.1以前では、署名アルゴリズムを個別にネゴシエーションしないため、この設定は適用されません。中間装置との互換性が必要な場合を除き、この設定の変更は推奨しません。
ssl-dh-param-file <file>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。独自の指定を明示していないすべての “bind” 行について、一時的なDiffie-Hellman (DHE) 鍵交換を使用するSSL/TLSハンドシェイクで使う、デフォルトのDHパラメーターを設定します。bindの証明書ファイルにカスタムDHパラメーターがあれば、それが優先されます。ssl-dh-param-fileでも証明書ファイルへの直接指定でもカスタムDHパラメーターを指定していない場合、tune.ssl.default-dh-paramを設定しない限り、DHE暗号は使用されません。後者を設定した場合は、指定したサイズの定義済みDHパラメーターを使用します。カスタムパラメーターの方が安全であることが知られているため、その使用を推奨します。OpenSSLコマンド “openssl dhparam <size>” でカスタムDHパラメーターを生成できます。1024ビットのDHパラメーターはもはや安全とは見なせないため、サイズは少なくとも2048にすることを推奨します。
ssl-passphrase-cmd <cmd> <args> ...
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。初期化中に暗号化された証明書を読み込むときに呼び出す、完全なコマンドラインを定義できます。コマンドには、スクリプトなど任意のプログラムを使用できます。最初の引数には暗号化された秘密鍵のパス、その後にユーザー定義の “args” パラメーターが渡されます。プログラムは、その暗号化された秘密鍵を復号できるパスフレーズを標準出力に出力すべきです。初期化中に新しい暗号化された秘密鍵を読み込むたびに、HAProxyはまず、すでに分かっているほかのすべてのパスフレーズで秘密鍵の復号を試みます。どれも成功しなかった場合に、パスフレーズコマンドを再度呼び出します。
ssl-propquery <query>
この設定は、OpenSSLのサポートを組み込んでビルドし、OpenSSLのバージョンが少なくとも3.0である場合にのみ使用できます。プロバイダーからアルゴリズムを取得するときに使用する、デフォルトのプロパティ文字列を定義できます。opensslのpropqueryオプションと同じように動作し、同じ構文に従います(https://www.openssl.org/docs/man3.0/man7/property.html を参照してください)。たとえば、fooとdefaultの両プロバイダーを読み込んでいる場合、propquery “?provider=foo” を指定すると、デフォルトでfooプロバイダーのアルゴリズム実装を選び、見つからなければdefaultプロバイダーの実装にフォールバックします。
ssl-provider <name>
この設定は、OpenSSLのサポートを組み込んでビルドし、OpenSSLのバージョンが少なくとも3.0である場合にのみ使用できます。初期化中にプロバイダーを読み込めます。読み込みに成功すると、そのプロバイダーが提供する機能をHAProxyで使用できるようになります。設定ファイルには複数の ‘ssl-provider’ オプションを指定でき、記述した順にプロバイダーを読み込みます。
プロバイダーを明示的に読み込むと、OpenSSLは ‘default’ プロバイダーを自動的に読み込まなくなります。OpenSSLでは、読み込むプロバイダーを設定ファイル(openssl.cnfなど)に直接定義することもできるため、プロバイダーを読み込むのに必ずしも ‘ssl-provider’ オプションが必要なわけではありません。CLIコマンド “show ssl providers” で、正常に読み込まれたすべてのプロバイダーを表示できます。
OpenSSLプロバイダーのデフォルトの検索パスは、“openssl version -a” コマンドの出力で確認できます。プロバイダーが別のディレクトリにある場合は、環境変数OPENSSL_MODULESに、そのプロバイダーがあるディレクトリを設定できます。
“ssl-propquery” と “ssl-provider-path” も参照してください。
ssl-provider-path <path>
この設定は、OpenSSLのサポートを組み込んでビルドし、OpenSSLのバージョンが少なくとも3.0である場合にのみ使用できます。OpenSSLがプロバイダーを探す際の検索パスを指定できます。環境変数OPENSSL_MODULESと同じように動作します。後続の ‘ssl-provider’ オプションに対して、新しい ‘ssl-provider-path’ を定義するまで使用されます。“ssl-provider” も参照してください。
ssl-load-extra-del-ext
HAProxyが追加のSSLファイルを検索する方法を設定できます。デフォルトでは、HAProxyはファイル名に新しい拡張子を追加します(例: “foobar.crt” に対して “foobar.crt.key” を読み込みます)。このオプションを有効にすると、新しい拡張子を追加する前に既存の拡張子を削除します(例: “foobar.crt” に対して “foobar.key” を読み込みます)。
このオプションが機能するには、crtファイルの拡張子が “.crt” でなければなりません。
このオプションは、バンドルの拡張子 (.ecdsa, .rsa. .dsa) に対応せず、それらを削除しようとはしません。
このオプションはデフォルトで無効です。“ssl-load-extra-files” も参照してください。
ssl-load-extra-files <none|all|bundle|sctl|ocsp|issuer|key>*
SSL証明書の読み込み中に、明示していないファイルをHAProxyが探す方法を変更します。このオプションは “bind” 行と “server” 行の両方に関連付けられた証明書に適用されますが、一部の追加ファイルは、“server” 行の証明書では機能上の効果を持ちません。
デフォルトでは、HAProxyは設定で指定していない多数のファイルを自動検出します。起動時間を最適化するために、この動作を無効にしたい場合があります。
“none”: 設定で指定したファイルだけを読み込みます。ファイルが存在しない場合も、証明書バンドルを読み込もうとはしません。ディレクトリの場合、証明書のベース名が同じでも、バンドルにまとめようとはしません。
“all”: これがデフォルトの動作です。バンドル、sctl、ocsp、issuer、keyをすべて読み込もうとします。
“bundle”: 設定で指定したファイルが存在しない場合、HAProxyは 「証明書バンドル」を読み込もうとします。証明書バンドルを扱うのはフロントエンド側だけで、バックエンド証明書では機能しません。
HAProxy 2.3以降では、バンドルを同じOpenSSL証明書ストアに読み込まず、各証明書を別のストアに読み込みます。これは、複数の “crt” を宣言することと同じです。この動作にはOpenSSL 1.1.1が必要です。つまり、バンドルは現在では後方互換性のためだけに使用され、RSA/ECCを併用するbind設定には、もはや必須ではありません。
これらのPEMファイルを、HAProxyが認識する 「証明書バンドル」にまとめるには、次の命名規則に従わなければなりません。バンドルに含めるすべてのPEMファイルは同じベース名を持ち、鍵の種類を示す接尾辞を付ける必要があります。現在サポートする接尾辞は、rsa、dsa、ecdsaの3つです。たとえば、www.example.com にRSAファイルとECDSAファイルの2つのPEMファイルがある場合、名前は “example.pem.rsa” と “example.pem.ecdsa” にしなければなりません。ファイル名の最初の部分は任意で、接尾辞だけが重要です。このバンドルをHAProxyに読み込むには、ベース名だけを指定します。
例: bind :8443 ssl crt example.pem
接尾辞はHAProxyに渡さない点に注意してください。これによって、HAProxyに証明書バンドルを探すよう指示します。
HAProxyは、バンドル内のすべてのPEMファイルを、複数の “crt” に個別に設定したかのように読み込みます。
各ファイルを個別に読み込むため、バンドルの読み込みは、ディレクトリの読み込みに影響しなくなりました。
CLIでは、バンドルは別々のファイルとして扱われ、コミットにはバンドルの拡張子が必要です。
複数証明書のバンドルでは、OCSPファイル (.ocsp)、発行者ファイル (.issuer)、証明書の透明性 (.sctl)、および秘密鍵 (.key) をサポートします。
“sctl”: crtキーワードごとに “<basename>.sctl” の読み込みを試みます。バックエンド証明書に指定した場合も読み込みますが、機能上の効果はありません。
“ocsp”: crtキーワードごとに “<basename>.ocsp” の読み込みを試みます。バックエンド証明書に指定した場合も読み込みますが、機能上の効果はありません。
“issuer”: OCSPファイルの発行者がPEMファイルに含まれていない場合、"<basename>.issuer" の読み込みを試みます。バックエンド証明書に指定した場合も読み込みますが、機能上の効果はありません。
“key”: PEMファイルに秘密鍵が含まれていない場合、秘密鍵を含むファイル “<basename>.key” の読み込みを試みます。
デフォルトの動作は “all” です。
例:
関連項目: “crt”、bindオプションについての5.1節 、serverオプションについての5.2節 。
ssl-security-level <number>
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html で説明されているOpenSSLのセキュリティレベルを選択できます。このレベルは、HAProxy内のすべてのSSLコンテキストに適用されます。サポートする値は0から5までだけです。
デフォルト値は、OpenSSLのバージョン、ディストリビューション、およびライブラリのコンパイル方法によって異なります。
このディレクティブには、少なくともOpenSSL 1.1.1が必要です。
ssl-server-verify [none|required]
サーバー側のSSL検証のデフォルト動作を指定します。’none’ を指定すると、サーバー証明書を検証しません。コマンドラインオプション ‘-dV’ で強制しない限り、デフォルトは ‘required’ です。
ssl-skip-self-issued-ca
自己発行CA、つまりx509ルートCAは、証明書チェーンの検証の基点です。クライアントが持っていなければならないため、サーバーから送信しても意味がありません。標準的な設定では、このようなCAをPEMファイルに含めないようにする必要があります。このオプションを使うと、クライアントには送信せずに、PEMファイル内にこのようなCAを残せます。用途は、’.issuer’ ファイルを必要とせずにocsp用の発行者を提供し、‘issuers-chain-path’ と共有できるようにすることです。これは、中間証明書を持たないすべての証明書に関係します。BoringSSLではocspの処理に発行者が不要で、.issuerを無視するため、効果はありません。少なくともOpenSSL 1.0.2が必要です。
stats calculate-max-counters [on|off]
統計の最大値カウンターの計算を有効または無効にします。必要なければ、無効にすることで性能が少し向上する可能性があります。デフォルトはonです。
stats maxconn <connections>
デフォルトでは、統計ソケットの同時接続数は10に制限されています。“stats maxconn” でこの値を変更できます。
stats socket [<address:port>|<path>] [param*]
UNIXソケットを <path> に、またはTCPv4/v6アドレスを <address:port> にバインドします。このソケットへの接続では、各種の統計情報の出力を取得でき、一部の実行時設定を変更するコマンドも発行できます。詳細は、管理ガイドの9.3節
「Unixソケットコマンド」を参照してください。
“bind” 行でサポートするすべてのパラメーターに対応しています。たとえば、アクセスできるユーザーや、そのアクセス権を制限できます。詳細は、5.1節 を参照してください。
stats timeout <timeout, in milliseconds>
統計ソケットのデフォルトのタイムアウトは10秒です。“stats timeout” でこの値を変更できます。値はミリ秒で指定するか、{ us, ms, s, m, h, d } のいずれかの時間単位を接尾辞として付けなければなりません。
stats-file <path>
生成したhaproxyのstats-fileへのパスを指定します。haproxyは起動時に、内部カウンターへ値を事前に読み込みます。このstats-fileは、CLIコマンド “dump stats-file” で生成します。詳細は管理マニュアルを参照してください。
stress-level <level>
haproxyバイナリーにストレスをかける代替コードを有効にします。レベルは0から9までの整数です。デフォルト値の0では、ストレスをかける実行をすべて無効にします。レベル1から9に従って、haproxyバイナリーへのストレスを強めます。正のレベルを使用すると、性能が大幅に低下する場合があります。そのため、デバッグ目的で開発者からの依頼がある場合を除き、決して有効にすべきではありません。
strict-limits
setrlimitが失敗したとき、起動時にプロセスを失敗させます。HAProxyは、計算結果に従って最適なsetrlimitの設定を試みます。失敗すると警告を出力します。このオプションは、これらの制限の設定に失敗した場合に、HAProxyが明示的に失敗することを保証します。デフォルトで有効です。前に “no” キーワードを付けると、強制的に無効にできます。
thread-group <group> [<thread-range>...]
この設定は、スレッドのサポートを組み込んでビルドした場合にのみ使用できます。スレッドグループ <group> を構成するスレッドの一覧を列挙します。スレッド番号とグループ番号は1から始まります。スレッド範囲は、スレッド番号を個別に指定するか、下限と上限をダッシュ ‘-’ で区切って指定します(例: “1-16”)。未割り当てのスレッドは、未割り当てのスレッドグループに自動的に割り当てられます。このディレクティブで定義したスレッドグループには、定義したスレッド以外は決して追加されません。同じグループを複数回定義すると、新しい定義で以前の定義を上書きします。“nbthread” と “thread-groups” も参照してください。
thread-groups <number>
この設定は、スレッドのサポートを組み込んでビルドした場合にのみ使用できます。HAProxyのスレッドを、独立した <number> 個のグループに分割します。現在のデフォルト値は1です。スレッドグループを使うと、設定の手間は増えますが、スレッド間の共有を減らして競合を抑えられます。グループごとに最大64スレッドを設定できるため、64を超えるスレッドを使用する唯一の方法でもあります。グループ数の上限はコンパイル時に設定され、デフォルトは16です。“nbthread” も参照してください。
thread-hard-limit <number>
検出された、または設定されたスレッド数に上限を設けます。スレッド数を自動検出するOSで、汎用的かつ移植性のある設定を使いながら、CPU数より少ないスレッド数にしたい場合に特に役立ちます。“nbthread” はスレッド数を強制し、使用可能なCPU数を超えると警告が出て性能が低下します。一方、thread-hard-limitは最大値に上限を設けるだけで、スレッド数をその値以下に自動的に制限し、それより小さい値は増やしません。“nbthread” により大きな値を強制した場合は、thread-hard-limitが優先され、設定の不整合を修正できるように警告を出力します。デフォルトでは制限はありません。“nbthread” も参照してください。
uid <number>
プロセスのユーザーIDを <number> に変更します。このユーザーIDは、HAProxy専用、または同種の少数のデーモン専用にすることを推奨します。別のユーザーIDに切り替えるには、HAProxyをスーパーユーザー権限で起動しなければなりません。“gid” と “user” も参照してください。
ulimit-n <number>
プロセスごとのファイルディスクリプター数の上限を <number> に設定します。デフォルトでは自動計算するため、このオプションは使用しないことを推奨します。単にファイルディスクリプター数を制限するだけなら、代わりに “fd-hard-limit” を使用する方が適切です。
この自動リソース計算には、動的サーバーを含めない点に注意してください。多数の動的サーバーを使用する場合は、この値を手動で指定する必要があるかもしれません。
関連項目: fd-hard-limit、maxconn
unix-bind [ prefix <prefix> ] [ mode <mode> ] [ user <user> ] [ uid <uid> ] [ group
<group> ] [ gid <gid> ]
“bind” 文で宣言するUNIXリスニングソケットに共通の設定を定めます。これらの設定は通常必要ですが、プロセス固有でもあるため、主にUNIXソケットの宣言を簡単にし、誤りの危険を減らすために使用します。<prefix> を使うと、すべてのソケットパスをそのディレクトリからの相対パスに強制できます。別のコンポーネントのchrootにアクセスするために必要になることがあります。これらのパスは、HAProxy自身がchrootする前に解決されるため、絶対パスになります。<mode>、<user>、<uid>、<group>、<gid> は、いずれも “bind” 文の同名の設定と同じ意味です。両方に指定した場合は “bind” 文が優先されます。したがって、“unix-bind” の設定は、プロセス全体のデフォルト設定と見なせます。
unsetenv [<name> ...]
引数に指定した環境変数を削除します。一部の操作でユーザーの環境から継承されることがある、機密情報を隠すのに役立ちます。存在しなかった変数は警告せずに無視するため、操作後には、指定した変数がどれも残らないことが保証されます。変更は直ちに有効になり、設定ファイルの次の行では、これらの変数を参照できなくなります。“setenv”、“presetenv”、“resetenv” も参照してください。
user <user name>
“uid” と同様ですが、/etc/passwdからユーザー名 <user name> のUIDを取得して使用します。“uid” と “group” も参照してください。
node <name>
DNS名と同様に、英字、数字、ハイフン、アンダースコアだけを使用できます。
この文は、複数のプロセスまたはサーバーが同じIPアドレスを共有するHA構成で役立ちます。すべてのノードに異なるノード名を設定すると、どのサーバーがトラフィックを処理しているか、すぐに分かるようになります。
wurfl-cache-size <size>
WURFLのユーザーエージェントキャッシュのサイズを設定します。検索を高速にするため、処理済みのユーザーエージェントをLRUキャッシュに保持します。
- “0” : キャッシュを使用しません。
<size>: LRUキャッシュのサイズを要素数で指定します。
このオプションは、HAProxyをUSE_WURFL=1でコンパイルした場合にのみ使用できます。
wurfl-data-file <file path>
デバイス検出サービスに使用するWURFLデータファイルのパスを指定します。HAProxyがアクセスできるよう、ファイルには適切な権限を設定すべきです。
このオプションは、HAProxyをUSE_WURFL=1でコンパイルした場合にのみ使用できます。
wurfl-information-list [<capability>]*
挿入するヘッダーで使用する予定の、WURFLの機能、仮想機能、プロパティ名をスペースで区切った一覧です。機能と仮想機能の名前の完全な一覧は、ScientiamobileのWebサイトにあります。
有効なWURFLプロパティは次のとおりです。
-
wurfl_id 一致したデバイスのデバイスIDを格納します。
-
wurfl_root_id 一致したデバイスのデバイスルートIDを格納します。
-
wurfl_isdevroot 一致したデバイスがルートデバイスかどうかを示します。値は “TRUE” または “FALSE” です。
-
wurfl_useragent このWebリクエストで送られてきた元のユーザーエージェントです。
-
wurfl_api_version 現在使用中のLibwurfl APIのバージョンを表す文字列を格納します。
-
wurfl_info 解析したwurfl.xmlの情報と、その完全なパスを含む文字列です。
-
wurfl_last_load_time WURFLを最後に正常に読み込んだ時刻のUNIXタイムスタンプを格納します。
-
wurfl_normalized_useragent 正規化したユーザーエージェントです。
このオプションは、HAProxyをUSE_WURFL=1でコンパイルした場合にのみ使用できます。
wurfl-information-list-separator <char>
WURFLの結果を含むレスポンスヘッダーで、値を区切る文字です。指定しない場合は、デフォルトでコンマ (’,’) を使用します。
このオプションは、HAProxyをUSE_WURFL=1でコンパイルした場合にのみ使用できます。
wurfl-patch-file [<file path>]
WURFLパッチファイルのパスの一覧です。パッチは起動時、つまりchrootする前に読み込む点に注意してください。
このオプションは、HAProxyをUSE_WURFL=1でコンパイルした場合にのみ使用できます。
3.2. 性能のチューニング
busy-polling
状況によっては、特に可変周波数に対応するプロセッサーで低遅延を求める場合や、仮想マシン内で実行する場合、プロセスがポーラーでI/Oを待つたびに、プロセッサーがスリープに戻ったり、長時間ほかのVMに割り当てられたりして、遅延が過度に大きくなることがあります。このオプションは、ポーラーのタイムアウトを常にゼロにすることで、プロセッサーのスリープを防ぎます。プロセッサーが過熱する危険を伴いますが、遅延を大幅に減らせます(30から100マイクロ秒の短縮が観測されています)。スレッドと併用することもできますが、スレッドのバインドが不適切だと激しい競合が生じ、性能が悪化して、“show info” 出力のCPU stolenフィールドが大きな値になります。これによって、設定が不適切なスレッドを判別できます。このオプションを使用するときは、ネットワーク割り込みと同じプロセッサーでプロセスを実行しないことが重要です。同じコアを共有する複数のCPUスレッドでの使用も避けた方がよいでしょう。デフォルトで無効です。有効にした場合も、前に “no” キーワードを付けると強制的に無効にできます。“select” と “poll” ポーラーは、このオプションを無視します。
シームレスなリロードでは、古いプロセスに対してこのオプションを自動的に無効にします。現在の接続の終了を待って複数のプロセスがしばらく残る間に、CPUの競合が過度に発生するのを避けるためです。
max-spread-checks <delay in milliseconds>
デフォルトでは、HAProxyは、サーバー群のすべてのサーバーで最も短いヘルスチェック間隔の中に、ヘルスチェックの開始時刻を分散させようとします。同じサーバーで稼働するサービスに、一斉に負荷をかけるのを避けるためです。ただし、チェック間隔が長い場合(10秒以上)、サーバー群の最後のサーバーでテストが始まるまで時間がかかり、問題になることがあります。このパラメーターは、各サーバーのチェック間隔が長くても、最初と最後のチェックの間の遅延に上限を設けます。ただし、サーバーの間隔がそれより短い場合は、その間隔を守ります。
maxcompcpuusage <number>
新しいリクエストの圧縮を停止したり、処理中のリクエストの圧縮レベルを下げたりする前に、HAProxyが使用できるCPU使用率の上限を設定します。‘maxcomprate’ と同様に動作しますが、入力データの帯域幅ではなくCPU使用率を測定します。値は、HAProxyが使用するCPUの割合をパーセントで表します。100を指定すると制限を無効にします。デフォルト値は100です。より低い値を設定すると、圧縮処理によってプロセス全体が遅くなったり、高い遅延が生じたりすることを防げます。
maxcomprate <number>
プロセスごとの圧縮への入力速度の上限を、毎秒 <number> キロバイトに設定します。各ストリームで上限に達すると、そのストリームの処理中に圧縮レベルを下げます。ストリームの開始時点で上限に達している場合は、そのストリームをまったく圧縮しません。上限に達していない場合は、tune.comp.maxlevelまで圧縮レベルを上げます。ゼロは制限なしを意味し、これがデフォルト値です。
maxconn <number>
プロセスごとの同時接続数の上限を <number> に設定します。コマンドライン引数 “-n” と同等です。コマンドライン引数 “-n” で指定した値は、globalセクションのmaxconnより優先されます。HAProxyプロセスは、コンパイル時変数SYSTEM_MAXCONNを指定してコンパイルすることもでき、その場合は、これをシステムのmaxconnの上限として使用します。このSYSTEM_MAXCONNの制限も、コマンドライン引数 “-n” で実行時に回避できます。maxconnに達すると、プロキシは接続の受け付けを停止します。プロセスのファイルディスクリプター数のソフトリミット(“ulimit -n” コマンドで取得できます)は、指定したmaxconnに応じて自動調整します。“ulimit-n” も参照してください。注意: 一部のプラットフォームでは、“select” ポーラーは1024を超えるファイルディスクリプターを確実に扱うことができません。プラットフォームがselectだけに対応し、起動時に “select FAILED” と表示する場合は、動作するまでmaxconnを下げる必要があります(通常は500を少し下回る値です)。maxconnを設定しない場合は、“ulimit -nH” コマンドが示す現在のファイルディスクリプター数の制限を基に、自動計算します(ハードリミットとソフトリミットの大きい方を使用します)。その自動計算値は、“fd-hard-limit” と、コマンドラインオプション “-m” で強制した場合のメモリー制限によって、さらに小さくなることがあります。自動計算値は、バッファーサイズ、圧縮用に割り当てるメモリー、SSLキャッシュのサイズ、SSLを使用するかどうか、および関連するmaxsslconn(これも自動計算できます)にも依存します。
関連項目: fd-hard-limit、ulimit-n
maxconnrate <number>
プロセスごとの毎秒の接続数の上限を <number> に設定します。この制限に達すると、プロキシは接続の受け付けを停止します。各フロントエンドの容量に関係なく、全体の容量を制限できます。ただし、この制限はサービスを保護する手段としてしか使用できません。制限に達した際に、フロントエンド間で必ずしも公平に分配されるとは限らないため、各フロントエンドにも、想定する割り当てに近い値の制限を設けるとよいでしょう。また、tune.maxacceptを下げると公平性が改善する場合があります。
maxpipes <number>
プロセスごとのパイプ数の上限を <number> に設定します。現在、パイプを使用するのは、カーネルによるTCPスプライシングだけです。パイプには2つのファイルディスクリプターが含まれるため、“ulimit-n” の値も、それに応じて増えます。デフォルト値はmaxconn/4で、ほとんどの高負荷用途でも十分な値と考えられます。スプライス処理はパイプを動的に割り当て、解放し、通常のコピーにフォールバックできるため、この値が低すぎても、影響は性能に限られます。
maxsessrate <number>
プロセスごとの毎秒のセッション数の上限を <number> に設定します。この制限に達すると、プロキシは接続の受け付けを停止します。各フロントエンドの容量に関係なく、全体の容量を制限できます。ただし、この制限はサービスを保護する手段としてしか使用できません。制限に達した際に、フロントエンド間で必ずしも公平に分配されるとは限らないため、各フロントエンドにも、想定する割り当てに近い値の制限を設けるとよいでしょう。また、tune.maxacceptを下げると公平性が改善する場合があります。
maxsslconn <number>
プロセスごとの同時SSL接続数の上限を <number> に設定します。デフォルトではSSL固有の制限はなく、すべての接続にglobalのmaxconn設定を適用します。この制限を設定すると、opensslがメモリーを使いすぎて、mallocがNULLを返したときにクラッシュするのを防げます(残念ながら、opensslはこのような状態を確実には確認しません)。制限は受信接続と送信接続の両方に適用されるため、復号した後に暗号化する1つの接続は、2つのSSL接続として数える点に注意してください。この値を設定せず、メモリー制限を強制している場合は、メモリー制限、maxconn、バッファーサイズ、圧縮用に割り当てるメモリー、SSLキャッシュのサイズ、およびフロントエンド、バックエンド、または両方でのSSLの使用状況を基に、自動計算します。メモリー制限があり、maxconnもmaxsslconnも指定しない場合、HAProxyは、100%の接続を安全にSSLで処理できるように、これらの値を自動調整します。その際は、SSLを有効にしている側(フロントエンド、バックエンド、両方)を考慮します。
maxsslrate <number>
プロセスごとの毎秒のSSLセッション数の上限を <number> に設定します。この制限に達すると、SSLリスナーは接続の受け付けを停止します。各フロントエンドの容量に関係なく、SSLによる全体のCPU使用量を制限できます。ただし、この制限はサービスを保護する手段としてしか使用できません。制限に達した際に、フロントエンド間で必ずしも公平に分配されるとは限らないため、各フロントエンドにも、想定する割り当てに近い値の制限を設けるとよいでしょう。また、セッションを数えるのは、SSLスタックに入った後ではなく、入る前です。そのため、不正なハンドシェイクからもスタックを保護できます。tune.maxacceptを下げると、公平性が改善する場合もあります。
maxzlibmem <number>
zlibが使用できるRAMの上限を、プロセスごとにメガバイト単位で設定します。上限に達すると、RAMが利用可能になるまで、新しいストリームを圧縮しません。0を指定すると制限はありません。デフォルト値は0です。UNIXソケットで “show info” を実行すると、“MaxZlibMemUsage” 行にこの値をバイト単位で表示します。zlibが使用しているメモリーは、“ZlibMemUsage” にバイト単位で表示します。
no-memory-trimming
大量のメモリーの回収を試みるいくつかのタイミング(メモリー不足時やリロード時)で、メモリートリミング (“malloc_trim”) を無効にします。メモリーのトリミングは、システムのアロケーターに、未使用領域をすべて走査して解放させます。古いプロセスがそのメモリーを大きく使用する可能性は低いため、新しいプロセスに利用可能なメモリーを多く残す、好ましい動作と一般には考えられます。しかし、数万から数十万の同時接続を扱うシステムでは、メモリーの断片化が激しく、この解放操作に極めて長い時間がかかることがあります。その間、プロセスを通るトラフィックはすべて止まり、新しい接続も受け付けなくなり、一部のヘルスチェックも失敗する可能性があります。さらに、ウォッチドッグが作動して応答しないプロセスを強制終了し、巨大なコアダンプを残すこともあります。このような事象が発生する場合は、このオプションでトリミングを無効にして、新しいプロセスのためにメモリーを解放しようとする動作を止めることを推奨します。高度なメモリーアロケーターでは、通常この問題は発生しません。
noepoll
Linuxで “epoll” イベントポーリングシステムの使用を無効にします。コマンドライン引数 “-de” と同等です。次に使用するポーリングシステムは、通常 “poll” です。“nopoll” も参照してください。
noevports
Solaris 10以降から派生したSunOSシステムで、event portsイベントポーリングシステムの使用を無効にします。コマンドライン引数 “-dv” と同等です。次に使用するポーリングシステムは、通常 “poll” です。“nopoll” も参照してください。
nogetaddrinfo
名前解決でのgetaddrinfo(3)の使用を無効にします。コマンドライン引数 “-dG” と同等です。非推奨のgethostbyname(3)を使用します。
nokqueue
BSDで “kqueue” イベントポーリングシステムの使用を無効にします。コマンドライン引数 “-dk” と同等です。次に使用するポーリングシステムは、通常 “poll” です。“nopoll” も参照してください。
noktls
ktlsの使用を無効にします。コマンドライン引数 “-dT” と同等です。
nopoll
“poll” イベントポーリングシステムの使用を無効にします。コマンドライン引数 “-dp” と同等です。次に使用するポーリングシステムは “select” です。“poll” は、HAProxyがサポートするすべてのプラットフォームで使用できるため、無効にする必要はないはずです。“nokqueue”、“noepoll”、“noevports” も参照してください。
noreuseport
SO_REUSEPORTの使用を無効にします。socket(7)を参照してください。コマンドライン引数 “-dR” と同等です。
nosplice
Linuxで、ソケット間のカーネルTCPスプライシングの使用を無効にします。コマンドライン引数 “-dS” と同等です。データは、従来の、より移植性の高いrecv/send呼び出しでコピーするようになります。カーネルTCPスプライシングは、カーネル2.6の中でもごく新しい一部の版に限られます。2.6.25から2.6.28までのほとんどの版には不具合があり、破損したデータを転送するため、使用してはいけません。このオプションを使うと、疑わしい場合にカーネルスプライシングを全体で簡単に無効にできます。“option splice-auto”、“option splice-request”、“option splice-response” も参照してください。
profiling.memory { on | off }
関数ごとのメモリープロファイリングを有効 (‘on’) または無効 (‘off’) にします。ライブラリを含むプロセス内のあらゆる場所でのmalloc/calloc/realloc/free呼び出しの使用統計を保持し、CLIの “show profiling” コマンドで報告します。主に、プールでは説明できない異常なメモリー使用量が見られ、追加の情報が必要なときに使用します。性能への影響は通常1%程度で、スレッドが非常に多いマシンでは、もう少し大きくなる可能性があります。そのため、通常は本番環境でも使用できます。CLIの “set profiling memory” コマンドで、実行時にも同じ操作ができます。管理マニュアルを参照してください。
profiling.tasks { auto | on | off | lock | no-lock | memory | no-memory }*
タスクごとのCPUプロファイリングを有効 (‘on’) または無効 (‘off’) にします。‘auto’ を指定すると、アクティビティの “avg_loop_us” フィールドで報告される平均遅延が1000マイクロ秒以上になったスレッドで、自動的にプロファイリングを有効にします。遅延が990マイクロ秒未満に戻ると、自動的に無効にします(この値は直近1024ループの平均なので、急には変化せず、短いスパイクを大きく平滑化する傾向があります)。過負荷のシステム、コンテナー、仮想マシンや、システムがスワップするときにも、時折自動的に作動することがあります(ロードバランサーでは、スワップは絶対に発生してはいけません)。
タスクのプロファイリングが有効な場合、HAProxyは、各タスクがロックを保持する時間やロックを待つ時間、さらにプールキャッシュにヒットしない場合に、メモリー割り当てが成功するまで待つ時間も収集できます。遅延の原因の一部を理解するのに役立つことがあります。そのためには、追加のキーワード “lock”(ロック時間の収集を有効化)、“no-lock”(無効化)、“memory”(メモリー割り当て時間の収集を有効化)、“no-memory”(無効化)を指定できます。高負荷のシステムでは、無視できないCPUへの影響(3-10%)があるため、デフォルトでは有効にしません。この負荷が発生するのは、プロファイリングが実際に動作している間だけです。したがって、“auto” モードでは、HAProxyがプロファイリングを有効にすると判断したときだけ発生します。
タスクごとのCPUプロファイリングは、どこに時間を費やし、どのリクエストがどのほかのリクエストにどのような影響を与えるかを報告するのに、とても便利です。有効にしても、全体の性能への影響は通常1%未満です。そのため、問題を検出したときだけ動作するよう、デフォルトの ‘auto’ のままにすることを推奨します。この機能には、クロック識別子CLOCK_MONOTONICとCLOCK_THREAD_CPUTIME_IDを指定したclock_gettime(2)システムコールに対応するシステムが必要です。対応していなければ、報告する時間はゼロになります。このオプションは、CLIの “set profiling” で実行時に変更できます。
spread-checks <0..50, in percent>
たとえば、多数の論理サーバーが同じ物理サーバー上にある場合など、エージェントチェックやヘルスチェックを厳密な間隔で送信するのを避けたいことがあります。このパラメーターを使うと、チェック間隔に0から+/- 50%のランダムな変動を加えられます。2から5までの値で、よい結果が得られるようです。デフォルト値は0のままです。
ssl-engine <name> [algo <comma-separated list of algorithms>]
OpenSSLエンジンを <name> に設定します。<name> に指定できる値の一覧は、“openssl engine” コマンドで取得できます。この文は複数回使用でき、その場合は複数の暗号エンジンを有効にします。サポートしていないエンジンを参照すると、HAProxyは起動できません。最近のプロセッサーでは、多くのエンジンが、純粋なソフトウェア処理よりもHTTPSの性能を低下させる点に注意してください。オプションのコマンド “algo” は、OpenSSL関数ENGINE_set_default_string()を使って、ENGINEが提供するデフォルトのアルゴリズムを設定します。“ALL” を指定すると、すべての暗号処理にそのエンジンを使用します。algoの一覧を指定しない場合も、“ALL” を使用します。異なるアルゴリズムをコンマで区切って指定でき、RSA、DSA、DH、EC、RAND、CIPHERS、DIGESTS、PKEY、PKEY_CRYPTO、PKEY_ASN1などを含められます。これは、opensslの設定ファイルと同じ形式です: https://www.openssl.org/docs/man1.0.2/apps/config.html
HAProxyバージョン2.6では、デフォルトのビルドでエンジンのサポートを無効にしました。このオプションは、対応するサポートを組み込んでHAProxyをビルドした場合にのみ使用できます。ssl-engineが必要な場合は、USE_ENGINE=1フラグを指定してHAProxyを再ビルドできます。
ssl-mode-async
SSLコンテキストにSSL_MODE_ASYNCモードを追加します。非同期処理に対応するSSLエンジンを使用する場合、非同期TLS I/O操作を有効にします。現在の実装は、最大32エンジンをサポートします。OpenSSLのASYNC APIは、読み取り/書き込みバッファーの移動をサポートせず、HAProxyのバッファー管理と互換性がありません。そのため、読み取り/書き込み操作では非同期モードを無効にします(有効になるのは、初回と再ネゴシエーションのハンドシェイク中だけです)。
tune.applet.zero-copy-forwarding { on | off }
アプレットで、データのゼロコピー転送を有効 (‘on’) または無効 (‘off’) にします。デフォルトで有効です。
関連項目: tune.disable-zero-copy-forwarding。
tune.buffers.limit <number>
プロセスごとに割り当てられるバッファー数に、厳密な上限を設定します。デフォルト値はゼロで、無制限を意味します。緊急時のために予約するバッファー数を満たすよう、制限は自動的に再調整されるため、ユーザーが複雑な計算をする必要はありません。この値を強制すると、適切な動作を維持しながら、プロセスが使用するメモリー量を制限するのに特に役立ちます。上限に達すると、バッファーを要求したタスクは、別のバッファーが解放されるまで待ちます。制限が妥当な範囲であれば、通常この待ち時間は非常に短く、体感できません。しかし、過去からのいくつかの制約によって、バージョンを重ねる中でこの仕組みは弱まりました。バッファー不足が続く一部の状況では、タイムアウトするまでタスクが停止することが分かっているため、絶対に必要な場合を除き、使用を避けた方が安全です。
tune.buffers.reserve <number>
メモリー不足で割り当てに失敗する状況でのみ使用するため、事前に割り当てて予約するバッファー数を、スレッドごとに設定します。最小値は0で、デフォルトは4です。コア開発者が非常に具体的な理由で変更を提案する場合を除き、ユーザーがこの値を変更する理由はありません。
tune.bufsize <size>
バッファーのサイズをバイト単位で設定します。小さな値にすると、同じRAM容量でより多くのストリームを共存させられます。大きな値にすると、非常に大きなCookieを使う一部のアプリケーションが動作できるようになります。デフォルト値は16384で、ビルド時に変更できます。この値は、デフォルトから変更しないことを強く推奨します。値が非常に小さいと、統計など一部のサービスが動作しなくなり、デフォルトより大きいと、メモリー使用量が増え、システムがメモリー不足に陥る可能性があります。少なくとも、この値を増やした倍率に応じて、globalのmaxconnを同じ倍率で減らすべきです。また、HTTP/2を使用するには、この値が16384以上でなければなりません。さらに、256 MB(268435456 バイト)未満でなければなりません。HTTPリクエストのヘッダーブロックが (tune.bufsize - tune.maxrewrite) より大きい場合、HAProxyはHTTP 400 (Bad Request) エラーを返します。同様に、HTTPレスポンスのヘッダーブロックがこのサイズより大きい場合は、HTTP 502 (Bad Gateway) を返します。このパラメーターで指定した値は、32ビットマシンでは8の倍数、64ビットマシンでは16の倍数へ、自動的に切り上げる点に注意してください。関連項目: tune.bufsize.large、tune.bufsize.small。
tune.bufsize.large <size>
大きなバッファーのサイズをバイト単位で設定します。デフォルトでは、大きなバッファーのサポートは無効で、この値を設定して明示的に有効にしなければなりません。
これらのバッファーは、通常のバッファーサイズを変更せずに、より多くのデータをバッファーに保持する必要がある、特定の状況向けに設計されています。大きなバッファーが暗黙的に使用されることはありません。関連項目: tune.bufsize。
大きなバッファーを設定すると、起動時にスレッドごとに、内部処理用の特別な大きなバッファーを3つ割り当てる点に注意してください。
tune.bufsize.small <size>
小さなバッファーのサイズをバイト単位で設定します。デフォルト値は1024です。
これらのバッファーは、メモリー消費が限られ、通常サイズのバッファーを割り当てる必要はなさそうな、特定の状況向けに設計されています。ただし、小さなバッファーでは足りない場合は、自動的に再割り当てし、標準サイズのバッファーに切り替えます。
現時点で自動的に使用するのは、レスポンスヘッダーを送信するHTTP/3プロトコルだけです。それ以外では、“use-small-buffers” オプションで、特定のプロキシに対して小さなバッファーのサポートを有効にできます。関連項目: tune.bufsize。
関連項目: option use-small-buffers
tune.cli.max-payload-size <size>
CLIのコマンドに渡すペイロードで、許容するサイズの上限を設定します。
CLIでは、コマンドラインの長さはバッファーサイズに制限されます。つまり、すべてのコマンドとその引数は、処理するためにバッファーに収まらなければなりません。ただし、コマンドラインの最後のコマンドに渡せるペイロードは除きます。このペイロードには、必要に応じて専用の領域を割り当てられ、そのサイズをこのパラメーターで制限します。デフォルト値は128KBです。
ほとんどの用途には十分な値のはずですが、変更する場合は慎重に選ばなければなりません。非常に大きな値は、HAProxyの性能に影響する可能性があります。コマンドによっては、巨大なペイロードの処理にかなり時間がかかり、ウォッチドッグを作動させるおそれがあります。
CLIの詳細は、管理マニュアルを参照してください。
tune.comp.maxlevel <number>
圧縮レベルの上限を設定します。圧縮レベルは、圧縮時のCPU使用量に影響します。この値は、圧縮時のCPU使用量に影響します。圧縮を使う各ストリームは、この値で圧縮アルゴリズムを初期化します。デフォルト値は1です。
tune.defaults.purge
動的バックエンドをサポートするため、現在は、名前付きのdefaultsセクションをすべて解析後もメモリーに保持します。実行時に追加するバックエンドは、名前付きのdefaultsを基に設定しなければならないため、これが必要です。
defaultsのインスタンス数が多い場合、かなりのメモリーを消費する可能性があります。このような場合で、動的バックエンドが不要なら、このオプションを使用して、解析後にdefaultsセクションを強制的に削除できます。ただし、参照元のプロキシがコピーできない設定を含む、参照されているdefaultsセクションは、引き続き保持しなければなりません。たとえば、defaultsセクションでTCP/HTTPルールやtcpcheckのルールセットを定義する場合が該当します。
tune.disable-fast-forward
データの高速転送を無効にします。高速転送は、ストリームを起こさずに、一方から他方へ直接データを渡すことで転送を最適化する仕組みです。このディレクティブで、その最適化を無効にできます。カーネルTCPスプライシングとゼロコピー転送もすべて無効にする点に注意してください。このコマンドは通常の使用を意図したものではなく、一般には、複雑なデバッグ作業で開発者が提案する場合にだけ使用します。
tune.disable-zero-copy-forwarding
データのゼロコピー転送を全体で無効にします。ゼロコピー転送は、チャネルのバッファーを使用しないことで、データの高速転送を最適化する仕組みです。このディレクティブで、その最適化を無効にできます。カーネルTCPスプライシングもすべて無効にする点に注意してください。
関連項目: tune.pt.zero-copy-forwarding、tune.applet.zero-copy-forwarding、tune.h1.zero-copy-fwd-recv、tune.h1.zero-copy-fwd-send、tune.h2.zero-copy-fwd-send、tune.quic.zero-copy-fwd-send
tune.epoll.mask-events <event[,...]>
HAProxyの歴史の中で、Linuxカーネルのepollの仕組みの不具合による、複雑な問題がいくつか発生しました。通常は非常にまれで、報告者の環境以外では再現せず、epollを無効にしてpollへ切り替えることでしか回避できない場合があります。これは、高性能を求める環境では満足できる方法ではありません。問題は毎回、ごく特定の、まれなイベントの種類にだけ影響するため、それらをマスクできれば、より受け入れやすい回避策になる可能性があります。このオプションは、一部のまれなイベントを警告せずに無視し、入力イベント(種類を特定しない着信イベントを通知するもの)に置き換えることで、それを可能にします。その結果、一部の場所で高速なエラー処理経路を避け、通常の経路だけを使用します。カーネルの不具合を診断または回避するために専門家から指示された場合を除き、決して使用すべきではありません。
このオプションは、マスクするイベントを表す単語をコンマで区切った一覧を、1つの引数として受け取ります。現在サポートするイベントは次のとおりです: - “err”: EPOLLERRイベントをマスクします - “hup”: EPOLLHUPイベントをマスクします - “rdhup”: EPOLLRDHUPイベントをマスクします
例:
tune.events.max-events-at-once <number>
非同期タスクハンドラー(event_hdl API)が、一度に処理できるイベント数を設定します。<number> は1から10000までにすべきです。値が大きいと、タスクが中断せずに重い処理を行い、スレッドの競合を引き起こす可能性があります。一方、値が小さいと、実行のたびに十分な数のイベントを消費できず、イベントの生成側に追いつけないため、タスクの再スケジュールが繰り返される可能性があります。デフォルト値は、ビルド時に強制できます。そうしなければ、100になります。
tune.fail-alloc
DEBUG_FAIL_ALLOCを指定してコンパイルした場合、または “-dMfail” を指定して起動した場合に、メモリー割り当ての試行が失敗する確率をパーセントで指定します。0(失敗しない)から100(成功しない)まででなければなりません。デバッグや、メモリー割り当ての失敗を適切に処理できることの確認に役立ちます。指定しなければ、比率は0です。ただし、コマンドラインオプション “-dMfail” は、失敗率を自動的に1%にするため、テストのために設定を変更する必要はありません。
tune.fd.edge-triggered { on | off } [ EXPERIMENTAL ]
対応するFDで、エッジトリガー方式のポーリングを有効 (‘on’) または無効 (‘off’) にします。現在サポートするのはepollだけです。epoll_ctl()の呼び出し数を大幅に減らし、状況によっては性能を少し改善する場合があります。まだ実験的な機能で、不具合が残っていると接続が停止するおそれがあり、デフォルトでは無効です。
tune.glitches.kill.cpu-usage <number>
不具合が多すぎる接続を強制終了する、CPU使用率の下限を0から100までで設定します。対象は、glitches-thresholdの制限に達した接続です。非常に長く続く接続が、性能に影響を与えずに不正な動作をすることが多い環境では、悪影響がない間はその動作にかかわらず接続を維持し、CPUが忙しくなってから強制終了したい場合があります。このパラメーターは、不具合数のしきい値に達した接続を、CPU使用率が指定した値以上なら積極的に強制終了し、それ未満なら決して強制終了しないように指定します。CPU使用率はスレッドごとに測定するため、不正に動作する接続が1つだけでも強制終了される場合があります。デフォルトはゼロで、glitches-thresholdに達した接続は自動的に強制終了されます。目安として、通常観測するCPU使用率の2倍、または通常のCPU使用率にアイドル分の半分を加えた値を設定します(たとえば、通常のCPU使用率が60%なら、80を設定することが考えられます)。tune.h2.fe.glitches-threshold、tune.quic.fe.sec.glitches-threshold、tune.h1.fe.glitches-thresholdのいずれも設定していなければ、このパラメーターは効果がありません。globalの “tune.h2.fe.glitches-threshold”、“tune.h1.fe.glitches-threshold”、“tune.quic.fe.sec.glitches-threshold” も参照してください。
tune.h1.be.glitches-threshold <number>
HTTP/1バックエンド接続の不具合数のしきい値を設定し、しきい値に達した後は接続を自動的に強制終了します。不正に動作する接続に対して、明示的なルールを書かずに自動的に強制終了できます。デフォルト値はゼロで、しきい値を設定しないことを意味し、どのイベントも接続の切断を引き起こしません。典型的なイベントには、形式が不正でも “accept-unsafe-violations-in-http-response” によって受け入れたヘッダーがあります。ゼロ以外を指定するなら、多少の不具合があるサーバーに影響を与えずに効果を得られるよう、数百または数千程度にすべきでしょう。“tune.glitches.kill.cpu-usage” を使い、CPU使用率が一定の水準を超えたときだけ接続を強制終了することもできます。設定したしきい値の75%で、接続をクローズモードに切り替え、該当する場合は"Connection: close"を通知し、穏やかな切断を試みる点に注意してください。これによって、多少の不具合がある接続は、進行中の転送を中断する危険を冒さずに、しばらくすると使用されなくなります。
関連項目: tune.h1.fe.glitches-threshold、bc_glitches、tune.glitches.kill.cpu-usage
tune.h1.fe.glitches-threshold <number>
HTTP/1フロントエンド接続の不具合数のしきい値を設定し、しきい値に達した後は接続を自動的に強制終了します。不正に動作する接続に対して、明示的なルールを書かずに自動的に強制終了できます。デフォルト値はゼロで、しきい値を設定しないことを意味し、どのイベントも接続の切断を引き起こしません。典型的なイベントには、形式が不正でも “accept-unsafe-violations-in-http-request” によって受け入れたヘッダーがあります。ゼロ以外を指定するなら、多少の不具合があるクライアントに影響を与えずに効果を得られるよう、数百または数千程度にすべきでしょう。“tune.glitches.kill.cpu-usage” を使い、CPU使用率が一定の水準を超えたときだけ接続を強制終了することもできます。設定したしきい値の75%で、接続をクローズモードに切り替え、該当する場合は"Connection: close"を通知し、穏やかな切断を試みる点に注意してください。これによって、仕様に多少違反するクライアントも、新しい接続を確立して影響なく動作を続ける機会を得られます。進行中の転送を中断する危険がある、強制的な切断を引き起こさずに済みます。
関連項目: tune.h1.be.glitches-threshold、fc_glitches、tune.glitches.kill.cpu-usage
tune.h1.zero-copy-fwd-recv { on | off }
H1マルチプレクサーで、データのゼロコピー受信を有効 (‘on’) または無効 (‘off’) にします。デフォルトで有効です。
関連項目: tune.disable-zero-copy-forwarding、tune.h1.zero-copy-fwd-send
tune.h1.zero-copy-fwd-send { on | off }
H1マルチプレクサーで、データのゼロコピー送信を有効 (‘on’) または無効 (‘off’) にします。デフォルトで有効です。
関連項目: tune.disable-zero-copy-forwarding、tune.h1.zero-copy-fwd-recv
tune.h2.be.glitches-threshold <number>
バックエンド接続の不具合数のしきい値を設定し、そこに達した接続を自動的に強制終了します。不正に動作する接続に対して、明示的なルールを書かずに自動的に強制終了できます。デフォルト値はゼロで、しきい値を設定しないことを意味し、どのイベントも接続の切断を引き起こしません。一部のH2サーバーは、長く続く接続で時折、少数の不具合を起こす場合があります。そのため、ゼロ以外を指定するなら、多少の不具合があるサーバーに影響を与えずに効果を得られるよう、数百または数千程度にすべきでしょう。“tune.glitches.kill.cpu-usage” を使い、CPU使用率が一定の水準を超えたときだけ接続を強制終了することもできます。設定したしきい値の75%で、将来のストリームに対するGOAWAYを通知し、穏やかな切断を試みる点に注意してください。これによって、多少の不具合がある接続は、進行中の転送を中断する危険を冒さずに、しばらくすると使用されなくなります。
関連項目: tune.h2.fe.glitches-threshold、bc_glitches、tune.glitches.kill.cpu-usage
tune.h2.be.initial-window-size <number>
送信接続のHTTP/2初期ウィンドウサイズを設定します。これは、サーバーがHAProxyからの確認応答を待たずに応答できるバイト数です。この設定は、ヘッダーには影響せず、ペイロードの内容にだけ影響します。指定しない場合は、tune.h2.initial-window-sizeで設定した共通のデフォルト値を適用します。この値を少し増やすと、クライアント間で不公平が生じる代わりに、ダウンロードを高速化したり、サーバーのCPU使用量を減らしたりできる場合があります。不公平を生じさせないtune.h2.be.rxbufを、代わりに使用する方が適切です。この設定は、リソース使用量には影響しません。
関連項目: tune.h2.initial-window-size。
tune.h2.be.max-concurrent-streams <number>
送信接続ごとのHTTP/2同時ストリーム数の上限(サーバーへの1つの接続で、応答待ちのリクエスト数)を設定します。指定しない場合は、tune.h2.max-concurrent-streamsで設定したデフォルトを適用します。デフォルトの100より小さくすると、サーバーに対して維持する確立済み接続は増えますが、サイトの応答性が改善する可能性があります。“http-reuse” が “always” の場合は、同じ接続に異なるクライアントを混在させすぎないよう、この値を減らすことを推奨します。あるクライアントがほかより遅いと、「先頭ブロッキング」と呼ばれる仕組みが、その接続を共有する全クライアントのダウンロード速度に連鎖的な影響を及ぼしやすいためです(この場合、tune.h2.be.initial-window-sizeを低く保ってください)。この値を増やさないことを強く推奨します。低い値(通常は1..5)で動作させるのが最適な場合もあります。
tune.h2.be.max-frames-at-once <number>
バックエンド接続で一度に処理する、HTTP/2受信フレーム数の上限を設定します。非常に大きなバッファーを扱う場合は、小さな値(数十から数百)にすると、遅延を低く保ち、複数の接続間の公平性を改善するのに役立ちます。デフォルト値はゼロで、制限を設けないことを意味します。
tune.h2.be.rxbuf <size>
送信接続のHTTP/2受信バッファーサイズを、バイト単位で設定します。サイズはtune.bufsizeの倍数へ切り上げ、データをアップロードするすべてのストリームで共有します(HEADERSフレームとDATAフレームの両方が対象です)。どの場合も、各ストリームには必ず1つのバッファーを与え、未使用バッファーの7/8を、ペイロードをダウンロードするストリーム間で共有します。これによって、アップロード性能を大幅に改善し、http-reuseが “always” のとき、複数のクライアントで共有するバックエンド接続の先頭ブロッキング (HoL) を回避できます。通知するストリームごとのウィンドウは、空き領域を反映して自動調整するため、実際にはtune.h2.be.initial-window-sizeを変更する必要はないはずです。すべてのストリームを処理するのに必要なサイズより小さい値を設定した場合は、その最小サイズを使用します。デフォルト値は約1600kです(各16kBのバッファーを持つ100ストリーム)。
関連項目: tune.h2.be.initial-window-size、tune.h2.fe.rxbuf、http-reuse。
tune.h2.fe.glitches-threshold <number>
フロントエンド接続の不具合数のしきい値を設定し、そこに達した接続を自動的に強制終了します。不正に動作する接続に対して、明示的なルールを書かずに自動的に強制終了できます。デフォルト値はゼロで、しきい値を設定しないことを意味し、どのイベントも接続の切断を引き起こしません。一部のH2クライアントは、長く続く接続で時折、少数の不具合を起こす場合があります。そのため、ゼロ以外を指定するなら、多少の不具合があるクライアントに影響を与えずに効果を得られるよう、数百または数千程度にすべきでしょう。“tune.glitches.kill.cpu-usage” を使い、CPU使用率が一定の水準を超えたときだけ接続を強制終了することもできます。設定したしきい値の75%で、将来のストリームに対するGOAWAYを通知し、穏やかな切断を試みる点に注意してください。これによって、仕様に多少違反するクライアントも、新しい接続を確立して影響なく動作を続ける機会を得られます。進行中の転送を中断する危険がある、強制的な切断を引き起こさずに済みます。
関連項目: tune.h2.be.glitches-threshold、fc_glitches、tune.glitches.kill.cpu-usage
tune.h2.fe.initial-window-size <number>
受信接続のHTTP/2初期ウィンドウサイズを設定します。これは、クライアントがHAProxyからの確認応答を待たずにアップロードできるバイト数です。この設定は、ヘッダーには影響せず、ペイロードの内容(POSTリクエストの本文)にだけ影響します。指定しない場合は、tune.h2.initial-window-sizeで設定した共通のデフォルト値を適用します。この値を増やすと、アップロードを高速化できる場合があります。デフォルト値はtune.bufsize (16384) と等しく、pingの往復時間が100ミリ秒ならストリームごとに少なくとも1.25 Mbps、1ミリ秒なら125 Mbpsの帯域幅を実現できます。リソース使用量には影響しません。大きすぎる値を使用すると、大容量のアップロードと並行してページにアクセスする際に、クライアントの応答性が低下する可能性があります。不公平を生じさせないtune.h2.fe.rxbufを、代わりに使用する方が適切です。
関連項目: tune.h2.initial-window-size。
tune.h2.fe.max-concurrent-streams <number> [args...]
受信接続ごとのHTTP/2同時ストリーム数の上限(クライアントからの1つの接続で、応答待ちのリクエスト数)を設定します。指定しない場合は、tune.h2.max-concurrent-streamsで設定したデフォルトを適用します。デフォルトの100より大きくすると、遅延の大きいネットワークで、小さなオブジェクトが多数ある複雑なサイトのページ読み込み時間が、多少改善する場合があります。一方、クライアントが一度により多くのリソースを割り当てられるため、メモリー使用量が増える可能性もあります。デフォルト値の100は通常適切で、この値は変更しないことを推奨します。同時実行数が多いと、多数のストリームを使う接続を大量に扱う際の処理負荷と遅延にも影響し、サービス拒否攻撃を仕掛けやすくするおそれがあります。このコマンドは、数値の後に次のオプション引数を指定できます。
- rq-load {
<number>| auto | ignore }:
- min
<number>:
例:
tune.h2.fe.max-frames-at-once <number>
フロントエンド接続で一度に処理する、HTTP/2受信フレーム数の上限を設定します。非常に大きなバッファーを扱う場合は、小さな値(数十から数百)にすると、遅延を低く保ち、複数の接続間の公平性を改善するのに役立ちます。デフォルト値はゼロで、制限を設けないことを意味します。
tune.h2.fe.max-rst-at-once <number>
フロントエンド接続で一度に処理する、HTTP/2受信RST_STREAM数の上限を設定します。指定した数のRST_STREAMフレームを受信すると、接続ハンドラーを優先度の低いキューに移し、ほかのすべてのタスクの後に処理します。非常に小さな値(1または数個)にすると、RST_STREAMの大量送信による影響を大幅に減らすのに役立ちます。ユーザーがブラウザーの停止ボタンをクリックしたときにもRST_STREAMは発生しますが、キューに入れ直すことで増える数ミリ秒の遅延は、通常体感できません。一方、この処理は、大量送信による負荷を大幅に減らすのに通常有効です。デフォルト値はゼロで、制限を設けないことを意味します。
tune.h2.fe.max-total-streams <number>
受信接続ごとに処理する、HTTP/2ストリームの総数の上限を設定します。上限に達すると、HAProxyは穏やかな切断のためのGOAWAYフレームを送信し、保留中のすべてのストリームが閉じた後に接続を閉じることをクライアントに通知します。実際には、クライアントはこれを受信すると、できるだけ早く接続を閉じ、次のリクエスト用に新しい接続を確立する傾向があります。クライアントが非常に長く接続し続け、サーバー群の中で偏りを生じさせる場合などに、これが有用で望ましいことがあります。たとえば、非常に動的な環境では、負荷の増加に対応して新しいロードバランサーを随時作成し、負荷が下がったら、確立済みの接続を切らずに停止したい場合があります。ここで上限を設定すると、接続の寿命が制限されて頻繁に更新され、その一部は別のノードに確立される可能性があるため、既存のリソースが速やかに解放されます。
この上限と、前述の “tune.h2.fe.max-concurrent-streams” には、暗黙の関係があることを理解することが重要です。HAProxyは、クライアントとフロントエンドの間ですでに送信中になっている可能性がある、保留中のストリームを常に受け入れて処理します。そのため、通知する上限には、max-concurrent-streamsで設定した値を必ず自動的に加えます。この値を厳密な上限とし、仕様に違反するクライアントがこれを超えた場合は接続を閉じます。したがって、ログから接続ごとのリクエスト数を数えると、クライアントがストリームを作成する速度によって、max-total-streamsから (max-total-streams + max-concurrent-streams) までの値が観測されます。
デフォルト値はゼロで、プロトコルに由来する上限 (2^30 ~= 10.7億) 以外の制限を設けません。1000程度の値でも、ほとんどのクライアントに体感できる遅延を生じさせずに、頻繁な接続の更新を促せます。値が小さすぎると、頻繁なTLS再接続によってCPU使用量が増え、ページの読み込み時間も増加する可能性があります。一部の負荷テストツールは再接続に対応せず、この設定でエラーを報告する場合があるため、性能ベンチマークを実行するときは無効にする必要があるかもしれません。“tune.h2.fe.max-concurrent-streams” も参照してください。
tune.h2.fe.rxbuf <size>
受信接続のHTTP/2受信バッファーサイズを、バイト単位で設定します。サイズはtune.bufsizeの倍数へ切り上げ、データをアップロードするすべてのストリームで共有します(HEADERSフレームとDATAフレームの両方が対象です)。どの場合も、各ストリームには必ず1つのバッファーを与え、未使用バッファーの7/8を、ペイロードをアップロードするストリーム間で共有することで、アップロード性能を大幅に改善できます。通知するストリームごとのウィンドウは、空き領域を反映して自動調整するため、実際にはtune.h2.fe.initial-window-sizeを変更する必要はないはずです。すべてのストリームを処理するのに必要なサイズより小さい値を設定した場合は、その最小サイズを使用します。デフォルト値の1600k(各16kBのバッファーを持つ100ストリーム)では、RTTが100msのクライアントに対して、約130 Mbpsのアップロード速度を実現できます。
関連項目: tune.h2.fe.initial-window-size、tune.h2.be.rxbuf。
tune.h2.header-table-size <number>
HTTP/2の動的ヘッダーテーブルのサイズを設定します。デフォルトは4096バイトで、65536バイトを超えることはできません。大きな値にすると、一部のクライアントは、対応状況によって、より小さなリクエストを送信できる場合があります。このメモリー量は、HTTP/2接続ごとに消費します。変更しないことを推奨します。
tune.h2.initial-window-size <number>
受信接続と送信接続の両方について、HTTP/2初期ウィンドウサイズのデフォルト値を設定します。受信接続ではtune.h2.fe.initial-window-sizeを指定していない場合に、送信接続ではtune.h2.be.initial-window-sizeを指定していない場合に、この値を使用します。初期値と、ストリームごとの最小値の両方に使用します。デフォルト値は16384 (tune.bufsize) で、アップロードでは、pingの往復時間が100ミリ秒のネットワークでストリームごとに少なくとも約1.25 Mbps、1ミリ秒のローカルネットワークで125 Mbpsの帯域幅を実現できます。tune.h2.be.rxbufとtune.h2.fe.rxbufで定めた制限の範囲で、使用中の受信バッファー数が上限に達していない場合、未使用のバッファーを受信ストリーム間で共有します。そのため、通常はこのデフォルト設定を変更する意味はありません。この値を変更すると、アップロード速度が上がる一方、ダウンロード時にクライアント間の不公平も増すため、代わりに、接続方向別のtune.h2.fe.initial-window-sizeとtune.h2.be.initial-window-sizeを使用することを推奨します。
tune.h2.log-errors { none | connection | stream }
H2デマルチプレクサーで、ログを生成するエラーのレベルを設定します。デフォルトは “stream” で、デマルチプレクサーで発生したすべてのデコードエラーについて、ログを出力します。“connection” は、接続を無効にするエラーだけをログに出力します。“none” は、どのデコードエラーについてもログを出力しません。問題が深刻な間は一時的に “none” に切り替える必要があるとしても、プロトコルの異常を検出するため、少なくとも “connection” に設定することを推奨します。
tune.h2.max-concurrent-streams <number>
接続ごとのHTTP/2同時ストリーム数の上限(1つの接続で応答待ちのリクエスト数)のデフォルト値を設定します。受信接続ではtune.h2.fe.max-concurrent-streamsを指定していない場合に、送信接続ではtune.h2.be.max-concurrent-streamsを指定していない場合に、この値を使用します。デフォルト値は100です。接続の方向によって影響が異なるため、詳細は前述の両設定を参照してください。この設定は使用せず、方向別の設定に切り替えることを推奨します。ゼロを指定すると制限を無効にし、単一のクライアントが、HAProxyで割り当てられるだけのストリームを作成できるようになります。この値を変更しないことを強く推奨します。
tune.h2.max-frame-size <number>
HAProxyが受信可能として相手に通知する、HTTP/2フレームサイズの上限を設定します。デフォルト値は、16384とバッファーサイズ (tune.bufsize) の大きい方です。いずれの場合も、HAProxyはバッファーより大きなフレームサイズへの対応を通知しません。主な用途は、大きなバッファーを使用するときに、最大フレームサイズの設定を制限することです。フレームサイズが大きすぎると、性能に影響したり、一部の相手が不正に動作したりする可能性があります。この値を変更しないことを強く推奨します。
tune.h2.zero-copy-fwd-send { on | off }
H2マルチプレクサーで、データのゼロコピー送信を有効 (‘on’) または無効 (‘off’) にします。デフォルトで有効です。
関連項目: tune.disable-zero-copy-forwarding
tune.http.cookielen <number>
キャプチャーするCookieの長さの上限を設定します。“capture cookie xxx len yyy” に指定できる最大値となり、それより大きい値は、この値に自動的に切り詰めます。すべてのCookieキャプチャーは、個別の設定値に関係なく、このサイズのメモリーを割り当てるため(同じプールを共有します)、大きすぎる値を設定しないことが重要です。この値はリクエストとレスポンスそれぞれに適用するため、接続ごとに割り当てるメモリーは、この値の2倍です。指定しない場合、上限は63文字です。この値を変更しないことを推奨します。
tune.http.logurilen <number>
ログに記録するリクエストURIの長さの上限を設定します。重要なクエリ文字列を含む長いリクエストURIが、ログ行で切り詰められるのを防ぎます。syslogの制限とは関係ありません。この上限を増やす場合は、’log … len yyy’ パラメーターも増やすことができます。syslogデーモンにも、専用の設定ディレクティブが必要になる場合があります。デフォルト値は1024です。
tune.http.maxhdr <number>
受信するHTTPメッセージで許容するヘッダー数の上限を設定します。先頭行を含めたヘッダー数がこの値を超えるメッセージは、リクエストなら “400 Bad Request”、レスポンスなら “502 Bad Gateway” のステータスコードで拒否します。デフォルト値は101です。広く使用されているApacheサーバーも同じ上限を採用していることから、あらゆる用途に十分な値です。不具合のあるアプリケーションが修正されるまでの間、一時的に動作させるために、この上限を増やすと役立つ場合があります。使用できる範囲は1..32767です。ヘッダーを追加するたびに、ストリームごとに32ビットのメモリーを消費するため、この上限を大きくしすぎないでください。
HTTP/1.1はテキストプロトコルなので、メッセージ送信時には特別な制限はありません。メッセージの解析時に制限すれば十分です。HTTP/2とHTTP/3はバイナリープロトコルで、エンコード処理が必要です。プロトコルで定められた制約を守るため、ヘッダーのエンコード時にも上限を設けます。この上限は十分に大きいものの、意図的に文書化していません。同じ理由で、デコードの初期段階にも同じ上限を適用します。
tune.idle-pool.shared { full | on | off }
同じサーバーのアイドル接続プールを、スレッド間で共有するかどうかを制御します。同じスレッドグループの全スレッドで共有する ‘on’、すべてのスレッドで共有する ‘full’、無効にする ‘off’ を指定できます。デフォルトでは、サーバーへの持続接続数を最小限にし、接続の再利用率を最適化するため、同じスレッドグループのスレッド間で共有します (‘on’)。ほかのスレッドグループとの共有は、性能に影響する可能性があるため、デフォルトでは有効にしませんが、接続の再利用を最大化することを優先する場合には役立ちます。デバッグのためや、HAProxyの接続再利用に不具合が疑われるときは、このオプションを “off” にして、複数スレッド間のアイドルプール共有を強制的に無効にすると便利な場合があります。このオプションを無効にする前に、高い性能を得るために接続の再利用に依存するすべてのサーバーで、“pool-low-conn” に保守的な値を設定することを強く推奨します。そうしないと、スレッド数が増えるにつれて、接続が非常に頻繁に閉じられる可能性があります。
tune.idletimer <timeout>
空のバッファーが、おそらくアイドル状態のストリームに関連付いているとHAProxyが判断するまでの時間を設定します。大きなデータと小さなデータを交互に転送するときに、一部のパケットサイズを最適に調整するために使用します。splice()を使うかどうか、SSLで大きなバッファーを送信するかどうかの判断を、このパラメーターで調節します。値はミリ秒単位で、0から65535までです。ゼロを指定すると、HAProxyはアイドルストリームを検出しようとしません。デフォルトは1000で、エンドユーザーの操作の間(たとえば、クリックする前にページを読む時間)を適切に検出できるようです。この値を変更する理由はないはずです。後述のtune.ssl.maxrecordを参照してください。
tune.listener.default-shards { by-process | by-thread | by-group }
通常、すべての “bind” 行は、単一のシャード、つまりプロセスの全スレッドが待ち受ける単一のソケットを作成します。スレッドが多いと効率が悪く、ポーリング状態の更新や各スレッドへのイベント配信で、カーネルに大きな負荷を生じさせることもあります。最近のOSは、受信接続の負荷分散をサポートします。同じアドレスとポートに複数のソケットをバインドできるようにし、受信接続を各ソケットへ均等に振り分けることで、各スレッドは、自分がバインドされているソケットで待つ接続だけを扱います。これによって、カーネル側の負荷を大きく減らし、受信接続の処理性能を向上させます。HAProxyでは通常、“bind” 行の “shards” 設定で有効にします。このデフォルトは1で、各リスナーがプロセス内で単一になることを意味します。プロセッサーが多いシステムでは、デフォルトを “by-thread” にしてスレッドごとに常に1つのリスニングソケットを作るか、“by-group” にしてスレッドグループごとに常に1つ作る方が便利な場合があります。“by-thread” では、各リスナーにスレッド数と同じ数のソケットが必要になるため、ファイルディスクリプターの使用量に注意してください。また、一部のOS(FreeBSDなど)では、同じアドレスのソケット数は256以下に制限されます。“by-group” は、スレッドグループが単一のデフォルト構成では “by-process” と同等です。この仕組みに対応していないシステムでは、同じソケットを共有する動作にフォールバックします。デフォルトは “by-group” で、複数のバインドをサポートしないシステムやソケットファミリーでは、“by-process” にフォールバックします。
tune.listener.multi-queue { on | fair | off }
リスナーの複数キューによる接続受け付けを、有効 (‘on’ / ‘fair’) または無効 (‘off’) にします。リスナー自身だけで受け付ける代わりに、“bind” 行で実行を許可されたすべてのスレッドに、受信トラフィックを分散します。これによって、より均等にトラフィックを分散し、拡張性を大きく改善できます。特に、外部の処理(たとえば、あるスレッドと競合するネットワーク割り込み)によって、スレッドごとの負荷が不均一になり得る環境で有効です。デフォルトの “on” モードは、サンプルの中から接続数が最も少ないスレッドを選び、割り当てを最適化します。長く続く接続では、全スレッドを稼働させ続けられるため、最適な選択となることが多いでしょう。もう1つの “fair” モードは、その時点の負荷にかかわらず、すべてのスレッドを順に選びます。短命な接続や、スレッドが非常に多く、最初のモードでは最も負荷の低いスレッドを見つける確率が低いマシンに、より適している場合があります。最後に、トラブルシューティングや、接続が短命で、OSがすでに十分よく分散していると判断できる状況では、“off” で再分散の仕組みを強制的に無効にできます。デフォルトは “on” です。
tune.lua.bool-sample-conversion { normal | pre-3.1-bug }
HAProxyのサンプルオブジェクトをLuaへ渡すときに、どのように扱うかを明示的に指定します。たとえば、Luaスクリプトからネイティブのコンバーター、サンプル取得関数、変数などを使用するとき、HAProxyは内部のsmp型を対応するLuaの型へ変換します。従来の実装では、真偽値の扱いに曖昧さがあります。LuaからHAProxyのsmpへの変換では真偽値を正しく保持しますが、HAProxyのsmpからLuaへの変換では、誤って整数へ変換していました。つまり、真偽値を返すサンプル取得関数やコンバーターをLuaから使用すると、整数の0または1を返していました。残念ながら、Luaでは真偽値と整数を相互に置き換えられません。そのため、曖昧さを避けるには、“tune.lua.bool-sample-conversion” を、“normal”(従来の動作を廃して一貫性を高めます)、または “pre-3.1-bug”(従来の動作を強制して、既存のスクリプトのロジックが不正に動作するのを防ぎます)に、明示的に設定しなければなりません。明示的に設定せず、設定ファイルからLuaスクリプトを読み込むと、HAProxyは警告を出力し、従来の動作に合わせて、暗黙に “pre-3.1-bug” をデフォルトとします。使用中のLuaスクリプトが、HAProxyのboolサンプルを真偽値として正しく扱っていることを確認した後に、このオプションを “normal” に設定することを推奨します。
この設定を有効にするには、すべての “lua-load” または “lua-load-per-thread” ディレクティブより前に指定しなければなりません。そうしないと無視されます。
tune.lua.burst-timeout <timeout>
「バースト」実行タイムアウトは、すべてのLuaハンドラーに適用します。タイムアウトするまでにハンドラーが終了または処理を譲渡しなければ、処理を中止します。スレッドの競合や、トラフィックを処理できない時間が長くなりすぎること、最終的にはウォッチドッグの作動によるプロセスのクラッシュを防ぐためです。処理の譲渡をまたいで時間を累積する、ほかのLuaタイムアウトとは異なり、burst-timeoutは、Luaの1回の実行区間が設定したタイムアウトを超えないことを保証します。
ここでいう処理の譲渡とは、core.(m)sleep()やcore.yield()のようにLuaの処理を譲渡する関数を明示的に呼び出すか、自動的な強制譲渡(tune.lua.forced-yieldを参照)によって、Luaの実行を実際に中断することです。関連するタスクが再スケジュールされると、後で実行を再開します。すべてのLuaハンドラーが処理を譲渡できるわけではないため、譲渡できるハンドラーと、できないハンドラーを区別する必要があります。
処理を譲渡できるハンドラー(タスク、アクションなど)でタイムアウトする場合、そのシステムに対して “tune.lua.forced-yield” が大きすぎる可能性があります。小さくすると改善する場合がありますが、Lua関数内の要所に手動の処理譲渡を追加すると効果があるかどうかを確認するのもよいでしょう。また、中断できない特定のLuaライブラリ関数に、ハンドラーが時間をかけすぎている可能性もあります。
処理を譲渡できないハンドラー(Luaコンバーター、サンプル取得関数)では、単純に計算量が多すぎることを示している場合があります。このようなハンドラーは、リクエストの実行をブロックすることが多いため、リクエスト処理が先に進めるよう、すぐに終了することが期待されます。その点から、設計が不適切なのかもしれません。この場合は、“tune.lua.forced-yield” を小さくしても効果がないため、Lua関数をより高速に動作するよう最適化するのが、一般的な解決方法です。
このタイムアウトでは、Luaが実際に実行している時間だけを数えます。Luaがcore.sleepを実行した場合、スリープ時間は含めません。デフォルトのタイムアウトは1000msです。
注意: ハンドラーからGCサイクルを開始すると(明示的に要求した場合も、しばらくしてLuaが自動的に開始した場合も)、GCサイクルの時間も含めます。
GCサイクルの時間を差し引く方法がないため、飽和したシステムでは、誤検知を引き起こす場合があります(GCが追いつくのに苦労し、利用可能な実行時間の大半を消費するためです)。そのような場合は、次のような解決方法が考えられます。
- スクリプトを最適化してLuaのメモリー使用量を減らせるか確認します。
- LuaのGCパラメーターを細かく調整するか、手動のGCサイクルを要求します。両方を行うこともできます。
(参照: https://www.lua.org/manual/5.4/manual.html#pdf-collectgarbage )
- tune.lua.burst-timeoutを増やします。
0を設定すると、この保護を完全に無効にします。
tune.lua.forced-yield <number>
このディレクティブは、Luaエンジンが <number> 個の命令を実行するたびに、処理を強制的に譲渡させます。長いスクリプトを中断し、HAProxyのスケジューラーが、接続の受け付けやトラフィックの転送など、ほかのタスクを処理できるようにします。デフォルト値は、“lua-load-per-thread” で読み込むスクリプトでは10000命令、“lua-load” で読み込むスクリプトではMAX(500, 10000 / nbthread)命令です(複数のスレッドがグローバルなLuaロックを奪い合う競合を避けながら性能を確保する、最適な値であることが分かっています)。
HAProxyが頻繁にLuaコードを実行し、より高い応答性が必要なら、この値を小さくできます。Luaコードがかなり長く、その結果がデータの処理に絶対に必要なら、<number> を増やせます。ただし、マルチスレッドでは競合が増える可能性があるため、値は慎重に設定すべきです。
tune.lua.log.loggers { on | off }
現在のプロキシに適用されるロガーがあれば、そのロガーを通じたLuaスクリプトの出力の記録を、有効 (‘on’) または無効 (‘off’) にします。
デフォルトは ‘on’ です。
tune.lua.log.stderr { on | auto | off }
stderrを通じたLuaスクリプトの出力の記録を、有効 (‘on’) または無効 (‘off’) にします。‘auto’ の場合は、次のいずれかに当てはまるときに、stderrへの記録を ‘on’ にします。
- tune.lua.log.loggersが 'off' に設定されている場合。
- プロキシ外のコンテキストでスクリプトを実行し、グローバルロガーがない場合。
- プロキシのコンテキストでスクリプトを実行し、ロガーが関連付けられていない場合。
有効にすると、tune.lua.log.loggersで設定したログに加えて、このログも出力する点に注意してください。
デフォルトは ‘auto’ です。
tune.lua.maxmem <number>
Luaが使用できるRAMの上限を、プロセスごとにメガバイト単位で設定します。デフォルトはゼロで、無制限を意味します。スクリプトの不具合によってシステムがメモリー不足にならないよう、上限を設定することが重要です。
tune.lua.openlibs [all | none | <lib>[,<lib>...]]
Luaの状態を初期化するときに読み込む、Lua標準ライブラリを選択します。引数は、table、io、os、string、math、utf8、package、debugから選んだライブラリ名を、コンマで区切った一覧です。一覧の代わりに、特別な値 “all” または “none” を使用できます。“none” とライブラリ名を組み合わせることはできません。デフォルト値は “all” です。
baseとcoroutineライブラリは、この設定に関係なく常に読み込みます。baseはHAProxyが依存するLuaの基本関数を提供し、coroutineは、HAProxyがcoroutine.create()を独自の安全な実装で上書きするために必要です。
この設定に関係なく、HAProxyではfork()と新しいスレッドの作成を、すでにデフォルトで禁止しています。再び有効にできるのは、globalの “insecure-fork-wanted” ディレクティブだけです。読み込むライブラリを制限すると、Luaスクリプトにさらす攻撃対象をさらに減らせます。具体的には: - “os” を除くと、os.execute()とos.exit()を防ぎます - “io” を除くと、io.open()とio.popen()を防ぎます - “package” を除くと、require()によるネイティブCモジュールの読み込みを防ぎます - “debug” を除くと、debug.getupvalue()、debug.getmetatable()、debug.sethook()によるHAProxy内部の調査を防ぎます
例:
この設定は、すべての “lua-load”、“lua-load-per-thread”、“lua-prepend-path” ディレクティブより前に指定しなければなりません。そうしないと、解析エラーを返します。
tune.lua.service-timeout <timeout>
Luaサービスの実行タイムアウトです。無限ループや、Luaで時間をかけすぎることを防ぐのに役立ちます。Luaが実際に実行している時間だけを数えます。Luaがスリープした場合、その時間は含めません。デフォルトのタイムアウトは4sです。
tune.lua.session-timeout <timeout>
Luaセッションの実行タイムアウトです。無限ループや、Luaで時間をかけすぎることを防ぐのに役立ちます。Luaが実際に実行している時間だけを数えます。Luaがスリープした場合、その時間は含めません。デフォルトのタイムアウトは4sです。
tune.lua.task-timeout <timeout>
用途は “tune.lua.session-timeout” と同じですが、このタイムアウトはタスク専用です。タスクは、HAProxyの稼働期間中ずっと存在することがあるため、デフォルトではタイムアウトを設定しません。サーバーをチェックするタスクなどが、その例です。
tune.max-checks-per-thread <number>
スレッドごとの実行中チェック数を設定します。この数を超えると、スレッドはヘルスチェックを実行するために、負荷の低いスレッドを積極的に探すか、自分で実行中のチェック数が減るまでキューで待機させます。デフォルト値はゼロで、この制限を設けないことを意味します。非常に多数の高コストのチェックを多くのスレッドで実行し、負荷が不均等で、起動時のヘルスチェックが不規則にタイムアウトするような環境で、必要になる場合があります。典型例は、古い版よりヘルスチェックのCPU負荷が約20倍になるOpenSSL 3.0を使用する場合です。これによって、すべてのスレッド間でヘルスチェックの処理量を均等化しようとします。大半の構成では、このパラメーターを変更する必要はありません。チェックの実行が遅い場合、値が小さすぎると、ヘルスチェックが大幅に遅くなる可能性がある点に注意してください。
tune.maxaccept <number>
プロセスがほかの処理へ切り替える前に、続けて受け付けられる接続数の上限を設定します。単一プロセスモードでは、以前は、接続頻度が高いときに値を大きくすると性能が上がりましたが、複数キューでは、もはやそうではありません。この値はリスナーごとに適用され、リスナーがバインドされているプロセス数を考慮します。最もよい結果が得られた4をデフォルトとします。古い設定から大幅に大きな値を引き継いでいる場合は、削除することで、性能と応答時間の両方が改善する可能性があります。マルチプロセスモードでは、リスナーがバインドされているプロセス数の2倍で割ります。-1を指定すると、制限を完全に無効にします。通常は、この値を調整する必要はないはずです。
tune.maxpollevents <number>
ポーリングシステムを呼び出したときに、一度に処理できるイベント数の上限を設定します。デフォルト値は、OSに合わせた値です。200より小さくすると、ネットワーク帯域幅を犠牲にして遅延がわずかに減り、200より大きくすると、遅延を犠牲にして帯域幅がわずかに増える傾向が観測されています。設定値は1000000以下でなければなりません。
tune.maxrewrite <number>
予約するバッファー領域のサイズを、バイト単位で設定します。予約領域は、ヘッダーの書き換えや追加に使用します。ソケットからの最初の読み取りは、bufsize-maxrewriteを超えてバッファーを埋めることはありません。従来のデフォルトはbufsizeの半分でしたが、大量のヘッダーを追加することはまれなので、あまり意味はありません。大きすぎると、大きなリクエストやレスポンスを処理できなくなります。小さすぎると、すでに大きなリクエストやPOSTリクエストに、新しいヘッダーを追加できなくなります。一般には、1024程度にするのが適切です。bufsizeの半分より大きい場合は、自動的にその半分へ再調整します。そのため、bufsizeを変更するときに心配する必要はありません。
tune.max-rules-at-once <number>
処理の譲渡に対応するルールセット評価関数で、一度に評価できるルール数の上限を設定します。たとえば、“tcp-request content” や “http-request” ルールを大量に含む設定は、珍しくありません。評価を中断しなければ、同じポーリングループ内で、あるルールセットのすべてのルールを評価します。そのため、多数のルールと、CPU負荷の高いアクション(コンテンツを処理するものなど)を組み合わせると、スレッドの競合が生じる可能性があります。このオプションは、コンテンツを扱うルールセット(コンテンツ検査のため、すでに処理の譲渡に対応するもの)について、同じポーリングループで実行するルール数が <number> を超えないことを保証します。具体的には、評価関数に処理を強制的に譲渡させ、次のポーリングループで評価を再開させます。
対象のルールセットは次のとおりです。
- “tcp-request content”
- “tcp-response content”
- “http-request”
- “http-response”
デフォルト値は50です。
tune.memory.hot-size <number>
スレッドごとに、ローカルキャッシュで即座に使用できる状態に保持し、ほかのスレッドが決して回収できないメモリー量を設定します。このメモリーへのアクセスは、ロック不要で非常に高速です。スレッド間の競合が極端に激しい状況で、よい性能を保つには、十分な量を確保することが不可欠です。値はバイト単位で、デフォルト値は、ビルド時にCONFIG_HAP_POOL_CACHE_SIZEで設定します。そのデフォルトは524288 (512 kB) です。特に、性能プロファイルでメモリー割り当てへの負荷が大きいことが分かる場合など、一部の用途では、大きな値にすると性能が向上する可能性があります。経験上、CPUコアごとのL2キャッシュサイズの1倍から2倍が、適切な値です。大きすぎる値は、CPUのL3キャッシュを非効率に使用して性能を低下させ、メモリーの消費量も増やします。この値は変更しないか、少しずつ増やすことを推奨します。スレッドごとのCPUキャッシュを完全に無効にするには、非常に小さな値でも機能する場合がありますが、コマンドラインで “-dMno-cache” を使用する方が適切です。
tune.notsent-lowat.client <size>
カーネルがソケットごとに行うバッファリングを調整し、バッファー内のデータ量が、この値と測定したウィンドウサイズの合計に達すると、ソケットの送信側がいっぱいであることを通知するようにします。ソケットバッファーには、必要最小限のバイト数に加え、HAProxyが再び送信を試みるまでに送信する分に相当する、小さな余裕だけを残すという考え方です。小さい値(通常はtune.bufsize程度)を設定すると、システムバッファーのメモリー使用量と、バッファー内のデータを送り出すことで生じるアプリケーションレベルの遅延を、大幅に減らせます。対応するシステムでは、通常、tune.sndbuf.clientとtune.sndbuf.clientより、効果的で正確な設定になります。接続ごとに適用し(設定に応じて、クライアントからの接続、またはサーバーへの接続)、TCP接続でのみ使用します。デフォルトはゼロで、無制限を意味します。Linuxでのみ利用できます。
tune.pattern.cache-size <number>
パターン検索キャッシュのサイズを <number> エントリーに設定します。過去の検索と結果を記憶するLRUキャッシュです。ACLとマップが行う、処理の遅いパターン検索で使用します。具体的には、“sub”、“reg”、“dir”、“dom”、“end”、“bin” の照合方法と、大文字と小文字を区別しない文字列を対象とします。パターン式に適用するため、設定の同じ行で指定したすべてのパターン(ファイルから読み込んだものも含みます)の中から検索した結果を、記憶できます。HTTPアクションやCLIで更新したエントリーは、自動的に無効にします。キャッシュサイズのデフォルトは10000エントリーです。キャッシュはスレッドまたはプロセスごとに保持するため、そのメモリー使用量は、32ビットシステムではプロセスまたはスレッドごとに約5 MB、64ビットシステムでは約8 MBに収まります。このキャッシュには、ごくわずかな衝突のリスクがあり、その程度はキャッシュサイズを2^64で割った値です。通常、毎秒10000リクエスト、デフォルトの10000エントリーのキャッシュサイズでは、総当たり攻撃によって1回の衝突が生じる確率は、60年後に1%、または6年後に0.1%です。これは、部品の経年劣化によってメモリーが破損するリスクより、はるかに小さいと考えられます。受け入れられない場合は、このパラメーターを0にすると、キャッシュを無効にできます。
tune.peers.max-updates-at-once <number>
メッセージの送信時に、HAProxyが一度に処理を試みる、スティックテーブルの更新数の上限を設定します。更新するデータの取得には、いくつかのロック操作が必要です。制限しないと、スレッド数の多いマシンではCPU負荷が高くなり、古いプロセスと新しいプロセス間の初回の一括転送中に、トラフィックの遅延が増える場合もあります。一方、小さすぎる値でも、CPUのオーバーヘッドが増え、完了までの時間が長くなる場合があります。デフォルト値は200で、変更しないことを推奨します。
tune.pipesize <size>
カーネルのパイプバッファーのサイズを、このサイズ(バイト単位)に設定します。デフォルトでは、システム標準のパイプサイズを使用します。ただし、TCPスプライシングを使用する場合、パイプサイズを大きくすると、性能が向上することがあります。特に、パイプが埋まらず、splice()を何度も呼び出していると疑われる場合が該当します。カーネルのメモリー使用量に影響するため、影響を理解していない場合は変更してはいけません。
tune.pool-high-fd-ratio <number>
接続を再利用できず、新しい接続を作成する必要があるときに、アイドル接続の終了を開始する、HAProxy全体のファイル記述子使用数の上限を設定します。値は、HAProxyが使用できるファイル記述子の最大数に対する割合(パーセント)です。デフォルトは25です(ファイル記述子の4分の1を使うと、フロント側の最大接続数のおよそ半分について、バックエンド側にアイドル接続を保持できます。接続の再利用を目的とする一般的な場合、これ以上にしても、おそらくあまり意味はありません)。
tune.pool-low-fd-ratio <number>
再利用のために、接続をアイドルプールへ追加するのをやめる、HAProxy全体のファイル記述子使用数の上限を設定します。値は、HAProxyが使用できるファイル記述子の最大数に対する割合(パーセント)です。デフォルトは20です。
tune.pt.zero-copy-forwarding { on | off }
パススルー・マルチプレクサーで、データのゼロコピー転送を有効 (‘on’) または無効 (‘off’) にします。使用するには、カーネルのスプライシングも設定する必要があります。デフォルトで有効です。
関連項目: tune.disable-zero-copy-forwarding、option splice-auto、option splice-request、option splice-response
tune.quic.be.cc.cubic-min-losses <number>
Cubic輻輳制御アルゴリズムが、実際に損失イベントとみなすために必要な、損失パケット数を定義します。通常、損失イベントはすべて輻輳の結果とみなし、それだけで、Cubicは小さいウィンドウから再開します。しかし実験によると、輻輳とはまったく関係のない、さまざまな原因で損失が生じることがあります。これは、単に見かけ上の損失と呼べるもので、ウィンドウを調整しても、通信を遅くする以外の効果はありません。よくある原因としては、無線の電波状態の悪化、順序が入れ替わった配送、クライアントのCPU負荷が高いことによる不規則な遅延、システムタイマーの精度不足などが挙げられます。この設定では、2つのACKの間に累積した損失を、損失イベントとみなすための最小数(デフォルトは1)を変更し、見かけ上の損失に対して、Cubicを少し寛容にできます。実験では、大幅な改善が観測された例もありますが、常に、再送で無駄になる帯域幅の増加と、輻輳したリンクを飽和させるリスクの増加を伴いました。値2は、いくつかの指標を比較するために、短時間使用できます。専門家が事前に状況を分析していない限り、決して2を超える値にしないでください。デフォルト値と最小値は1です。常に1を使用してください。
tune.quic.cc.cubic.min-losses <number> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.cc.hystart { on | off }
QUIC接続で、HyStart++ (RFC 9406) アルゴリズムを有効 (‘on’) または無効 (‘off’) にします。これは、多くのパケット損失を引き起こす可能性がある、輻輳制御アルゴリズムのスロースタート段階の代わりに使用します。デフォルトでは無効です。
tune.quic.cc-hystart { on | off } (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.cc.max-frame-loss <number>
同じQUICフレームを、損失したと判定できる回数の上限を設定します。超えると、その接続は失敗したものとみなし、直ちに閉じます。
デフォルト値は10です。
tune.quic.max-frame-loss <number> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.cc.max-win-size <size>
フロントエンド側またはバックエンド側の、単一のQUIC接続の輻輳制御器に対する、最大ウィンドウサイズのデフォルト値を設定します。値は整数で記述し、任意で接尾辞 ‘k’、’m’、‘g’ を付けられます。10kから4gの範囲でなければなりません。
QUICマルチプレクサーも、データ送信時に新しいストリームバッファーを割り当てられるか判断するため、現在の輻輳ウィンドウサイズを使用します。そのため、最大輻輳ウィンドウサイズは、このアロケーターの上限としても機能します。
デフォルト値は480kです。
bindとserverの “quic-cc-algo” オプションも参照してください。
tune.quic.frontend.default-max-window-size <size> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.cc.reorder-ratio <0..100, in percent>
計算したパケット並べ替えしきい値に適用する比率です。小さすぎると、多数のパケット損失を検出する場合があります。
デフォルト値は50です。
tune.quic.reorder-ratio <0..100, in percent> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.max-idle-timeout <timeout>
フロントエンド側またはバックエンド側で、QUICのmax_idle_timeoutトランスポートパラメーターを設定します。HAProxyの時間形式に従い、ミリ秒単位で表します。接続が実効的な期間にわたって非アクティブであった場合に、通知せずに接続を閉じるまでの時間を決定します。両方のエンドポイントが、次のようにネゴシエートした同じ値を使用します。- 両方のパラメーターがゼロでなければ、両者の最小値 - 片方だけがゼロでなければ、両者の最大値 - 両方のパラメーターがゼロなら、この機能を無効にします。
デフォルト値は30sです。
tune.quic.frontend.max-idle-timeout <timeout> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.sec.glitches-threshold <number>
フロントエンド側またはバックエンド側の接続ごとに、異常の回数のしきい値を設定します。このしきい値に達すると、接続を自動的に終了します。これにより、明示的なルールを書かずに、不正な動作をする接続を自動的に終了できます。デフォルト値はゼロです。しきい値を設定しないことを意味し、どのイベントでも接続を閉じません。QUICクライアントによっては、長時間維持した接続で、ときどき少数の異常を引き起こすことがあります。そのため、多少の不具合があるクライアントに影響を与えずに効果を得るには、ゼロ以外の値を設定する場合、数百や数千程度にすべきでしょう。“tune.glitches.kill.cpu-usage” を使用すると、CPU使用率が一定の水準を超えた場合にのみ、接続を終了することもできます。
関連項目: fc_glitches、tune.glitches.kill.cpu-usage
tune.quic.frontend.glitches-threshold <number> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.fe.sec.retry-threshold <number>
半開接続の数がこの値に達すると、設定したすべてのQUICリスナーについて、Retry機能を動的に有効にします。半開接続とは、ハンドシェイクがまだ成功も失敗もしていない接続です。この設定を機能させるには、クラスターシークレットを設定する必要があります。設定していない場合は、通知せずに無視します(“cluster-secret” の設定を参照)。QUIC Retryの使用を強制している場合も、通知せずに無視します(“quic-force-retry” を参照)。
デフォルト値は100です。
QUIC Retryの詳細は、https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1.2 を参照してください。
tune.quic.retry-threshold <number> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.fe.sock-per-conn { default-on | force-off }
QUICのフロントエンド接続で、受信と送信にソケットをどのように使用するかを、グローバルに指定します。各接続がリスナーのソケットを共有するか、それぞれの接続で専用のソケットを割り当てられます。
デフォルト値は “default-on” です。QUIC接続ごとに、専用のソケットを割り当てます。QUICトラフィックが大量にある場合に、最もよい性能を得るために推奨する選択肢です。また、QUIC接続でデータを失わずにソフトストップを適切に実行し、sendto()操作中の一時的なエラーを効率的に処理できるようにする、唯一の方法でもあります。ただし、UDPネットワークスタックの高度な機能に依存します。プラットフォームに互換性がないと判断した場合、HAProxyは起動時に、自動的に “force-off” モードへ切り替えます。特権ポートで動作するQUICリスナーでは、uid 0での実行が必要になる場合や、対象uidにそのポートへのバインドを許可するため、システムケーパビリティなど、OS固有の調整が必要になる場合がある点に注意してください。globalの “setcap” ディレクティブも参照してください。
値 “force-off” は、共有するリスナーのソケットで、QUICの転送を行うことを意味します。FDの消費量を減らせるため、トラフィックが少ない場合には、適切な妥協点となり得ます。ただし、多数のスレッド間でリスナーを共有する場合や、多数のQUIC接続を同時に使用できる場合は、CPU使用率が高くなるため、性能は最適になりません。
この設定は、各bindの “quic-socket” オプションと組み合わせて適用します。グローバルな調整で “default-on” モードを使用すると、“quic-socket listener” を指定したものを除き、各リスナーで有効にします。一方、グローバルに “force-off” を使用すると、個別の設定に関係なく、すべてのリスナーのインスタンスに適用します。
tune.quic.socket-owner { connection | listener } (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。新しいオプションの名前は “tune.quic.fe.sock-per-conn” です。従来の値 “connection” は “default-on” に、“listener” は “force-off” に対応します。
tune.quic.be.stream.data-ratio <0..100, in percent>
この設定は、各ストリームで転送中のデータバイト数の、厳密な上限を設定できます。QUICストリームの接続単位のrxbuf設定に対する割合(パーセント)で表し、その結果をbufsizeの単位で切り上げます。
デフォルト値は90です。アップロードは1つまたは少数のストリームでのみ行い、残りはダウンロードにのみ使用する、最も一般的なWebの利用形態に適しています。ストリームの接続単位のrxbuf上限が妥当な水準であれば、開いているストリームのうち、一部だけが最大容量まで割り当てられるようにします。
多数のアップロード用ストリームを並行して使用し、ストリーム間の不公平が問題になっているアプリケーションでは、この比率を下げて、公平性を高め、ストリームごとの帯域幅を減らすことが、適切な場合があります。
関連項目: “tune.quic.be.stream.rxbuf”、“tune.quic.fe.stream.rxbuf”、“tune.quic.be.stream.max-concurrent”、“tune.quic.fe.stream.max-concurrent”
tune.quic.frontend.stream-data-ratio <0..100, in percent> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.stream.max-concurrent <number>
フロントエンド側では、通知するinitial_max_streams_bidiトランスポートパラメーターの値として使用します。接続の存続期間中、リモートピアが同時に開くことを許可する、双方向ストリーム数の上限として適用します。実質的に、HTTP/3クライアントの同時リクエスト数を制限します。
デフォルト値は100です。小さくすると、ストリームの受信バッファリング能力を制限し、アップロードのスループットが低下する場合がある点に注意してください。QUICストリームの接続単位のrxbuf設定を増やすと、改善できます。
バックエンド側では、単一の接続で多重化する同時リクエスト数を制限するため、HAProxyがローカルで適用します。ピアのフロー制御によって、さらに制限される場合があります。サイトの応答性を高めるため、開くバックエンド接続数が増えることと引き換えに、デフォルト値の100を下げる必要がある場合があります。フロントエンド側と同様、この設定は受信バッファリング能力にも直接影響しますが、こちらではHTTPのダウンロード能力を制限します。主に “tune.bufsize” より大きいHTTPレスポンスを扱う場合は、QUICストリームのrxbuf設定を増やせます。
関連項目: “tune.quic.be.stream.rxbuf”、“tune.quic.fe.stream.rxbuf”、“tune.quic.be.stream.data-ratio”、“tune.quic.fe.stream.data-ratio”
tune.quic.fe.stream.max-total <number>
単一のQUIC接続で処理できるリクエスト数の上限を設定します。この総数に達すると、接続の正常な終了処理を開始します。HTTP/3では、GOAWAYフレームに相当します。残っている転送がすべて完了すると、最後に接続を閉じます。
この設定は、QUICのフロー制御機構を通じて、接続に対する厳密な上限として適用します。ピアが違反した場合は、直ちに接続を閉じます。
この設定を使用すると、クライアントがリクエストの送信を続けるために、ときどき新しい接続を開くよう強制し、接続を長く維持しすぎることを防げます。ただし、値が小さいと、TLSハンドシェイクによって、クライアント側の遅延と、両側のCPU消費量が増えます。
デフォルト値は0です。QUICプロトコルの符号化による制限(2^60、10億の10億倍を超える数)以外に、特別な制限を設けないことを意味します。
tune.quic.frontend.max-streams-bidi <number> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.stream.rxbuf <size>
この設定は、QUICのフロントエンド接続で転送中のデータバイト数の、厳密な上限です。initial_max_dataトランスポートパラメーターの値として再利用します。遅延に応じて、ピアのアップロード帯域幅に直接影響し、HAProxyの接続ごとのメモリー消費量にも直接影響します。
デフォルト値は0です。max-concurrentとbufsizeの積から、自動的に生成しなければならないことを意味します。たとえば、バックエンドのアプリケーションが、遅延の大きなネットワークで大量のアップロードを行う場合は、増やせます。
関連項目: “tune.quic.be.stream.max-concurrent”、“tune.quic.fe.stream.max-concurrent”、“tune.quic.be.stream.data-ratio”、“tune.quic.fe.stream.data-ratio”
tune.quic.frontend.max-data-size <size> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.tx.pacing { on | off }
QUIC送信のペーシング機能を、有効 (‘on’) または無効 (‘off’) にします。デフォルトで有効です。ペーシングの目的は、データの送信を平準化して、ネットワーク上の損失を減らすことです。大半の状況では、再送を避けることで、ネットワークのスループットが大幅に向上します。ただし、帯域幅が非常に大きく、遅延の小さいネットワークでは、意図しない遅延を防ぎ、CPU消費量を減らすため、無効にするとよい場合があります。
bindとserverの “quic-cc-algo” オプションも参照してください。
tune.quic.disable-tx-pacing (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.be.tx.udp-gso { on | off }
QUIC送信のUDP GSO機能を、有効 (‘on’) または無効 (‘off’) にします。デフォルトで有効です。このカーネル機能は、単一のシステムコールで複数のデータグラムを送信でき、大量の転送で効率がよくなります。送信に問題があると疑われる場合、開発者の提案に従って無効にするとよい場合があります。
tune.quic.disable-udp-gso (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.listen { on | off }
フロントエンド側のQUICトランスポートプロトコルを無効にします。QUICリスナーはすべて作成しますが、着信データグラムを待ち受けません。そのため、HAProxyはフロントエンド側のQUICトラフィックを処理しません。
デフォルト値は “on” です。QUICトラフィックに問題があると疑われる場合、このオプションを使用すると、個々の設定行を変更せずに、QUICリスナーを簡単に切り替えられます。
サンプル取得関数 “quic_enabled” も参照してください。
tune.quic.mem.tx-max <size>
QUICスタックがトランスポート層で送信に使用できる、メモリー量の上限を設定します。転送中のバイト数と、マルチプレクサーの出力バッファーの、両方の上限として機能します。スレッドの競合を避けるため、この上限は厳密には適用しないので、状況によっては超える場合がある点に注意してください。また、各接続は常に、少なくとも2つのデータグラムのウィンドウを使用できるため、適切なmaxconnと組み合わせて使用すべきです。
tune.quic.frontend.max-tx-mem <size> (deprecated)
このキーワードは3.3で非推奨となり、3.5で削除します。QUIC設定を整理する作業の一環です。使用した場合は、フロントエンドの接続にのみ適用します。
tune.quic.zero-copy-fwd-send { on | off }
QUICマルチプレクサーで、データのゼロコピー送信を有効 (‘on’) または無効 (‘off’) にします。デフォルトで有効です。
関連項目: tune.disable-zero-copy-forwarding
tune.renice.runtime <number>
この設定オプションは、-20から19までの値を受け付けます。man 2 setpriorityに記載された、スケジューリング優先度を適用します。設定の解析後に適用するため、ワーカーまたは単独で動作するプロセスだけが、この優先度を適用します。通常は、設定の解析を行うプロセス(tune.renice.startup)より、高い優先度になるように設定します。
関連項目: tune.renice.startup
tune.renice.startup <number>
この設定オプションは、-20から19までの値を受け付けます。man 2 setpriorityに記載された、スケジューリング優先度を適用します。残りの設定を適用する前に、この優先度を適用するため、設定の解析時に優先度を下げたい場合に役立ちます。設定の解析前に、単独で動作するプロセスまたはワーカーに適用します。設定を解析した後は、tune.renice.runtimeを使用していなければ、以前の優先度に戻します。
関連項目: tune.renice.runtime
tune.rcvbuf.backend <size>
接続されていないソケットの、カーネルの受信バッファーサイズを、このサイズに固定します。フロントエンドで、リスナーモードのQUICとlog-forwardに使用できます。システムのデフォルトのバッファーは、集約された大量のトラフィックを受信するソケットには小さすぎる場合があります。その場合、損失や、QUICでは再送が生じる可能性があり、トラフィックが多いときに、接続の確立が遅くなる場合があります。値はバイト単位で、各ソケットに適用します。リスナーモードでは、すべての接続でソケットを共有し、ソケットの総数は、“bind” 行の “shards” の値で決まります。一律に適切な値はありません。接続ごとに想定するサイズに、想定する接続数を掛けた値が、適切な値になります。大きな値は、カーネルが縮小する場合があります。接続されたソケットに対応する “tune.rcvbuf.client” と “tune.rcvbuf.server”、および送信側の設定である “tune.sndbuf.backend” と “tune.sndbuf.frontend” も参照してください。
tune.rcvbuf.client <size>
クライアント側またはサーバー側の、カーネルのソケット受信バッファーサイズを、指定したバイト数に固定します。すべてのTCP/HTTPフロントエンドとバックエンドに適用します。通常は決して設定すべきではありません。デフォルトのサイズ (0) では、利用できるメモリー量に応じて、カーネルが値を自動調整します。ただし、非常に小さい値(たとえば4096)に設定すると、受信したデータを大量にバッファリングするのを防ぎ、カーネルのメモリーを節約できる場合があります。ただし、値を小さくすると、CPU使用率が大幅に増えます。
tune.recv_enough <size>
HAProxyは、短い読み取りがソケットバッファーの終わりを示すことを検出するため、いくつかの手掛かりを使用します。そのうちの1つが、読み取りで <recv_enough> バイトを超えるデータが返ることです。デフォルトは10136(1448ずつの7セグメント)です。この設定でデフォルト値を変更すると、telnetやSSHセッションなど、多数の短いメッセージを扱う処理に、より適切に対応できます。
tune.ring.queues <number>
リングバッファーの前に設ける、書き込みキューの数を設定します。デバッグ中のトレースのCPU使用率に影響する場合があり、値が小さすぎても大きすぎても、大きな影響が生じる可能性があります。適切な値は、開発者が実験で決定しているため、特定の問題への対処を試みるために指示された場合を除き、変更を試みる理由はないはずです。最適な値は時とともに変わる可能性があるため、バージョンアップ後も設定に残すべきではありません。
tune.runqueue-depth <number>
タスクを実行するとき、一度に処理できるタスク数の上限を設定します。デフォルト値はスレッド数に応じて決まりますが、35から280の範囲にあり、最も高いリクエスト処理速度と、最も小さい遅延が得られる傾向があります。大きくすると、I/Oの処理に遅延が生じる場合があり、小さすぎると、余分なオーバーヘッドが生じる場合があります。スレッド数が多い場合は、小さい値が有利です。かなり大きな値を試す場合は、最大遅延を可能な限り抑えるため、tune.sched.low-latencyと、場合によってはtune.fd.edge-triggeredも有効にすると、役立つ場合があります。
tune.sched.low-latency { on | off }
低遅延タスクスケジューラーを、有効 (‘on’) または無効 (‘off’) にします。デフォルトでは、最も効率がよいため、HAProxyは複数のクラスのタスクを、クラスごとにまとめて処理します。しかし、tune.runqueue-depthを大きな値にして実行すると、リクエストや接続の遅延に、測定できるほどの影響が出る場合があります。この低遅延設定を有効にすると、優先度の低いクラスのタスクが存在する場合、常に、ほかのタスクより先に実行します。大量のトラフィックがある中でも、新しいリクエストや接続が受ける最大遅延を減らせますが、その大量のトラフィックへの影響は大きくなります。通常の用途では、無効のままにしておく方が適切です。デフォルト値はoffです。
tune.sndbuf.backend <size>
接続されていないソケットの、カーネルの送信バッファーサイズを、このサイズに固定します。バックエンド側のUNIXソケットとUDPログ、およびフロントエンド側のリスナーモードのQUICに使用できます。システムのデフォルトのバッファーは、多くの接続(またはログ送信元)で共有するソケットには小さすぎる場合があります。その場合、損失や再送が生じる可能性があり、トラフィックが多いときに、新しい接続の確立が遅くなります。値はバイト単位で、各ソケットに適用します。リスナーモードでは、すべての接続でソケットを共有し、ソケットの総数は、“bind” 行の “shards” の値で決まります。一律に適切な値はありません。接続ごとに想定するサイズに、想定する接続数を掛けた値が、適切な値になります。大きな値は、カーネルが縮小する場合があります。接続されたソケットに対応する “tune.sndbuf.client” と “tune.sndbuf.server”、および受信側の設定である “tune.rcvbuf.backend” と “tune.rcvbuf.frontend” も参照してください。
tune.sndbuf.client <size>
クライアント側またはサーバー側の、カーネルのソケット送信バッファーサイズを、指定したバイト数に固定します。すべてのTCP/HTTPフロントエンドとバックエンドに適用します。通常は決して設定すべきではありません。デフォルトのサイズ (0) では、利用できるメモリー量に応じて、カーネルが値を自動調整します。ただし、非常に小さい値(たとえば4096)に設定すると、受信したデータを大量にバッファリングするのを防ぎ、カーネルのメモリーを節約できる場合があります。ただし、値を小さくすると、CPU使用率が大幅に増えます。もう1つの用途は、極端に遅いクライアントで、カーネルがバッファーの大部分を読み取られるまで待ってから、HAProxyに再び通知するために発生する、書き込みタイムアウトを防ぐことです。Linuxで性能を損なわずに、メモリー使用量と応答性を、より細かく制御できる効果的な設定については、tune.notsent-lowat.clientとtune.notsent-lowat.serverも参照してください。
tune.ssl.cachesize <number>
グローバルなSSLセッションキャッシュのサイズを、ブロック数で設定します。ブロックは、ピア証明書を含まない、符号化されたセッションを格納するのに十分な大きさです。ピア証明書を含む、符号化されたセッションは、その証明書のサイズに応じて、複数のブロックに格納します。ブロックは、約200バイトのメモリーを使用します(sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE という、shctx_init 関数で使用する計算に基づきます)。デフォルト値は、ビルド時に指定できます。指定しなければ、20000です。キャッシュがいっぱいになると、最も長く使用されていないエントリーを削除し、再割り当てします。値を大きくすると、各ユーザーのセッションを可能な限り長く保持できるため、このような削除と、CPU負荷の高いSSLハンドシェイクの回数が減ります。すべてのエントリーは、起動時に事前割り当てします。値を0にすると、SSLセッションキャッシュを無効にします。
tune.ssl.capture-buffer-size <number>
Client Helloの暗号リスト、拡張リスト、楕円曲線リスト、楕円曲線点の形式をキャプチャーするために使用する、バッファーの最大サイズを設定します。値が0(デフォルト値)の場合は、キャプチャーを無効にします。それ以外の場合は、SSL/TLS接続ごとにバッファーを割り当てます。
tune.ssl.certificate-compression { auto | off }
この設定は、TLS 1.3の拡張である、証明書圧縮機能 (RFC 8879) を設定できます。
“auto” に設定すると、TLSライブラリのデフォルト値を使用します。
“off” では、この機能を明示的に無効にしようとします。HAProxyは、圧縮した証明書の送信も、受け入れも試みなくなります。
バックエンド側とフロントエンド側の両方を設定します。
このキーワードは、OpenSSL >= 3.2.0で対応しています。
デフォルト値はautoです。
tune.ssl.default-dh-param <number>
DHE鍵交換で、一時的なDiffie-Hellman鍵を生成するために使用する、Diffie-Hellmanパラメーターの最大サイズを設定します。最終的なサイズは、サーバーのRSA(またはDSA)鍵のサイズに合わせようとしますが(たとえば、2048ビットのRSA鍵に対して、2048ビットの一時DH鍵)、この最大値は超えません。1024以上の値だけを指定できます。大きな値はCPU負荷を増やし、1024ビットを超える値には、Java 7以前のクライアントが対応していません。静的なDiffie-Hellmanパラメーターを、証明書ファイル内に直接指定するか、ssl-dh-param-fileパラメーターで指定した場合、この値は使用しません。default-dh-paramとssl-dh-param-fileのどちらも定義せず、対象のフロントエンドのサーバーPEMファイルにも、独自のDHパラメーターを指定しなければ、そのフロントエンドではDHE暗号を使用できません。
tune.ssl.force-private-cache
このオプションは、すべてのプロセス間でのSSLセッションキャッシュの共有を無効にします。クライアントがランダムなプロセスに到達することで、多数の再ネゴシエーションが必要になるため、通常は使用すべきではありません。ただし、SSLキャッシュの同期方法をいずれも使用できない、一部のOSでは、必要になる場合があります。この場合、SSLの層の手前に、ハッシュに基づくロードバランシングの層を追加すると、セッションを共有できない影響を抑えられる場合があります。
tune.ssl.hard-maxrecord <number>
SSL_write()に一度に渡す、バイト数の上限を設定します。デフォルト値の0は、無制限を意味します。tune.ssl.maxrecordとは異なり、この設定は動的には調整しません。レコードを小さくすると、スループットが低下する場合がありますが、メモリー消費量の小さいクライアントを扱う際に、必要になることがあります。
tune.ssl.keylog { on | off }
このオプションは、TLS鍵のログ記録を有効にします。SSLセッションごとのメモリー消費量が増え、性能が低下する可能性があるため、注意して使用すべきです。デフォルトでは無効です。
Wiresharkでトラフィックを復号するために必要なSSLKEYLOGFILEの生成には、これらのサンプル取得関数を使用すべきです。
https://tlswg.org/sslkeylogfile/draft-ietf-tls-keylogfile.html
SSLKEYLOGは、次の形式の行が並んだものです。
ClientRandomは、サンプル取得関数 %[ssl_fc_client_random,hex] が提供します。secretとLabelは、以下の表で確認できます。この表のすべてのラベルを含むSSLKEYLOGFILEを生成する必要があります。
以下のサンプル取得関数は、16進数の文字列を返すため、変換する必要はありません。
これらの取得関数は、フロントエンド (fc) 側とバックエンド (bc) 側にあります。“xx” を “fc” または “bc” に置き換え、適切な側を使用してください。
OpenSSL 1.1.1でのみ利用でき、TLS1.3セッションで役立ちます。
TLS < 1.3でSSLKEYLOGFILEの内容を生成するには、次の行だけが必要です。
“CLIENT_RANDOM %[ssl_fc_client_random,hex] %[ssl_fc_session_key,hex]”
syslogには理想的ではありませんが、次のようなlog-formatで、完全な鍵ログを生成できます。
HAProxyは、上記の形式を、“log-format” ディレクティブで直接使用できる、定義済みの環境変数としても提供します。
tune.ssl.keyupdate-rate-limit <limit>
毎秒受け入れるKeyUpdateの数を <limit> に制限し、超えると、フラッドとみなして接続を終了します。KeyUpdateの処理はCPU負荷が高く、大量に受信する理由はほとんどありません。値 “0” を使用すると、レート制限を無効にします。デフォルト値は100です。
tune.ssl.lifetime <timeout>
キャッシュしたSSLセッションが、有効でいられる時間を設定します。秒単位で表し、デフォルトは300 (5 min) です。キャッシュがいっぱいになると、設定した存続期間に関係なく、最も長く使用されていないセッションを削除するため、その時間だけセッションが維持されることを保証しないと、理解することが重要です。この設定の実際の役割は、セッションを長く使用しすぎることを防ぐことです。
tune.ssl.maxrecord <number>
データ転送の開始時に、SSL_write()に渡すバイト数の上限を設定します。デフォルト値の0は、無制限を意味します。SSL/TLSでは、クライアントはレコード全体を受信して初めて、データを復号できます。レコードが大きい場合、処理を開始する前に、最大16kBのデータをダウンロードしなければならないことがあります。値を制限すると、遅延が大きい、または帯域幅の小さいネットワーク上のブラウザーで、ページの読み込み時間が改善する場合があります。SSL/TLSにオーバーヘッドがあることを考慮しながら、1または2 TCPセグメント(通常、EthernetでTCPタイムスタンプを有効にすると1448バイト、無効にすると1460バイト)に収まる、最適な値を見つけることを推奨します。一般的な値である1419と2859は、テストでよい結果が得られました。“strace -e trace=write” を使用して、最適な値を見つけてください。HAProxyは、アイドル状態のストリームを検出すると、自動的にこの設定へ切り替えます(上記のtune.idletimerを参照)。tune.ssl.hard-maxrecordも参照してください。
tune.ssl.ssl-ctx-cache-size <number>
生成した証明書を格納するキャッシュのサイズを、<number> エントリーに設定します。これはLRUキャッシュです。SSL証明書の動的な生成は負荷が高いため、キャッシュします。キャッシュサイズのデフォルトは1000エントリーです。
tune.streams-elasticity <number>
すべての接続が確立しているときに、最大同時接続数 (maxconn) に対して、フロントエンド接続ごとに割り当てるストリーム数の、目標割合を定義します。この指標は、HTTP/2やQUICなど、各接続が複数のストリームを受け取れる、多重化プロトコルに適用します。常に少なくとも1つを保証するため、割合は100%以上でなければなりません。接続の設定中に、HAProxyは目標の比率を保ちながら、設定した上限まで、追加のストリームを動的に通知します。接続の確立時には、各フロントエンド接続に、少なくとも1つのストリームを割り当てます。追加のストリームは、目標割合と、設定したストリームの上限に基づいて割り当てます。これにより、負荷の変化に応じた、効率的なストリームの割り当てを実現します(負荷が低ければストリームを多くし、高ければ少なくします)。
ページごとのオブジェクトが多い、動的なサイトでは、比率を大きくすると、接続ごとに多くのストリームを使用できるため、有利です。平均して使用するストリームが少ないサイト(WebSocket、アプリケーションコード)では、120や150に近い、小さい比率(接続数より20から50%多いストリーム数)が適している場合があります。負荷が継続する状況で、ストリーム数が過剰になるのを防げます。
デフォルト値は0で、このレベルでは制限を適用しないことを意味します。そのため、H2とQUICの設定だけを適用します(接続ごとに100ストリームというデフォルト設定では、10000%に相当します)。小規模な構成(maxconnが千程度)では、引き続きこの設定を推奨します。中規模の構成(数千から数万の接続)では、通常、比率を1000から5000の間に設定し、最大負荷時に、接続ごとに10から50のストリームを使用できるようにします。大規模な構成(数十万から数百万の接続)では、より小さい値(120から200)を使用し、最大負荷時に、接続ごとに平均1.2から2のストリームを使用できるようにする場合があります。
HTTP/2とは異なり、QUICは、接続の存続期間中に、同時ストリーム数を動的に調整できます。ただし、QUICのフロー制御はHTTP/2より厳格なため、QUICを使用する場合は、接続に余分な遅延が生じないよう、十分に大きな値を指定する方が適切です。また、0-RTTを有効にしたQUICリスナーには、制限があります。この場合、ピアに通知する初期値は、ストリームの弾力的な割り当てを無視し、“tune.quic.fe.stream.max-concurrent” の設定だけに従います。ただし、この初期通知が終わった後、接続の存続期間中は、ストリームの弾力的な割り当てが引き続き機能します。
キュー内のものを含む、バックエンドのアクティブなストリームの総数を監視すると、持続可能な目標負荷の実用的な指標となり、過剰なリソース割り当てを避けるのに役立ちます。
tune.stick-counters <number>
接続またはリクエストが、“tcp-request” または “http-request” ルールの “track-sc*” アクションで、同時に追跡できるスティックカウンターの数を設定します。デフォルト値は、ビルド時にマクロMAX_SESS_STK_CTRで設定し、標準では3です。この設定で、ビルド時に渡した値を無視して変更できますが、100を超える値には設定できません。複雑な設定をHAProxyへ移植するときに、増やす必要がある場合がありますが、そのコストには注意が必要です。各エントリーは、接続ごとに16バイト、リクエストごとに16バイトを使用します。使用しない場合でも、すべてのリクエストについて、この領域をすべて割り当て、ゼロで初期化する必要があります。そのため、値を10にすると、リクエストごとのメモリー消費量が320バイト増え、リクエストごとにそのメモリーを消去するため、測定できるほどのCPUへの影響があります。一方、“track-sc” ルールを使用しない場合は、値を小さくできます(0も有効で、スティックカウンターを完全に無効にします)。
tune.takeover-other-tg-connections <value>
デフォルトでは、ほかのスレッドグループのアイドル接続を、使用しようとはしません。ただし、この動作は変更できます。<value> に指定できる値は、次のとおりです。デフォルトの “none” では、ほかのスレッドグループのアイドル接続を、使用しようとはしません。“restricted” では、reverse httpなど、新しい接続を作成できないプロトコルを使用している場合、またはstrict-maxconnを使用している場合にのみ、ほかのスレッドからアイドル接続を取得しようとします。“full” では、常に、ほかのスレッドグループでアイドル接続を探します。ほかのスレッドグループの接続を使用すると、性能が低下する場合があるため、本当に必要な場合以外は使用すべきではありません。現在、この動作はtune.idle-pool.sharedが制御します。このキーワードは、古い設定との互換性のためだけに残しており、今後、非推奨にする予定です。
tune.vars.global-max-size <size>
これら5つの調整設定は、変数システムが使用するメモリー量の上限を管理するのに役立ちます。“global” は、すべてのスコープで使用できるメモリーの総量を制限します。“proc” はプロセススコープ、“sess” はセッションスコープ、“txn” はトランザクションスコープ、“reqres” は各リクエストまたはレスポンスの処理で使用するメモリーを制限します。メモリーの集計は階層的であり、広い範囲の上限には、狭い範囲の使用量を含めます。つまり、“proc” は “sess” を、“sess” は “txn” を、“txn” は “reqres” を含みます。
たとえば、“tune.vars.sess-max-size” を100に制限すると、“tune.vars.txn-max-size” と “tune.vars.reqres-max-size” も、100を超えられません。100バイトを含む変数 “txn.var” を作成すると、使用できる領域をすべて消費します。実行時に上限を超えても、エラーメッセージは出ませんが、値が切り詰められたり、破損したりする可能性がある点に注意してください。そのため、すべての変数を格納するのに必要な領域を、必ず正確に見積もってください。
tune.zlib.memlevel <number>
各ストリームのzlib初期化時に使用する、memLevelパラメーターを設定します。圧縮処理の内部状態に、どの程度のメモリーを割り当てるかを定義します。値1は、メモリー使用量が最小ですが、速度が遅く、圧縮率も下がります。値9は、最適な速度のために、最大のメモリーを使用します。1から9までの値を指定できます。デフォルト値は8です。
tune.zlib.windowsize <number>
各ストリームのzlib初期化パラメーターとして、ウィンドウサイズ(履歴バッファーのサイズ)を設定します。値を大きくすると、メモリー使用量が増える代わりに、圧縮率が向上します。8から15までの値を指定できます。デフォルト値は15です。
3.3. デバッグ
anonkey <key>
グローバルな匿名化キーを <key> に設定します。キーは、0から4294967295までの、32ビットの数値でなければなりません。匿名化モードを有効にした場合、CLIコマンドがデフォルトで使用するキーです。実行時に、CLIコマンド “set anon global-key” で設定することもできます。管理マニュアルの、コマンドライン引数 “-dC” も参照してください。
debug.counters { on | off }
コード内のイベントカウンターの更新を、有効 (‘on’) または無効 (‘off’) にします。CLIコマンド “debug counters” で、種類 “CNT” として表示するカウンターです。これらのカウンターは、DEBUG_COUNTERSを1以上に設定してビルドした場合にのみ利用できます。値1では、デフォルトでカウンターを更新せず(“debug.counters off”)、値2では、デフォルトで更新します(“debug.counters on”)。通常は、開発者に依頼された場合や、異常に多くのCPUを消費していると疑われる場合を除き、変更する理由はありません(後者の場合は、カウンターのダンプを添えて、開発者に報告する必要があります)。CLIコマンド “debug counters” で、実行時に状態を変更することもできます。管理マニュアルを参照してください。
force-cfg-parser-pause <timeout>
このコマンドは、設定パーサーを <timeout> ミリ秒間、一時停止します。開発や、初期化スクリプトのタイムアウトのテスト、特に、非常に長いリロードを模擬する場合に役立ちます。expose-experimental-directivesを設定する必要があります。
<timeout> は、デフォルトではミリ秒単位で指定する、タイムアウト値です。ただし、この文書の冒頭で説明したように、数値に単位を付けると、ほかの単位でも指定できます。
例:
quick-exit
メモリーオブジェクトとリスナーの解放を省略し、リロード時の古いプロセスの終了を速めます。これらはすべて、プロセスの終了時にOSが回収するためです。改善はわずかです(非常に大きな設定でも、せいぜい数百ミリ秒程度)。実際の主な用途は、deinit()コードに不具合が見つかった場合に、それを回避することです。開発者から指示されない限り、使用しない方が適切です。
quiet
起動時にメッセージを一切表示しません。コマンドライン引数 “-q” と同じです。
warn-blocked-traffic-after <time>
動けなくなったタスクがトラフィックをブロックしている場合に、標準エラー出力へ警告を出すまでの、待ち時間を調整できます。待ち時間はミリ秒単位で表し、デフォルトは100 msです。指定できる値は、1 ms以上1000 ms以下でなければなりません。小さい値では警告が頻繁に出て、大きい値ではまれにしか出ません。いずれにしても、ウォッチドッグは、1秒間応答しない状態が2回続く暴走タスクを終了するため、1000 msの待ち時間では、通常、警告は出ません。長い応答時間や、対話型セッションのぎこちない動きなど、ユーザー体験を損なう可能性がある、設定の異常を検出するため、10から100msの間の値を使用することを推奨します。たとえば、重い計算を行う、設計の不適切なLuaのサンプル取得関数や、評価コストが非常に高い、巨大なmap_regまたはmap_regmのマップファイルが、こうした問題を引き起こす場合があります。比較すると、TLSハンドシェイクは1から2ミリ秒、16kBのHTTPレスポンスバッファーの圧縮は約1ミリ秒かかる場合があります。出力には、問題を起こしたタスクのスレッドダンプと、バックトレース、時間を費やしている場所の特定に役立つコンテキストを含みます。
zero-warning
このオプションを設定すると、HAProxyは、設定の処理と適用中に警告が出た場合、起動を拒否します。つまり、パラメーターの不適切な組み合わせや、設定できなかった非常に高い上限などに関する警告があると、プロセスは起動中にエラーで終了します。起動の遅い段階で出る、一部の警告は検出できません。たとえば、“daemon” モードや “master-worker” モードでグループIDを変更するときに、補助グループの破棄に失敗した場合や、fork()後にプロセスをダンプ可能に設定できなかった場合です。実行時に出る警告も検出しません。微妙な誤りの検出や、明快で将来のバージョンにも対応できる設定の維持に役立つため、頻繁に変更しない設定では、このオプションを指定することを強く推奨します。このような場合、“haproxy -c” もエラーを報告する点に注意してください。このオプションは、コマンドライン引数 “-dW” と同じです。
3.4. HTTPClientの調整
HTTPClientは、内部のHTTPライブラリです。さまざまなサブシステムから、たとえばLuaスクリプト内で使用できます。HTTPClientはデータの転送経路では使用しません。つまり、HAProxyを通過するHTTPトラフィックとは関係ありません。
httpclient.resolvers.disabled <on|off>
httpclientのDNS名前解決を無効にします。“default” resolversセクションを作成しないようにします。
デフォルト値はoffです。
httpclient.resolvers.id <resolvers id>
このオプションは、httpclientが名前解決を試みるために使用する、resolversセクションを定義します。
デフォルトの選択は、resolvers ID “default” です。このオプションを使用しないデフォルトの場合は、セクションが見つからなければ、単に名前解決を無効にします。
一方、このオプションを明示的に有効にした場合は、読み込みに失敗すると、設定エラーになります。
httpclient.resolvers.prefer <ipv4|ipv6>
このオプションは、名前解決で使用したいIPファミリーを選択できます。ネットワークでIPv6を使用できない場合に便利です。デフォルトの選択は “ipv6” です。
httpclient.retries <number>
このオプションは、リクエストが失敗した場合に、httpclientが再試行する回数を設定できます。backendの “retries” キーワードと同じ動作です。
デフォルト値は3です。
httpclient.ssl.ca-file <cafile>
このオプションは、サーバー証明書の検証に使用する、ca-fileを定義します。server行の “ca-file” オプションと、同じパラメーターを受け付けます。
このオプションを使用しないデフォルトの場合、値は “@system-ca” で、システムのCAを読み込もうとします。失敗すると、httpclientのSSLを無効にします。
一方、このオプションを明示的に有効にした場合は、失敗すると設定エラーになります。
httpclient.ssl.verify [none|required]
server行のverifyオプションと同じ動作です。’none’ を指定すると、サーバー証明書を検証しません。デフォルトの選択は “required” です。
このオプションを使用しないデフォルトの場合、値は “required” です。失敗すると、httpclientのSSLを無効にします。
一方、このオプションを明示的に有効にした場合は、失敗すると設定エラーになります。
httpclient.timeout.connect <timeout>
httpclientの接続試行について、デフォルトの最大待ち時間を設定します。
引数:
デフォルト値は5000msです。
13 - 4. プロキシ
プロキシの設定は、次のセクションに記述できます。
- defaults [
<name>] [ from<defaults_name>] - frontend
<name>[ from<defaults_name>] - backend
<name>[ from<defaults_name>] - listen
<name>[ from<defaults_name>]
“frontend"セクションは、クライアント接続を受け付けるリッスンソケットの集合を記述します。
“backend"セクションは、受け付けた接続を転送するためにプロキシが接続するサーバーの集合を記述します。
“listen"セクションは、フロントエンドとバックエンドの両方を1つのセクションにまとめた完全なプロキシを定義します。通常、TCPのみのトラフィックに有用です。
“defaults"セクションは、すべての設定をドキュメント記載の値にリセットし、後続のセクションで使う新しい値をあらかじめ設定します。“frontend”、“backend”、“listen"の各セクションは、必ずdefaultsセクションから初期設定を取得します。デフォルトでは、新しく作成するセクションより前に現れる最後のdefaultsセクションを使います。セクション行の任意のキーワード"from"の後に名前を指定すれば、初期設定の取得元となる特定の"defaults"セクションを明示できます。“defaults"セクションに名前は必須ではありませんが、読みやすさのために名前を付けることを推奨します。また、デフォルトの直前のセクション以外を指定するには、名前を付ける必要があります。“defaults"セクションの名前は任意なので、デフォルトの名前チェックは非常に緩く、重複も許されます。ただし、“defaults"セクションがほかのセクションから参照される場合、その名前はすべてのプロキシ名に課される構文に従い、defaultsセクション間で一意でなければなりません。現在何が許されているかにかかわらず、一般にセクション名の重複を避け、プロキシ名と同じ構文に従うことを推奨します。将来のバージョンでは、この規則が強制される可能性があります。また、defaultsセクションをあるプロキシが明示的に使用し、同時に別のプロキシが最後に定義されたセクションとして暗黙的に使用すると、警告が出ます。常に明示的な参照を使うか、暗黙的な使用専用の共通defaultsセクションを最後に追加して、両方の使い方を混在させないことを強く推奨します。
defaultsセクション自体が別のdefaultsセクションから初期設定を取得し、複数階層にわたって設定を継承することも可能です。これは、デフォルト設定の組をまとめた設定プロファイル(TCP用とHTTP用、短いタイムアウト用と長いタイムアウト用など)を作るのに便利ですが、継承関係がすぐに追いにくくなることがあります。
デフォルトでは、名前付きdefaultsセクションは設定解析後も保持されます。これにより、バックエンドを動的に作成するときに再利用できます。この動作は"tune.defaults.purge"キーワードでグローバルに変更できます。
すべてのプロキシ名は、英大文字と英小文字、数字、’-’(ダッシュ)、’_’(アンダースコア)、’.’(ドット)、’:’(コロン)で構成しなければなりません。ACL名は大文字と小文字を区別するため、“www"と"WWW"は異なるプロキシです。
従来は、一定の条件(フロントエンド/バックエンドの機能が同じでない場合など)を満たせば、プロキシ名の重複が認められていました。しかし、ログに多くの問題を生じさせ、CLI操作、スティックテーブルの命名、統計情報の取得にも混乱を招いていました。現在は、それぞれの機能にかかわらず、2つのプロキシには異なる名前を付ける必要があります。
現在、主に2つのプロキシモードをサポートしています。レイヤー4とも呼ばれる"tcp"と、レイヤー7とも呼ばれる"http"です。レイヤー4モードでは、HAProxyは両端の間で双方向のトラフィックを単に転送します。レイヤー7モードでは、HAProxyがプロトコルを解析し、任意の条件に基づいてリクエストやレスポンスの任意の内容を許可、ブロック、切り替え、追加、変更、削除できます。
HTTPモードでは、接続上を流れるリクエストとレスポンスに適用する処理は、フロントエンドとバックエンドのHTTPオプションの組み合わせによって決まります。HAProxyは3つの接続モードをサポートしています。
-
KAL:接続維持(“option http-keep-alive”)。デフォルトのモードです。すべてのリクエストとレスポンスを処理し、レスポンスから次のリクエストまでの間も接続を開いたままアイドル状態に保ちます。
-
SCL:サーバー側を切断(“option http-server-close”)。レスポンスの終わりを受信するとサーバー側の接続を閉じますが、クライアント側の接続は開いたままにします。
-
CLO:切断(“option httpclose”)。レスポンスの終わりで接続を閉じ、両方向に"Connection: close"を付加します。
フロントエンドとバックエンドを通過する接続に実際に適用されるモードは、次の表に従い両方のプロキシのモードから決まります。要するに、モードの関係は対称であり、接続維持が最も弱く、切断が最も強いオプションです。
バックエンドのモード
TCPフロントエンドをHTTPバックエンドにつなぐことも可能です。HTTPトラフィックだけを扱う場合には意味がありませんが、同じフロントエンドで複数のプロトコルを扱うために使えます。この場合、クライアント接続はまず生のTCP接続として処理され、その後HTTPにアップグレードされます。アップグレード前は、生データに対してコンテンツ処理を実行します。アップグレード後は、データを解析してHTXと呼ばれる内部表現で保存するため、生の表現には依存できなくなります。元に戻す方法はありません。
アップグレードには、その場で行うアップグレードと、ストリームを破棄するアップグレードの2種類があります。前者はTCPからHTTP/1へのアップグレードです。HTTP/1ではリクエスト処理が直列に行われるため、アプリケーションストリームを維持できます。後者はTCPからHTTP/2へのアップグレードです。HTTP/2は多重化プロトコルなので、アプリケーションストリームをどのHTTP/2ストリームにも対応付けられず、破棄されます。その後、HAProxyが下位層のH2マルチプレクサーで新しいHTTP/2ストリームを受信すると、新しいアプリケーションストリームが作成されます。この違いによってデータの処理方法が大きく変わるため、理解しておくことが重要です。HTTP/1へのアップグレードでは、生データに対してすでに行ったコンテンツ処理が失われたり再実行されたりすることはありません。一方、HTTP/2へのアップグレードでは、アプリケーションストリームが別々になり、各ストリームに対してすべてのフロントエンドルールが必ず評価されます。また、前述のとおり最初のTCPストリームは破棄されますが、それはフロントエンドルールが評価された後です。
TCPプロキシからHTTP処理を行う際には、もう1つ重要な点があります。HAProxyはtcp-request contentルールからHTTP/1をその場で解析できますが、HTTP/2ではできません。解析できるのはHTTP/2のプリフェイスだけです。これは、TCPでHTTPコンテンツを解析するうえで大きな制約です。具体的には、受信データがHTTPかどうかしか分かりません。たとえば、HTTP/1では簡単にできるHostヘッダーの値に基づくバックエンドの選択ができません。ただし、この欠点を緩和する方法はあります。
HTTPへのアップグレード方法は2つあります。従来からの方法は、HTTPバックエンドを選択することです。バックエンドが設定されるとアップグレードが行われます。このため、その場で行うアップグレードでは、HTTPデータ処理にバックエンドの設定だけが考慮されます。ストリームを破棄するアップグレードでは、アプリケーションストリームが破棄されるため、その処理は停止します。この方法では、前述のとおりHTTP/2接続でバックエンドを選択する際にできることが非常に限られ、ストリームが破棄されるため、あまり意味もありません。もう1つの方法は、“switch-mode http"アクションを使い、tcp-request contentルールの評価中にアップグレードすることです。この場合、フロントエンドのコンテキストでアップグレードするため、そのフロントエンドでHTTPディレクティブを定義できます。その場で行うアップグレードでは、できるだけ早い段階からHTTP解析のすべての機能を使えます。HTTPフロントエンドに近い動作です。ストリームを破棄するアップグレードでは、限られた情報からバックエンドを選んでも意味がない点を除き、何も変わりません。当然、この方法を推奨します。したがって、tcp-request contentルールでリクエストのプロトコルを調べ、HTTPへアップグレードするだけで十分です。残りのHTTP操作はすべて、フロントエンドのhttp-requestルールセットに移せます。ただし、tcp-request contentルールが各ストリームで引き続き評価されることは変えられません。
4.1. プロキシキーワード一覧表
以下のキーワードをサポートしています。多くは、限られた種類のセクションでのみ使用できます。一部のキーワードは、分かりにくい、または機能に制限のある古い構文を引き継いでおり、代わりに推奨される新しいキーワードがあるため、“deprecated”(非推奨)と記されています。”(*)“の付いたキーワードは、“no option contstats"のように"no"を前に付けて、任意に意味を反転できます。これは、デフォルトで有効なオプションを特定のインスタンスで無効にする必要がある場合に役立ちます。また、これらのオプションには"default"を前に付けることもでき、先行する"defaults"セクションでの指定にかかわらずデフォルト設定に戻せます。defaultsセクションでサポートされ、”(!)“の付いたキーワードは、名前付きdefaultsセクションでのみ使用でき、名前のないセクションでは使用できません。
注意:危険で推奨されない一部のディレクティブは、以下の表には意図的に掲載していません。これらのディレクティブの説明自体はありますが、表から除外することも、使用を思いとどまらせるための手段です。
4.2. アルファベット順のキーワードリファレンス
このセクションでは、各キーワードとその使い方を説明します。
acl <aclname> <criterion> [flags] [operator] <value> ...
アクセスリストを宣言または補完します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 可 | 可 | 可
このディレクティブは名前付きdefaultsセクションでのみ使用でき、名前のないセクションでは使用できません。defaultsセクションで定義されたACLは、そのセクションを使用するほかのセクションからは参照できません。
例:
ACLの使用方法については、セクション7 を参照してください。
backlog <conns>
想定するリスナーのバックログサイズをヒントとしてシステムに伝えます。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
このオプションは、QUICを含むストリームリスナーでのみ意味を持ちます。ただし、QUICインスタンスでの動作は同じではありません。
QUIC以外のすべてのリスナーでは、SYNフラッド攻撃への対策として、システムのSYNバックログサイズを増やす方法があります。システムによっては、システムパラメーターで調整できる場合、まったく調整できない場合、listen()システムコール時にアプリケーションから渡されるヒントを使う場合があります。デフォルトでは、HAProxyはフロントエンドのmaxconn値をlisten()システムコールに渡します。この値を利用できるシステムでは、別の値を指定できると役立つことがあるため、このbacklogパラメーターが用意されています。
Linux 2.4では、システムはこのパラメーターを無視します。Linux 2.6ではヒントとして使われ、システムは指定値を上回る最小の2の累乗まで受け付けますが、一定の上限(通常32768)を超えることはありません。
QUICリスナーでは、backlogは、進行中のハンドシェイクの最大数と、受け付けを待つ接続数の両方に共通の上限を設定します。ハンドシェイク段階は主にリモートピアとのネットワーク遅延に依存しますが、次の段階はhaproxyの負荷だけに依存します。どちらかの上限に達すると、haproxyは受信したINITIALパケットの破棄を始め、過剰な接続が減り始めるまで、新しい接続を一切割り当てないようにします。この状況により、ブラウザーが通知なしでHTTPのバージョンを下げ、TCPに切り替える可能性があります。
“maxconn"および対象OSのチューニングガイドも参照してください。
balance <algorithm> [ <arguments> ]
バックエンドで使用する負荷分散アルゴリズムを定義します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
ほかのアルゴリズム、モード、オプションを何も設定していない場合、バックエンドの負荷分散アルゴリズムは"random"になります。アルゴリズムは、各バックエンドにつき1回だけ設定できます。
NTLMのように同じ接続を必要とする認証方式では、URIに基づくアルゴリズムを使ってはなりません。後続のリクエストが別のバックエンドサーバーにルーティングされ、NTLMが依存する誤った前提が成り立たなくなるためです。
TCP/HTTPの例:
LOGバックエンドの例:
注意:“check_post"拡張を"url_param"と併用する際は、以下の注意点と制限を考慮する必要があります。
- すべてのPOSTリクエストが検討対象となります。パラメーターが、バイナリデータを含む可能性のあるボディーやエンティティー内にあるかどうかを判断する方法がないためです。したがって、ボディーにURLパラメーターがないPOSTリクエストを検討対象から除くために、別の方法が必要になることがあります(acl http_endを参照)。
- リクエストバッファーのサイズより大きな`<max_wait>`の値を使っても意味はなく、役に立ちません。バッファーサイズはビルド時に設定され、デフォルトは16 kBです。
- Content-Encodingはサポートされていません。パラメーターの検索はおそらく失敗します。また、負荷分散はラウンドロビンにフォールバックします。
- Expect: 100-continueはサポートされていません。負荷分散はラウンドロビンにフォールバックします。
- Transfer-Encoding (RFC7230 3.3.1)は最初のチャンクでのみサポートされています。パラメーター値の全体が最初のチャンクに含まれていない場合、サーバーの選択は未定義になります(実際には、最初のチャンクに実際に現れた量によって定義されます)。
- この機能は100、411、または501応答の生成をサポートしていません。
- 場合によっては、"check_post"を指定すると、メッセージ本文の内容全体を走査しようとする可能性があります。通常、線形空白または制御文字が見つかると、URLパラメーターリストと思われる部分の終わりを示すため、走査は終了します。SGML型のメッセージ本文では、おそらく問題になりません。
関連項目: “dispatch”, “cookie”, “transparent”, “hash-type”
be-unpublished
バックエンドを非公開状態で開始するように指示します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
実際には、他のプロキシが現在のプロキシを参照するuse_backendおよびdefault_backendルールは無視され、次のコンテンツスイッチングルールが評価されます。ただし、“force-be-switch"ルールを用いることでこれをバイパスできます。
この状態は無効状態に似ていますが、いくつかの違いがあります。まず、非公開バックエンドは完全に初期化され、サーバーのヘルスチェックもアクティブなままです。最後に、CLI上の"publish backend"コマンドにより、バックエンドを公開することができます。管理マニュアルを参照してください。
関連項目: “force-be-switch”
bind [<address>]:<port_range> [, ...] [param*]
フロントエンドで1つ以上のリスニングアドレスおよび/またはポートを定義します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 不可
引数:
コンマで区切られたaddress:portの組み合わせのリストを指定できます。フロントエンドはこれらのすべてのアドレスでリッスンします。フロントエンドでリッスン可能なアドレスおよびポートの数に固定の上限はなく、またフロントエンド内の"bind"文の数にも上限はありません。
例:
注意: Linuxの抽象名前空間ソケットに関して、“abns"HAProxyソケットはsun_pathの全長をアドレス長として使用します。他のプログラム(例: socat)はデフォルトで文字列長のみを使用します。socatの抽象ソケット定義に”,unix-tightsocklen=0"オプションを渡すことでHAProxyと互換性を持たせることができます。または、“abnsz"HAProxyソケットファミリを使用してください。
“source”、“option forwardfor”、“unix-bind”、PROXYプロトコルのドキュメント、およびbindオプションについて説明するセクション5 も参照してください。
capture cookie <name> len <length>
リクエストおよびレスポンスの両方でCookieをキャプチャし、ログに記録します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 不可
引数:
最初のCookieだけをキャプチャします。“cookie"リクエストヘッダーと"set-cookie"レスポンスヘッダーの両方を監視します。通常、ユーザーのCookieはログインページでしか変わらないため、ユーザー間でセッションの混線や盗用を引き起こすアプリケーションのバグを調べるのに特に役立ちます。
クライアントがCookieを提示しなかった場合、関連するログカラムには”-“が報告されます。サーバーがリクエストに対してCookieを割り当てなかった場合、レスポンスカラムには”-“が報告されます。
キャプチャはフロントエンドでのみ実行されます。これは、特定のフロントエンドに対してバックエンドによってログフォーマットが変化しないようにするためです。将来的に変更される可能性があります。また、フロントエンド内に"capture cookie"ステートメントは1つしか指定できません。最大キャプチャ長はグローバル"tune.http.cookielen"設定で設定され、デフォルトは63文字です。“defaults"セクションでキャプチャを指定することはできません。
例:
“capture request header”、“capture response header”、およびログについて説明するセクション8 も参照してください。
capture request header <name> len <length>
指定されたリクエストヘッダーの最後の出現をキャプチャし、ログに記録します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 不可
引数:
ヘッダーの最後の出現箇所の値を完全にキャプチャします。値は波括弧(’{}’)で囲んでログに追加されます。複数のヘッダーをキャプチャする場合は縦棒(’|’)で区切り、設定で宣言した順序で表示します。存在しないヘッダーは空文字列としてログに記録します。リクエストヘッダーのキャプチャの一般的な用途には、仮想ホスティング環境の"Host"フィールド、アップロードをサポートする場合の"Content-length”、実際のユーザーとロボットをすばやく区別するための"User-agent”、プロキシ環境でリクエストの送信元を調べるための"X-Forwarded-For"があります。
“User-agent"などのヘッダーをキャプチャすると、空白もログに記録され、ログ解析が難しくなる場合があります。ログパーサーが波括弧を手掛かりに処理できるほど賢くないと分かっている場合は、記録する内容に注意してください。
キャプチャするリクエストヘッダーの数にも長さにも制限はありませんが、ストリームあたりのメモリー使用量を抑えるには、数を少なく、長さを短くしておくのが賢明です。同じフロントエンドでログ形式を一貫させるため、ヘッダーキャプチャはフロントエンドでのみ宣言できます。“defaults"セクションでキャプチャを指定することはできません。
例:
“capture cookie”、“capture response header”、およびログについて説明するセクション8 も参照してください。
capture response header <name> len <length>
指定したレスポンスヘッダーの最後の出現箇所をキャプチャし、ログに記録します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 不可
引数:
ヘッダーの最後の出現箇所の値を完全にキャプチャします。結果は波括弧(’{}’)で囲み、キャプチャしたリクエストヘッダーの後にログへ追加します。複数のヘッダーをキャプチャする場合は縦棒(’|’)で区切り、設定で宣言した順序で表示します。存在しないヘッダーは空文字列としてログに記録します。レスポンスヘッダーのキャプチャの一般的な用途には、返却予定のバイト数を示す"Content-length"ヘッダーや、リダイレクトを追跡するための"Location"ヘッダーがあります。
キャプチャするレスポンスヘッダーの数にも長さにも制限はありませんが、ストリームあたりのメモリー使用量を抑えるには、数を少なく、長さを短くしておくのが賢明です。同じフロントエンドでログ形式を一貫させるため、ヘッダーキャプチャはフロントエンドでのみ宣言できます。“defaults"セクションでキャプチャを指定することはできません。
例:
“capture cookie”、“capture request header”、およびログについて説明するセクション8 も参照してください。
clitcpka-cnt <count>
クライアント側で接続を切断する前に、TCPが送信するkeepaliveプローブの最大数を設定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
このキーワードはソケットオプションTCP_KEEPCNTに対応しています。このキーワードが指定されない場合、システム全体のTCPパラメーター(tcp_keepalive_probes)が使用されます。この設定の利用可能性はオペレーティングシステムに依存します。Linuxで動作することが知られています。
参照:“option clitcpka”、“clitcpka-idle”、“clitcpka-intvl”。
clitcpka-idle <timeout>
クライアント側でTCP keepaliveパケットの送信を有効にした場合に、TCPがkeepaliveプローブの送信を開始するまでに接続がアイドル状態を維持する必要がある時間を設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
このキーワードはソケットオプションTCP_KEEPIDLEに対応しています。このキーワードが指定されない場合、システム全体のTCPパラメーター(tcp_keepalive_time)が使用されます。この設定の利用可能性はオペレーティングシステムに依存します。Linuxで動作することが知られています。
参照:“option clitcpka”、“clitcpka-cnt”、“clitcpka-intvl”。
clitcpka-intvl <timeout>
クライアント側の個々のkeepaliveプローブ間の時間を設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
このキーワードはソケットオプションTCP_KEEPINTVLに対応しています。このキーワードが指定されない場合、システム全体のTCPパラメーター(tcp_keepalive_intvl)が使用されます。この設定の利用可能性はオペレーティングシステムに依存します。Linuxで動作することが知られています。
参照:“option clitcpka”、“clitcpka-cnt”、“clitcpka-idle”。
compression algo <algorithm> ...
HTTP圧縮を有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
現在サポートされているアルゴリズムは次のとおりです。
圧縮はAccept-Encodingリクエストヘッダーに応じて有効になります。identityでは、このヘッダーを考慮しません。バックエンドサーバーがHTTP圧縮をサポートしている場合、これらのディレクティブは何も行いません。HAProxyは圧縮済みのレスポンスを認識し、再度圧縮しません。バックエンドサーバーがHTTP圧縮をサポートせず、リクエストにAccept-Encodingヘッダーがある場合、HAProxyは該当するレスポンスを圧縮します。
次の場合、圧縮は無効になります。* リクエストが"Accept-Encoding"ヘッダーでサポートされる圧縮アルゴリズムを通知していない * レスポンスメッセージがHTTP/1.1以上でない * HTTPステータスコードが200、201、202、203のいずれでもない * レスポンスに"Content-Length"ヘッダーも、最後の値が"chunked"である"Transfer-Encoding"もない * レスポンスに"Content-Type"ヘッダーがあり、その最初の値が"multipart"で始まる * レスポンスの"Cache-control"ヘッダーに"no-transform"の値がある * User-Agentが"Mozilla/4"に一致する。ただし、XP SP2のMSIE 6、またはMSIE 7以降は除く * レスポンスに、すでに圧縮されていることを示す"Content-Encoding"ヘッダーがある(compression offloadを参照) * レスポンスに無効な"ETag"ヘッダーまたは複数のETagヘッダーがある * ペイロードサイズが最小サイズより小さい(compression minsize-resを参照)
注意:圧縮ではWarningヘッダーは送出されません。
例:
関連項目: “compression offload”、“compression direction”、“compression minsize-req"および"compression minsize-res”
compression minsize-req <size>
圧縮を適用するペイロードの最小サイズをバイト単位で設定します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
このサイズ未満のペイロードは圧縮されず、圧縮の効果が大きくないデータに対する不要なCPUオーバーヘッドを回避します。“minsize-req"はリクエストに、“minsize-res"はレスポンスに適用されます。デフォルト値は0です。
compression offload
HAProxyを圧縮オフローダーとしてのみ動作させます。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 可
“offload"設定によりHAProxyはAccept-Encodingヘッダーを削除し、バックエンドサーバーがレスポンスを圧縮しないようにします。すべての圧縮処理がHAProxyの配置されている一か所に集中するため、この設定を使わないことを強く推奨します。ただし、一部の配置構成では、無効にできない不具合のあるHTTP圧縮実装を持つゲートウェイの前段にHAProxyが配置される場合があります。その場合、HAProxyでゲートウェイが無効なペイロードを出力するのを防げます。設定でヘッダーを単に削除しても機能しません。ヘッダーの解析より前に適用され、HAProxy自身の圧縮を妨げるためです。このような状況では、“offload"設定を使用することを推奨します。
この設定がdefaultsセクションで使用された場合、警告が発行され、オプションは無視されます。
参照:“compression type”、“compression algo”、“compression direction”。
compression direction <direction> (deprecated)
HAProxyがリクエストとレスポンスの両方を圧縮できるようにします。有効な値は"request”(リクエストのみ圧縮)、“response”(レスポンスのみ圧縮)、“both”(両方圧縮)です。デフォルト値は"response"です。
このディレクティブは、従来の"filter compression"が有効な場合にのみ関係があります。明示的なcomp-reqとcomp-resフィルターでは、圧縮方向の指定が冗長になるためです。
使用可能なコンテキスト: http
参照:“compression type”、“compression algo”、“compression offload”。
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
バックエンドでCookieに基づく接続先の固定を有効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
HTTPバックエンドごとに接続先を固定するクッキーは1つだけ指定でき、defaultsセクションで宣言できます。クッキーの値は、“server"ステートメントの"cookie"キーワードの後に指定された値になります。特定のサーバーにクッキーが宣言されていない場合、クッキーは設定されません。
例:
参照:“balance source”、“capture cookie”、“server”、“ignore-persist”。
declare capture [ request | response ] len <length>
キャプチャスロットを宣言します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 不可
引数:
この宣言はフロントエンドまたはlistenセクションでのみ利用可能ですが、予約されたスロットはバックエンドでも使用できます。“request"キーワードはリクエストで使用するキャプチャスロットを割り当て、“response"キーワードはレスポンスで使用するキャプチャスロットを割り当てます。
関連項目:“capture-req”、“capture-res”(サンプルコンバーター)、“capture.req.hdr”、“capture.res.hdr”(サンプル取得)、“http-request capture"および"http-response capture”。
default-server [param*]
バックエンド内のサーバーのデフォルトオプションを変更します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
例:
関連項目:“server”、およびサーバーオプションに関するセクション5 。
default_backend <backend>
どの"use_backend"ルールにも一致しなかった場合に使用するバックエンドを指定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
“use_backend"キーワードを使用してフロントエンドとバックエンド間でコンテンツスイッチングを行う場合、どのルールにも一致しなかったときに使用するバックエンドを指定しておくと便利なことがよくあります。一般に、振り分け先が決まらないすべてのリクエストを受け取る動的バックエンドです。
バックエンドが無効化または非公開になっている場合、そのバックエンドを対象とするdefault_backendルールは無視され、ストリーム処理は元のプロキシのままになります。
例:
参照:“use_backend”。
description <string>
listen、フロントエンド、またはバックエンドの説明を記述します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 可
引数:文字列
HAProxyのHTML統計ページで関連オブジェクトを説明する文を追加できます。説明は、該当オブジェクト名の右側に表示されます。<string>引数内でバックスラッシュによるスペースのエスケープは必要ありません。
disabled
プロキシ、フロントエンド、またはバックエンドを無効にします。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
“disabled"キーワードは、主にリッスンポートを解放するため、またはサービスを一時的に無効にするために、インスタンスを無効にします。インスタンス自体は作成され、設定も検査されますが、“stopped"状態で作成され、統計にもその状態で表示されます。トラフィックを受信せず、ヘルスチェックやログも送信しません。“defaults"セクションに"disabled"キーワードを追加すると、多数のインスタンスを一括で無効にできます。
デフォルトでは、無効化されたバックエンドはコンテンツスイッチングの対象にできません。ただし、“force-be-switch"を使用すると、トラフィックの一部はこの制限を無視できます。
参照:“enabled”、“force-be-switch”。
dispatch <address>:<port> (deprecated)
デフォルトサーバーのアドレスを設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
引数:
“dispatch"キーワードは、他のサーバーが接続を受け付けられない場合に使用するデフォルトサーバーを指定します。過去には、接続先を固定しない接続を補助的なロードバランサーに転送するために使用されていました。単純な構文のため、単純なTCPリレーにも使われていました。設定を明確にするため、このキーワードを使わず、代わりに"server"ディレクティブを使用することを推奨します。
このキーワードは、内部的な制限(SSLやアイドル接続などをサポートしない)のため、3.3で非推奨となり、3.5で削除される予定です。使用すると警告が発生しますが、グローバルセクションで"expose-deprecated-directives"ディレクティブを有効にすると、この警告を抑制できます。
このディレクティブを使わずに実行する正しい方法は、同じアドレスとポートを持つサーバーを単に宣言することです。“dispatch"ディレクティブが他のサーバーと混在している場合、これらのサーバーは、負荷分散アルゴリズムで決して選ばれないよう、重みをゼロに設定することを推奨します。
例:
参照:“server”。
dynamic-cookie-key <string>
バックエンドの動的Cookieの秘密鍵を設定します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:使用する秘密鍵。
動的クッキーが有効化されている場合(クッキーの"dynamic"ディレクティブを参照)、各サーバーに対して、サーバーのIPアドレス、TCPポート、およびシークレットキーのハッシュを使用して動的クッキーが作成されます(“server"行で明示的に指定されていない場合)。これにより、サーバーが動的に追加または削除されても、複数のロードバランサー間でセッションの接続先を固定できます。
enabled
プロキシ、フロントエンド、またはバックエンドを有効にします。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
“enabled"キーワードは、defaultsで"disabled"に設定されている場合に、インスタンスを明示的に有効化するために使用されます。使用されることは非常にまれです。
参照:“disabled”。
errorfile <code> <file>
HAProxyが生成するエラーの代わりにファイルの内容を返します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
このキーワードは、サーバーが返すエラーを書き換えることを意図しているわけではなく、HAProxyが検出して返すエラーを対象とすることを理解することが重要です。そのため、対応するエラーは少数に限定されます。
“monitor-uri"ルールに一致するリクエストには、コード200が返されます。
ファイルはHAProxyの起動時に解析され、HTTP仕様に従って有効な内容でなければなりません。設定されたバッファーサイズ(BUFSIZE、通常は16 kB)を超えないことを推奨します。超えると内部エラーが返されます。また、すべてのサーバーがダウンしたときにクライアントとHAProxyの間でループが起き、画像の代わりにエラーが返されることを避けるため、ローカルコンテンツ(たとえば画像)への参照を含めないことも賢明です。最後に、“http-after-response"ルールが動作する余地を確保するため、レスポンスは(tune.bufsize - tune.maxrewrite)を超えることはできません(“tune.maxrewrite"を参照)。
ファイルは設定と同時に読み込まれ、メモリに保持されます。このため、プロセスがchrootされた後でもエラーが返され続け、プロセス実行中にファイルの変更は反映されません。これらのファイルを作成する簡単な方法は、403ステータスコードに関連付け、ブロックされたURLにリクエストを送信することです。
参照:“http-error”、“errorloc”、“errorloc302”、“errorloc303”。
例:
errorfiles <name> [<code> ...]
<name> http-errorsセクションで定義されたエラーファイルのすべて、または一部をインポートします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
名前が<name>のhttp-errorsセクションで定義されたエラーが、現在のプロキシにインポートされます。ステータスコードが指定されていない場合、http-errorsセクションのすべてのエラーファイルがインポートされます。そうでない場合、列挙されたステータスコードに関連するエラーファイルのみがインポートされます。これらのエラーファイルは、プロキシで既に定義されたカスタムエラーを上書きし、その後に定義されたもので上書きされる場合もあります。機能的には、“errorfile"ディレクティブを使ってすべてのエラーファイルを手動で宣言することとまったく同じです。
関連項目:“http-error”、“errorfile”、“errorloc”、“errorloc302”、“errorloc303”、およびhttp-errorsに関するセクション12.4 。
例:
errorloc <code> <url>
HAProxyが生成するエラーの代わりに、URLへのHTTPリダイレクトを返します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
このキーワードは、サーバーが返すエラーを書き換えることを意図しているわけではなく、HAProxyが検出して返すエラーを対象とすることを理解することが重要です。そのため、対応するエラーは少数に限定されます。
“monitor-uri"ルールに一致するリクエストには、コード200が返されます。
両方のキーワードはHTTP 302ステータスコードを返す点に注意してください。これはクライアントに指定されたURLを同じHTTPメソッドで取得するように通知します。POSTなどのGET以外のメソッドの場合、クライアントに送られたURLがGET以外を許可していないことがあり、大きな問題になる場合があります。この問題を回避するには、“errorloc303"を使用してください。これはHTTP 303ステータスコードを返し、URLをGETリクエストで取得しなければならないことをクライアントに示します。
参照:“http-error”、“errorfile”、“errorloc303”。
errorloc303 <code> <url>
HAProxyが生成するエラーの代わりに、URLへのHTTPリダイレクトを返します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
このキーワードは、サーバーが返すエラーを書き換えることを意図しているわけではなく、HAProxyが検出して返すエラーを対象とすることを理解することが重要です。そのため、対応するエラーは少数に限定されます。
“monitor-uri"ルールに一致するリクエストには、コード200が返されます。
両方のキーワードはHTTP 303ステータスコードを返す点に注意してください。これはクライアントに指定されたURLを同じHTTP GETメソッドで取得するように通知します。これにより、“errorloc"と302コードに関連する一般的な問題が解決されます。HTTP/1.1以前に設計された非常に古いブラウザーでは対応していない可能性がありますが、現時点でそのような問題は報告されていません。
参照:“http-error”、“errorfile”、“errorloc”、“errorloc302”。
email-alert from <emailaddr>
メールアラートのエンベロープおよびヘッダーで使用する送信元メールアドレスを宣言します。このアドレスがメールアラートの送信元になります。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
“email-alert mailers"と"email-alert to"も設定されている必要があり、これらが設定されていると、プロキシでメールアラートの送信が有効になります。
関連項目:“email-alert level”、“email-alert mailers”、“email-alert myhostname”、“email-alert to”、およびmailersに関するセクション12.3 。
email-alert level <level>
メールアラートの送信対象となるメッセージの最大ログレベルを宣言します。 これはメールアラートの送信をフィルタリングする役割を果たします。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
デフォルトのレベルはalertです。
“email-alert from”、“email-alert mailers"および"email-alert to"も設定されている必要があり、これらが設定されていると、プロキシでメールアラートの送信が有効になります。
次の場合にアラートが送信されます。
- 一時停止していないサーバーがダウンと判定され、
<level>がalert以下の場合 - 一時停止中のサーバーがダウンと判定され、
<level>がnotice以下の場合 - サーバーが稼働中と判定されるかdrain状態に入り、
<level>がnotice以下の場合 - “option log-health-checks"が有効で、
<level>がinfo以下であり、ヘルスチェックのステータス更新が発生した場合
関連項目:“email-alert from”、“email-alert mailers”、“email-alert myhostname”、“email-alert to”、およびmailersに関するセクション12.3 。
email-alert mailers <mailersect>
メールアラートの送信に使用するmailersを宣言します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
“email-alert from"と"email-alert to"も設定されている必要があり、これらが設定されていると、プロキシでメールアラートの送信が有効になります。
関連項目:“email-alert from”、“email-alert level”、“email-alert myhostname”、“email-alert to”、およびmailersに関するセクション12.3 。
email-alert myhostname <hostname>
mailersとの通信に使用する宛先ホスト名アドレスを宣言します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
デフォルトではシステムのホスト名を使用します。
“email-alert from”、“email-alert mailers"および"email-alert to"も設定されている必要があり、これらが設定されていると、プロキシでメールアラートの送信が有効になります。
関連項目:“email-alert from”、“email-alert level”、“email-alert mailers”、“email-alert to”、およびmailersに関するセクション12.3 。
email-alert to <emailaddr>
メールアラートのエンベロープの宛先アドレスとヘッダーのToアドレスの両方を指定します。メールアラートの送信先となるアドレスです。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
“email-alert mailers"と"email-alert to"も設定されている必要があり、これらが設定されていると、プロキシでメールアラートの送信が有効になります。
関連項目:“email-alert from”、“email-alert level”、“email-alert mailers”、“email-alert myhostname”、およびmailersに関するセクション12.3 。
error-log-format <fmt>
フロントエンド側の接続エラー時に使用するログ形式文字列を指定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
このディレクティブは、エラー、タイムアウト、再試行、再振り分け、またはHTTPステータスコード5xxに関連する情報を含むログに使用するログフォーマット文字列を指定します。このフォーマットは、“log-separate-errors"オプションの対象となるすべてのログ行に使用され、セクション8.2.5 で説明される接続エラーも含みます。
このディレクティブがdefaultsセクションで使用される場合、以降のすべてのフロントエンドは同じログフォーマットを使用します。カスタムログフォーマット文字列について詳しくはセクション8.2.6 を参照してください。
“error-log-format"ディレクティブは、それより前の"error-log-format"ディレクティブを上書きします。
force-persist { if | unless } <condition>
ダウンしたサーバーへ接続先を強制的に固定する条件を宣言します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
デフォルトでは、リクエストはダウン状態のサーバーに配信されません。“option persist"を使用すると強制的に配信できますが、これは無条件に作用し、“option redispatch"が設定されている場合は有効なサーバーへ再振り分けされます。そのため、メンテナンス作業のために人為的にダウン状態とされたサーバーへ一部のリクエストを強制的に届ける方法は、ほとんどありません。
“force-persist"文では、ACLに基づくさまざまな条件を宣言できます。条件を満たすと、リクエストはサーバーのダウン状態を無視し、そのサーバーへの接続を試みます。これにより、ヘルスチェックにはまだエラーを返すサーバーを起動し、特別に設定したブラウザーでサービスをテストできます。便利な方法として、特定の送信元IPアドレスや特定のCookieを利用できます。Cookieには、テストページからブラウザー上で簡単に追加や削除ができる利点もあります。サービスを確認した後は、ヘルスチェックに有効なレスポンスを返すことで、一般にサービスを公開できます。
接続先の強制的な固定は、“if"条件が満たされた場合、または"unless"条件が満たされない場合に有効になります。これを使用すると、最終的な再振り分けは常に無効になります。
関連項目:“option redispatch”、“ignore-persist”、“persist”、およびACLの使用方法に関するセクション7 。
external-check command <command>
external-checkの実行時に起動する実行可能ファイルです。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
コマンドに渡す引数は次のとおりです。
<proxy_address> <proxy_port> <server_address> <server_port>
<proxy_address>および<proxy_port>は、IPv4、IPv6、またはUNIXソケットである最初のリスナーから得られます。UNIXソケットリスナーの場合、proxy_addressはソケットのパスとなり、<proxy_port>は文字列"NOT_USED"になります。バックエンドセクションではリスナーを特定できないため、<proxy_address>および<proxy_port>はともに文字列値"NOT_USED"を持ちます。
一部の値は環境変数でも渡されます。
環境変数:
コマンドが実行され、終了ステータスがゼロであれば、チェックは成功と見なされます。それ以外の場合は、チェックは失敗と見なされます。
例:
参照:“external-check”、“option external-check”、“external-check path”。
external-check path <path>
external-checkの実行時に使用するPATH環境変数の値です。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
デフォルトのパスは"“です。
例:
参照:“external-check”、“option external-check”、“external-check command”。
force-be-switch { if | unless } <condition>
バックエンドインスタンスが無効化または非公開の場合でも、コンテンツスイッチングで選択できるようにします。管理者は、外部に公開する前にサービスへのトラフィックをテストするためにこのルールを使用できます。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 不可
参照:“be-unpublished”、“disabled”。
filter <name> [param*]
プロキシに接続されたフィルターリストに、フィルター<name>を追加します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 可
引数:
同じプロキシでフィルター行を複数回使用できます。必要に応じて同じフィルターを複数回参照できます。
例:
関連項目: セクション9 。
fullconn <conns>
サーバーがmaxconnに達するバックエンド負荷を指定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
サーバーに"maxconn"パラメーターが指定されている場合、その同時接続数はこの値を超えません。さらに"minconn"パラメーターが指定されている場合、バックエンドの負荷に応じた動的な制限を示します。このサーバーは常に少なくとも<minconn>個の接続を受け入れ、<maxconn>を超えることはなく、バックエンドの同時接続数が<conns>を下回る場合、制限は両方の値の間で連続的に変化します。これにより、通常の負荷時にはサーバーの負荷を制限しつつ、高い負荷時には許容負荷を引き上げ、極端な負荷時にもサーバーを過負荷にしないようにできます。
この値を正確に設定するのは難しいため、HAProxyは自動的に、このバックエンドに分岐する可能性のあるすべてのフロントエンドのmaxconnの合計の10%を設定します(“use_backend"および"default_backend"ルールに基づく)。これにより、設定を省略しても安全です。ただし、動的な名前を含む"use_backend"は、一致するかどうかを判断できないため、カウントされません。
例:
参照:“maxconn”、“server”。
guid <string>
このプロキシの、大文字と小文字を区別するグローバルに一意なIDを指定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 可
<string>は、すべてのHAProxy設定において、オブジェクトの種類にかかわらず一意でなければなりません。ユーザーが命名ポリシーを選択できるよう、形式は指定されていません。唯一の制限は長さで、127文字を超えることはできません。すべての英数字および’.’、’:’、’-’、’_‘の各文字が有効です。関連項目:“shm-stats-file”。
hash-balance-factor <factor>
負荷上限付きコンシステントハッシュの分散係数を指定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 不可 | 可
引数:
“hash-type consistent"を使用するサーバーに"hash-balance-factor"を指定すると、一部のハッシュバケットがほかのバケットよりはるかに多くのリクエストを受け取っても、一つのサーバーに同時にリクエストが集中しすぎるのを防ぐアルゴリズムを有効にします。<factor>を0(デフォルト)にすると、この機能は無効になります。それ以外では、<factor>は100より大きいパーセント値です。たとえば、<factor>が150の場合、どのサーバーの負荷も平均の1.5倍を超えることは許されません。サーバーの重みを使用している場合は、その重みも考慮します。
最初の候補のサーバーが不適格な場合、アルゴリズムはリクエストのハッシュに基づいて別のサーバーを選択し、余力のあるサーバーが見つかるまで続けます。<factor>を高い値に設定するとサーバー間の不均衡をより大きく許容し、<factor>を低い値に設定すると平均的にチェックするサーバーが多くなるため、パフォーマンスに影響します。妥当な値は125から200です。
この設定は、内部でコンシステントハッシュの仕組みを利用する"balance random"でも使用されます。
参照:“balance”、“hash-type”。
hash-preserve-affinity { always | maxconn | maxqueue }
サーバーが飽和状態またはキューが満杯の状態にあるときに、ハッシュ負荷分散を使用してストリームをサーバーに割り当てる方法を指定します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
次の値を指定できます。
- "always" : これはデフォルトの戦略です。サーバーが現在飽和しているかどうかにかかわらず、ハッシュに基づいてストリームがサーバーに割り当てられます。
- "maxconn" : この戦略を選択すると、"maxconn"が設定されていて現在飽和しているサーバーはスキップされ、ハッシュリングをたどって別のサーバーが選択されます。"maxconn"を設定していないサーバーには影響しません。すべてのサーバーが飽和している場合、リクエストはハッシュリング上で最初に選択されたサーバーの直前にある最後のサーバーのキューに入れられます。
- "maxqueue": この戦略を選択すると、"maxconn"が設定され、"maxqueue"がゼロ以外の値に設定されていて(キューサイズに制限がある)、現在キューが満杯のサーバーはスキップされます。ハッシュリングをたどって別のサーバーが選択されます。"maxconn"と"maxqueue"の双方の設定がそろっていないサーバーには影響しません。
参照:“maxconn”、“maxqueue”、“hash-balance-factor”。
hash-type <method> <function> <modifier>
ハッシュをサーバーに対応付ける方法を指定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
デフォルトのハッシュタイプは"map-based"であり、ほとんどの用途で推奨されます。デフォルトの関数は"sdbm"です。関数はハッシュ対象となる値の範囲に基づいて選ぶことを推奨します。
参照:“balance”、“hash-balance-factor”、“hash-preserve-affinity”、“server”。
http-after-response <action> <options...> [ { if | unless } <condition> ]
すべてのレイヤー7レスポンス(サーバー、アプレット/サービス、内部レスポンス)のアクセス制御です。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 可 | 可 | 可
http-after-responseステートメントはレイヤー7処理に適用されるルールセットを定義します。ルールは、フロントエンド、listen、またはバックエンドセクションで宣言された順序に従って評価されます。これらのルールはレスポンスに適用されるため、バックエンドのルールが先に適用され、その後フロントエンドのルールが適用されます。どのルールにも、任意でACLに基づく条件を後置できます。その場合、条件が真と評価されたときにのみルールが評価されます。
http-responseルールとは異なり、これらはサーバーからのレスポンスだけでなく、HAProxyが生成するすべてのレスポンスにも適用されます。これらのルールは、データ転送フェーズの前、レスポンス解析の最後に評価されます。
条件はアクションが実行される直前に評価され、アクションは正確に1回実行されます。したがって、条件の評価に使われる要素がアクションによって変更されても問題ありません。また、同じ条件を複数のアクションで共有できるため、最初のアクションが条件の評価結果を変えるだけで、残りのアクションを暗黙的に無効にできます。これは、変数が空の場合に、さまざまなソースから値を割り当てようとするときなどに利用されます。インスタンスあたりの"http-after-response"ステートメントの数に制限はありません。
構文における"http-after-response"の直後の最初のキーワードはルールのアクションであり、必要に応じてアクションに応じた数の引数が続くことがあります。対応するアクションおよびそれぞれの構文は、セクション4.3 「アクション」に記載されています(“HTTP Aft"にチェックがあるアクションを参照してください)。
このディレクティブは、名前付きのdefaultsセクションでのみ使用でき、無名のセクションでは使用できません。defaultsセクションで定義したルールは、関連付けられたプロキシセクションのルールより先に評価されます。曖昧さを避けるため、この場合、フロントエンド機能を持つプロキシとバックエンド機能を持つプロキシが、同じdefaultsセクションを使用することはできません。つまり、listenセクションは、このようなルールを定義したdefaultsセクションを使用できません。
注意:リクエスト解析の初期段階で発生したエラーは、HTTP解析を行う前に、より低いレベルでマルチプレクサーが処理します。したがって、これらのエラーに対してはhttp-after-responseルールセットは評価されません。
例:
http-check comment <string>
後続のhttp-checkルールのコメントを定義します。ルールが失敗した場合にログに記録されます。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
connect、send、expectルールにのみ使用できます。わかりやすいエラー報告を作成するのに役立ちます。
参照:“option httpchk”、“http-check connect”、“http-check send”、“http-check expect”。
http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]
HTTPヘルスチェックを実行するため、新しい接続を開きます。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
tcp-checkヘルスチェックと同様に、HTTPヘルスチェックを実行するための接続を設定できます。このディレクティブは、複数のリクエスト/レスポンスをやり取りするシナリオを記述するときにも使用することを推奨します。このシナリオでは、異なるポートやサーバーを使う場合もあります。
server行にもserver portディレクティブにもTCPポートが設定されていない場合、http-checkシーケンスの最初のステップとして"http-check connect"でポートを指定しなければなりません。
http-checkルールセットでは’connect’が必須であり、ルールセットは’connect’ルールで開始しなければなりません。管理者が自分の操作を理解したうえで実行するようにすることが目的です。
connectでルールセットを開始しなければならない場合でも、その前にset-var、unset-var、commentルールを置くことができます。
例:
参照:“option httpchk”、“http-check send”、“http-check expect”。
http-check disable-on-404
ヘルスチェックへのHTTP/404レスポンスを受けた場合に、メンテナンスモードを有効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
このオプションを設定すると、HTTPコード404を返すサーバーを以後の負荷分散から除外しますが、接続先が固定された接続は引き続き受け付けます。Web管理者がサーバーをグレースフルシャットダウンするための便利な方法です。また、このモード中にサーバーの障害を検出しても、alertではなくnoticeだけを生成します。サーバーが再び2xxまたは3xxを返すと、直ちにサーバー群へ戻します。このモードのサーバーは、統計ページの状態欄に"NOLB"と表示されます。このオプションは"httpchk"オプションと組み合わせた場合にのみ動作します。“http-check expect"と併用すると、このオプションが優先され、404レスポンスは引き続きソフトストップとして扱われます。すでに停止しているサーバーは、404を返しても停止したままです。このオプションは稼働中のサーバーに対してのみ評価します。
参照:“option httpchk”、“http-check expect”。
http-check expect [min-recv <int>] [comment <msg>]
HTTPヘルスチェックでレスポンスの内容や特定のステータスコードを考慮するようにします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
デフォルトでは、“option httpchk"はレスポンスステータス2xxおよび3xxを有効とみなし、それ以外を無効とみなします。“http-check expect"を使用すると、有効または無効とみなす内容を定義します。バックエンド内では、“http-check"ステートメントは1つだけサポートされています。サーバーが応答しない、またはタイムアウトした場合、チェックは明らかに失敗します。利用可能な一致条件は次のとおりです:
レスポンスは、グローバルな"tune.bufsize"オプションで定義されたサイズに制限されることに注意してください。デフォルトは16384バイトです。したがって、“string"または"rstring"を使用する場合、大きすぎるレスポンスには必須のパターンが含まれない可能性があります。大きなレスポンスがどうしても必要な場合は、グローバル変数を設定してデフォルトの最大サイズを変更できます。ただし、特に正規表現を使う場合、非常に大きなレスポンスの解析でCPUサイクルを浪費することがある点を念頭に置いてください。より小さなリソースをチェック対象にする方が常に望ましいです。
http-checkルールセットでは、最後のexpectルールは暗黙的に定義されることがあります。最後の"http-check send"の後にexpectルールが指定されていない場合、2xxまたは3xxステータスコードに一致する暗黙のexpectルールが定義されます。“http-check"ルールがまったくなく、“option httpchk"だけが設定されている場合にも、このルールが定義されます。
最後に、“http-check expect"が"http-check disable-on-404"と組み合わせられている場合、サーバーが404を返したときは後者が優先されます。
例:
参照:“option httpchk”、“http-check connect”、“http-check disable-on-404”、“http-check send”。
http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
HTTPヘルスチェック中に送信するリクエストに、ヘッダーのリスト、本文、またはその両方を追加できます。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
“option httpchk"ディレクティブで定義されたリクエスト行に加えて、これはHTTPヘルスチェック中に送信するリクエストにヘッダーと任意の本文を追加する正しい方法です。本文が定義されている場合、対応する"Content-Length"ヘッダーが自動的に追加されます。したがって、“http-check send"で指定するリクエストには、このヘッダーや"Transfer-encoding"ヘッダーを含めないことを推奨します。含まれている場合は無視されます。“option httpchk"行のバージョン文字列の後にヘッダーを追加する従来の方法は、現在非推奨です。
また、“http-check send"はHTTP keep-aliveをサポートしていません。hdrエントリーでConnectionヘッダーがすでに設定されていない限り、“Connection: close"ヘッダーが自動的に追加されることに留意してください。
Hostヘッダーとリクエストのauthorityが両方定義されている場合、自動的に同期されることに注意してください。HTTPリクエストを送信する際、リクエストにHostヘッダーが挿入されると、それに応じてリクエストのauthorityが更新されます。したがって、Hostヘッダーの値が、設定したリクエストのauthorityを上書きする場合があっても驚かないでください。
また、現在のところ、HTTP/1.1以上のリクエストにはHostヘッダーが自動的に追加されないことに注意してください。明示的に追加することを推奨します。
参照:“option httpchk”、“http-check send-state”、“http-check expect”。
http-check send-state
HTTPヘルスチェックで状態ヘッダーの送出を有効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
このオプションが設定されている場合、HAProxyは各サーバーがHAProxyによってどのように認識されているかを示すパラメーターのリストを含む特別なヘッダー"X-Haproxy-Server-State"を常に送信します。たとえば、HAProxyにアクセスできない状態でサーバーを操作し、オペレーターがHAProxyからまだ稼働中と認識されているか、またはファーム内で最後のサーバーかを確認する必要がある場合に使用できます。
ヘッダーはセミコロンで区切られたフィールドで構成され、最初のフィールドは単語(“UP”、“DOWN”、“NOLB”)です。その後に、状態遷移までに必要なチェックの総数に対する有効なチェック数が、統計インターフェースと同じ形式で続く場合があります。続くフィールドは”<variable>=<value>“の形式で、統計インターフェースに表示される値を順不同で示します:- 変数"address"は、バックエンドサーバーのアドレスを含みます。これはサーバー宣言の<address>フィールドに対応します。UNIXドメインソケットの場合、値は"unix"になります。
- 変数"port"は、バックエンドサーバーのポートを含みます。これはサーバー宣言の`<port>`フィールドに対応します。UNIXドメインソケットの場合、値は"unix"になります。
- 変数"name"は、バックエンド名、スラッシュ("/")、サーバー名の順に含みます。サーバーが複数のバックエンドでチェックされる場合に使用できます。
- 変数"node"は、グローバルな"node"変数で設定されたHAProxyノード名を含みます。未指定の場合はシステムのホスト名が使用されます。
- 変数"weight"は、サーバーの重みを示し、スラッシュ("/")の後にファームの合計重み(使用可能なサーバーのみをカウント)が続きます。これにより、このサーバーに障害が発生したときに他のサーバーが負荷を処理できるかどうかを把握できます。
- 変数"scur"は、サーバー上の現在の同時接続数を示し、スラッシュ("/")の後に同じバックエンドのすべてのサーバーの接続数の合計が続きます。
- 変数"qcur"は、サーバーのキューにある現在のリクエスト数を示します。
アプリケーションサーバーが受信するヘッダーの例:
参照:“option httpchk”、“http-check disable-on-404”、“http-check send”。
http-check set-var(<var-name>[,<cond>...]) <expr>
この操作は変数の内容を設定します。変数はインラインで宣言されます。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
例:
http-check unset-var(<var-name>)
変数のスコープ内でその変数への参照を解放します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
例:
http-error status <code> [content-type <type>]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
HAProxyが生成するエラーの代わりに使用するカスタムエラーメッセージを定義します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
このディレクティブは、“errorfile"の代わりにカスタムエラーメッセージを定義するために使用できます。“errorfile"ディレクティブと同様に、HAProxyが検出して返すエラーに使用します。errorfileを定義した場合はHAProxyの起動時に解析され、HTTP標準に準拠していなければなりません。生成するレスポンスは、設定されたバッファーサイズ(BUFFSIZE)を超えてはなりません。超えると内部エラーを返します。また、http-after-responseルールでこれらのエラーを書き換えることを検討している場合は、予約済みのバッファー領域を利用できるようにしておくことを推奨します(“tune.maxrewrite"を参照)。
ファイルは設定と同時に読み込み、メモリーに保持します。このため、プロセスがchrootされてもエラーを返し続け、プロセスの実行中はファイルの変更を反映しません。
注意:リクエスト解析の初期段階で発生する400/408/500エラーは、下位のマルチプレクサーで処理します。このレベルではカスタム形式に対応していません。そのため、“errorfile"ディレクティブで定義した静的なエラーメッセージのみを使用できます。ただし、この制限があるのは、リクエストヘッダーの解析中、または二つのトランザクションの間だけです。
“errorfile”、“errorfiles”、“errorloc”、“errorloc302”、“errorloc303”、およびhttp-errorsに関するセクション12.4 も参照してください。
http-request <action> [options...] [ { if | unless } <condition> ]
レイヤー7リクエストのアクセス制御です。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 可 | 可 | 可
http-request文は、レイヤー7の処理に適用するルールセットを定義します。ルールはfrontend、listen、backendセクションで宣言順に評価します。各ルールの後には、任意でACLに基づく条件を付けられます。その場合は、条件が真と評価されたときにのみ、そのルールを評価します。
条件はアクションを実行する直前に評価し、アクションは一度だけ実行します。そのため、アクションが条件の一部として検査される要素を変更しても問題ありません。また、複数のアクションが同じ条件に依存することもできるため、条件の評価結果を変える最初のアクションだけで、残りのアクションを暗黙に無効にできます。たとえば、変数が空の場合に、さまざまな取得元から値を代入しようとする際に利用します。インスタンスごとの"http-request"文の数に制限はありません。
構文中の"http-request"直後のキーワードはルールのアクションで、その後に必要に応じてアクションの引数を指定します。引数の数はアクションによって異なります。対応するアクションとそれぞれの構文は、セクション4.3 「アクション」に列挙しています(“HTTP Req"にチェックが付いているアクションを参照)。
このディレクティブは、名前付きのdefaultsセクションでのみ使用でき、無名のセクションでは使用できません。defaultsセクションで定義したルールは、関連付けられたプロキシセクションのルールより先に評価されます。曖昧さを避けるため、この場合、フロントエンド機能を持つプロキシとバックエンド機能を持つプロキシが、同じdefaultsセクションを使用することはできません。つまり、listenセクションは、このようなルールを定義したdefaultsセクションを使用できません。
例:
例:
例:
“stats http-request”、ユーザーリストに関するセクション12.2 、およびACLの使用に関するセクション7 も参照してください。
http-response <action> <options...> [ { if | unless } <condition> ]
レイヤー7レスポンスのアクセス制御です。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 可 | 可 | 可
http-response文は、レイヤー7の処理に適用するルールセットを定義します。ルールはfrontend、listen、backendセクションで宣言順に評価します。レスポンスに適用するため、まずバックエンドのルールを適用し、その後にフロントエンドのルールを適用します。各ルールの後には、任意でACLに基づく条件を付けられます。その場合は、条件が真と評価されたときにのみ、そのルールを評価します。
条件はアクションを実行する直前に評価し、アクションは一度だけ実行します。そのため、アクションが条件の一部として検査される要素を変更しても問題ありません。また、複数のアクションが同じ条件に依存することもできるため、条件の評価結果を変える最初のアクションだけで、残りのアクションを暗黙に無効にできます。たとえば、変数が空の場合に、さまざまな取得元から値を代入しようとする際に利用します。インスタンスごとの"http-response"文の数に制限はありません。
構文中の"http-response"直後のキーワードはルールのアクションで、その後に必要に応じてアクションの引数を指定します。引数の数はアクションによって異なります。対応するアクションとそれぞれの構文は、セクション4.3 「アクション」に列挙しています(“HTTP Res"にチェックが付いているアクションを参照)。
このディレクティブは、名前付きのdefaultsセクションでのみ使用でき、無名のセクションでは使用できません。defaultsセクションで定義したルールは、関連付けられたプロキシセクションのルールより先に評価されます。曖昧さを避けるため、この場合、フロントエンド機能を持つプロキシとバックエンド機能を持つプロキシが、同じdefaultsセクションを使用することはできません。つまり、listenセクションは、このようなルールを定義したdefaultsセクションを使用できません。
例:
例:
“http-request”、ユーザーリストに関するセクション12.2 、およびACLの使用に関するセクション7 も参照してください。
http-reuse { never | safe | aggressive | always }
アイドル状態のHTTP接続をリクエスト間でどのように共有できるかを宣言します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
HTTPリクエストごとにバックエンドサーバーへの接続を新たに確立するコストを避けるため、HAProxyは使用後のアイドル接続を開いたまま保持しようとします。この接続はサーバーごとに、プールと呼ばれるリストに格納し、共通の主要属性の組み合わせでグループ化します。後続のHTTPリクエストでは、対応するプールから同じ属性を持つ互換性のある接続を検索し、新しい接続を確立する代わりに、その接続を再利用します。
サーバーで保持するアイドル接続数の上限は、serverキーワード"pool-max-conn"で指定できます。未使用の接続は、“pool-purge-delay"の間隔で定期的に削除します。
特定のリクエストでアイドル接続を再利用できるかどうかを判断する際には、次の接続属性を使用します。
- 送信元と宛先のアドレス
- プロキシプロトコル
- TOSおよびmarkソケットオプション
- 接続名。“pool-conn-name"式があれば、その評価結果で決まります。なければ"sni"式を使用し、そのデフォルトは"req.hdr(host),field(1,:)“です。つまり、受信したリクエストの"Host"ヘッダーフィールドから、コロンとポート番号を除いた値を使用します。
追加の制限により、接続の検索や再利用を行わない場合もあります。これは、キーワードの引数で指定する再利用方針で決まります。
- "never":アイドル接続をセッション間で共有しません。このモードを明示的に指定して、defaultsセクションから継承した別の方針を取り消したり、トラブルシューティングに使用したりできます。
たとえば、古い不具合のあるアプリケーションが、同じ接続上の複数のリクエストは同じクライアントから来るとみなし、そのアプリケーションを修正できない場合は、一つのバックエンドで接続の共有を無効にすることが望ましい場合があります。
その例としては、トンネルモードでCookieを挿入し、最初のリクエストより後のリクエストを検査しない古いHAProxyが考えられます。
- "safe":デフォルトであり、推奨する方針です。セッションの最初のリクエストは必ず専用の接続で送信し、後続のリクエストだけをほかの既存接続に振り分けられます。これにより、リクエストの送信中にサーバーが接続を閉じても、ブラウザーは利用者に通知せずにリトライするかどうかを判断できます。通常のkeep-aliveとまったく同じなので、副作用はないはずです。
ヘッドオブラインブロッキングのあるプロトコルを使う接続(h2またはfcgiを使用するバックエンド)には、特別な処理もあります。この場合、一つ以上のストリームを処理している間、使用中の接続は同じセッションのストリームを処理するために予約します。処理するストリームがなくなると接続を解放し、再利用できるようになります。
- "aggressive":このモードは、すべてのサーバーが必ずしも把握されておらず、最初のリクエストの大半を既存接続で送れると有益なWebサービス環境で役立つ場合があります。この場合、最初のリクエストの送信に使用できる既存接続は、すでに一度以上再利用され、サーバーが接続の再利用に正しく対応していると確認できたものに限られます。
クライアントが時折失敗するリクエストをリトライできると確信でき、積極的な接続の再利用による利点が、まれな接続失敗の欠点を大きく上回る場合にのみ使用すべきです。
- "always":このモードを推奨するのは、接続の解放直後にサーバーへの経路が既存接続を切断することはないと分かっている場合だけです。セッションの最初のリクエストを既存接続で送れます。バックエンドがキャッシュサーバー群であれば、各サーバーの動作が一貫しやすく接続の共有が有益なので、"safe"より性能を大きく向上させられる場合があります。
このモードでは、使えない接続が利用可能な状態で残らないように、"http-keep-alive"タイムアウトを短く保つことを推奨します。多くの場合、"aggressive"と同程度の性能向上が得られますが、リスクは増えます。"aggressive"より状況が改善する場合にのみ使用すべきです。
NTLMのような、接続に依存する不適切な認証方式を使う接続は、可能であれば専用とマークし、共有しません。ただし、多重化できるプロトコルを使用し、再利用モードのレベルをデフォルトの"safe"より高くしている場合は、接続がすでに共有されていることを妨げるものがないため、この限りではありません。
処理後のアイドル接続を開いたまま保持するか閉じるかは、“tune.pool-low-fd-ratio”(デフォルト:20%)と"tune.pool-high-fd-ratio”(デフォルト:25%)にも従います。これらは、ファイルディスクリプターの総数に対してアイドル接続が使用する割合を示します。前者のしきい値を超えるとHAProxyはレスポンス後の接続の保持を控え、後者を超えるとアイドル接続を積極的に切断します。グローバルの"maxconn"が低すぎる場合や、フロントエンドではHTTP/2またはHTTP/3のトラフィックが多く接続数が少ない一方、バックエンドではHTTP/1接続を使用する場合など、アイドル接続の割合が非常に高い構成では、開いたまま保持する接続が少なすぎて、再利用率が低くなることがあります。この場合は、これらのしきい値を調整するか、単にグローバルの"maxconn"を増やすことが望ましい場合があります。
まれに、ホスト名で送信TLS接続を区別し(フォワードプロキシなど)、リクエストの多くが異なるホストを宛先とする場合は、再利用率が非常に低くなります。この仕組みは、リソースを使い果たさずにサービスを提供するために必要な平均接続数を継続的に測定するため、あまり使わない接続の自動削除が、再利用の機会より先に働きます。そのような場合、“pool-low-conn"を想定する平均アイドル接続数に近い値にすると、より多くの接続を保持できることがあります。スレッドがほかのスレッドの接続を取得して利用可能な接続プールを縮小する代わりに、自分で接続を確立するよう促すためです。
ローカルのサーバーが、複数のホスト名やワイルドカードに対応する一つの証明書を使って複数のサイトを運用している場合は、“server"行に"no-sni-auto"を指定するだけのほうが効果的な場合があります。一つのHost名専用に接続を予約するのを避けられ、再利用率が大きく上がります。ただし、サーバーによってはHostとSNIの照合を過度に行い、後続のリクエストを拒否することがあるため、このオプションには事前の確認が必要です。デフォルトの動作(“sni-auto”)は、そのようなサーバーでも安全に動作することを優先します。
スレッドグループを明示的に有効にしている場合、アイドル接続を使えるのは同じグループのスレッド間だけであることに注意が必要です。そのため、グループ間の負荷の偏りによって、より多くのアイドル接続が必要となり、再利用率が低くなる場合があります。この場合も同じ対策を適用できます(グローバルの"maxconn"を増やすか、プールの割合を増やす)。
“option http-keep-alive”、“pool-conn-name”、“pool-max-conn”、“pool-purge-delay”、“server maxconn”、“sni”、“thread-groups”、“tune.pool-high-fd-ratio”、“tune.pool-low-fd-ratio"も参照してください。
http-send-name-header [<header>]
リクエストにサーバー名を追加します。<header>で指定されたヘッダー文字列を使用します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
“http-send-name-header"文は、リクエストをネットワークに送信する直前に、<header>という名前のヘッダーフィールドを、送信先サーバーの名前に設定します。すでに存在する同名のヘッダーはすべて削除します。リトライや再振り分けの際にもヘッダーフィールドを更新し、常に接続を試みているサーバーを示します。接続の確立手順の非常に遅い段階でこのヘッダーを変更するため、すでに変更済みのヘッダーに予期しない影響が生じる場合があります。たとえば、connection、content-length、transfer-encodingなどの転送に関わるヘッダーに使用すると、無効なリクエストをサーバーへ送る可能性が高くなります。そのため、host、content-length、transfer-encoding、connectionというヘッダー名は禁止されています。
参照:“server”。
id <value>
プロキシに永続的なIDを設定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 可
引数:なし
プロキシに永続的なIDを設定します。このIDは一意で、正の値でなければなりません。設定しなければ、未使用のIDを自動的に割り当てます。従来の動作により、1は明示的に設定しない限り使用しません。したがって、自動割り当てされる最小値は2です。このIDは現在、統計でのみ返します。
ignore-persist { if | unless } <condition>
接続先の固定を無視する条件を宣言します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
デフォルトでは、Cookieによる接続先の固定を有効にしている場合、そのCookieを含むすべてのリクエストは無条件で同じ接続先を使用します(対象のサーバーが正常に稼働していることが前提です)。
“ignore-persist"文では、ACLに基づくさまざまな条件を宣言できます。条件を満たすと、リクエストは接続先の固定を無視します。接続先の固定が不要なことが多い静的ファイルへのリクエストを負荷分散する際に役立つ場合があります。また、特定のUser-Agent(Webクローラーのボットなど)について、接続先の固定を完全に無効にするためにも使用できます。
“if"条件を満たした場合、または"unless"条件を満たさない場合に、接続先の固定を無視します。
例:
“force-persist”、“cookie”、およびACLの使用に関するセクション7 も参照してください。
load-server-state-from-file { global | local | none }
HAProxyのシームレスなリロードを可能にします。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
このディレクティブは、前の実行プロセスのサーバー状態を保存したファイルをHAProxyに指定します。これにより、新しいプロセスは起動時のトラフィック処理前に、リロードがなかったかのように、以前の状態をサーバーに適用できます。“load-server-state-from-file"ディレクティブの目的は、使用するファイルをHAProxyに伝えることです。現在の引数は2つだけで、状態の読み込みを無効にするか、すべてのバックエンドとサーバーを含むファイルから状態を読み込むかを指定します。状態ファイルは、統計ソケットで"show servers state"コマンドを実行し、その出力をリダイレクトして生成できます。
ファイル形式にはバージョンがあり、厳密に定められています。理解するには、“show servers state"コマンドのドキュメントを参照してください(管理ガイドの第9.3章)。
引数:
注意:- サーバーのIPアドレスはデフォルトでリロードをまたいで保持しますが、サーバーの"init-addr"設定で優先順位を変更できます。つまり、実行中にCLIで変更したIPアドレスは保持され、状態ファイルを使用している場合は、ローカルリゾルバー(/etc/hostsなど)の変更が反映されない可能性があります。
- サーバーの重みは、以前と新しい設定ファイルの間で変更されていない限り、前の実行プロセスから適用します。
例:最小構成
global
stats socket /tmp/socket
server-state-file /tmp/server_state
defaults
load-server-state-from-file global
backend bk
server s1 127.0.0.1:22 check weight 11
server s2 127.0.0.1:22 check weight 12
その後、次のコマンドを実行できます。
ファイル/tmp/server_stateの内容は、次のようになります。
例:最小構成
global
stats socket /tmp/socket
server-state-base /etc/haproxy/states
defaults
load-server-state-from-file local
backend bk
server s1 127.0.0.1:22 check weight 11
server s2 127.0.0.1:22 check weight 12
その後、次のコマンドを実行できます。
ファイル/etc/haproxy/states/bkの内容は、次のようになります。
参照:“server-state-file”、“server-state-file-name”、“show servers state”。
log global
インスタンスごとのイベントとトラフィックのログ記録を有効にします。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
プレフィックス:
引数:
接続のどの情報をログに記録するかを決めるのはフロントエンドであり、コンテンツスイッチングの場合はバックエンドのログエントリーが無視されることに注意してください。接続は"info"レベルで記録します。
ただし、バックエンドでのログの宣言は、サーバーの状態変化をどのように、どこへ記録するかを定義します。サーバーが稼働状態になるときは"notice”、終了シグナルとサービスの最終的な終了は"warning”、サーバーのダウンは"alert"レベルで記録します。
注意:RFC3164に従い、メッセージは送出前に1024バイトに切り詰められます。
例:
log-format <fmt>
トラフィックログに使用するカスタムログ形式文字列を指定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
このディレクティブは、この行を使用するフロントエンドを通過するトラフィックのすべてのログに用いる、ログ形式の文字列を指定します。defaultsセクションで使用すると、それ以降のすべてのフロントエンドが同じログ形式を使用します。カスタムログ形式の文字列について詳しく説明したセクション8.2.6 を参照してください。
接続エラーの場合だけに使用する専用のlog-formatも定義できます。“error-log-format"オプションを参照してください。
“log-format"ディレクティブは、以前の"option tcplog”、“log-format”、“option httplog”、“option httpslog"ディレクティブを上書きします。
log-format-sd <fmt>
RFC5424のstructured-dataを生成するために使用するカスタムログ形式文字列を指定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
このディレクティブは、この行を使用するフロントエンドを通過するトラフィックのすべてのログに用いる、RFC5424のstructured-dataのログ形式文字列を指定します。defaultsセクションで使用すると、それ以降のすべてのフロントエンドが同じログ形式を使用します。ログ形式の文字列について詳しく説明したセクション8.2.6 を参照してください。
RFC5424のstructured-data部分について詳しくは、https://tools.ietf.org/html/rfc5424#section-6.3 を参照してください。
注意:このログ形式文字列は、ログ形式を"rfc5424"に設定したロガーでのみ使用します。
例:
log-steps <steps>
トランザクション処理のどの段階でログを生成するかを指定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
TCP/HTTPトランザクションの処理中、HAProxyは処理のさまざまな段階(accept、connect、request、response、close)でログを生成できます。
デフォルトでは、HAProxyはログ形式の式で使用するすべての項目を取得できるようになった時点で、トランザクションごとに一つのログを出力します。このため、“option logasap"を使用しない限り、実際には通常、トランザクションの終了時(HTTPではレスポンスの終了後、TCPでは接続の終了後)にログを出力します。
“log-steps"ディレクティブは、ログを出力する正確な時点を細かく指定でき、同じトランザクションで複数のログを出力することもできます。特別な値’all’で利用可能なすべてのログ生成箇所を有効にすると、acceptからcloseまでトランザクションを追跡できます。また、ログを生成する箇所の名前をコンマで区切って個別に指定し、出力の時点を選択して有効にすることもできます。
一般的なログの発生元は、accept、connect、request、response、closeです。
例:
ログ生成の段階として指定した箇所(accept、closeなど)は、log-profilesの’on’ディレクティブの後でそのまま使用できます。“log-steps"とlog-profilesを組み合わせると、トランザクションの処理中にHAProxyが自動生成するログを細かく制御できます。
この設定はフロントエンドでのみ有効で、バックエンドでは無視されます。
参照:“log-profile”。
log-tag <string>
すべての送信ログに使用するログタグを指定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
syslogヘッダーのtagフィールドを、この文字列に設定します。デフォルトではglobalセクションのlog-tagを使用し、設定されていなければコマンドラインから起動したプログラム名(通常は"HAProxy”)を使用します。同じホスト上の複数プロセスや、同じプロセス内の顧客ごとのインスタンスを区別する際に役立つ場合があります。バックエンドでは、サーバーの稼働状態やダウン状態への変化に関するログにこのタグを使用します。たとえば、defaultsセクションで収容する顧客に対応したlog-tagを設定し、その顧客のすべてのフロントエンドとバックエンドを続けて記述した後、新しいdefaultsセクションで別の顧客の設定を始めると便利です。グローバルの"log-tag"ディレクティブも参照してください。
max-keep-alive-queue <value>
keep-alive接続を維持するサーバーキューの最大サイズを設定します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
HTTPキープアライブは、可能な限り同じサーバー接続を再利用しようとしますが、逆効果になる場合もあります。たとえば、一つのサーバーに接続が多数あり、ほかのサーバーはアイドル状態である場合です。特に静的コンテンツを配信するサーバーで当てはまります。
この設定は、キューに入っている接続数のしきい値を定めます。その値に達すると、HAProxyは同じサーバーの再利用を試みるのをやめ、別のサーバーの検索を優先します。デフォルトの-1は、制限がないことを意味します。0は、keep-aliveリクエストをキューに入れないことを意味します。低遅延で到達できる非常に近いサーバーで、keep-aliveの切断による影響が小さい場合は、小さい値を推奨します(ローカルの静的コンテンツサーバーでは、たとえば10以下を使用できます)。遅延の大きいリモートサーバーでは、その遅延や別のサーバーを選ぶコストを補うために、より大きい値が必要な場合があります。
401レスポンスに続いて同じサーバーに固定されるレスポンスには影響しません。キューで待つ必要があっても、引き続き同じサーバーに送られます。
“option http-server-close”、“option prefer-last-server”、serverの"maxconn”、およびCookieによる接続先の固定も参照してください。
max-session-srv-conns <nb>
特定のクライアントセッションについて、アイドル状態で保持できる送信接続数の上限を設定します。デフォルトは5です(ビルド時に定義するMAX_SRV_LISTと厳密に同じ値です)。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
maxconn <conns>
フロントエンドの最大同時接続数を固定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
システムが対応していれば、大規模なサイトでは、この上限を非常に高くすると役立つ場合があります。クライアントの接続試行を応答がないままにせず、HAProxyで接続キューを管理できるためです。この値はグローバルのmaxconnを超えないようにすべきです。また、接続にはtune.bufsize(デフォルトで16kB)のバッファーが二つと、その他のデータが含まれ、確立した接続一つあたり約33kBのRAMを消費することにも注意してください。つまり、RAMを1GB搭載した中規模のシステムは、適切に調整すれば約20000-25000の同時接続を処理できます。
また、<conns>を大きな値に設定すると、サーバーの容量ではその負荷を受け止められない場合があります。そのため、通常はサーバーに妥当な接続数の上限を設定するのが賢明です。
この値をデフォルトのゼロにすると、グローバルの"maxconn"の値を使用します。
“server”、globalセクションの"maxconn”、“fullconn"も参照してください。
mode { tcp|http|log|spop }
インスタンスの動作モードまたはプロトコルを設定します。使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 可 引数:
コンテンツスイッチングを行う場合、フロントエンドとバックエンドは同じモード(通常はHTTP)でなければなりません。そうでなければ、設定を拒否します。
例:
monitor fail { if | unless } <condition>
監視用HTTPリクエストに失敗を報告する条件を追加します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 不可
引数:
この文は、監視リクエストへのレスポンスで障害を報告させる条件を追加します。デフォルトでは、外部コンポーネントが監視専用のURIに問い合わせると、200レスポンスを返します。上記の条件のいずれかを満たすと、HAProxyは200の代わりに503を返します。HAProxyが報告する可用性に基づいて複数サイト間の経路広告を決定する外部コンポーネントに、サイトの障害を報告する際に非常に役立ちます。その場合、“nbsrv"条件を含むACLを使用します。“monitor fail"はHTTPモードでのみ動作します。必要に応じて、両方のステータスメッセージを"errorfile"または"errorloc"で調整できます。
例:
参照:“monitor-uri”、“errorfile”、“errorloc”。
monitor-uri <uri>
外部コンポーネントの監視リクエストが使用するURIを捕捉します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
フロントエンドが<uri>を参照するHTTPリクエストを受信すると、HAProxyは転送もログへの記録も行わず、“monitor fail"で定義した障害条件に応じて、“HTTP/1.0 200 OK"または"HTTP/1.0 503 Service unavailable"を返します。通常、前段のHTTP監視プローブは、これだけで、リクエストをバックエンドサーバーへ転送せずにサービスが正常に稼働していると判断できます。HTTPメソッド、バージョン、すべてのヘッダーは無視しますが、リクエストは少なくともHTTPとして有効でなければなりません。このキーワードは、HTTPモードのフロントエンドでのみ使用できます。
監視リクエストは、リクエストの解析直後、“http-request"よりも前という、非常に早い段階で処理します。それより前に適用するルールセットはtcp-requestだけです。また、監視リクエストはログに記録できず、これは意図した動作です。監視用のURIは一つだけ設定でき、複数の"monitor-uri"文がある場合は最後の文で使用するURIを定義します。このURIは、HAProxyの正常性を上位のコンポーネントに報告するためだけに使用します。ただし、“monitor fail"とACLで条件を任意の数だけ追加し、考えられるどのようなチェックにも結果を合わせられます(通常はバックエンドで利用可能なサーバー数です)。
注意:<uri>がスラッシュ(’/’)で始まる場合、リクエストのURIではなくパスと照合します。HTTP/2リクエストをmonitor-uriと一致させるための回避策です。HTTP/2では、クライアントは絶対URIだけを送信することが推奨されています。
例:
参照:“monitor fail”。
option abortonclose
クライアントが接続を閉じたときに、未開始の処理を早期に中止する機能を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
TCP接続は、方向ごとに独立して閉じられます。一方の方向だけを閉じた接続は、一般に「ハーフクローズ」と呼びます。HTTPが主に「クローズモード」で動作し、接続ごとに一つのリクエストと一つのレスポンスをやり取りしてから閉じていた頃は、スクリプトで動作するクライアントが、リクエストを送信し、送信側を閉じてレスポンスを待ち、接続終了の通知を受けて処理を終えることがよくありました。しかし、keep-aliveやより高度なプロトコルの登場によって、このような動作はほぼ見られなくなりました。レスポンスを受信する前にクライアントが閉じるのは、基本的に、利用者が転送を中断したい場合か、タイムアウトが発生して接続が閉じられる場合だけです。
この二つの状況(ハーフクローズと中断)は、サーバー側(ここではHAProxyのリスナー)から区別できません。クライアントが中断しても接続を維持し、リクエストの処理を続けると、多くのリソースを消費するため問題になります。特に、利用者が「再読み込み」ボタンを押した結果の切断であれば、以前のリクエストが中断されないまま新しいリクエストがキューに入ることになります。逆に、このようなハーフクローズの状況で常に処理を中断すると、多くのTCPアプリケーションや、内部ネットワークで古いエージェントと通信する一部のHTTPアプリケーションも動作しなくなります。
“abortonclose"オプションで、望む動作を選択できます。- フロントエンドに指定すると、ハーフクローズされた接続で待機中のTLSハンドシェイクを処理しません。これは、HAProxyのアクティブノードからバックアップノードへのVRRPフェイルオーバーのような高負荷時に、利用者がHTTPSリクエスト中に「再読み込み」を押すことで発生する場合があります。すべてのクライアントが新しいノードに同時に再接続し、全員がコストの高い完全なTLSハンドシェイクを行う必要があります。数秒以上かかると、一部の利用者は断念する可能性が高く、そのハンドシェイクのためにCPUを浪費しても意味がありません。TLSハンドシェイクのCPUコストを考慮すると、インターネットに公開するフロントエンドでは、このオプションを有効にしておくことを推奨します。受信TLS接続では、これがデフォルトです。
- バックエンドに指定すると、ハーフクローズされた接続では、まだサーバーへ送っていないリクエスト(キューで待機中、または接続を試みているもの)の中断を試みます。
サーバーがすでにリクエストを処理している場合は、サーバーへの接続もハーフクローズに切り替え、同じ状況をサーバーに通知します。その後どう処理するかはサーバーが決定します。HTTPモードのバックエンドでは、これがデフォルトです。
インターネットに公開するTLSエンドポイントとHTTPサービスでは、このオプションを有効にし、純粋なTCPサービスや外部に公開しない旧来の環境では無効にすることを推奨します。HTTPバックエンドではデフォルトで有効です。バックエンドセクション自体、または継承元の"defaults"セクションで、前に"no"キーワードを付けると明示的に無効にできます。また、TLSリスナーでもデフォルトで有効です。フロントエンド、または継承元の"defaults"セクションで"no option abortonclose"を指定すると、同様に明示的に無効にできます。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
“timeout queue"と、serverの"maxconn"および"maxqueue"パラメーターも参照してください。
option accept-invalid-http-request (deprecated)
HTTPリクエスト解析の制約緩和を有効または無効にします。
“accept-invalid-http-request"キーワードは非推奨です。代わりに"option accept-unsafe-violations-in-http-request"を使用してください。
option accept-invalid-http-response (deprecated)
HTTPレスポンス解析の制約緩和を有効または無効にします。
“accept-invalid-http-response"キーワードは非推奨です。代わりに"option accept-unsafe-violations-in-http-response"を使用してください。
option accept-unsafe-violations-in-http-request
HTTPリクエスト解析の制約緩和を有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
デフォルトでは、HAProxyはメッセージの解析について各HTTP RFCに準拠します。つまり、解析は厳格で、不正な形式のメッセージにはクライアントへエラーを返します。このようなメッセージは、主にサーバーの弱点を悪用し、セキュリティフィルターを回避する攻撃に使われるため、これは望ましい動作です。不具合のあるブラウザーが、設定や実装などの理由でこれらのRFCに従わず、問題がすぐに修正されない場合もあります。その場合、このオプションを指定してHAProxyのパーサーを緩和し、一部の無効なリクエストを受け付けられます。歴史的な理由から、ルールの大半はH1の解析に関するものです。新しいHTTPバージョンはより整っている傾向があり、アプリケーションもそのプロトコルにより厳密に従います。
このオプションを設定すると、次の規則が適用されます。
* H1でのみ、ヘッダー名にNULL文字を含む無効な文字があっても拒否しません。ただし、そのヘッダーは削除します。
* H1でのみ、ヘッダー値のNULL文字が許可されます。
* H1でのみ、URI内の127を超える文字を受け付けます。URIに使用できる文字はRFC3986で厳密に定められており、0-31、32(空白)、34('"')、60('<')、62('>')、92('\')、94('^')、96('`')、123('{')、124('|')、125('}')、127(削除)、およびそれより大きい文字は通常、許可されません。
H1では、(0..32)の範囲の文字と127は常に拒否します。127を含まず、それを超えるすべての文字も、このオプションを有効にした場合を除いて拒否します。その他の文字(33..126)は一切検査しません。
* H1とH2では、フラグメント参照(パスの後の'#')を含むURLを受け付けます。
* H1でのみ、CONNECTリクエストのauthorityを検査しません。
* H1でのみ、authorityとHostヘッダーの値の照合を行いません。
* H1でのみ、HTTPバージョンの検査を緩和します。バージョンを指定しないHTTP/0.9のGETリクエスト、異なるプロトコル名(RTSPなど)、およびメジャーバージョンとマイナーバージョンの両方に複数桁を使う表記を許可します。
* H1でのみ、有効な"Sec-Websocket-Key"ヘッダーフィールドを提示しないWebSocket(RFC6455)リクエストを受け付けます。
このオプションは、アプリケーションの不具合を隠し、セキュリティ上の抜け穴を生むため、決してデフォルトで有効にすべきではありません。問題を確認した後にのみ導入すべきです。
このオプションを有効にすると、不正であっても受け入れたH1リクエストを取得し、後からUNIX統計ソケットの"show errors"リクエストで解析できるようにします。問題が解決したかどうかの確認にも役立ちます。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
“option accept-unsafe-violations-in-http-response"と、統計ソケットの"show errors"も参照してください。
option accept-unsafe-violations-in-http-response
HTTPレスポンス解析の制約緩和を有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
“option accept-unsafe-violations-in-http-request"と同様に、このオプションを使うとHTTPレスポンスの解析規則を緩和できます。信頼できる旧式サーバーからの一部の不正なレスポンスを受け入れる場合に限って有効にするべきです。歴史的な理由から、規則のほとんどはH1の解析に関するものです。新しいHTTPバージョンはより整備されている傾向があり、アプリケーションもそのプロトコルにより厳密に従います。
このオプションを設定すると、次の規則が適用されます。
* H1でのみ、3桁より長くても値が16ビットに収まるステータスコードは拒否しません。
* H1でのみ、ヘッダー名にNULL文字を含む無効な文字があっても拒否しません。ただし、そのヘッダーは削除します。
* H1でのみ、ヘッダー値のNULL文字が許可されます。
* H1でのみ、Transfer-Encodingヘッダーの空の値や、複数の"chunked"値を受け付けます。
* H1でのみ、authorityとHostヘッダーの値の照合を行いません。
* H1でのみ、HTTPバージョンの検査を緩和します。
異なるプロトコル名(RTSPなど)と、メジャーおよびマイナーバージョンの
両方に複数桁の数値を使用できるようになります。
* H1でのみ、有効な"Sec-Websocket-Accept"ヘッダーフィールドを提示しないWebSocket(RFC6455)レスポンスを受け付けます。
このオプションは、アプリケーションの不具合を隠し、セキュリティ上の抜け穴を生むため、決してデフォルトで有効にすべきではありません。問題を確認した後にのみ導入すべきです。
このオプションを有効にすると、レスポンスの誤ったヘッダー名も受け付けますが、レスポンス全体をキャプチャし、後からUNIX統計ソケットの"show errors"リクエストで解析できるようにします。これは、問題が解決したことの確認にも役立ちます。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
“option accept-unsafe-violations-in-http-request"と、統計ソケットの"show errors"も参照してください。
option allbackups
すべてのバックアップサーバーを同時に使用するか、最初のサーバーのみを使用します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
デフォルトでは、通常のサーバーがすべてダウンすると、最初の稼働中のバックアップサーバーがすべてのトラフィックを受け取ります。一つでは足りないため、複数のバックアップを同時に使用したほうがよい場合もあります。“option allbackups"を有効にすると、通常のサーバーがすべて利用できないときに、すべてのバックアップサーバー間で負荷分散します。同じ負荷分散アルゴリズムを使用し、サーバーの重みも考慮します。そのため、バックアップサーバー間の優先順位はなくなります。
このオプションは主に、アプリケーションが完全に停止しているときに「お詫び」ページを返すための、静的なサーバー群で使用します。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
option checkcache
すべてのサーバーレスポンスを解析し、キャッシュ可能なCookieを含むレスポンスを遮断します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
一部の高水準フレームワークは、いたるところでアプリケーションのCookieを設定し、レスポンスのキャッシュ方法を開発者が十分に制御できるとは限りません。キャッシュ可能なオブジェクトとともにセッションCookieが返されると、同じキャッシュを経由するユーザー間で、セッションが混同されたり盗まれたりする危険が高まります。状況によっては、機密性の高いセッション情報を外部に流してしまうより、レスポンスをブロックするほうがよい場合があります。
“checkcache"オプションは、すべてのサーバーレスポンスを詳細に検査し、キャッシュの可否についてHTTP仕様に厳密に準拠しているかを確認します。レスポンスの"Cache-control”、“Pragma”、“Set-cookie"ヘッダーを注意深く検査し、クライアント側のプロキシがCookieをキャッシュするリスクがないか確認します。このオプションを有効にすると、クライアントに送れるのは次のレスポンスだけです:- “Set-Cookie"ヘッダーがないもの。- ステータスコードが200、203、204、206、300、301、404、405、410、414、501以外で、サーバーが"Cache-control: public"ヘッダーフィールドを設定していないもの。- GET、HEAD、OPTIONS、TRACE以外のメソッドを使用したリクエストへのレスポンスで、サーバーが’Cache-Control: public’ヘッダーフィールドを設定していないもの。- ‘Pragma: no-cache’ヘッダーを持つもの。- ‘Cache-control: private’ヘッダーを持つもの。- ‘Cache-control: no-store’ヘッダーを持つもの。- ‘Cache-control: max-age=0’ヘッダーを持つもの。- ‘Cache-control: s-maxage=0’ヘッダーを持つもの。- ‘Cache-control: no-cache’ヘッダーを持つもの。- ‘Cache-control: no-cache=“set-cookie”‘ヘッダーを持つもの。- ‘Cache-control: no-cache=“set-cookie,‘ヘッダーを持つもの(set-cookieの後にほかのフィールドを指定できます)。 - 鮮度情報(“max-age"または"s-maxage"を持つ"Cache-control”、または"Expires"ヘッダー)も検証子(“ETag"または"Last-Modified"ヘッダー)も持たないもの。仕様に準拠したキャッシュは、このようなレスポンスを保存しないためです。
レスポンスがこれらの要件を満たさない場合、“http-response deny"ルールによる拒否と同様にブロックされ、“HTTP 502 bad gateway"になります。セッション状態には"PH–“が表示され、プロキシがヘッダー処理中にレスポンスをブロックしたことを示します。さらに、修正が必要であることを管理者に知らせるため、ログにアラートが出力されます。
アプリケーションへの影響が大きいため、本番環境に導入する前に、このオプションを有効にしてアプリケーションを十分にテストするべきです。また、危険につながる可能性のあるアプリケーションの動作を報告するので、本番環境で使わない場合でも、テスト中は常に有効にしておくのがよい方法です。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
option clitcpka
クライアント側のTCP keepaliveパケットの送信を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
クライアントとサーバーの間にファイアウォールなどのセッションを認識するコンポーネントがあり、プロトコルが長いアイドル期間を含む非常に長いセッションを使う場合(リモートデスクトップなど)、途中のコンポーネントが、長時間アイドル状態にあったセッションを期限切れにするおそれがあります。
ソケットレベルのTCP keep-aliveを有効にすると、システムは接続の相手側へ定期的にパケットを送信し、接続を維持します。keep-aliveプローブの間隔はシステムだけが制御し、オペレーティングシステムとその調整パラメーターの両方に依存します。
キープアライブパケットは、アプリケーションレベルでは送信も受信もされないことを理解する必要があります。それを認識するのはネットワークスタックだけです。そのため、プロキシの片側ですでにキープアライブを使って接続を維持していても、そのキープアライブパケットがプロキシの反対側に転送されることはありません。
これはHTTP keep-aliveとは関係がありません。
“clitcpka"オプションを使うと、接続のクライアント側でTCPキープアライブプローブの送信を有効にします。HAProxyとクライアントの間でセッションの期限切れが見られる場合に役立つはずです。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option srvtcpka”、“option tcpka”。
option contstats
トラフィック統計の継続的な更新を有効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
デフォルトでは、統計の計算に使うカウンターは、ストリームが終了したときだけ増加します。小さなオブジェクトを配信する場合は十分に機能しますが、大きな画像やアーカイブなどの大きなオブジェクト、または音声や映像のストリーミングでは、HAProxyのカウンターから作ったグラフがハリネズミのようにとがった形になります。このオプションを有効にすると、ストリームの途中でもカウンターを頻繁に、通常は5秒ごとに増加させるため、多くの場合、滑らかなグラフを作れます。再集計は頻繁に通る処理経路に直接影響し、セッション数が非常に多いと大量の起床処理が発生して性能がわずかに低下する可能性があるため、デフォルトでは有効にしていません。
option disable-h2-upgrade
HTTP/1.xクライアント接続からの暗黙的なHTTP/2へのアップグレードを有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
デフォルトでは、あるHTTP接続で最初に受信したリクエストがHTTP/2の接続プリフェイス(文字列"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n”)に一致すると、HAProxyはHTTP/1.xクライアント接続をHTTP/2接続へ暗黙にアップグレードできます。これにより、SSLを使わない接続でもHTTP/1.xとHTTP/2のクライアントをサポートできます。暗黙のアップグレードを無効にするには、このオプションを使用しなければなりません。このアップグレードはHTTPプロキシだけがサポートするため、このオプションも同様です。また、bind行に"proto h2"を指定すると、平文接続でHTTP/2を強制することもできます。このオプションは、すべてのbind行に適用します。特定のbind行で暗黙のHTTP/2アップグレードを無効にするには、“proto h1"を使用できます。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
option dontlog-normal
正常に成功した接続のログ記録を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
毎秒数千の接続を扱う大規模なサイトでは、ログ記録が大きな負担になることがあります。ログを無効にせざるを得ず、本番環境の問題をデバッグできないサイトさえあります。このオプションを設定すると、エラー、タイムアウト、再試行、再振り分けのいずれも起きていない正常な接続を、ログに記録しません。これにより、異常を記録するためのディスク領域を確保できます。HTTPモードではレスポンスのステータスコードを確認し、5xxの応答コードは引き続き記録します。
複雑な問題を解決する手掛かりは、この設定では記録されない通常のログにあることが多いため、このオプションの使用は強く非推奨とします。ログを分ける必要がある場合は、代わりに"log-separate-errors"オプションを参照してください。
“log”、“dontlognull”、“log-separate-errors”、およびログに関するセクション8 も参照してください。
option dontlognull
データのない接続のログ記録を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
環境によっては、各種システムが稼働しているかを確認するため、定期的に接続するコンポーネントがあります。別のロードバランサーや監視システムが、その例です。デフォルトでは、単純なポートのプローブやスキャンでもログが生成されます。このような接続でログが埋まりすぎる場合は、“dontlognull"オプションを有効にすると、データを一切転送していない接続を記録しないようにできます。通常、この種のプローブが該当します。ただし、エラーは引き続きクライアントへ返し、統計にも計上します。これも望ましくない場合は、代わりにoption http-ignore-probesを使用できます。
一般に、管理できない環境(インターネットなど)では、このオプションを使用しないことを推奨します。使用すると、スキャンやその他の悪意のある活動がログに記録されなくなるためです。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
“log”、“http-ignore-probes”、“monitor-uri”、およびログに関するセクション8 も参照してください。
option external-check
サーバーのヘルスチェックに外部プロセスを使用します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
外部コマンドを使って、サーバーの正常性を確認できます。“external-check command"で指定した実行ファイルを実行することで実現します。
グローバル設定の"external-check"を設定する必要があります。
参照:“external-check”、“external-check command”、“external-check path”。
option forwarded [ proto ]
サーバーに送信するリクエストへのrfc 7239 forwardedヘッダーの挿入を有効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
HAProxyはリバースプロキシとして動作するため、サーバーではリクエストの一部の情報(送信元のクライアントIPアドレス、使用したプロトコルなど)が失われます。
この制限への一般的な対処方法は、よく知られたx-forward-forやx-forward-* 系のヘッダーを使い、このコンテキストの一部を背後のサーバーやアプリケーションに伝えることです。この方法は機能しており、広く導入されていますが、IETFが公式にサポートするものではなく、相互運用性やセキュリティの問題の原因になることがあります。
これを解決するため、IETFが新しいHTTP拡張としてforwardedヘッダー(RFC7239)を定めました。詳細はhttps://www.rfc-editor.org/rfc/rfc7239.html を参照してください。
この一つのヘッダーで多数の詳細情報を伝えられ、特に重要な点として、プロキシを連鎖させたときの問題を解決できます(RFCは、連鎖した複数のプロキシが、既存のヘッダーにそれぞれの値を追加することを認めています)。
このオプションはdefaults、listen、backendセクションに指定できますが、frontendセクションでは無視されます。
option forwardedを引数なしで設定すると、デフォルトの暗黙の動作を使用します。デフォルトではprotoパラメーターを有効にし、元のクライアントIPを挿入します。
同等の明示的な手動設定は次のようになります。
‘by’キーワードは、forwardedヘッダーの’by’パラメーター(“nodename”)を有効にします。リクエストを扱うプロキシの情報を埋め込めます。‘by’の値には、プロキシのIP(宛先アドレス)を設定します。UNIXリスナーなど、利用できない場合は、‘by’を"unknown"に設定します。
‘by-expr’キーワードは、forwardedヘッダーの’by’パラメーター(“nodename”)を有効にします。リクエストを扱うプロキシの情報を埋め込めます。‘by’の値には、サンプル式<by_expr>の結果が有効であればその結果を設定し、そうでなければ"unknown"を設定します。
‘for’キーワードは、forwardedヘッダーの’for’パラメーター(“nodename”)を有効にします。リクエストを送るクライアントの情報を埋め込めます。‘for’の値には、クライアントのIP(送信元アドレス)を設定します。UNIXリスナーなど、利用できない場合は、‘for’を"unknown"に設定します。
‘for-expr’キーワードは、forwardedヘッダーの’for’パラメーター(“nodename”)を有効にします。リクエストを送るクライアントの情報を埋め込めます。‘for’の値には、サンプル式<for_expr>の結果が有効であればその結果を設定し、そうでなければ"unknown"を設定します。
‘by_port’キーワードは、‘by’パラメーターに"nodeport"情報を渡すために使用します。‘by_port’には’by’または’by-expr’の設定が必要で、なければ無視されます。“nodeport"には、利用可能であればプロキシのポート(宛先ポート)を設定し、利用できなければ無視します。
‘by_port-expr’キーワードは、‘by’パラメーターに"nodeport"情報を渡します。‘by_port-expr’には’by’または’by-expr’の設定が必要で、なければ無視します。“nodeport"には、サンプル式<by_port_expr>の結果が有効であればその結果を設定し、そうでなければ無視します。
‘for_port’キーワードは、‘for’パラメーターに"nodeport"情報を渡すために使用します。‘for_port’には’for’または’for-expr’の設定が必要で、なければ無視されます。“nodeport"には、利用可能であればクライアントのポート(送信元ポート)を設定し、利用できなければ無視します。
‘for_port-expr’キーワードは、‘for’パラメーターに"nodeport"情報を渡します。‘for_port-expr’には’for’または’for-expr’の設定が必要で、なければ無視します。“nodeport"には、サンプル式<for_port_expr>の結果が有効であればその結果を設定し、そうでなければ無視します。
例:
参照:“option forwardfor”、“option originalto”。
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
サーバーに送信するリクエストへのX-Forwarded-Forヘッダーの挿入を有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
HAProxyはリバースプロキシとして動作するため、サーバーから見るクライアントのアドレスはHAProxyのIPアドレスになります。サーバーのログにクライアントのIPアドレスを記録したい場合、これが問題になることがあります。解決するには、HAProxyからサーバーに送るすべてのリクエストに、広く知られたHTTPヘッダー"X-Forwarded-For"を追加できます。このヘッダーの値は、クライアントのIPアドレスを表します。常に既存のヘッダー一覧の末尾に追加するため、サーバーは、このヘッダーの最後の出現箇所だけを常に使用するよう設定しなければなりません。この標準的なヘッダーの使用を有効にする方法は、サーバーのマニュアルを参照してください。クライアントがすでにこのヘッダーを付けている可能性もあるため、最後の出現箇所だけを使用しなければなりません。
“header"キーワードを使うと、既定の"X-Forwarded-For"を置き換える別のヘッダー名を指定できます。別のアプリケーション(stunnelなど)がすでに付けた"X-Forwarded-For"ヘッダーがあり、それを保持する必要がある場合に便利です。また、バックエンドサーバーが"X-Forwarded-For"ヘッダーを使わず、別のヘッダーを必要とする場合にも使えます(たとえば、Zeus Web Serversは"X-Cluster-Client-IP"を必要とします)。
クライアントから直接アクセスする場合と、リバースプロキシ経由でアクセスする場合とで、同じHAProxyインスタンスを共有することがあります。たとえば、SSLリバースプロキシでHTTPSトラフィックを復号する場合です。“except"キーワードの後にネットワークアドレスを指定すると、既知の送信元アドレスまたはネットワークに対して、ヘッダーの追加を無効にできます。この場合、そのネットワークに一致する送信元IPからのリクエストには、このヘッダーを追加しません。プライベートネットワークや127.0.0.1での使用が一般的です。IPv4とIPv6の両方をサポートします。
別の方法として、“if-none"キーワードを指定すると、ヘッダーが存在しない場合にだけ追加します。HAProxyに届くヘッダーをエンドユーザーが制御できるとセキュリティ上の問題になる可能性があるため、完全に信頼できる環境でのみ使用するべきです。
このオプションはフロントエンドとバックエンドのどちらでも指定できます。少なくとも一方で使用していれば、ヘッダーを追加します。両方でheaderサブ引数を定義している場合は、バックエンドの設定がフロントエンドより優先されます。“if-none"引数については、フロントエンドかバックエンドの少なくとも一方が指定していなければ、その側がヘッダーの追加を必須としているため、そちらが優先されます。
例:
参照:“option httpclose”、“option http-server-close”、“option http-keep-alive”。
option h1-case-adjust-bogus-client
仕様に準拠しないクライアントに送信するHTTP/1ヘッダーの大文字・小文字の調整を有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
RFC7230が規定するとおり、ヘッダー名は大文字と小文字を区別しないため、標準となる大文字・小文字の表記はありません。アプリケーションは、大文字と小文字を区別せずに扱わなければなりません。しかし、標準に違反し、ブラウザーがよく使う大文字・小文字の表記に誤って依存するアプリケーションもあります。HTTP/2では、すべてのヘッダー名を小文字で交換しなければならず、HAProxyも同じ規則に従うため、この問題は重大になります。HTTPのバージョンに関係なく、クライアントとサーバーには、すべてのヘッダー名を小文字で送ります。
HAProxyがHTTP/1レスポンスを受信すると、ヘッダー名を小文字に変換し、その表記で処理してクライアントに送ります。クライアントがHTTPの標準に違反し、HAProxyからのレスポンスを処理できないと分かっている場合は、このオプションを有効にし、globalディレクティブ"h1-case-adjust"または"h1-case-adjust-file"で表記を変えるヘッダーの一覧を指定すると、レスポンスを整形してクライアントへ送る際に、小文字のヘッダー名を別の表記に変換できます。このような回避策が必要なクライアントはコンテンツスマグリング攻撃に弱い可能性があり、必ず修正しなければならないため、クライアントを修正するまでの一時的な回避策としてのみ使用しなければなりません。
このオプションは、標準に準拠したクライアントには影響しません。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option h1-case-adjust-bogus-server”、“h1-case-adjust”、“h1-case-adjust-file”。
option h1-case-adjust-bogus-server
仕様に準拠しないサーバーに送信するHTTP/1ヘッダーの大文字・小文字の調整を有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
RFC7230が規定するとおり、ヘッダー名は大文字と小文字を区別しないため、標準となる大文字・小文字の表記はありません。アプリケーションは、大文字と小文字を区別せずに扱わなければなりません。しかし、標準に違反し、ブラウザーがよく使う大文字・小文字の表記に誤って依存するアプリケーションもあります。HTTP/2では、すべてのヘッダー名を小文字で交換しなければならず、HAProxyも同じ規則に従うため、この問題は重大になります。HTTPのバージョンに関係なく、クライアントとサーバーには、すべてのヘッダー名を小文字で送ります。
HAProxyがHTTP/1リクエストを受信すると、ヘッダー名を小文字に変換し、その表記で処理してサーバーに送ります。サーバーがHTTPの標準に違反し、HAProxyからのリクエストを処理できないと分かっている場合は、このオプションを有効にし、globalディレクティブ"h1-case-adjust"または"h1-case-adjust-file"で表記を変えるヘッダーの一覧を指定すると、リクエストを整形してサーバーへ送る際に、小文字のヘッダー名を別の表記に変換できます。このような回避策が必要なサーバーはコンテンツスマグリング攻撃に弱い可能性があり、必ず修正しなければならないため、サーバーを修正するまでの一時的な回避策としてのみ使用しなければなりません。
このオプションは、標準に準拠したサーバーには影響しません。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option h1-case-adjust-bogus-client”、“h1-case-adjust”、“h1-case-adjust-file”。
option http-buffer-request
処理を進める前にHTTPリクエスト本文全体を待つ機能を有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
判断を下す前に、HTTPリクエストのボディを待ちたい場合があります。たとえば、“balance url_param"はこれを行います。最初の用途は、サーバーへ接続する前に、低速なクライアントからのリクエストをバッファーに格納することです。もう一つは、リクエストのボディの内容に基づいて、振り分け先を決めることです。フロントエンドまたはバックエンドにこのオプションを設定すると、ボディ全体を受信するかリクエストバッファーがいっぱいになるまで、HTTPの処理を待機させます。フロントエンドとバックエンドの間でバッファリングしない転送を期待するなど、HTTPを不適切に使うアプリケーションでは、望ましくない副作用が起きる可能性があります。そのため、デフォルトで使用することは明確に避けるべきです。
参照:“option http-no-delay”、“timeout http-request”、“http-request wait-for-body”。
option http-drop-request-trailers
サーバーへの送信時に、リクエストからHTTPトレーラーを削除します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 不可 | 可
引数:なし
このオプションを有効にすると、リクエスト内のHTTPトレーラーを、サーバーへ送信する前にすべて削除します。
RFC9110#section-6.5.1は、トレーラーフィールドをヘッダーフィールドに統合できると規定しています。意図して行うべき処理ですが、アプリケーションによっては問題になることがあります。特に、悪意のあるクライアントがセキュリティ上重要なヘッダーフィールドをトレーラー部分に隠し、途中のコンポーネントが特別な確認なしにヘッダーへ統合する場合です。その場合、バックエンドでこのオプションを有効にすると、サーバーへ送信する前に、リクエスト内で見つかったトレーラーフィールドをすべて破棄します。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option http-drop-response-trailers”。
option http-drop-response-trailers
クライアントへの送信時に、レスポンスからHTTPトレーラーを削除します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
このオプションは"option http-drop-request-trailers"と似ていますが、レスポンスをクライアントに送る前に、そのトレーラーフィールドを破棄するために使用しなければなりません。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option http-drop-request-trailers”。
option http-ignore-probes
データのない接続とリクエストのタイムアウトのログ記録を有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
最近、一部のブラウザーが"pre-connect"機能を実装し始めました。利用者が訪問するかもしれない場合に備え、最近訪れたWebサイトに投機的に接続する機能です。その結果、Webサイトへの接続が多数確立され、先にタイムアウトすると408 Request Timeout、ブラウザーが先に閉じると400 Bad Requestになります。これらはログを埋め、エラーカウンターを増加させます。すでに"option dontlognull"がありますが、この場合には不十分です。代わりに、このオプションは次の処理を行います。- 閉じるまでに何も受信しなかった接続では、400/408メッセージをクライアントに送らないようにします。- この状況ではログを一切出さないようにします。- エラーカウンターを一切増加させないようにします。
このようにして、何も送られない接続を通知なしで無視します。ただし、実際の問題も隠すため、必要であることが明らかな場合を除き、使用しないほうがよいでしょう。リクエストを受信できず408になる最も一般的な理由は、クライアントとVPNなどの途中の要素でMTUが一致せず、大きすぎるパケットが遮断されることです。この問題は、POSTリクエストや大きなCookieを含むGETでよく見られます。検出する唯一の手段がログであることも多くあります。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
“log”、“dontlognull”、“errorfile”、およびログに関するセクション8 も参照してください。
option http-keep-alive
HTTP/1.x接続で、クライアントからサーバーまでのHTTP keep-aliveを有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
既定では、HAProxyはHTTP/1.xの持続的接続をキープアライブモードで扱います。各接続についてリクエストとレスポンスを処理し、その後、両側の接続をアイドル状態のまま保持します。このモードは、“option http-server-close"や"option httpclose"などのオプションで変更できます。このオプションを使うとキープアライブモードに戻せるため、defaultsセクションで別のモードが使われている場合に便利です。
“option http-keep-alive"を設定すると、クライアント側とサーバー側の両方でHTTPキープアライブモードを有効にします。サーバーへのアイドル接続を保持する代わりに、クライアント側(低速なネットワーク)の遅延を最小にし、サーバー側で最も速くセッションを再利用できます。一般に、小さなオブジェクトでは、“http-server-close"オプションに比べて約二倍のリクエストレートを達成できます。このオプションが役立つ主な状況は、次の二つです。
- サーバーがHTTPに準拠せず、リクエストではなく接続を認証する場合
(NTLM認証など)
- サーバーから対象のオブジェクトを取得するコストと比べて、サーバーへの接続を確立するコストが大きい場合です。
最後のケースは、サーバーがキャッシュ用の高速な静的サーバーである場合に起こり得ます。
現在、ログにはリクエストが同じセッションから来たかどうかは示されません。ログに記録される受け入れ日時は前のリクエストの終了時刻に対応し、リクエスト時間は新しいリクエストを待っていた時間に対応します。キープアライブのリクエスト時間にも、“timeout http-keep-alive”、またはそれが未設定なら"timeout http-request"で定義したタイムアウトが適用されます。
このオプションは、以前の"option httpclose"または"option http-server-close"を無効にし、置き換えます。
“option httpclose”、“option http-server-close”、“option prefer-last-server”、“option http-pretend-keepalive"も参照してください。
option http-no-delay
HTTPでは性能よりも対話の遅延を低く抑えることを優先するよう、システムに指示します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
HTTPでは、各ペイロードは単方向で、双方向のやり取りという概念はありません。どのエージェントも、妥当に短い遅延の範囲で、データをある程度キューに格納することが想定されています。ごくまれに、HTTPプロトコルを不適切に使い、単一のリクエスト中に両方向で多数のデータチャンクを交互に送り、ペイロードの段階で高度な双方向性を期待するサーバー間アプリケーションがあります。これはHTTPの仕様ではまったくサポートせず、大半のプロキシやサーバーでは動作しません。このようなアプリケーションがHAProxyを経由すると、動作はしますが、性能を優先するネットワークの最適化により、大きな遅延が発生します。パケットを満杯にしてから送るため、十分なデータがそろうまで待つようシステムに指示するためです。典型的な遅延は往復ごとに約200 msです。これは異常な使い方でのみ起きます。CONNECTリクエストやWebSocketなど、通常の使い方には影響しません。
接続が使用するフロントエンドまたはバックエンドのどちらかに"option http-no-delay"を指定すると、やり取りをできる限り速くするため、この種の最適化をすべて無効にします。ただし、別の場所で動作しなくなる可能性があるため、機能を保証するものではありません。それでも、HAProxy経由で動作する場合は、可能な限り速く動作します。このオプションをデフォルトで決して使用すべきではありません。また、このような不具合のあるアプリケーションが見つからない限り、一切使用すべきではありません。使用すると帯域とCPUの使用量が増え、遅延が大きい環境では性能が大幅に低下する可能性があります。
参照:“option http-buffer-request”。
option http-pretend-keepalive
サーバーへのHTTP/1.x接続で、HAProxyがkeepaliveを通知するかどうかを定義します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
“option http-server-close"または"option httpclose"を使う場合、HAProxyはサーバーに転送するHTTP/1.xリクエストに、“Connection: close"ヘッダーを追加します。ところが一部のサーバーは、このヘッダーを見ると、まったく無関係であるにもかかわらず、長さが不明なレスポンスにチャンク転送符号化を使わなくなります。その結果、クライアントやキャッシュは、レスポンスが不完全であることに気付かずに受信し、完全なものとみなす可能性があります。
“option http-pretend-keepalive"を設定すると、HAProxyは接続を維持するとサーバーに思わせます。これにより、サーバーは前述の望ましくない異常な動作に切り替わらなくなります。HAProxyはレスポンス全体を受け取ると、“option httpclose"と同じようにサーバーとの接続を閉じます。その結果、クライアントは通常のレスポンスを取得し、サーバー側の接続も正しく閉じられます。
このオプションは、デフォルトでは有効にしないことを推奨します。大半のサーバーは、最後のパケットの後に自ら接続を閉じるほうが効率的で、バッファーも少し早く解放できるためです。また、ネットワーク上のパケットが増えることで、全体の最大性能がわずかに低下する可能性があります。ただし、有効にすると、HAProxyの処理は少し減ります。したがって、構成全体でHAProxyがボトルネックになっている場合は、CPUサイクルをいくらか節約できるかもしれません。
このオプションはbackendセクションとlistenセクションで設定できます。frontendセクションで使用すると無視され、起動時に警告を出します。バックエンドに関係するオプションなので、フロントエンドで設定する実質的な理由はありません。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option httpclose”、“option http-server-close”、“option http-keep-alive”。
option http-restrict-req-hdr-names { preserve | delete | reject }
“[a-zA-Z0-9-]“以外の文字を含むHTTPリクエストヘッダー名に対するHAProxyの方針を設定します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
このオプションは、リクエストのヘッダー名を英数字とハイフン([A-Za-z0-9-])に制限するために使用できます。ヘッダー名の一部の文字を扱えない、HTTPに準拠していないサーバーと相互運用するために、必須となる場合があります。FastCGIアプリケーションでも、ヘッダー名の英数字以外の文字をすべてアンダースコア(’_’)に置き換えるため、必須となる場合があります。その結果、ヘッダー名を取り違えさせてルールを回避することが容易になります。たとえば、“X-Forwarded-For"と"X_Forwarded-For"は、FastCGIではどちらも"HTTP_X_FORWARDED_FOR"に変換します。
このオプションはプロキシごとに、http-requestルールの評価後に評価されます。
option http-server-close
サーバー側のHTTP/1.x接続のクローズを有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
デフォルトでは、HAProxyはHTTP/1.xの持続的接続をキープアライブモードで扱います。各接続でリクエストとレスポンスを処理し、両側の接続をアイドル状態のまま保持します。“option http-server-close"や"option httpclose"などのオプションで、このモードを変更できます。“option http-server-close"を設定すると、クライアント側ではHTTPキープアライブとパイプライン処理をサポートしたまま、サーバー側でHTTP接続を閉じるモードを有効にします。これにより、クライアント側(低速なネットワーク)の遅延を最小にし、サーバー側で最も速くセッションを再利用して、“option httpclose"と同様にサーバーのリソースを節約します。また、RFC7230の要件に準拠していれば、キープアライブをサポートしないサーバーに対しても、クライアント側ではキープアライブモードでサービスを提供できます。ただし、一部のサーバーはリクエスト内に"Connection: close"を見ると、これらの要件に常に従うとは限りません。その場合、キープアライブは一切使用されません。“option http-pretend-keepalive"を有効にすると回避できます。
現在、ログにはリクエストが同じセッションから来たかどうかは示されません。ログに記録される受け入れ日時は前のリクエストの終了時刻に対応し、リクエスト時間は新しいリクエストを待っていた時間に対応します。キープアライブのリクエスト時間にも、“timeout http-keep-alive”、またはそれが未設定なら"timeout http-request"で定義したタイムアウトが適用されます。
このオプションはフロントエンドとバックエンドの両方で設定できます。接続を保持するフロントエンドまたはバックエンドの少なくとも一方で有効になっていれば、有効になります。それ以前の"option httpclose"や"option http-keep-alive"は無効化され、このオプションに置き換わります。フロントエンドとバックエンドのオプションが異なる場合の組み合わせについては、4節 「プロキシ」を確認してください。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option httpclose”、“option http-pretend-keepalive”、“option http-keep-alive”。
option http-use-proxy-header
Connectionの代わりに、非標準のProxy-Connectionヘッダーを使用します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
RFC7230は、HTTP/1.1エージェントが持続的接続と非持続的接続のどちらを望むかを示すために、Connectionヘッダーを使わなければならないと明記しています。しかし、ブラウザーとプロキシは、プロキシ経由の接続ではこのヘッダーを無視し、代わりに文書化されていない非標準のProxy-Connectionヘッダーを使います。ブラウザーとこの種のプロキシの間にロードバランサーを置くと、HAProxyの解釈とクライアントとプロキシの合意が異なるため、問題が起きます。
このオプションをフロントエンドで設定すると、HAProxyはプロキシを介したリクエストを検出したときに、その非標準ヘッダーを使うよう自動的に切り替えられます。ここでは、URIが’/‘でも’*‘でも始まらないリクエストを、プロキシを介したリクエストと定義します。HTTPトンネルモードとは互換性がありません。このオプションを指定できるのはフロントエンドだけで、そのリクエストの処理全体に影響します。
また、このオプションを設定した場合、認証が必要なリクエストがプロキシ経由のものであれば、自動的にプロキシ認証ヘッダーを使うよう切り替えます。これにより、既存のプロキシの前段で認証を確認または強制できます。
通常、プロキシの前段以外では、このオプションは使用しないことを推奨します。
参照:“option httpclose”、“option http-server-close”。
option httpchk
サーバーの稼働状態の確認にHTTPプロトコルを使用します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
既定では、サーバーのヘルスチェックはTCP接続の確立を試みるだけです。“option httpchk"を指定すると、TCP接続の確立後に完全なHTTPリクエストを送信します。2xxと3xxのレスポンスは正常と見なし、それ以外は応答がない場合も含めて、すべてサーバーの障害と見なします。
“http-check"ディレクティブと組み合わせると、HTTPヘルスチェックで送信するリクエストや、レスポンスを照合するルールをカスタマイズできます。TCPヘルスチェックの"tcp-check"ディレクティブと同様に、送信と応答検証のシーケンスを設定することもできます。
HTTPヘルスチェック用の接続を開く際は、既定ではサーバーの設定を使用します。ただし、“http-check connect"ルールを使ってサーバーのパラメーターを上書きすることもできます。
“httpchk"オプションは必ずしもHTTPバックエンドを必要とせず、通常のTCPバックエンドでも機能します。inetdデーモンを使い、専用ポートにバインドした単純なスクリプトを確認する場合に特に便利です。ただし、内部では常にHTXマルチプレクサーを使用します。そのため、リクエストの形式とレスポンスの解析には厳密な規則が適用されます。
例:
関連項目: “option ssl-hello-chk”、“option smtpchk”、“option mysql-check”、“option pgsql-check”、“http-check”、およびserverオプションの"check”、“port”、“inter"を参照してください。
option httpclose
HTTP/1.x接続のクローズを有効または無効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
既定では、HAProxyはHTTP/1.xの持続的接続をキープアライブモードで扱います。各接続についてリクエストとレスポンスを処理し、その後、両側の接続をアイドル状態のまま保持します。このモードは、“option http-server-close"や"option httpclose"などのオプションで変更できます。
“option httpclose"を設定すると、HAProxyは設定した場所に応じて、クライアントまたはサーバーとの接続を閉じます。クライアント接続にはフロントエンド、サーバー接続にはバックエンドの設定を適用します。リスナーで設定した場合は、クライアントとサーバーの両方の接続に適用します。各方向で"Connection: close"ヘッダーがすでに設定されているかを確認し、なければ追加します。
このオプションは"option http-pretend-keepalive"と組み合わせることもできます。その場合、“Connection: close"リクエストヘッダーの送信は無効になりますが、レスポンス全体を受信した後には接続を閉じます。
以前の"option http-server-close"または"option http-keep-alive"を無効にし、置き換えます。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option http-server-close”。
option httplog [ clf ]
HTTPリクエスト、ストリームの状態、タイマーのログ記録を有効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
既定のログ出力形式は情報が乏しく、送信元と宛先のアドレス、およびインスタンス名しか含みません。“option httplog"を指定すると、各ログ行に含まれる情報が大幅に増えます。HTTPリクエスト、接続タイマー、ストリーム状態、接続数、取得したヘッダーとCookie、フロントエンド・バックエンド・サーバーの名前、そしてもちろん送信元アドレスとポートなどが含まれますが、これらに限りません。
“option httplog"だけを指定すると、デフォルトで設定されていた’clf’モードを自動的に解除します。
“option httplog"は、それより前のすべての"log-format"ディレクティブを上書きします。
ログについては、セクション8 も参照してください。
option httpslog
HTTPSリクエスト、ストリームの状態、タイマーのログ記録を有効にします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
デフォルトのログ出力形式は情報が乏しく、送信元と宛先のアドレス、およびインスタンス名だけを含みます。“option httpslog"を指定すると、各ログ行に含まれる情報が大幅に増えます。HTTPリクエスト、接続タイマー、ストリーム状態、接続数、取得したヘッダーとCookie、フロントエンド・バックエンド・サーバーの名前、SSL証明書の検証とSSLハンドシェイクの状態、そしてもちろん送信元アドレスとポートなどを含みますが、これらに限りません。
“option httpslog"は、それより前のすべての"log-format"ディレクティブを上書きします。
ログについては、セクション8 も参照してください。
option idle-close-on-response
ソフトストップの進行中は、アイドル状態のフロントエンド接続を閉じないようにします。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
デフォルトでは、ソフト停止中にアイドル接続を閉じます。環境によっては、プロキシと通信するクライアントが、後でリクエストを送るためにアイドル接続を用意していることがあります。書き込みエラー時に適切な再試行を行わないと、HAProxyのリロード中にエラーが起きる可能性があります。適切な実装では接続や書き込みのエラー時に再試行するべきですが、このオプションは、バージョン2.4より前のHAProxyとの後方互換性を保つために導入しました。実際、v2.4より前のHAProxyは、最後のリクエストとレスポンスを待ち、閉じる前に"connection: close"ヘッダーを追加して、接続を再利用できなくなることをクライアントに通知していました。
実際の例では、AWSでHAProxyの前段にALBを配置した環境で、この動作が確認されました。結果として、HAProxyのリロード中にALBが502を返しました。
このオプションを使うと、接続が長時間アイドル状態のままである場合に、古いプロセスの数が増える可能性があることに注意してください。頻繁にリロードする場合は、クライアントタイムアウトや"hard-stop-after"パラメーターを、それに応じて調整する必要があるかもしれません。
参照:“timeout client”、“timeout client-fin”、“timeout http-request”、“hard-stop-after”。
option independent-streams
両方向で独立したタイムアウト処理を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
既定では、ソケットからデータを送信すると、そのソケットの書き込みタイムアウトと読み取りタイムアウトの両方を更新します。ソケットで通信が行われていると見なし、データを受信すべきかどうかを推測するほかの手段がないためです。
このデフォルトの動作は、ほぼすべてのアプリケーションにとって望ましいものですが、無効にして、受信データがある場合だけ読み取りタイムアウトを更新したい状況もあります。telnetセッションのように、タイムアウトが長く、やり取りするデータが少ないストリームが該当します。サーバーが突然消えると、送信データがシステムのソケットバッファーに蓄積し、両方のタイムアウトが正しく更新されます。サーバーが受信していないと知る手段がないため、タイムアウトしません。しかし、基盤となるプロトコルが送信したデータを常にエコーする場合は、読み取りタイムアウトだけで問題を検出できます。より多くのデータをやり取りするプロトコルでは、データがソケットバッファー内に長く蓄積しないため、この問題は起きません。
このオプションをフロントエンドで設定すると、クライアントへのデータ送信に伴う読み取りタイムアウトの更新を無効にします。この用途はおそらくあまりありません。バックエンドで設定すると、サーバーへのデータ送信に伴う読み取りタイムアウトの更新を無効にします。この設定により、低速回線からの大きなHTTP POSTは通常失敗するようになるため、注意して使用してください。
参照:“timeout client”、“timeout server”、“timeout tunnel”。
option ldap-check
サーバーの確認にLDAPv3ヘルスチェックを使用します。
使用可能なコンテキスト:tcp
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
サーバーがTCP接続を受け入れるかだけでなく、LDAPv3で正しく通信するかを確認できます。このオプションを設定すると、LDAPv3の匿名のシンプルバインドメッセージをサーバーに送り、レスポンスを解析してLDAPv3のバインドレスポンスメッセージを探します。
LDAPレスポンスのresultCodeが成功を示す場合にのみ、サーバーを有効とみなします(http://tools.ietf.org/html/rfc4511#section-4.1.9 )。
bindリクエストのログ記録はサーバーによって異なります。設定方法はサーバーのドキュメントを参照してください。
例:
参照:“option httpchk”。
option log-health-checks
ヘルスチェックの状態更新のログ記録を有効または無効にします。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
デフォルトでは、サーバーがUP状態のときは失敗したヘルスチェック、DOWN状態のときは成功したヘルスチェックを記録するため、追加情報の量は限られます。
このオプションを有効にすると、ヘルスチェックのステータスやサーバーの正常性の変化がすべて記録されます。そのため、サーバーがクラッシュする前に時々チェックに失敗していたことや、有効なHTTPステータスを返さなくなった正確な時点、続いてポートが接続を拒否し始めた時点、最後にサーバーがまったく応答しなくなった時点を把握できます。
ヘルスチェックに起因しない状態の変更(CLIでの有効化や無効化など)は、このオプションでは意図的にログに記録しません。
関連項目: “option httpchk”、“option ldap-check”、“option mysql-check”、“option pgsql-check”、“option redis-check”、“option smtpchk”、“option tcp-check”、“log”、およびログについて説明する8節 を参照してください。
option log-separate-errors
完全には成功しなかった接続のログレベルを変更します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
ログの中からエラーを見つけることは、必ずしも簡単ではありません。このオプションを使うと、HAProxyは、エラー、タイムアウト、再試行、再振り分け、HTTPの5xxステータスコードなど、関心を引く可能性のある情報を含むログのレベルを上げます。レベルは"info"から"err"に変わります。これにより、大半のsyslogデーモンで、別のファイルにも記録できます。ただし、元のファイルから削除しないよう注意してください。非常に重要な情報となる順序が分からなくなるためです。
このオプションを使うと、毎秒数千の接続を扱う大規模なサイトで、通常のトラフィックを循環バッファーに記録し、量の少ないエラーログだけをアーカイブできます。
“log”、“dontlognull”、“dontlog-normal”、およびログに関するセクション8 も参照してください。
option logasap
早期のログ記録を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
デフォルトでは、log-format文字列の定義に使用するすべてのログ形式のエイリアスとサンプル取得が値を返したとき、またはストリームが終了したときに、ログを出力します。これにより、組み込みのlog-format文字列で、転送時間やバイト数をログメッセージに含められます。
大きなファイルの転送やRDPなど、長時間続く接続を扱う場合、リクエストや接続がログに現れるまで時間がかかることがあります。“option logasap"を使うと、mode tcpではサーバーへの接続が確立した時点、mode httpではサーバーがヘッダー全体を送った時点で、直ちにログメッセージを作成します。ログでは、総バイト数はメッセージを作成するまでに転送したデータ量だけとなり、総時間も、残りの接続存続時間や転送時間を含まなくなるため、それらの情報が欠けます。HTTPの場合、少なくとも転送予定のバイト数がログに分かるよう、Content-Lengthレスポンスヘッダーを取得しておくのがよい方法です。
例:
“option httplog”、“capture response header”、およびログに関するセクション8 も参照してください。
option mysql-check [ user <username> [ { post-41 | pre-41 | post-80 } ] ]
サーバーの確認にMySQLヘルスチェックを使用します。
使用可能なコンテキスト:tcp
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
ユーザー名を指定した場合、チェックではMySQLセッションを正しく閉じるため、Client Authenticationパケット一つとQUITパケット一つの、計二つのMySQLパケットを送ります。続いて、MySQLのHandshake InitializationパケットやErrorパケットを解析します。基本的ですが有用なテストで、サーバーにエラーや接続中断を発生させません。ただし、ロックされておらず、権限を持ち、パスワードを設定していないユーザーが必要です。必要に応じてリソースを制限し、権限を抑えた基本的なMySQLユーザーを作成するには、次のようにします。
ユーザー名を指定しない場合(非推奨であり、推奨しません)、チェックではMysqlのHandshake InitializationパケットまたはErrorパケットを解析するだけで、何も送信しません。チェックが頻繁すぎる場合や、トラフィックが十分にない場合に、ロックアウトが発生することが報告されています。この場合は、MySQLの"max_connect_errors"の値を確認する必要があります。前の接続が中断した後、MySQLの"max_connect_errors"未満の試行回数で接続に成功すると、そのホストのエラー数がゼロに戻るためです。HAProxyを実行するサーバーがブロックされた場合、解除する唯一の方法は"FLUSH HOSTS"文です。
データベースの存在や整合性は確認しないことに注意してください。これらを確認するには、たとえばxinetdを使う外部チェックを利用できます。
このチェックにはMySQL >=3.22が必要です。古いバージョンにはTCPチェックを使用してください。
受信側のMySQLサーバーは通常、IPアドレスに基づく権限の照合や接続のログ記録など、さまざまな目的でクライアントのIPアドレスを知る必要があります。可能であれば、“source"キーワードの"usesrc"引数を使い、サーバーへの接続時にクライアントのIPアドレスを送信元として使うのが賢明な場合がよくあります。これには、透過プロキシ機能を組み込んでビルドしておくことと、MySQLサーバーがHAProxyの稼働するマシンを経由してクライアントへルーティングすることが必要です。
参照:“option httpchk”。
option nolinger
クローズ直後のセッションリソースの解放を有効または無効にします。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
クライアントやサーバーが正常な手順を踏まずに接続を切断した場合(物理的に切断された場合など)、セッションのタイムアウトが発生してセッションを閉じます。ただし、システム内ではしばらくFIN_WAIT1状態のまま残り、リソースを使用するため、新しい接続を確立する能力が制限される可能性があります。
このような場合、“option nolinger"を有効にすると、ソケットを閉じたときに保留中のデータをシステムが直ちに削除するよう強制できます。その結果、TCP RSTを送信し、保留中のデータを切り捨て、セッションをシステムのテーブルから即座に削除します。クライアントから見た一般的な影響は、リダイレクトやエラーレスポンスなど、最後のデータブロックとともに接続を閉じた場合に、レスポンスが切り詰められることです。サーバー側では、トンネル内でクライアントの中断を転送する際に、送信元ポートを直ちに解放できる場合があります。どちらの場合もTCPリセットを送信しますが、セッションを即座に破棄するため、再送は行いません。パケット損失のあるネットワークでは、特に損失が発生する側にファイアウォールがあると、問題が増える可能性があります。ファイアウォールがリセットを受信して処理し、自身のセッションを削除した結果、相手側からの再送も含め、そのセッションの以後のトラフィックをすべて遮断する場合があるためです。相手側がリセットを受信できなかった場合、以後RSTを一切受信できず、ファイアウォールに多数の遮断パケットが記録される可能性があります。
以上の理由から、最後の手段としてどうしても必要な場合を除き、このオプションを使用しないことを強く推奨します。ほとんどの場合、“client-fin"または"server-fin"タイムアウトを使えば、より信頼できる動作で同様の結果を得られます。Linuxでは、bindまたはserverの"tcp-ut"設定を使うこともできます。
このオプションは、必要な側に応じて、フロントエンドとバックエンドのどちらでも使用できます。クライアント向けにはフロントエンドで、サーバー向けにはバックエンドで使用してください。技術的には"defaults"セクションでもサポートされますが、使用してはならないセクションに誤って継承され、問題を引き起こすおそれがあるため、そこで使用してはなりません。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
“timeout client-fin”、“timeout server-fin”、bindまたはserverの"tcp-ut"キーワードも参照してください。
option originalto [ except <network> ] [ header <name> ]
サーバーに送信するリクエストへのX-Original-Toヘッダーの挿入を有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
HAProxyは透過モードで動作できるため、クライアントからの各リクエストをプロキシに転送し、HAProxy自体も複雑なSQUID環境へ各リクエストを中継できますが、SO_ORIGINAL_DSTで取得した宛先ホストの情報は失われます。宛先IPアドレスに基づくアクセスルールを使いたい場合、これは問題になります。解決するには、HAProxyからサーバーに送るすべてのリクエストに、新しいHTTPヘッダー"X-Original-To"を追加できます。このヘッダーの値は、元の宛先IPアドレスを表します。このヘッダーの最後の出現箇所だけを常に使うよう、設定しなければなりません。クライアントがすでにこのヘッダーを付けている可能性もあるため、最後の出現箇所だけを使用しなければなりません。
“header"キーワードを使うと、既定の"X-Original-To"を置き換える別のヘッダー名を指定できます。別のアプリケーションがすでに付けた"X-Original-To"ヘッダーがあり、それを保持する必要がある場合に便利です。また、バックエンドサーバーが"X-Original-To"ヘッダーを使わず、別のヘッダーを必要とする場合にも使えます。
クライアントから直接アクセスする場合と、リバースプロキシ経由でアクセスする場合とで、同じHAProxyインスタンスを共有することがあります。たとえば、SSLリバースプロキシでHTTPSトラフィックを復号する場合です。“except"キーワードの後にネットワークアドレスを指定すると、既知の宛先アドレスまたはネットワークに対して、ヘッダーの追加を無効にできます。この場合、そのネットワークに一致する宛先IPには、このヘッダーを追加しません。プライベートネットワークや127.0.0.1での使用が一般的です。IPv4とIPv6の両方をサポートします。
このオプションはフロントエンドとバックエンドのどちらでも指定できます。少なくとも一方で使用していれば、ヘッダーを追加します。両方でheaderサブ引数を定義している場合は、バックエンドの設定がフロントエンドより優先されます。
例:
参照:“option httpclose”、“option http-server-close”。
option persist
ダウンしたサーバーに接続先を強制的に固定する機能を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
停止したサーバーを参照するCookieを含むHTTPリクエストがバックエンドに届くと、デフォルトでは、別のサーバーへ振り分け直します。どうしても必要な場合は、“option persist"を使って、まず停止したサーバーにリクエストを送るよう強制できます。典型的な用途は、サーバーが極端に高負荷で、稼働と停止を繰り返している場合です。この場合、利用者は、正しく処理されることを期待して、セッションを開始したサーバーに引き続き振り分けられます。サーバーが完全に停止し、まったく接続できない場合に、最終的には利用可能な別のサーバーへクライアントを振り分けられるよう、“option redispatch"との併用を推奨します。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option redispatch”、“retries”、“force-persist”。
option pgsql-check user <username>
サーバーの確認にPostgreSQLヘルスチェックを使用します。
使用可能なコンテキスト:tcp
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
このチェックは、PostgreSQLのStartupMessageを送信し、AuthenticationリクエストまたはErrorResponseメッセージを待ちます。基本的ですが有用なテストで、サーバーにエラーや接続中断を発生させません。このチェックは"mysql-check"と同一です。
参照:“option httpchk”。
option prefer-last-server
負荷分散された複数のリクエストを同じサーバーに維持できるようにします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
使用する負荷分散アルゴリズムが非決定的で、前のリクエストを送ったサーバーへの接続をHAProxyがまだ保持している場合、同じセッションの後続リクエストを、できるだけ同じサーバーへ送りたいことがあります。ただし、HAProxyが保証なしに適用を試みる優先方針を示すだけなので、接続先の固定とは異なります。実際の用途は、サーバーへのキープアライブ接続です。このオプションを使うと、HAProxyは、別のサーバーへ振り分け直して接続を閉じる代わりに、そのサーバーに関連付けられた同じ接続の再利用を試みます。静的ファイルを配信するサーバーで有用な場合があります。ハッシュアルゴリズムとの併用には、あまり意味がありません。非決定的な負荷分散アルゴリズムでは、HAProxyはすでに、401を返すサーバーや407(認証が必要)を返すプロキシに、自動的に接続を固定しようとします。これは、不完全なNTLM認証チャレンジを使うために必須であり、不具合のあるアプリケーションのトラブルシューティングにも大いに役立ちます。このような環境でも、ほかのレスポンスのたびにトラフィックを振り分け直すことを避けるため、option prefer-last-serverが望ましい場合があります。
どの負荷分散アルゴリズムが決定的とみなされるか、ここで明確にしておくと役立つでしょう。決定的なアルゴリズムは、利用可能なサーバーの集合が変わらない限り、同じクライアントデータに対して常に同じサーバーを選択します。一般に、受信リクエストのハッシュや検索によって対象のサーバーを選びますが、常にそうとは限りません。たとえば、“static-rr"も、サーバーの静的な重みに基づいて選択し、予測できるため、決定的とみなせます。“sticky"アルゴリズムは、再度訪れるクライアントに決定的な振り分けを提供します。
非決定的なアルゴリズムは、サーバーの動的な状態や単純な順番の切り替えに基づいてサーバーを選択するため、連続する二つのリクエストが同じサーバーに届く保証はありません。option prefer-last-serverは、特にこれらのアルゴリズム向けに設計されています。roundrobinやleastconnがその例です。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option http-keep-alive”。
option redispatch
接続失敗時のセッションの再分配を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
HTTPモードでは、Cookieが指定するサーバーが停止すると、クライアントがそのサーバーに固定されたままになる可能性があります。たとえば、“option persist"や"force-persist"を使っている場合です。クライアントはCookieを消去できないため、サービスにアクセスできなくなります。
“option redispatch"を指定すると、プロキシはCookieまたは一貫性ハッシュに基づく接続先の固定を解除し、稼働中のサーバーに再配分できます。
稼働系サーバーは、利用可能なサーバー一覧の一部から選択します。停止状態でもメンテナンス状態でもない稼働系サーバー(つまり、ヘルスチェックを行わないもの、またはチェックで"up"と確認されたもの)を、次の順序で選択します。
リトライが発生すると、HAProxyは直前とは別のサーバーの選択を試みます。新しいサーバーは、現在のサーバー一覧から選択します。
ただし、再試行の間に一覧が更新されると、接続がバックアップサーバーへ振り分けられることがあります。たとえば、再試行が多数発生し、その間に、サーバーの停止を確認して一覧から除き、バックアップサーバーの一覧に切り替えるだけの時間が経過する場合です。
接続が複数回失敗した場合に、別のサーバーへの接続を再試行することもできます。当然ながら、“retries"をゼロ以外の値に設定しておく必要があります。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option persist”、“force-persist”、“retries”。
option redis-check
サーバーの確認にredisヘルスチェックを使用します。
使用可能なコンテキスト:tcp
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
サーバーがTCP接続を受け入れるかだけでなく、REDISプロトコルで正しく通信するかを確認できます。このオプションを設定すると、PING redisコマンドをサーバーに送り、レスポンスを解析して”+PONG"レスポンスメッセージを探します。
例:
参照:“option httpchk”、“option tcp-check”、“tcp-check expect”。
option smtpchk
サーバーの確認にSMTPヘルスチェックを使用します。
使用可能なコンテキスト:tcp
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
“option smtpchk"を設定すると、ヘルスチェックはTCP接続の後にSMTPコマンドを送信する形になります。このコマンドは、既定では"HELO localhost"です。サーバーの返すコードを解析し、“2"で始まるコードだけを正常と見なします。それ以外の応答は、応答がない場合も含めてすべてエラーとなり、サーバーの停止を示します。
このテストは、SMTPサーバーまたはリレーで使用することを想定しています。リクエストによっては、サーバーが接続試行のたびにログを記録しない場合もあるため、動作を改善できるよう試すとよいでしょう。設定を調整するより、ポート25にtelnetで接続するほうが簡単なことがよくあります。
受信SMTPサーバーは通常、スパムのフィルタリング、なりすましの防止、ログ記録など、さまざまな目的でクライアントのIPアドレスを知る必要があります。可能であれば、“source"キーワードの"usesrc"引数を使い、サーバーへの接続時にクライアントのIPアドレスを送信元として使うのが賢明な場合がよくあります。これには、透過プロキシ機能を組み込んでビルドしておく必要があります。
例:
参照:“option httpchk”、“source”。
ソケットごとに個別の統計を収集・提供する機能を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
option splice-auto
両方向のソケットで、自動的なカーネルアクセラレーションを有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
フロントエンドまたはバックエンドのどちらかでこのオプションを有効にすると、HAProxyは、クライアントとサーバーの間で、どちらの方向にもデータを転送する際に、カーネルのTCPスプライシングを使うかどうかを自動的に判断します。ヒューリスティックを使い、カーネルのスプライシングで性能が向上するかを見積もります。両方向は独立に扱います。過剰な使用を抑えるため、ヒューリスティックはあまり積極的には適用しません。このオプションには、コンパイル時にスプライシングを有効にしておく必要があります。globalオプション"nosplice"で、全体で無効にすることもできます。spliceはパイプを使うため、十分な数の空きパイプが必要です。
重要な注意: カーネルによるTCPスプライシングは、カーネル2.6.25で初めて登場したLinux固有の機能です。データをユーザー空間にコピーせずにソケット間で転送する、カーネルによる高速化機能で、性能の向上とCPUサイクルの節約に明確な効果があります。初期の実装の多くには不具合があり、データを破損させたり、非効率だったりするため、デフォルトでは有効にしていません。使用には細心の注意を払うべきです。実装が正しく動作するかを検出することはできませんが、正しく動く実装を初めて提供したバージョンは2.6.29です。判断に迷う場合は、globalキーワード"nosplice"で、スプライシングを全体で無効にできます。
例:
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
“option splice-request”、“option splice-response”、グローバルオプション"nosplice"と"maxpipes"も参照してください。
option splice-request
リクエスト用ソケットで、自動的なカーネルアクセラレーションを有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
フロントエンドまたはバックエンドのどちらかでこのオプションを有効にすると、HAProxyは可能な限りカーネルのTCPスプライシングを使い、クライアントからサーバーへデータを転送します。空きパイプがなくなった場合は、recv/send方式を使うこともあります。このオプションには、コンパイル時にスプライシングを有効にしておく必要があります。globalオプション"nosplice"で、全体で無効にすることもできます。spliceはパイプを使うため、十分な数の空きパイプが必要です。
重要な注意:使用上の制限は"option splice-auto"を参照してください。
例:
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
“option splice-auto”、“option splice-response”、グローバルオプション"nosplice"と"maxpipes"も参照してください。
option splice-response
レスポンス用ソケットで、自動的なカーネルアクセラレーションを有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
フロントエンドまたはバックエンドのどちらかでこのオプションを有効にすると、HAProxyは可能な限りカーネルのTCPスプライシングを使い、サーバーからクライアントへデータを転送します。空きパイプがなくなった場合は、recv/send方式を使うこともあります。このオプションには、コンパイル時にスプライシングを有効にしておく必要があります。globalオプション"nosplice"で、全体で無効にすることもできます。spliceはパイプを使うため、十分な数の空きパイプが必要です。
重要な注意:使用上の制限は"option splice-auto"を参照してください。
例:
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
“option splice-auto”、“option splice-request”、グローバルオプション"nosplice"と"maxpipes"も参照してください。
option spop-check
サーバーの確認にSPOPヘルスチェックを使用します。
使用可能なコンテキスト:tcp
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
サーバーがTCP接続を受け入れるかだけでなく、SPOPプロトコルで正しく通信するかを確認できます。このオプションを設定すると、HAProxyとサーバーの間でHELLOハンドシェイクを行い、レスポンスを解析してエラーが報告されていないことを確認します。
例:
参照:“option httpchk”。
option srvtcpka
サーバー側のTCP keepaliveパケットの送信を有効または無効にします。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
クライアントとサーバーの間にファイアウォールなどのセッションを認識するコンポーネントがあり、プロトコルが長いアイドル期間を含む非常に長いセッションを使う場合(リモートデスクトップなど)、途中のコンポーネントが、長時間アイドル状態にあったセッションを期限切れにするおそれがあります。
ソケットレベルのTCP keep-aliveを有効にすると、システムは接続の相手側へ定期的にパケットを送信し、接続を維持します。keep-aliveプローブの間隔はシステムだけが制御し、オペレーティングシステムとその調整パラメーターの両方に依存します。
キープアライブパケットは、アプリケーションレベルでは送信も受信もされないことを理解する必要があります。それを認識するのはネットワークスタックだけです。そのため、プロキシの片側ですでにキープアライブを使って接続を維持していても、そのキープアライブパケットがプロキシの反対側に転送されることはありません。
これはHTTP keep-aliveとは関係がありません。
“srvtcpka"オプションを使うと、接続のサーバー側でTCPキープアライブプローブの送信を有効にします。HAProxyとサーバーの間でセッションの期限切れが見られる場合に役立つはずです。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option clitcpka”、“option tcpka”。
option ssl-hello-chk
サーバーの確認にSSLv3 client helloヘルスチェックを使用します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
SSLベースのプロトコルをHAProxy経由でTCPモードで中継する場合、サーバーがTCP接続を受け入れるかだけでなく、SSLで正しく通信するかを確認できます。“option ssl-hello-chk"を設定すると、サーバーへの接続が確立した後に、純粋なSSLv3のClient Helloメッセージを送り、レスポンスを解析してSSLのServer Helloメッセージを探します。レスポンスにこのServer Helloメッセージが含まれる場合だけ、サーバーを有効とみなします。
これまでにテストしたサーバーは、すべてSSLv3のClient Helloメッセージに正しく応答します。また、そのほとんどはHelloメッセージだけを含むリクエストをログにすら記録しないため、好都合です。
このチェックはSSLメッセージを組み立てるため、HAProxyにSSLサポートが組み込まれていなくても動作します。SSLサポートがある場合は、このチェックの代わりに、組み込みのSSLヘルスチェックを使うのが最善です。
参照:“option httpchk”、“check-ssl”。
option tcp-check
tcp-checkのsend/expectシーケンスを使用してヘルスチェックを実行します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
このヘルスチェック方式は、“tcp-check"コマンドの一覧と組み合わせて、送信と期待値の確認からなるヘルスチェックのシーケンスに対応するためのものです。
TCPチェックは現在、4種類の動作モードをサポートします。- “tcp-check"ディレクティブがない場合: ヘルスチェックは接続試行だけを行います。これが引き続きデフォルトのモードです。
- "tcp-check send"または"tcp-check send-binary"だけが指定されている場合:
接続の開始とともに文字列を送信するために使用します。
一部のプロトコルでは、たとえば"QUIT"メッセージを送ることで、
ヘルスチェックのたびにサーバーが接続エラーを記録するのを防げます。
この場合も、チェック結果は接続を開始できるかどうか
だけによって決まります。
- "tcp-check expect"だけが指定されている場合: バナーのテストに使います。
接続を開き、HAProxyはサーバーが何らかの内容を提示するのを待ちます。
その内容は、指定したルールを満たさなければなりません。
チェックの結果は、内容とルールが一致するかどうかによって決まります。
POP、IMAP、SMTP、FTP、SSH、TELNETに適しています。
- "tcp-check send"と"tcp-check expect"の両方を指定した場合: Hello型のプロトコルをテストするために使用します。HAProxyがメッセージを送り、サーバーが応答すると、そのレスポンスを解析します。チェックの結果は、レスポンスの内容とルールの照合に基づきます。バインドやリクエストとレスポンスのモデルが必要なプロトコルによく適しています。LDAP、MySQL、Redis、SSLなどが該当しますが、これらにはすでに、各プロトコルをより深く理解する専用のチェックがあります。このモードでは、複数の問い合わせを送り、複数の回答を解析できます。
第5のモードでは、スクリプトのさまざまな段階にコメントを挿入できます。
作成する各tcp-checkルールには、“comment"ディレクティブの後に文字列を指定できます。この文字列をログに記録し、デバッグモードでは標準エラー出力にも表示します。利用者に分かりやすいエラー報告に役立ちます。もちろん、“comment"は省略可能です。
ヘルスチェックの実行中は、“tcp-check set-var"操作でデータサンプルを保存するための変数スコープが利用できます。“tcp-check unset-var"を使えば、それらの変数を解放できます。
例:
参照:“tcp-check connect”、“tcp-check expect”、“tcp-check send”。
option tcp-smart-accept
acceptシーケンスでACKパケットを1つ節約する機能を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:なし
HTTP接続要求が届くと、システムはHAProxyに代わって確認応答を返します。続いてクライアントが直ちにリクエストを送り、システムはHAProxyに新しい接続を通知する間に、そのリクエストにも確認応答を返します。その後、HAProxyがリクエストを読み取り、レスポンスを返します。リクエストへの確認応答はHAProxyがレスポンスを送る際に一緒に返せるため、システムが送信するTCP ACKが一つ余分であることになります。
このため、HTTPモードでは、HAProxyは、サポートするプラットフォーム(現在は少なくともLinux)で、この不要なACKを送らないようシステムに自動的に要求します。レスポンスの到着に想定以上の時間がかかっても、システムは40 ms後にACKを送るため、問題が生じることはないはずです。
複雑なネットワークのデバッグでは、この最適化を無効にしたい場合があります。遅延ACKがあると、パケットがどこで遅れているかを特定する際に、トラブルシューティングが複雑になるためです。“no option tcp-smart-accept"を指定すると、通常の動作に戻せます。
HTTP以外のプロキシでも、“option tcp-smart-accept"を指定するだけで強制的に有効にできます。たとえば、SMTPのようにサーバーが最初に送信するサービスでも、意味を持つ場合があります。
defaultsセクションでこのオプションを強制的に設定することは避けるよう推奨します。判断に迷う場合は、前に"default"キーワードを付けて自動設定値に戻すか、“no"キーワードで無効にすることを検討してください。
参照:“option tcp-smart-connect”。
option tcp-smart-connect
connectシーケンスでACKパケットを1つ節約する機能を有効または無効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
特定のシステム(少なくともLinux)では、接続要求に対して空のACKを直ちに送る代わりに、バッファー内のリクエストを直接送るよう、HAProxyがカーネルに要求できます。これによりネットワーク上のパケットを一つ減らせるため、性能が向上します。また、受信接続と同時にリクエストを取得できるため、一部のサーバーにも有用です。
この機能は、バックエンドで"option tcp-smart-connect"を設定すると有効になります。ネットワークのトラブルシューティングが複雑になるため、デフォルトでは有効にしていません。
これを有効にする意味があるのは、HTTPのようにクライアントが最初に送信するプロトコルだけです。それ以外で、ACKの代わりに送るデータがなければ、通常のACKを送信します。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
参照:“option tcp-smart-accept”。
option tcpka
両側のTCP keepaliveパケットの送信を有効または無効にします。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
クライアントとサーバーの間にファイアウォールなどのセッションを認識するコンポーネントがあり、プロトコルが長いアイドル期間を含む非常に長いセッションを使う場合(リモートデスクトップなど)、途中のコンポーネントが、長時間アイドル状態にあったセッションを期限切れにするおそれがあります。
ソケットレベルのTCP keep-aliveを有効にすると、システムは接続の相手側へ定期的にパケットを送信し、接続を維持します。keep-aliveプローブの間隔はシステムだけが制御し、オペレーティングシステムとその調整パラメーターの両方に依存します。
キープアライブパケットは、アプリケーションレベルでは送信も受信もされないことを理解する必要があります。それを認識するのはネットワークスタックだけです。そのため、プロキシの片側ですでにキープアライブを使って接続を維持していても、そのキープアライブパケットがプロキシの反対側に転送されることはありません。
これはHTTP keep-aliveとは関係がありません。
“tcpka"オプションを使うと、接続のクライアント側とサーバー側の両方で、TCPキープアライブプローブの送信を有効にします。ただし、両側に適用する意味があるのは、“defaults"または"listen"セクションだけです。フロントエンドで使用するとクライアント側だけ、バックエンドで使用するとサーバー側だけにキープアライブを適用します。このため、設定をフロントエンドとバックエンドに分けている場合は、“option clitcpka"と"option srvtcpka"を明示的に使用することを強く推奨します。
参照:“option clitcpka”、“option srvtcpka”。
option tcplog [clf]
ストリームの状態とタイマーを含む、TCP接続の詳細なログ記録を有効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
デフォルトのログ出力形式は情報が乏しく、送信元と宛先のアドレス、およびインスタンス名だけを含みます。“option tcplog"を指定すると、各ログ行に含まれる情報が大幅に増えます。接続タイマー、ストリーム状態、接続数、フロントエンド・バックエンド・サーバーの名前、そしてもちろん送信元アドレスとポートなどを含みますが、これらに限りません。このオプションは、TCPだけを扱うプロキシで、クライアントとサーバーのどちらが切断したりタイムアウトしたりしたかを調べるために役立ちます。通常のHTTPプロキシでは、さらに情報が豊富な"option httplog"を使うほうがよいでしょう。
“option tcplog"は、それより前のすべての"log-format"ディレクティブを上書きします。
“option httplog"およびログに関するセクション8 も参照してください。
option transparent (deprecated)
クライアント側の透過プロキシを有効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
このオプションは、レイヤー3のロードバランサーにレイヤー7での接続先の固定を提供するために導入しました。リモートアドレス宛ての受信接続をローカルプロセス(ここではHAProxy)に転送するOSの機能を使い、当初要求されたアドレスをそのプロセスに知らせる仕組みです。このオプションを使うと、Cookieのないセッションは、受信リクエストの元の宛先IPアドレス(別の機器のアドレスに一致するはずです)に転送します。一方、Cookieを含むリクエストは、引き続き適切なサーバーに転送します。
よくある誤解とは異なり、このオプションによって、HAProxyが接続確立時にクライアントのIPをサーバーへ提示することはありません。
内部的な技術上の制約がいくつもあったため、このオプションは3.3以降、非推奨になりました。使用すると警告を出しますが、どうしても必要な場合は、globalキーワード"expose-deprecated-directives"で警告を抑止できます。
正しい方法は、アドレス0.0.0.0のサーバーを宣言することです。そのサーバーが、期待する宛先アドレスへの接続を担当します。また、対象サーバーへのアイドル接続も適切に処理します。
例:
“source"キーワードの"usesrc"引数、および"bind"キーワードの"transparent"オプションも参照してください。
option use-small-buffers [ queue | l7-retries | check ]*
指定されたカテゴリで小さいバッファーのサポートを有効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
このオプションを使うと、メモリーを節約するため、さまざまな箇所で小さなバッファーのサポートを有効にできます。パラメーターを指定しないデフォルトでは、使用できるすべての箇所で、可能な限り小さなバッファーを使います。次の箇所に使用を限定することもできます。
- queue:設定すると、接続がキューに入る際に、リクエストが十分小さければ、小さいバッファーに保存します。
- l7-retries:設定すると、L7リトライが有効な場合に、小さいバッファーでリクエストを保存します。
- check:設定すると、ヘルスチェックリクエストに小さいバッファーを使用します。
有効にすると小さなバッファーを使いますが、使用可能な場合に限ります。データが大きすぎる場合は、自動的に通常のバッファーを使用します。小さなバッファーのサイズは、global設定"tune.bufsize.small"で変更できます。
“defaults"セクションでこのオプションを有効にしている場合、特定のインスタンスで前に"no"キーワードを付けると無効にできます。
tune.bufsize.smallも参照してください。
persist rdp-cookie
RDP Cookieに基づく接続先の固定を有効にします。
使用可能なコンテキスト:tcp
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
この文は、RDP Cookieに基づく接続先の固定を有効にします。RDP Cookieには、既知のサーバーの一覧からサーバーを見つけるために必要な情報がすべて含まれています。そのため、このオプションをバックエンドで設定すると、リクエストを解析し、RDP Cookieが見つかった場合はデコードします。Cookieが既知のサーバーに一致し、そのサーバーがまだUP状態である場合(または"option persist"が設定されている場合)、接続をそのサーバーに転送します。
これはTCPバックエンドでのみ意味を持ちます。ただし、動作させるには、リクエストバッファーにRDP Cookieが存在することを確認できるだけの時間、フロントエンドで待機している必要があります。これは、“rdp-cookie"負荷分散方式と同じ要件です。そのため、すべての文を一つの"listen"セクションにまとめることを強く推奨します。
また、ターミナルサーバーがこのRDP Cookieを送信するのは、“token redirection mode"に設定されている場合だけです。これは、“IP address redirection"オプションが無効であることを意味します。この点を理解することが重要です。
例:
“balance rdp-cookie”、“tcp-request”、“req.rdp_cookie” ACLも参照してください。
quic-initial <action> [ { if | unless } <condition> ]
受信したQUIC Initialパケットに対して、アクションを実行します。“tcp-request connection"とは異なり、接続を構成する要素の生成や、SSLハンドシェイクの開始と完了より前に実行するため、接続試行を拒否する場合に効率的です。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 可 | 可 | 不可
引数:
このアクションは、QUICパケットの解析の早い段階で実行します。そのため、サポートするアクションは最小限で、次のものだけです。- accept - dgram-drop - reject - send-retry
rate-limit sessions <rate>
フロントエンドで毎秒受け付ける新しいセッション数の上限を設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
フロントエンドの毎秒の新規セッション数が指定した値に達すると、レートが再び上限を下回るまで、新しい接続の受け入れを停止します。その間、保留中のセッションはソケットのバックログ(システムのバッファー)内に保持され、HAProxyは待機中のセッションがあることさえ認識しません。負荷の高いサービスに非常に低い上限を適用する場合は、“backlog"キーワードでソケットのバックログを増やすことが適切な場合があります。
この機能は、接続を使った攻撃や、負荷に弱いサーバーに対するサービスの不正利用を遮断する際に、特に効果的です。セッションレートをミリ秒ごとに測定するため、極めて正確です。また、上限は直ちに適用し、しきい値の検出に待ち時間は一切必要ありません。
例:SMTPの接続レートを毎秒最大10に制限します。
注意: 最大レートに達してもフロントエンドの状態は変わりませんが、“socket-stats"オプションを有効にしている場合、そのソケットは統計に"WAITING"として表示されます。
“backlog"キーワードと"fe_sess_rate” ACL条件も参照してください。
redirect location <loc> [code <code>] <option> [{if | unless} <condition>]
if/unlessによる条件の一致または不一致に応じて、HTTPリダイレクトを返します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 可
ifでは条件に一致した場合、unlessでは一致しない場合に、HTTPリクエストに対してリダイレクトのレスポンスを返します。条件を指定しなければ、無条件にリダイレクトします。
引数:
例: ログインURLだけをHTTPSに移します。
例: ‘/‘のない記事へのリクエストにリダイレクトを返します。
例:HAProxyがSSLを処理する場合に、すべてのHTTPトラフィックをHTTPSにリダイレクトします。
例: すべてのホストのうち、接頭辞’www.‘が付いていないものにそれを追加します。
例: 古いURLだけを新しいURLへ恒久的にリダイレクトします。
ACLの使用方法については、セクション7 を参照してください。
retries <value>
失敗後にサーバーに対して行う再試行の回数を設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
既定では、再試行は新しい接続の試行にのみ適用されます。ただし、“retry-on"ディレクティブを使用すると、ほかの条件(空のレスポンス、望ましくないステータスコードなど)でも再試行が発生する場合があります。それぞれが一回の試行として数えられ、試行の合計回数がここで指定した値に達すると、エラーが返されます。
再起動中のサーバーに直ちに再接続することを避けるため、同じサーバーへ再試行する前に、min(“timeout connect”, 一秒)の待ち時間を設けます。
“option redispatch"を設定すると、Cookieが別のサーバーを参照していても、一部の再試行をほかのサーバーで行うことがあります。“option redispatch"に引数を渡さない限り、既定では最後の再試行だけが対象です。
参照:“option redispatch”。
retry-on [space-delimited list of keywords]
失敗したリクエストの自動再試行を、どのような場合に試みるかを指定します。この設定が有効なのは"mode"がhttpの場合だけで、それ以外では通知なしで無視します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
このディレクティブを使用すると、以前の設定はすべて新しい設定に置き換わります。累積はしません。
“none"と"conn-failure"以外を使うと、バッファーを割り当ててリクエスト全体をコピーする必要があるため、メモリーと性能に影響します。単一のバッファーに収まらないリクエストは、決して再試行しません(globalのtune.bufsize設定を参照してください)。
リクエストで渡す一意のトランザクションIDなど、リプレイを防ぐ仕組みをアプリケーションが備えているか、同じリクエストを再実行しても影響がないことを確認しなければなりません。そうでなければ、retry-onに"conn-failure"と"none"以外の値を使うことは非常に危険です。静的ファイルのサーバーとキャッシュは、一般に、どの種類の再試行に対しても安全とみなされます。ステータスコードを使うと、メモリー不足やファイルシステムの問題など、異常な動作をするサーバーを早く離れるために役立つ場合があります。ただし、その場合は、直ちに別のサーバーへ接続を振り分け直すのがよいこともあります(“option redispatch"を参照してください)。最後に、障害の原因の多くはリクエストそのものであり、サーバーの異常を引き起こすリクエストを再試行すると、そのサーバーの状況、あるいは再振り分けの場合はサービス全体の状況を、さらに悪化させることが多い点を理解することが重要です。
再送されたリクエストをアプリケーションがどのように扱うかを正確に把握していない限り、このディレクティブは使用しないことを推奨します。
デフォルトは"conn-failure"です。
例:
参照:“retries”、“option redispatch”、“tune.bufsize”。
server <name> <address>[:[port]] [param*]
バックエンド内のサーバーを宣言します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
引数:
例:
注意: Linuxの抽象名前空間ソケットに関して、“abns"HAProxyソケットはsun_pathの全長をアドレス長として使用します。他のプログラム(例: socat)はデフォルトで文字列長のみを使用します。socatの抽象ソケット定義に”,unix-tightsocklen=0"オプションを渡すことでHAProxyと互換性を持たせることができます。または、“abnsz"HAProxyソケットファミリを使用してください。
“default-server”、“http-send-name-header”、およびserverオプションに関するセクション5 も参照してください。
server-state-file-name [ { use-backend-name | <file> } ]
読み込み、ロードし、このバックエンドで使用可能なサーバーに適用するサーバー状態ファイルを設定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
これは、“load-server-state-from-file"ディレクティブが"local"に設定されている場合にのみ適用されます。<file>が指定されていない場合、“use-backend-name"が使用されている場合、またはこのディレクティブが設定されていない場合は、バックエンド名を使用します。<file>がスラッシュ’/‘で始まる場合は絶対パスと見なします。それ以外の場合は、globalディレクティブ"server-state-base"に<file>を連結します。
例:下記の最小限の設定では、HAProxyはサーバー状態ファイル’/etc/haproxy/states/bk’を探します。
global
server-state-file-base /etc/haproxy/states
backend bk
load-server-state-from-file
参照:“server-state-base”、“load-server-state-from-file”、“show servers state”。
server-template <prefix> <num | range> <fqdn>[:<port>] [params*]
共通のパラメーターでサーバーを初期化するテンプレートを設定します。サーバーの名前は、<prefix>と<num | range>パラメーターから作成します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
引数:
例:
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
発信接続の送信元アドレスを設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
“source"キーワードは、特定のアドレスからしかサーバーへの接続が許可されない、複雑な環境で役立ちます。たとえば、パブリックゲートウェイを経由する際にプライベートアドレスを使う必要があり、システムが適切な送信元アドレスを自動的に選べないと分かっている場合に必要になることがあります。
一部のパッチを適用したLinuxカーネルで利用できる拡張を、省略可能な"usesrc"キーワードから使用できます。システム自体には属していないIPアドレスで、サーバーへ接続できるようにします。これを"完全透過プロキシモード"と呼びます。動作させるには、接続先のサーバーが、このアドレスへの戻りのトラフィックを、HAProxyを実行するマシン経由でルーティングしなければなりません。また、通常、そのマシンでIP転送を有効にしておく必要があります。
この"完全透過プロキシ"モードでは、サーバーに提示するIPアドレスを、特定のアドレスに固定できます。ただし、実際にはあまり使われません。より一般的なのは、クライアントのIPアドレスを提示するようHAProxyに指示する使い方です。これには、次の二つの方法があります。
- クライアントのIPアドレスとポートを提示します。最も透過的なモードですが、
同じ接続が異なる状態で二度観測される可能性があるため、マシンで
IP接続追跡が有効な場合は問題を起こすことがあります。
ただし、すべてのクライアントの範囲を使用できるため、
送信側のアドレスとポートの組み合わせが64kに制限されないという
大きな利点があります。
- クライアントのIPアドレスだけを提示し、空きポートを選びます。この方法も適切ですが、透過性は少し下がります(下流のファイアウォールのログが上流のものと一致しません)。同時接続数が通常の64kポートに制限される欠点もあります。ただし、上流と下流でポートが異なるため、同じセッションの再利用によって、マシン内のIP接続追跡が混乱することはありません。
このオプションは、バックエンド内のすべてのサーバーに対する既定の送信元を設定します。“defaults"セクションでも指定できます。サーバーの"source"オプションを使えば、サーバーごとに送信元アドレスをさらに細かく指定できます。詳細は5節 を参照してください。
“usesrc"を動作させるには、root権限、または対応システムでは"cap_net_raw"ケーパビリティが必要です。グローバルディレクティブ"setcap"も参照してください。
例:
関連項目: 5節 のサーバーオプション"source”、www.balabit.com のLinuxカーネル用Tproxyパッチ、“bind"キーワードを参照してください。
srvtcpka-cnt <count>
サーバー側で接続を切断するまでに、TCPが送信するkeepaliveプローブの最大数を設定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
このキーワードはソケットオプションTCP_KEEPCNTに対応しています。このキーワードが指定されない場合、システム全体のTCPパラメーター(tcp_keepalive_probes)が使用されます。この設定の利用可能性はオペレーティングシステムに依存します。Linuxで動作することが知られています。
参照:“option srvtcpka”、“srvtcpka-idle”、“srvtcpka-intvl”。
srvtcpka-idle <timeout>
サーバー側でTCPキープアライブパケットの送信を有効にしている場合、TCPがプローブの送信を始めるまでに必要な、接続のアイドル時間を設定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
このキーワードはソケットオプションTCP_KEEPIDLEに対応しています。このキーワードが指定されない場合、システム全体のTCPパラメーター(tcp_keepalive_time)が使用されます。この設定の利用可能性はオペレーティングシステムに依存します。Linuxで動作することが知られています。
参照:“option srvtcpka”、“srvtcpka-cnt”、“srvtcpka-intvl”。
srvtcpka-intvl <timeout>
サーバー側の個々のkeepaliveプローブ間の時間を設定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
このキーワードはソケットオプションTCP_KEEPINTVLに対応しています。このキーワードが指定されない場合、システム全体のTCPパラメーター(tcp_keepalive_intvl)が使用されます。この設定の利用可能性はオペレーティングシステムに依存します。Linuxで動作することが知られています。
参照:“option srvtcpka”、“srvtcpka-cnt”、“srvtcpka-idle”。
stats admin { if | unless } <cond>
if/unlessによる条件の一致または不一致に応じて、統計の管理者レベルを有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 可
このステートメントは、if/unlessによる条件の一致または不一致に応じて、統計の管理者レベルを有効にします。
adminレベルでは、Webインターフェースからサーバーを有効化・無効化できます。安全上の理由から、統計ページは既定では読み取り専用です。セクションに"stats scope"ディレクティブが設定されている場合は、それらが指定したプロキシだけが状態の変更を受け入れ、それ以外へのアクセスは拒否されます。
現在、POSTリクエストのサイズは、バッファーサイズから予約領域を引いた値に制限されています。そのため、サーバーの一覧が長すぎるとリクエストを処理できません。一度に変更するサーバーを少数にすることを推奨します。
これらの管理用POSTリクエストは、CSRF攻撃を受けやすくなっています。Origin(OriginがなければReferer)がHostヘッダーに一致することを確認して部分的に軽減していますが、攻撃を完全に防ぐには不十分です。完全に防御する方法はありません。公開インターフェースへの露出を避け、アクセスできる利用者を制限することを推奨します。
例:
例:
例:
関連項目: “stats enable”、“stats auth”、“stats http-request”、“stats scope”、userlistsについては12.2節 、ACLの使用については7節 を参照してください。
ssl-f-use [<sslbindconf> ...]*
現在のフロントエンドに証明書を割り当てます。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 不可
引数:
フロントエンド名の先頭に@を付けた名前(例:’@frontend1’)で自動作成されるcrt-listに、証明書<crtname>を割り当てます。
この暗黙的なcrt-listは、現在のフロントエンドのすべての"ssl” bind行に割り当てられます。
統計ソケットのcrt-listコマンドはこのcrt-listにも作用するため、証明書やSSLオプションを置き換えたり、削除したり、追加したりできます。
例:
参照:“crt-list”、“crt”。
stats auth <user>:<passwd>
認証付きの統計を有効にし、アカウントにアクセスを許可します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
この文は、デフォルトの設定で統計を有効にし、宣言したユーザーだけにアクセスを制限します。必要なユーザー数だけ許可するため、何度でも指定できます。有効なアカウントを使わずに統計へアクセスしようとすると、“401 Forbidden"レスポンスを返し、ブラウザーが有効なユーザー名とパスワードの入力を求めるようにします。ブラウザーに返す認証領域は、“stats realm"で設定できます。
認証方式はHTTP Basic認証なので、パスワードはネットワーク上を平文で流れます。このパスワードに機密性の高いものを使うべきではなく、他のアカウントと共用すべきでもないことを利用者に意識してもらうため、設定ファイルでも平文のパスワードを使用する設計にしています。
“stats scope"で、レポートに表示するプロキシの範囲を絞り込むこともできます。
この文だけでも統計の表示を有効にできますが、分かりにくいデフォルトのパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。
例:
参照:“stats enable”、“stats realm”、“stats scope”、“stats uri”。
stats enable
デフォルト設定で統計の報告を有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
この文は、ビルド時に定義したデフォルトの設定で統計の表示を有効にします。特に指定しない限り、次の設定を使います。- stats uri : /haproxy?stats - stats realm: “HAProxy Statistics” - stats auth : 認証なし - stats scope: 制限なし
この文だけでも統計の表示を有効にできますが、分かりにくいデフォルトのパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。
例:
参照:“stats auth”、“stats realm”、“stats uri”。
stats hide-version
統計を有効にし、HAProxyのバージョン表示を隠します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
統計ページでは、統計とともに有用な状態情報を表示でき、その中にはHAProxyのバージョンも含まれます。ただし、正確なバージョンを誰にでも知らせると、既知の弱点を狙った攻撃を助ける可能性があるため、一般に危険と考えられます。“stats hide-version"文は、統計レポートからバージョンを除きます。公開サイトや、ログイン名・パスワードが弱いサイトで推奨される設定であり、既定の動作でもあります。
この文だけでも統計の表示を有効にできますが、分かりにくいデフォルトのパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。
例:
参照:“stats auth”、“stats enable”、“stats realm”、“stats uri”、“stats show-version”。
stats http-request { allow | deny | auth [realm <realm>] }
統計のアクセス制御です。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
“http-request"と同様に、これらのオプションを使うと統計へのアクセスを細かく制御できます。各オプションの後にはif/unlessとACLを指定できます。最初に条件が一致したオプション(または条件のないオプション)で評価を終了します。“deny"では403エラーを返し、“allow"では通常の処理を行い、“auth"では401/407エラーコードを返すため、クライアントにはユーザー名とパスワードの入力が求められるはずです。
インスタンスあたりのhttp-requestステートメント数に固定の上限はありません。
“http-request”、ユーザーリストに関するセクション12.2 、およびACLの使用に関するセクション7 も参照してください。
stats realm <realm>
統計を有効にし、認証レルムを設定します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
レルムは単一の単語として読み取るため、含まれる空白は逆スラッシュ(’\’)でエスケープしてください。
この文は認証だけに関係するため、“stats auth"と組み合わせた場合にのみ有用です。
この文だけでも統計の表示を有効にできますが、分かりにくいデフォルトのパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。
例:
参照:“stats auth”、“stats enable”、“stats uri”。
stats refresh <delay>
自動更新付きの統計を有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
この文は、ロードバランサーの稼働状況を常時表示する監視画面で役立ちます。設定すると、HTMLレポートのページに"refresh”/“stop refresh"リンクを追加し、ページを自動更新するかどうかを利用者が選べるようにします。
この文だけでも統計の表示を有効にできますが、分かりにくいデフォルトのパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。
例:
参照:“stats auth”、“stats enable”、“stats realm”、“stats uri”。
stats scope { <name> | "." }
統計を有効にし、アクセス範囲を制限します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
この文を指定すると、この文で列挙したセクションだけがレポートに表示されます。それ以外はすべて非表示となり、adminモードで状態を変更しようとしても拒否されます。複数のセクションを表示する必要がある場合は、必要な回数だけこの文を指定できます。名前の確認は単純な文字列比較で行い、指定したセクション名が実際に存在するかどうかは一切確認しません。
この文だけでも統計の表示を有効にできますが、分かりにくいデフォルトのパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。
例:
参照:“stats auth”、“stats enable”、“stats realm”、“stats uri”、“stats admin”。
stats show-desc [ <desc> ]
統計ページでの説明の表示を有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
`<desc>` 表示する説明です。省略可能です。指定しない場合は、
globalセクションの説明を自動的に使用します。
顧客に共用サービスを提供し、顧客ごとにnodeやdescriptionを変えることが望ましい場合に有用な文です。
この文だけでも統計の表示を有効にできますが、分かりにくい既定のパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。既定では説明を表示しません。
例:
“show-node”、“stats enable”、“stats uri”、globalセクションの"description"も参照してください。
stats show-legends
統計ページでの追加情報の表示を有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
統計ページに追加情報を表示します。- cap: 機能(プロキシ)- mode: tcp、http、healthのいずれか(プロキシ)- id: SNMP ID(プロキシ、ソケット、サーバー)- IP(ソケット、サーバー)- cookie(バックエンド、サーバー)
この文だけでも統計の表示を有効にできますが、分かりにくい既定のパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。既定の動作では、この情報を表示しません。
参照:“stats enable”、“stats uri”。
stats show-modules
統計ページでの追加統計モジュールの表示を有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
行の末尾に新しい列を追加し、追加の統計値をツールチップとして表示します。
この文だけでも統計の表示を有効にできますが、分かりにくい既定のパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。既定の動作では、この情報を表示しません。
参照:“stats enable”、“stats uri”。
stats show-node [ <name> ]
統計ページでのホスト名の表示を有効にします。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
この文は、顧客に共有サービスを提供し、顧客ごとの統計ページでノード名や説明を変えたい場合に役立ちます。既定の動作では、ホスト名を表示しません。
この文だけでも統計の表示を有効にできますが、分かりにくいデフォルトのパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。
例:
“show-desc”、“stats enable”、“stats uri”、globalセクションの"node"も参照してください。
stats show-version
統計を有効にし、HAProxyのバージョンを表示します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:なし
統計ページでは、統計とともに有用な状態情報を表示でき、その中にはHAProxyのバージョンも含まれます。ただし、正確なバージョンを誰にでも知らせると、既知の弱点を狙った攻撃を助ける可能性があり、一般に危険と考えられるため、既定では無効になっています。“stats show-version"は、この情報の表示を有効にします。公開サイトや、ログイン名・パスワードが弱いサイトには推奨しません。
参照:“stats auth”、“stats enable”、“stats realm”、“stats uri”、“stats hide-version”。
stats uri <prefix>
統計を有効にし、アクセス用のURIプレフィックスを定義します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
統計のURIは、中継するトラフィックから取り出して処理するため、通常のアプリケーション内のページのように見えます。選んだURIがアプリケーションに決して現れないことを確認するよう、強く推奨します。そうでなければ、そのURIをアプリケーション内で利用することはできなくなります。
HAProxyに組み込まれる既定のURIは”/haproxy?stats"ですが、ビルド時に変更される可能性があるため、ここで常に明示的に指定するほうがよいでしょう。一般に、途中のプロキシが結果をキャッシュしないよう、URIに疑問符を含めるのがよい方法です。また、この接頭辞で始まる文字列はすべて統計リクエストとして受け入れられるため、疑問符を付けることで、有効なURIが同じ語で始まるのを避けやすくなります。
URIの接頭辞に”/“を使い、その文を専用の"listen"インスタンスに置くと、とても便利な場合があります。これにより、アドレスやポートを統計専用にしやすくなります。
この文だけでも統計の表示を有効にできますが、分かりにくいデフォルトのパラメーターに依存しないよう、ほかの設定もすべて指定することを推奨します。
例:
参照:“stats auth”、“stats enable”、“stats realm”。
stick match <pattern> [table <table>] [{if | unless} <cond>]
ユーザーをサーバーに固定する、リクエストパターンの一致条件を定義します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
引数:
プロトコルやアプリケーションによっては複雑なスティッキー処理のルールが必要で、Cookieやハッシュに単純に依存できるとは限りません。“stick match"文は、受信したリクエストや接続からスティッキー処理の判定基準を取り出すルールを記述します。使用可能なパターンと変換ルールの完全な一覧は、7節 を参照してください。
テーブルは、“stick-table"文で宣言しなければならず、パターンと互換性のある型でなければなりません。デフォルトでは、同じバックエンド内のテーブルを使います。“table"キーワードで参照すると、ほかのバックエンドと共有することもできます。別のテーブルを参照する場合、バックエンド内のサーバーIDを使います。デフォルトでは、サーバーIDの付番は各バックエンドで1から始まるため、サーバーの並び順だけで対応できます。ただし、不確かな場合は、サーバーの"id"設定でIDを明示的に指定することを強く推奨します。
“if"または"unless"の後に条件を指定することで、“stick match"文を適用する条件を制限できます。ACLに基づく条件については7節 を参照してください。
“stick match"文の数に上限はありません。適用されて一致した最初の文により、そのエントリーを作成したリクエストで使ったサーバーと同じサーバーに、リクエストを振り分けます。このように、複数の照合をフォールバックとして使用できます。
stickルールは接続先を固定するCookieの後に確認するため、Cookieによってすでにサーバーを選択している場合、接続先の固定に影響しません。これにより、Cookieを挿入するとともにIPアドレスでも照合し、HTTPとHTTPSの間で同じ接続先を維持することが、とても簡単になります。
例:
関連項目: “stick-table”、“stick on”、スティックテーブルについては11節 、ACLとサンプル取得については7節 を参照してください。
stick on <pattern> [table <table>] [{if | unless} <condition>]
ユーザーをサーバーに関連付けるリクエストパターンを定義します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
注意: この形式は、同じ引数を指定した"stick match"の後に"stick store-request"を置くことと完全に同じです。詳細は両方のキーワードを参照してください。保守しやすい設定を書くための便宜として提供しているだけです。
例:
“stick match”、“stick store-request”、およびスティックテーブルに関するセクション11 も参照してください。
stick store-request <pattern> [table <table>] [{if | unless} <condition>]
スティックテーブルにエントリーを作成するためのリクエストパターンを定義します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
引数:
プロトコルやアプリケーションによっては、接続先を固定するために複雑なルールが必要で、Cookieやハッシュだけには頼れない場合があります。“stick store-request"文は、リクエストのどの部分をいつ抽出するかを決めるルールを記述します。抽出したものを接続先の固定に使うテーブルへ保存し、後のリクエストで"stick match"文によって照合するためです。当然ながら、抽出する部分には意味があり、後のリクエストで一致する可能性がなければなりません。たとえば、クライアントのIPアドレスを保存することは、多くの場合、適切です。URLパラメーター内のIDを保存することも適切です。送信元ポートを保存しても、偶然一致するだけなので、ほとんど意味がありません。使用できるパターンと変換ルールの全一覧は、セクション7 を参照してください。
テーブルは、“stick-table"文で宣言しなければならず、パターンと互換性のある型でなければなりません。デフォルトでは、同じバックエンド内のテーブルを使います。“table"キーワードで参照すると、ほかのバックエンドと共有することもできます。別のテーブルを参照する場合、バックエンド内のサーバーIDを使います。デフォルトでは、サーバーIDの付番は各バックエンドで1から始まるため、サーバーの並び順だけで対応できます。ただし、不確かな場合は、サーバーの"id"設定でIDを明示的に指定することを強く推奨します。
“if"または"unless"の後に条件を指定することで、“stick store-request"文を適用する条件を制限できます。この条件はリクエストの解析中に評価されるため、どの判定基準でも使用できます。ACLに基づく条件については7節 を参照してください。
“stick store-request"文の数に上限はありませんが、リクエストまたはレスポンスごとに、同時に保存できる数は8に制限されます。ルール数に関係なく、リクエストまたはレスポンスから抽出した判定基準を、最大8個保存できます。一致した最初の8個だけを保持します。これを使うと、別のプロトコルやアクセス方法でも利用者を認識できる可能性を高めるため、複数のテーブルへ同時にデータを追加できます。同じテーブルに複数のstore-requestルールを指定することもでき、優先度の高い順に並べることで、最も適切な判定基準を選べます。各テーブルでは、最初に抽出した判定基準だけを保存します。同じテーブルを参照する後続のstore-requestルールはすべてスキップし、そのACLも評価しません。
“store-request"ルールは、サーバーへの接続が確立した後に評価します。これにより、実際にリクエストを処理したサーバーがテーブルに記録されます。
例:
関連項目: “stick-table”、“stick on”、スティックテーブルについては11節 、ACLとサンプル取得については7節 を参照してください。
stick store-response <pattern> [table <table>] [{if | unless} <condition>]
スティックテーブルにエントリーを作成するためのレスポンスパターンを定義します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
引数:
プロトコルやアプリケーションによっては、接続先を固定するために複雑なルールが必要で、Cookieやハッシュだけには頼れない場合があります。“stick store-response"文は、レスポンスのどの部分をいつ抽出するかを決めるルールを記述します。抽出したものを接続先の固定に使うテーブルへ保存し、後のリクエストで"stick match"文によって照合するためです。当然ながら、抽出する部分には意味があり、後のリクエストで一致する可能性がなければなりません。レスポンスのヘッダー内で見つかったIDを保存することは適切です。使用できるパターンと変換ルールの全一覧は、セクション7 を参照してください。
テーブルは、“stick-table"文で宣言しなければならず、パターンと互換性のある型でなければなりません。デフォルトでは、同じバックエンド内のテーブルを使います。“table"キーワードで参照すると、ほかのバックエンドと共有することもできます。別のテーブルを参照する場合、バックエンド内のサーバーIDを使います。デフォルトでは、サーバーIDの付番は各バックエンドで1から始まるため、サーバーの並び順だけで対応できます。ただし、不確かな場合は、サーバーの"id"設定でIDを明示的に指定することを強く推奨します。
“if"または"unless"の後に条件を指定することで、“stick store-response"文を適用する条件を制限できます。この条件はレスポンスの解析中に評価されるため、どの判定基準でも使用できます。ACLに基づく条件については7節 を参照してください。
“stick store-response"文の数に上限はありませんが、リクエストまたはレスポンスごとに、同時に保存できる数は8に制限されます。ルール数に関係なく、リクエストまたはレスポンスから抽出した判定基準を、最大8個保存できます。一致した最初の8個だけを保持します。これを使うと、別のプロトコルやアクセス方法でも利用者を認識できる可能性を高めるため、複数のテーブルへ同時にデータを追加できます。同じテーブルに複数のstore-responseルールを指定することもでき、優先度の高い順に並べることで、最も適切な判定基準を選べます。各テーブルでは、最初に抽出した判定基準だけを保存します。同じテーブルを参照する後続のstore-responseルールはすべてスキップし、そのACLも評価しません。ただし、store-requestルールが参照しているテーブルを、store-responseルールでも使用できます。つまり、各テーブルは、リクエストから厳密に一つ、レスポンスから厳密に一つの要素を同時に学習できます。
テーブルには、リクエストを実際に処理したサーバーが格納されます。
例:
関連項目: “stick-table”、“stick on”、スティックテーブルについては11節 、ACLとパターン抽出については7節 を参照してください。
stick-table type <type> size <size> [expire <expire>] [args...]
現在のセクションのスティックテーブルを設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 可
スティックテーブルを宣言して設定するために使用します。詳細とサポートされる引数の一覧は、11.1節 を参照してください。必須なのは型とサイズだけです。
tcp-check comment <string>
後続のtcp-checkルールのコメントを定義します。ルールが失敗した場合にログに記録されます。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
connect、send、expectルールにのみ使用できます。わかりやすいエラー報告を作成するのに役立ちます。
参照:“option tcp-check”、“tcp-check connect”、“tcp-check send”、“tcp-check expect”。
tcp-check connect [default] [port <expr>] [addr <ip>] [send-proxy] [via-socks4]
新しい接続を開きます。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
アプリケーションが複数のTCPポートを使用する場合や、HAProxyが一つのバックエンドで多数のサービスを負荷分散する場合は、サーバーが稼働していると判断する前に、すべてのサービスを個別に確認することが適切です。
server行にもserver portディレクティブにもTCPポートを設定していない場合、’tcp-check connect port <port>‘をシーケンスの最初の手順にしなければなりません。
tcp-checkルールセットには’connect’が必要で、先頭も’connect’ルールでなければなりません。管理者が操作の内容を理解していることを確実にするためです。
connectでルールセットを開始しなければならない場合でも、その前にset-var、unset-var、commentルールを置くことができます。
例:
参照:“option tcp-check”、“tcp-check send”、“tcp-check expect”。
tcp-check expect [min-recv <int>] [comment <msg>]
汎用ヘルスチェック中に収集・解析するデータを指定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
使用可能な一致方法は、意図的に対応するhttp-checkのものと似せてあります。
レスポンスのサイズは、globalオプション"tune.bufsize"で定義した値に制限され、デフォルトは16384バイトである点に注意してください。そのため、レスポンスが大きすぎると、“string”、“rstring”、またはバイナリーを使う場合に、必須のパターンが含まれない可能性があります。大きなレスポンスがどうしても必要な場合は、global変数を設定して、デフォルトの最大サイズを変更できます。ただし、非常に大きなレスポンスの解析は、特に正規表現を使う場合にCPUサイクルを浪費する可能性があり、常に小さなリソースを対象にチェックするほうがよい点を忘れないでください。また、現在のチェックでは、レスポンス内のヌル文字より後にある文字列や正規表現の一致を見つけることはできません。同様に、ヌル文字との照合を要求することもできません。
例:
“option tcp-check”、“tcp-check connect”、“tcp-check send”、“tcp-check send-binary”、“http-check expect”、tune.bufsizeも参照してください。
tcp-check send <data> [comment <msg>]
汎用ヘルスチェック中に問い合わせとして送信する文字列、またはカスタムログ形式を指定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
例:
“option tcp-check”、“tcp-check connect”、“tcp-check expect”、“tcp-check send-binary”、tune.bufsizeも参照してください。
tcp-check send-binary <hexstring> [comment <msg>]
生のTCPヘルスチェックでバイナリの問い合わせとして送信する、16進数字の文字列または16進数字のカスタムログ形式を指定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
例:
“option tcp-check”、“tcp-check connect”、“tcp-check expect”、“tcp-check send”、tune.bufsizeも参照してください。
tcp-check set-var(<var-name>[,<cond>...]) <expr>
この操作は変数の内容を設定します。変数はインラインで宣言されます。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
例:
tcp-check unset-var(<var-name>)
変数のスコープ内でその変数への参照を解放します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
例:
tcp-request connection <action> <options...> [ { if | unless } <condition> ]
レイヤー4の条件に応じて、着信接続に対してアクションを実行します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 可 | 可 | 不可
引数:
新しい受信接続を受け入れた直後に、条件を評価して、接続を受け入れるか、破棄するか、カウンターを追跡するかを決められます。まだ接続から何も読み取っておらず、バッファーも割り当てていないため、これらの条件にはデータの内容を使えません。非常に小さなオーバーヘッドで、さまざまな送信元からの接続を選別し、極めて速く受け入れたり破棄したりするために使用します。判断のために内容を検査する必要がある場合は、代わりに"tcp-request content"文を使用しなければなりません。
“tcp-request connection"ルールは、宣言されたとおりの順序で評価されます。一致するルールがない場合、またはルール自体がない場合、既定のアクションは受信接続を受け入れることです。追加できるルール数に特別な上限はありません。どのルールにも、省略可能なACLに基づく条件を後置できます。その場合は、条件が真と評価されたときだけルールを評価します。
条件はアクションを実行する直前に評価し、アクションは厳密に一度だけ実行します。そのため、条件の一部として確認する要素をアクションが変更しても、問題はありません。また、複数のアクションが同じ条件に依存する場合、条件の評価結果を変える最初のアクションだけで、残りのアクションを暗黙に無効にできます。たとえば、変数が空の場合に、さまざまな取得元から値を割り当てようとする際に使用します。
構文中で"tcp-request connection"の直後にあるキーワードがルールのアクションで、その後にアクションに応じた数の引数が続く場合があります。サポートされるアクションと、それぞれの構文は、4.3節 「アクション」に列挙されています(“TCP RqCon"にチェックが付いたアクションを参照してください)。
このディレクティブは、名前付きのdefaultsセクションでのみ使用でき、無名のセクションでは使用できません。defaultsセクションで定義したルールは、関連付けられたプロキシセクションのルールより先に評価されます。曖昧さを避けるため、この場合、フロントエンド機能を持つプロキシとバックエンド機能を持つプロキシが、同じdefaultsセクションを使用することはできません。つまり、listenセクションは、このようなルールを定義したdefaultsセクションを使用できません。
“if/unless"条件は省略可能です。アクションに条件が設定されていなければ、無条件に実行します。これは"track-sc*“アクションや、既定のアクションを拒否に変更する場合などに便利です。
例: 許可リスト内のホストからの接続をすべて受け入れ、頻度が高すぎる接続は数えずに拒否し、受け入れた接続を追跡します。その結果、不正利用を行う送信元からの接続レートに上限が設けられます。
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request connection reject if { src_conn_rate gt 10 }
tcp-request connection track-sc0 src
例: 許可リスト内のホストからの接続をすべて受け入れ、それ以外の接続を数え、頻度が高すぎるものを拒否します。その結果、不正利用に当たる接続は、頻度を下げない限りブロックされます。
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request connection track-sc0 src
tcp-request connection reject if { sc0_conn_rate gt 10 }
例:既知のすべてのプロキシからのトラフィックで、PROXYプロトコルを有効にします。
tcp-request connection expect-proxy layer4 if { src -f proxies.lst }
ACLの使用方法については、セクション7 を参照してください。
参照:“tcp-request session”、“tcp-request content”、“stick-table”。
tcp-request content <action> [{if | unless} <condition>]
レイヤー4-7の条件に応じて、新しいセッションに対してアクションを実行します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 可 | 可 | 可
引数:
リクエストの内容は、リクエスト処理の初期段階である"TCP content inspection”(TCPコンテンツ検査)で解析できます。この段階では、リクエストの内容が更新されるたびにACLベースのルールを評価し、“accept”、“reject”、“switch-mode"のいずれかのルールが一致するか、どのルールにも一致せずにTCPリクエストの検査待機時間が満了するまで続けます。
これらのルールと"tcp-request connection"ルールの最初の違いは、“tcp-request content"ルールでは、内容を使って判断できることです。多くの場合、プロトコルの識別や妥当性を判断します。二つ目は、内容に基づくルールをフロントエンドとバックエンドの両方で使用できることです。クライアントとHTTPキープアライブを使う場合、すべてのtcp-request contentルールを再び評価します。そのため、HAProxyは、スティッキーカウンターを"tcp-request connection"と"tcp-request content"のどちらのルールで割り当てたかを記録し、HTTPリクエストの処理後に、内容に関係するものをすべてクリアします。これにより、次のリクエストで再びルールを評価するときに、カウンターも再評価できます。ルールがL7の情報を追跡する場合や、L7に基づくACLを条件としている場合は、リクエストごとに追跡対象が変わる可能性があるため、特に重要です。
コンテンツに基づくルールは、宣言されたとおりの順序で評価されます。一致するルールがない場合、またはルール自体がない場合、既定のアクションは内容を受け入れることです。追加できるルール数に特別な上限はありません。
必須ではありませんが、“tcp-request connection"ルールではtrack-sc0、フロントエンドの"tcp-request content"ルールではtrack-sc1、バックエンドの"tcp-request content"ルールではtrack-sc2を使うことを推奨します。設定が読みやすくなり、トラブルシューティングも容易になるためです。ただし、これはあくまで指針であり、どのカウンターもどこででも使用できます。
構文中で"tcp-request content"の直後にあるキーワードがルールのアクションで、その後にアクションに応じた数の引数が続く場合があります。サポートされるアクションと、それぞれの構文は、4.3節 「アクション」に列挙されています(“TCP RqCnt"にチェックが付いたアクションを参照してください)。
このディレクティブは、名前付きのdefaultsセクションでのみ使用でき、無名のセクションでは使用できません。defaultsセクションで定義したルールは、関連付けられたプロキシセクションのルールより先に評価されます。曖昧さを避けるため、この場合、フロントエンド機能を持つプロキシとバックエンド機能を持つプロキシが、同じdefaultsセクションを使用することはできません。つまり、listenセクションは、このようなルールを定義したdefaultsセクションを使用できません。
“if/unless"条件は省略可能です。アクションに条件が設定されていなければ、無条件に実行します。これは"track-sc*“アクションや、既定のアクションを拒否に変更する場合などに便利です。
レイヤー7の内容に依存しない情報を追跡するには、特にHTTPフロントエンドで、“tcp-request session"ルールを使うことを推奨します。一部のHTTP処理はセッションレベルで行われ、リクエストが早い段階で拒否される場合があります。その場合、コンテンツレベルでの追跡に支障が出る可能性があります。このような信頼性に欠ける使い方をできる限り防ぐため、起動時に警告を出します。
HTTP固有のACLマッチは、必要なデータを抽出する前にバッファーの内容を事前に解析できるため、TCPプロキシでも"tcp-request content"ルールでレイヤー7の内容を照合できます。バッファー内の内容を有効なHTTPメッセージとして解析できない場合、ACLは一致しません。ここで使用するパーサーは、ほかのすべてのHTTP処理で使用するものとまったく同じなので、解析結果が異なる危険はありません。HTTPフロントエンドまたはHTTPバックエンドでは、接続処理の初期段階で、セッションレベルでHTTPを解析するため、ルールの初回評価時にはHTTPの内容が必ずすぐに利用できます。ただし、このようなプロキシでは"http-request"ルールを使用する方がはるかに自然であり、推奨されます。
ルールの処理時に情報が存在すれば、レイヤー7の情報を追跡することもできます。追跡するデータがまだ利用できない場合、ルール処理エンジンは検査待機時間が満了するまで待つことができます。
例:
例:
例:
例:
例:
例:
例:フロントエンドごと、バックエンドごとにカウンターを追跡し、バックエンドが不正利用を検出してgpc0を設定した場合に、その利用者をフロントエンドでブロックします。
frontend http
# Use General Purpose Counter 0 in SC0 as a global abuse counter
# protecting all our sites
stick-table type ip size 1m expire 5m store gpc0
tcp-request connection track-sc0 src
tcp-request connection reject if { sc0_get_gpc0 gt 0 }
...
use_backend http_dynamic if { path_end .php }
backend http_dynamic
# if a source makes too fast requests to this dynamic site (tracked
# by SC1), block it globally in the frontend.
stick-table type ip size 1m expire 5m store http_req_rate(10s)
acl click_too_fast sc1_http_req_rate gt 10
acl mark_as_abuser sc0_inc_gpc0(http) gt 0
tcp-request content track-sc1 src
tcp-request content reject if click_too_fast mark_as_abuser
ACLの使用方法については、セクション7 を参照してください。
“tcp-request connection”、“tcp-request session”、“tcp-request inspect-delay”、“http-request"も参照してください。
tcp-request inspect-delay <timeout>
コンテンツ検査中にデータを待つ最大許容時間を設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 可 | 可 | 可
引数:
HAProxyを主にTCPリレーとして使う場合、解析せずにあらゆる種類のプロトコルをサーバーに通す危険性が懸念されることがよくあります。リクエストの内容を解析するには、まずデータの転送を保留し、その後に解析しなければなりません。この文は、指定した時間を上限としてデータの転送を保留できるようにするだけです。
TCPの内容検査は、接続がフロントエンドに到達した直後のごく早い段階に適用され、次に接続がバックエンドへ転送された直後のごく早い段階にも適用されます。そのため、両方にtcp-requestルールがある場合、接続にはフロントエンドで最初の待機時間が発生し、バックエンドで2回目の待機時間が発生する可能性があります。
内容検査では、HAProxyは新しいチャンクが到着するたびに、データが部分的であることを考慮してすべてのルールを評価します。前述の待機時間内にどのルールも一致しない場合、待機時間の終了時に最後の検査を行い、このときは内容が確定したものとして扱います。待機時間を設定しない場合、HAProxyはまったく待機せず、利用できる情報に基づいて直ちに判定を適用します。当然ながら、これではあまり役に立たない可能性が高く、競合が生じる可能性もあるため、このような設定は推奨しません。
接続エラーまたはシャットダウンが発生した場合や、リクエストバッファーがいっぱいになった場合は、検査の待機時間が短くなります。
ルールが一致するとすぐにリクエストを解放し、通常どおり処理を続けます。どのルールにも一致せずにタイムアウトに達した場合、既定の方針では、そのまま通過させます。
ほとんどのプロトコルでは、クライアントの大半が接続直後にリクエスト全体を送信するため、数秒の設定で十分です。TCPの再送に備えて3秒以上を加えれば、それ以上は必要ありません。一部のプロトコルでは、たとえばクライアントがサーバーより先に送信しないことを保証する場合(SMTPなど)や、サーバーへデータを渡す前にクライアントからの送信を待つ場合(SSLなど)に、大きな値を使用する意味がある場合があります。クライアントのタイムアウトは、少なくとも検査の待機時間をカバーしなければなりません。そうでなければ、先にタイムアウトします。クライアントが接続を閉じた場合やバッファーがいっぱいになった場合、内容がそれ以上変わることはないため、待機時間は直ちに終了します。
このディレクティブは、名前付きのdefaultsセクションでのみ使用でき、無名のdefaultsセクションでは使用できません。プロキシは、自身のdefaultsセクションからこの値を継承します。
参照:“tcp-request content accept”、“tcp-request content reject”、“timeout client”。
tcp-request session <action> [{if | unless} <condition>]
レイヤー5の条件に応じて、検証済みのセッションに対してアクションを実行します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 可 | 可 | 不可
引数:
セッションが検証された後(つまり、すべてのハンドシェイクが完了した後)に、条件を評価して、そのセッションを受け入れるか、破棄するか、カウンターを追跡するかを判断できます。この段階ではまだバッファーが割り当てられておらず、処理を待機させることもできないため、条件にはデータの内容を使用できません。主な用途は、初期段階の情報を変数へコピーすること(セッション内では変数にアクセスできるため)や、ハンドシェイク後に収集した情報を追跡することです。後者には、SSLレベルの要素(SNI、暗号、クライアント証明書のCN)やPROXYプロトコルヘッダーの情報(たとえば、この方法で転送された送信元の追跡)があります。抽出した情報は、変数へコピーすることも、“track-sc"ルールで追跡することもできます。もちろん、ほかのルールセットと同じように、受け入れるか拒否するかを判断することもできます。ここで行う操作のほとんどは"tcp-request content"ルールでも実行できますが、HTTPではこれらのルールが新しいリクエストごとに評価されるため、それが常に許容できるとは限りません。たとえば、ルールが評価のたびにカウンターを増やす場合があります。また、送信元IPアドレスから位置情報で国を特定し、セッション全体で使用する変数へ代入した後、すべてのリクエストでHTTPヘッダーから送信元アドレスを書き換えることもできます。判断するために内容を検査する必要がある場合は、代わりに"tcp-request content"文を使用しなければなりません。
“tcp-request session"ルールは、宣言されたとおりの順序で評価されます。一致するルールがない場合、またはルール自体がない場合、既定のアクションは受信セッションを受け入れることです。追加できるルール数に特別な上限はありません。
構文中で"tcp-request session"の直後にあるキーワードがルールのアクションで、その後にアクションに応じた数の引数が続く場合があります。サポートされるアクションと、それぞれの構文は、4.3節 「アクション」に列挙されています(“TCP RqSes"にチェックが付いたアクションを参照してください)。
このディレクティブは、名前付きのdefaultsセクションでのみ使用でき、無名のセクションでは使用できません。defaultsセクションで定義したルールは、関連付けられたプロキシセクションのルールより先に評価されます。曖昧さを避けるため、この場合、フロントエンド機能を持つプロキシとバックエンド機能を持つプロキシが、同じdefaultsセクションを使用することはできません。つまり、listenセクションは、このようなルールを定義したdefaultsセクションを使用できません。
“if/unless"条件は省略可能です。アクションに条件が設定されていなければ、無条件に実行します。これは"track-sc*“アクションや、既定のアクションを拒否に変更する場合などに便利です。
例: 既定では元の送信元アドレスを追跡し、ローカルプロキシからの接続については、PROXYプロトコルのヘッダーで通知されたアドレスを追跡します。最初の接続レベルのルールは、これらの接続に対してPROXYプロトコルの受信を有効にします。二番目のルールは、必要に応じてデコードした後に、保持すると決めたアドレスを追跡します。
tcp-request connection expect-proxy layer4 if { src -f proxies.lst }
tcp-request session track-sc0 src
例: 許可リスト内のホストからのセッションをすべて受け入れ、頻度が高すぎるセッションは数えずに拒否し、受け入れたセッションを追跡します。その結果、不正利用を行う送信元からのセッションレートに上限が設けられます。
tcp-request session accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request session reject if { src_sess_rate gt 10 }
tcp-request session track-sc0 src
例: 許可リスト内のホストからのセッションをすべて受け入れ、それ以外のセッションを数え、頻度が高すぎるものを拒否します。その結果、不正利用に当たるセッションは、頻度を下げない限りブロックされます。
tcp-request session accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request session track-sc0 src
tcp-request session reject if { sc0_sess_rate gt 10 }
ACLの使用方法については、セクション7 を参照してください。
参照:“tcp-request connection”、“tcp-request content”、“stick-table”。
tcp-response content <action> [{if | unless} <condition>]
レイヤー4-7の条件に応じて、セッションのレスポンスに対してアクションを実行します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 不可 | 可 | 可
引数:
レスポンスの内容は、レスポンス処理の初期段階である"TCPコンテンツ検査"で解析できます。この段階では、レスポンスの内容が更新されるたびにACLに基づくルールを評価します。評価は、終端となるルールが一致するか、設定されているTCPレスポンスの検査待機時間が、どのルールにも一致せずに満了するまで続きます。
通常、これらの判断ではプロトコルの識別や妥当性を考慮します。
コンテンツに基づくルールは、宣言されたとおりの順序で評価されます。一致するルールがない場合、またはルール自体がない場合、既定のアクションは内容を受け入れることです。追加できるルール数に特別な上限はありません。
構文中で"tcp-response content"の直後にあるキーワードがルールのアクションで、その後にアクションに応じた数の引数が続く場合があります。サポートされるアクションと、それぞれの構文は、4.3節 「アクション」に列挙されています(“TCP RsCnt"にチェックが付いたアクションを参照してください)。
このディレクティブは、名前付きのdefaultsセクションでのみ使用でき、無名のセクションでは使用できません。defaultsセクションで定義したルールは、関連付けられたプロキシセクションのルールより先に評価されます。曖昧さを避けるため、この場合、フロントエンド機能を持つプロキシとバックエンド機能を持つプロキシが、同じdefaultsセクションを使用することはできません。つまり、listenセクションは、このようなルールを定義したdefaultsセクションを使用できません。
“if/unless"条件は省略可能です。アクションに条件が設定されていなければ、無条件に実行します。これは、既定のアクションを拒否に変更する場合などに便利です。
複数の種類のアクションをサポートしています。
“tcp-response content"ルールでレイヤー7の内容を照合することもできますが、その場合は完全なレスポンスがバッファーに格納されていることを確認する必要があります。そうでなければ、どの内容にも一致しません。これを実現する最もよい方法は、検査期間中にHTTPプロトコルを検出することです。
ACLの使用方法については、セクション7 を参照してください。
参照:“tcp-request content”、“tcp-response inspect-delay”。
tcp-response inspect-delay <timeout>
コンテンツ検査中にレスポンスを待つ最大許容時間を設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可(!) | 不可 | 可 | 可
引数:
このディレクティブは、名前付きのdefaultsセクションでのみ使用でき、無名のdefaultsセクションでは使用できません。プロキシは、自身のdefaultsセクションからこの値を継承します。
参照:“tcp-response content”、“tcp-request inspect-delay”。
timeout check <timeout>
追加のチェックタイムアウトを設定します。ただし、接続がすでに確立された後にのみ適用されます。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
設定すると、HAProxyはチェックの接続タイムアウトとしてmin(“timeout connect”, “inter”)を使用し、追加の読み取りタイムアウトとして"timeout check"を使用します。“min"を使用するのは、非常に長い"timeout connect"を設定している場合(たとえば、キューやtarpitのために必要だった場合)に、チェックが遅くならないようにするためです。(“timeout queue"と"timeout tarpit"を使用すれば常に回避できるため、これほど長い接続タイムアウトを設定する妥当な理由はないことにも注意してください。)
“timeout check"が設定されていない場合、HAProxyはチェック全体(接続+読み取り)のタイムアウトに"inter"を使用します。これは<1.3.15のすべてのバージョンとまったく同じ動作です。
ほとんどの場合、チェック用のリクエストは通常のリクエストよりはるかに単純で、短時間で処理できます。また、応答の遅いサーバーを除外したい場合もあるため、このタイムアウトは"timeout server"より小さくするべきです。
このパラメーターはバックエンド専用ですが、“defaults"セクションで一度指定して、すべてに適用できます。実際、これは設定を忘れないための最も簡単な方法の1つです。
参照:“timeout connect”、“timeout queue”、“timeout server”、“timeout tarpit”。
timeout client <timeout>
クライアント側の最大無通信時間を設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
非アクティブ時のタイムアウトは、クライアントからの確認応答またはデータ送信を待っている場合に適用されます。HTTPモードでは、クライアントがリクエストを送信する最初の段階と、レスポンスでサーバーが送信したデータを読み取っている間に、このタイムアウトを特に考慮することが重要です。ただし、最初の段階については、Slowlorisのような攻撃からHAProxyをよりよく保護するために、“timeout http-request"を設定する方が望ましいです。値の単位はデフォルトではミリ秒ですが、このドキュメントの冒頭で説明したように、数値の後ろに単位を付ければほかの単位も使用できます。TCPモードでは(HTTPモードでも程度は小さいものの)、デバッグが複雑になる状況を避けるため、クライアントのタイムアウトをサーバーのタイムアウトと同じ値にすることを強く推奨します。1つまたは複数のTCPパケットの損失に対応できるよう、3秒の倍数を少し上回るタイムアウト(4秒や5秒など)を指定するのがよい方法です。長時間続くストリームと短時間のストリームが混在する場合(WebSocketとHTTPなど)、トンネルでは"timeout client"と"timeout server"より優先される"timeout tunnel"と、半分閉じた接続用の"timeout client-fin"の利用を検討する価値があります。
このパラメーターはフロントエンド専用ですが、“defaults"セクションで一度指定すれば、すべてに適用できます。実際、設定し忘れを防ぐ最も簡単な方法の一つです。タイムアウトを指定しないと無期限になり、推奨されません。この使い方も受け入れられ、動作しますが、システム側のタイムアウトも設定されていない場合、期限切れのセッションがシステム内に蓄積するおそれがあるため、起動時に警告を出します。
参照:“timeout server”、“timeout tunnel”、“timeout http-request”。
timeout client-fin <timeout>
半クローズ状態の接続の、クライアント側の無通信タイムアウトを設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
非アクティブ時のタイムアウトは、すでに一方向が閉じられており、クライアントからの確認応答またはデータ送信を待っている場合に適用されます。このタイムアウトは、一方向が閉じられた接続だけに適用される点で"timeout client"と異なります。クライアントが正常に切断しない場合に、接続がFIN_WAIT状態のまま長く残るのを防ぐうえで特に役立ちます。この問題は、RDPやWebSocketのような長時間続く接続で特によく発生します。接続の一方向が閉じられると、このタイムアウトが"timeout tunnel"より優先される場合があることに注意してください。GOAWAYフレームを送信した後のアイドル状態のHTTP/2接続にも適用されます。これは多くの場合、接続が速やかに終了することを期待していることを示します。
このパラメーターはフロントエンド専用ですが、“defaults"セクションで一度指定すれば、すべてに適用できます。既定では未設定のため、片方向だけ閉じた接続にはほかのタイムアウト(timeout.clientまたはtimeout.tunnel)を使用します。
参照:“timeout client”、“timeout server-fin”、“timeout tunnel”。
timeout client-hs <timeout>
クライアントのTLSハンドシェイクが完了するまで待つ最大時間を設定します。TCP接続とQUIC接続の両方で使用できます。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
このハンドシェイクタイムアウトを設定しない場合、代わりにクライアントタイムアウトを使用します。
timeout connect <timeout>
サーバーへの接続試行が成功するまで待つ最大時間を設定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
サーバーがHAProxyと同じLANにあれば、接続はすぐに確立するはずです(数ミリ秒未満)。いずれにせよ、一回または複数回のTCPパケット損失に対応できるよう、タイムアウトを3秒の倍数より少し長く設定するのがよい方法です(たとえば4または5秒)。既定では、queueとtarpitのタイムアウトが指定されていない場合、接続タイムアウトはそれらの初期値も同じ値に設定します。
このパラメーターはバックエンド専用ですが、“defaults"セクションで一度指定すれば、すべてに適用できます。実際、設定し忘れを防ぐ最も簡単な方法の一つです。タイムアウトを指定しないと無期限になり、推奨されません。この使い方も受け入れられ、動作しますが、システム側のタイムアウトも設定されていない場合、失敗したセッションがシステム内に蓄積するおそれがあるため、起動時に警告を出します。
参照:“timeout check”、“timeout queue”、“timeout server”、“timeout tarpit”。
timeout http-keep-alive <timeout>
新しいHTTPリクエストの到着を待つ最大許容時間を設定します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
既定では、キープアライブ中に新しいリクエストを待つ時間は"timeout http-request"で設定します。ただし、これが常に便利とは限りません。接続を早く解放するためにキープアライブのタイムアウトを非常に短くしたい場合もあれば、キープアライブのタイムアウトは長くしつつ、リクエストが届き始めてからのタイムアウトは短く保ちたい場合もあります。
“http-keep-alive"タイムアウトは、これらの要件に対応します。レスポンスの送信後、新しいHTTPリクエストが届き始めるまでの待ち時間を定義します。リクエストの最初のバイトを検出した後は、“http-request"タイムアウトを使ってリクエスト全体の到着を待ちます。新しいリクエストの前にある空行は、タイムアウトを更新せず、新しいリクエストとしても数えません。
この二つのタイムアウトには、もう一つ違いがあります。timeout http-keep-alive中に接続が期限切れになった場合は、エラーを返さず、接続を閉じるだけです。リクエストがそろうのを待っている間に"http-request"で期限切れになった場合は、フロントエンドに"option http-ignore-probes"が設定されていない限り、接続を閉じる前にHTTP 408エラーをクライアントへ返します。
一般に、“timeout http-keep-alive"は、短時間の接続が大量に発生するサイトで、クライアントがそれ以外には何も行わない接続を長く開いたままにするのを防ぐ用途に適しています。HTTP/1.1では、値を数十から数百ミリ秒に設定することで実現できます。これにより、クライアントがページをリクエストした後、クライアントの次の動作を待つために接続を開いたままにせず、接続を閉じます。この場合、ブラウザーが新たに動作すると、TCPレイヤーやSSLレイヤーで新しいハンドシェイクが発生します。よくある用途は、HTTPSページへのリダイレクトだけを提供するHTTPサイトです。このような接続は、faviconの取得に使われる可能性がある場合を除いて再利用されないため、アイドル状態で長く維持しない方がよいでしょう。
逆の用途もあります。クライアントがアイドル接続を長時間(たとえば30秒から一分間)再利用できるようにしたいものの、非常に低コストな攻撃を避けるため、最初のリクエストにはそれほど長く待ちたくないサイトもあります。その場合、http-keep-aliveタイムアウトには大きな値を設定し、http-requestは小さい値(数秒)のままにします。
非常に小さな値を設定すると、パイプライン化されていない追加のリクエストは、別の接続で処理される可能性が高くなります。同じ接続で処理されるには、リクエストが実際にパイプライン化されている必要がありますが、HTTP/1.1ではこれは非常にまれです(レスポンスを待たずにリクエストを続けて送信することを指します)。ほとんどのHTTP/1.1実装は、リクエストを送信し、レスポンスを待ってから次のリクエストを送信します。数十万のクライアントがあるサイトでは、HTTP/1.1用にここで小さな値を設定すると、ハンドシェイクの計算コストが増える代わりに、使用するメモリーとソケットを減らせる利点があります。
HTTP/2を扱う場合、小さな値の設定には特に注意が必要です。HTTP/2は、TCPレイヤーやSSLレイヤーの再接続に伴うオーバーヘッドを減らすため、1つの接続上でリクエストを多重化する仕組みです。このプロトコルは制御フレームも使用し、TCP接続が早期に閉じられるとうまく処理できません。ごくまれに、HAProxyから出た後の転送中のデータが破棄され、レスポンスが途中で切れることがあります(この場合、HAProxyはエラーをログに記録することさえできません)。HTTP/2接続の小さめの初期値としては、4秒程度を推奨します。これにより、最新のkeep-alive実装の大半が、使われなくなった接続を不必要に開いたままにするのを防ぎながら、後続のリクエストではその接続を再利用できます。ただし、必要に応じて調整すべきであり、これはあくまで初期値です。
このパラメーターを設定しない場合、“http-request"タイムアウトが適用されます。両方とも設定しない場合は、さらに下のレベルで"timeout client"が引き続き適用されます。効果を得るにはフロントエンドに設定することを推奨します。ただし、フロントエンドがTCPモードの場合は、HTTPバックエンドのタイムアウトが使用されます。
参照:“timeout http-request”、“timeout client”。
timeout http-request <timeout>
完全なHTTPリクエストを待つ最大許容時間を設定します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
DoS対策として、クライアントのタイムアウトには影響を与えずに、HTTPリクエスト全体の受信に許容する最大時間を短くする必要がある場合があります。これにより、接続を確立したまま何も送信しない行為を防ぐことができます。クライアントのタイムアウトは非アクティブ時のタイムアウトであり、攻撃者が時々1文字ずつ送信すればタイムアウトしないため、このような不正利用を十分に防げません。HTTPリクエストのタイムアウトでは、クライアントがどのような速度で入力しても、時間内に完了しないリクエストは中止されます。タイムアウトすると、問題を通知するためHTTP 408レスポンスをクライアントへ送信し、接続を閉じます。ログには終了コード"cR"が記録されます。一部の最近のブラウザーには、この標準的で十分に文書化された動作に問題があるため、“option http-ignore-probes"または"errorfile 408 /dev/null"を使用して408コードを隠す必要がある場合があります。詳細は、セクション8.5 の終了コード"cR"の説明を参照してください。
既定では、このタイムアウトはリクエストのヘッダー部分だけに適用され、データには適用されません。空行を受信すると、それ以降は使用しません。“option http-buffer-request"と組み合わせると、リクエストのボディにも適用されます。“timeout http-keep-alive"が設定されていないキープアライブ接続では、二番目のリクエストを待つ際に再び使用します。
ほとんどのクライアントは接続直後にリクエスト全体を送るため、通常は数秒に設定すれば十分です。TCPの再送を考慮して3秒以上を加えれば、それ以上は必要ありません。非常に小さい値(たとえば50 ms)でも、ローカルネットワークではパケット損失がなければ通常は機能します。ただし、その場合はtelnetを使ってHTTPリクエストを手入力することができなくなります。
このパラメーターを設定しない場合、受信リクエストの各チャンクの間には、引き続きクライアントタイムアウトが適用されます。有効にするにはフロントエンドで設定するべきですが、フロントエンドがTCPモードの場合は、HTTPバックエンドのタイムアウトを使用します。
“errorfile”、“http-ignore-probes”、“timeout http-keep-alive”、“timeout client”、“option http-buffer-request"も参照してください。
timeout queue <timeout>
接続スロットが空くまでキューで待つ最大時間を設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
サーバーのmaxconnに達すると、接続はサーバー専用、またはバックエンド全体で共有するキューで待機します。無期限に待たないよう、キューで待機中のリクエストにはタイムアウトが適用されます。タイムアウトに達すると、そのリクエストが処理される見込みはほぼないと判断して破棄し、クライアントに503エラーを返します。
“timeout queue"文で、リクエストがキュー内で待機できる最大時間を指定できます。指定しない場合、“timeout queue"パラメーターのない旧バージョンとの後方互換性のため、バックエンドの接続タイムアウト(“timeout connect”)と同じ値を使用します。
参照:“timeout connect”。
timeout server <timeout>
サーバー側の最大無通信時間を設定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
非アクティブ時のタイムアウトは、サーバーからの確認応答またはデータ送信を待っている場合に適用されます。HTTPモードでは、サーバーがヘッダーを送信する必要のあるレスポンスの最初の段階に、このタイムアウトを特に考慮することが重要です。これは、リクエストに対するサーバーの処理時間を直接表すためです。ここに設定する値を決めるには、多くの場合、まず許容できないと考える応答時間を設定し、ログで応答時間の分布を確認して、それに合わせて値を調整するのがよい方法です。
値の単位はデフォルトではミリ秒ですが、このドキュメントの冒頭で説明したように、数値の後ろに単位を付ければほかの単位も使用できます。TCPモードでは(HTTPモードでも程度は小さいものの)、デバッグが複雑になる状況を避けるため、クライアントのタイムアウトをサーバーのタイムアウトと同じ値にすることを強く推奨します。想定するサーバーの応答時間にかかわらず、少なくとも1つまたは複数のTCPパケットの損失に対応できるよう、3秒の倍数を少し上回るタイムアウト(最低でも4秒や5秒など)を指定するのがよい方法です。長時間続くストリームと短時間のストリームが混在する場合(WebSocketとHTTPなど)、トンネルでは"timeout client"と"timeout server"より優先される"timeout tunnel"の利用を検討する価値があります。
このパラメーターはバックエンド専用ですが、“defaults"セクションで一度指定すれば、すべてに適用できます。実際、設定し忘れを防ぐ最も簡単な方法の一つです。タイムアウトを指定しないと無期限になり、推奨されません。この使い方も受け入れられ、動作しますが、システム側のタイムアウトも設定されていない場合、期限切れのセッションがシステム内に蓄積するおそれがあるため、起動時に警告を出します。
参照:“timeout client”、“timeout tunnel”。
timeout server-fin <timeout>
半クローズ状態の接続の、サーバー側の無通信タイムアウトを設定します。
使用可能なコンテキスト:tcp, http, log
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
非アクティブ時のタイムアウトは、すでに一方向が閉じられており、サーバーからの確認応答またはデータ送信を待っている場合に適用されます。このタイムアウトは、一方向が閉じられた接続だけに適用される点で"timeout server"と異なります。リモートサーバーが正常に切断しない場合に、接続がFIN_WAIT状態のまま長く残るのを防ぐうえで特に役立ちます。この問題は、RDPやWebSocketのような長時間続く接続で特によく発生します。接続の一方向が閉じられると、このタイムアウトが"timeout tunnel"より優先される場合があることに注意してください。この設定は機能を網羅するために用意されていますが、ほとんどの状況では必要ないはずです。
このパラメーターはバックエンド専用ですが、“defaults"セクションで一度指定すれば、すべてに適用できます。既定では未設定のため、片方向だけ閉じた接続にはほかのタイムアウト(timeout.serverまたはtimeout.tunnel)を使用します。
参照:“timeout client-fin”、“timeout server”、“timeout tunnel”。
timeout tarpit <timeout>
tarpitされた接続を維持する時間を設定します。
使用可能なコンテキスト: http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
“http-request tarpit"で接続にtarpitを適用すると、その接続を一定時間、何も処理せずに開いたまま保持し、その後に閉じます。“timeout tarpit"は、開いたまま保持する時間を定義します。
既定の単位はミリ秒ですが、このドキュメントの冒頭で説明したように、数値の後に単位を付ければ、ほかの単位でも指定できます。省略した場合は、“timeout tarpit"パラメーターがなかった旧バージョンとの後方互換性のため、バックエンドの接続タイムアウト(“timeout connect”)と同じ値を使用します。
参照:“timeout connect”。
timeout tunnel <timeout>
トンネルのクライアント側とサーバー側の最大無通信時間を設定します。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:
トンネルのタイムアウトは、クライアントとサーバーの間に双方向接続が確立され、その接続が両方向とも非アクティブのままになった場合に適用されます。接続がトンネルになると、このタイムアウトはクライアントとサーバーの両方のタイムアウトより優先されます。TCPでは、どちらの接続にもアナライザーが接続されていなくなった時点で、このタイムアウトを使用します(TCP内容ルールで受け入れられた場合など)。HTTPでは、接続がアップグレードされた場合(WebSocketプロトコルへ切り替える場合や、CONNECTリクエストをプロキシへ転送する場合など)、またはkeepalive/closeオプションを指定していない場合の最初のレスポンスの後に、このタイムアウトを使用します。
このタイムアウトは通常、長時間続く接続と併せて使用するため、“timeout client-fin"も設定するのが一般に適切です。これにより、クライアントが突然ネットワークからいなくなって接続を閉じる処理に確認応答を返さない場合や、シャットダウンを送信した後、未完了のデータに確認応答を返さなくなった場合に対応できます。これは、ファイアウォールのあるパケット損失の多いネットワークで発生することがあり、大量のセッションがFIN_WAIT状態にあることで検出できます。
既定の単位はミリ秒ですが、このドキュメントの冒頭で説明したように、数値の後に単位を付ければ、ほかの単位でも指定できます。通常のアイドル時間としてどれくらいを想定していても、一回または複数回のTCPパケット損失に対応できるよう、タイムアウトを3秒の倍数より少し長く設定するのがよい方法です(たとえば、最低でも4または5秒)。
このパラメーターはバックエンド専用ですが、“defaults"セクションで一度指定して、すべてに適用できます。実際、これは設定を忘れないための最も簡単な方法の1つです。
例:
参照:“timeout client”、“timeout client-fin”、“timeout server”。
transparent (deprecated)
クライアント側の透過プロキシを有効にします。
使用可能なコンテキスト:tcp, http
使用可能なセクション:defaults | frontend | listen | backend 可 | 不可 | 可 | 可
引数:なし
このキーワードは、レイヤー3ロードバランサーにレイヤー7での接続先の固定を提供するために導入されました。リモートアドレスへの着信接続をローカルプロセス(ここではHAProxy)にリダイレクトするOSの機能を使用し、最初に要求されたアドレスをそのプロセスに通知する仕組みです。このオプションを使用すると、Cookieのないセッションは、着信リクエストの元の宛先IPアドレス(ほかの機器のアドレスと一致しているはずです)へ転送され、Cookieのあるリクエストは引き続き適切なサーバーへ転送されます。
“transparent"キーワードは非推奨です。代わりに"option transparent"を使用してください。
よくある誤解とは異なり、このオプションによって、HAProxyが接続確立時にクライアントのIPをサーバーへ提示することはありません。
参照:“option transparent”。
unique-id-format <fmt>
各リクエストに一意のIDを生成します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 可 | 可 | 可 | 可
引数:
このキーワードは、カスタムログ形式を使用してリクエストごとにIDを作成します。一意のIDは、複雑なインフラストラクチャーの多数のコンポーネントを通るリクエストを追跡するのに役立ちます。作成したIDは、カスタムログ形式文字列で%IDエイリアスを使用してログに記録することもできます。
形式は、組み合わせたときに一意になることが保証される要素で構成することを推奨します。たとえば、複数のHAProxyインスタンスが関わる場合、ノード名を含めることが重要になる場合があります。着信接続の送信元と宛先のアドレスおよびポートをログに記録する必要があることもよくあります。同じ接続上で複数のリクエストを処理できるため、リクエストカウンターを含めると、それらを区別するのに役立つ場合があります。同様に、タイムスタンプはカウンターが一巡した場合の重複を防ぐのに役立つ場合があります。プロセスIDを記録すると、サービスの再起動後の衝突を防げます。
多くのフィールドでは、表記が短くなりログの容量を節約できるため、16進表記を推奨します。
通常の接続では、フロントエンドで設定した形式を使って一意のIDを生成します。ヘルスチェックでは、tcp-checkまたはhttp-checkルールセット内で"unique-id"取得処理を使う際に、バックエンドの形式を使用します。
例:
参照:“unique-id-header”。
unique-id-header <name>
HTTPリクエストに一意のIDヘッダーを追加します。
使用可能なコンテキスト: http
使用可能なセクション:defaults | frontend | listen | backend 可 | 可 | 可 | 不可
引数:
unique-id-formatを使って、サーバーへ送信するHTTPリクエストにunique-idヘッダーを追加します。unique-id-formatがなければ動作しません。
例:
use_backend <backend> [{if | unless} <condition>]
if/unlessによるACL条件の一致または不一致に応じて、特定のバックエンドへ切り替えます。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 可 | 可 | 不可
引数:
コンテンツスイッチングでは、接続がフロントエンドに到着し、いくつかの条件に応じて各バックエンドへ振り分けられます。条件とバックエンドの関係は"use_backend"キーワードで記述します。通常はHTTP処理で使用しますが、純粋なTCPでも使用できます。その場合、ステートレスACL(送信元アドレスの検証など)で内容を使用せずに処理する方法と、“tcp-request"ルールと組み合わせてペイロードの到着を待つ方法があります。
“use_backend"ルールはいくつでも指定できます。これらのルールはすべて宣言順に評価され、最初に一致したルールがバックエンドを割り当てます。そのバックエンドが停止していると見なされる場合も同じです。ただし、一致したルールの対象が無効化されている、または公開されていないバックエンドである場合は、そのルールを無視して評価を続けます。
最初の形式では、条件を満たす場合にバックエンドを使用します。2番目の形式では、条件を満たさない場合にバックエンドを使用します。有効な条件がない場合、“default_backend"で定義したバックエンドを、無効化または公開解除されていない限り使用します。デフォルトのバックエンドが利用できない場合、“listen"セクションでは同じセクション内のサーバーを使用します。フロントエンドの場合は、どのサーバーも使用せず、503 service unavailableレスポンスを返します。
TCPフロントエンドからHTTPバックエンドに切り替えることもできます。この場合、フロントエンドですでにHTTPプロトコルであることを確認していれば、直ちにバックエンドの処理に進みます。そうでなければ、バックエンドは完全なHTTPリクエストの到着を待ちます。この機能は、一つのポートで複数のプロトコルを解析する必要があり、その中にHTTPが含まれるフロントエンドに便利です。
<backend>が単純な名前の場合、設定時に解決され、指定したバックエンドが存在しないとエラーを報告します。一方、<backend>がカスタムログ形式の場合、設定時には検査できないため、バックエンド名を実行時に動的に解決します。結果のバックエンド名がどの有効なバックエンドにも対応しない場合、ほかのルールは評価せず、代わりにdefault_backendディレクティブを適用します。動的なバックエンド名を使用する場合、リクエストから許可されていないバックエンドを強制的に選択できないように、ほかのバックエンドが使用していない接頭辞を使うことを強く推奨します。
明示的な名前を指定した"use_backend"ルールは、バックエンドの"fullconn"設定を計算するために、フロントエンドとバックエンドの関連を検出する際にも使用されます。動的な名前では、この処理はできません。
“default_backend”、“tcp-request”、“fullconn”、“log-format”、およびACLに関するセクション7 も参照してください。
use-fcgi-app <name>
バックエンドに使用するFastCGIアプリケーションを定義します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
引数:
詳細は、FastCGIアプリケーションの設定に関するセクション10.1 を参照してください。
use-server <server> if <condition>
if/unlessで指定したACL条件の一致または不一致が成立する場合に限り、特定のサーバーを使用します。
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
引数:
既定では、バックエンドに届いた接続は、設定したアルゴリズムに従って利用可能なサーバー間で負荷分散されます。ただし、Cookieなどで接続先を固定する仕組みを使用しており、それがリクエスト内に見つかった場合は除きます。
あるサーバー専用のバックエンドを宣言せずに、特定のリクエストをそのサーバーへ転送したい場合があります。これは"use-server"ルールで実現できます。これらのルールは"redirect"ルールの後、Cookieの評価前に評価され、Cookieより優先されます。“use-server"ルールはいくつでも指定できます。すべてのルールを宣言順に評価し、最初に一致したルールがサーバーを割り当てます。
ルールが停止中のサーバーを指定し、“option persist"が使われておらず、force-persistルールも成立していない場合は、そのルールを無視します。一致するルールが見つかるまで、後続のルールの評価を続けます。
最初の形式では、条件を満たす場合にサーバーを使用します。2番目の形式では、条件を満たさない場合にサーバーを使用します。有効な条件がない場合、処理を続行し、ほかの接続先の固定の仕組みに従ってサーバーを割り当てます。
ルールが一致してもCookieの処理は引き続き行われますが、サーバーは割り当てないことに注意してください。これにより、接頭辞付きCookieから接頭辞を除去できます。
“use-server"文はHTTPモードとTCPモードの両方で動作するため、コンテンツに基づく検査に適しています。たとえば、暗黙のTLSを使用するプロトコルでは、TLSのSNIフィールドに従ってサーバー群の中からサーバーを選択できます(“req.ssl_sni"も参照)。また、これらのサーバーの重みをゼロに設定すると、ほかのトラフィックには使用されなくなります。
例:
<server>が単純な名前であれば、設定内の既存サーバーと照合し、指定したサーバーが存在しない場合はエラーを報告します。カスタムログ形式であれば、設定解析時には確認しません。実行時に有効なサーバー名を解決できず、そのuse-serverルールの条件であるACLが真を返した場合は、ほかのuse-serverルールを適用せず、負荷分散に切り替えます。
“use_backend”、serverに関するセクション5 、およびACLに関するセクション7 も参照してください。
4.3. アクションキーワードの一覧表
リクエストまたはレスポンスの処理のさまざまな段階で、複数のルールセットを評価します。各ルールセット内のルールでは、省略可能な条件が満たされた場合に、アクションを実行できます。
多数のアクションが標準で用意されており、内容の変更、処理の受け入れやブロック、内部状態の変更などを行えます。また、Luaで新しいアクションを定義することもできます。その場合、名前には必ず"lua.“の接頭辞が付きます。
以前は特定のルールセットでしか使えないアクションもありましたが、現在は多くのアクションを複数のルールセットで使用できます。このセクションの一覧では、次のルールセットの略称にチェックを付けて、サポートされる各アクションをどこで使用できるかを示します。
- QUIC Ini:アクションは"quic-initial"ルールで有効です。
- TCP RqCon:アクションは"tcp-request connection"ルールで有効です。
- TCP RqSes:アクションは"tcp-request session"ルールで有効です。
- TCP RqCnt:アクションは"tcp-request content"ルールで有効です。
- TCP RsCnt:アクションは"tcp-response content"ルールで有効です。
- HTTP Req:アクションは"http-request"ルールで有効です。
- HTTP Res:アクションは"http-response"ルールで有効です。
- HTTP Aft:アクションは"http-after-response"ルールで有効です。
同じ略語を、後述のリファレンスのセクション4.4 でも使用します。
4.4. アルファベット順のアクションリファレンス
このセクションでは、各アクションとその使い方を詳しく説明します。ルールセットを示す用語と記号には、前述の4.3節 と同じものを使います。
accept
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | - | - | -
ルールの評価を停止し、リクエストまたはレスポンスがチェックを通過できるようにします。このアクションは終端となるため、現在のセクションでは、同じルールセットに含まれる後続のルールは評価されません。“allow"アクションとの違いは、歴史的な互換性のため、TCPおよびQUICルールでは"accept”、HTTPルールでは"allow"を使うことだけです。後述の"allow"アクションも参照してください。
add-acl(<file-name>) <key fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
ACLに新しいエントリーを追加します。ACLはファイルから読み込まれていなければなりません(ダミーの空ファイルでも構いません)。更新するACLのファイル名を丸括弧内で渡します。引数は<key fmt>の1つです。これはセクション8.2.6
で説明するカスタムログ形式の規則に従い、新しいエントリーの内容を収集します。値の重複を避けるため、挿入前にACLを検索します。統計ソケットの"add acl"コマンドに相当しますが、HTTPリクエストを契機に実行できます。
add-header <name> <fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
<name>で指定した名前と、カスタムログ形式の規則に従う<fmt>で定義した値を持つHTTPヘッダーフィールドを追加します(セクション8.2.6
のカスタムログ形式を参照)。接続固有の情報(クライアントのSSL証明書など)をサーバーへ渡したり、複数のヘッダーを1つにまとめたりする場合に特に役立ちます。このルールは処理を終了させないため、ほかの同様のルールも追加できます。ヘッダーは直ちに追加されるので、あるルールで前のルールが追加したヘッダーを再利用できる場合があります。
add-headers-bin <expr> [ prefix <str> ]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
“add-header"アクションの変種で、ヘッダーの名前と値をvarintでエンコードしたバイナリー文字列として渡します。varint形式については、“req.hdrs_bin"サンプル取得を参照してください。ヘッダー名を事前に知らなくても、複数のヘッダーを一度に設定したい場合に役立ちます。これらのヘッダーはHTTPパーサーで検証されていないため、不正なメッセージを送信する原因となる可能性があり、最悪の場合はリクエストスマグリング攻撃につながる可能性があります。挿入するヘッダー数も重要です。tune.http.maxhdrによって制限されるためです。オプションのprefixを指定すると、エンコードされた文字列のうち、<str>で始まるヘッダーだけを設定します。
例:
allow
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
ルールの評価を停止し、リクエストがチェックを通過できるようにします。このアクションは終端となるため、現在のセクションでは、同じルールセットに含まれる後続のルールは評価されません。“accept"アクションとの違いは、歴史的な互換性のため、TCPルールでは"accept”、HTTPルールでは"allow"を使うことだけです。前述の"accept"アクションも参照してください。
attach-srv <srv> [name <expr>] [ EXPERIMENTAL ]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | X | - | - | - | - | -
HTTP/2接続が正しく確立された後に、その接続を捕捉するために使用します。接続の向きをバックエンド側へ反転し、サーバー<srv>のアイドルプールに挿入します。‘rhttp@‘アドレスを持つサーバーでのみ使用できます。
接続は、<expr>の評価結果で定義される名前で、サーバーのアイドルプールに挿入されます。この名前は、“pool-conn-name"または"sni"パラメーターが適用されるリクエストで照合されます。詳細は"http-reuse"を参照してください。
リバースHTTPは現在も活発に開発されており、今後、設定方法が変わる可能性があります。そのため、内部では実験的機能として扱われており、このディレクティブより前の行に"expose-experimental-directives"が記載されていなければなりません。
非常によく似た、別の独立したプロトコルも開発中です。 https://www.ietf.org/archive/id/draft-bt-httpbis-reverse-http-00.html を参照してください。
auth [realm <realm>]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
ルールの評価を停止し、直ちにHTTP 401または407エラーコードを返して、有効なユーザー名とパスワードの提示を求めます。これ以降の"http-request"ルールは評価されません。省略可能な"realm"パラメーターもサポートされており、レスポンスで返す認証領域(通常はアプリケーション名)を設定します。
対応するプロキシのエラーメッセージを使用します。このメッセージは、“errorfile"または"http-error"ディレクティブでカスタマイズできます。401レスポンスでは、WWW-Authenticateヘッダーのすべての出現箇所を削除し、認証領域”<realm>“に対するBasic認証チャレンジを含む新しいヘッダーに置き換えます。407レスポンスでは、Proxy-Authenticateヘッダーに同じ処理を行います。エラーメッセージを変更してはならない場合は、代わりに"http-request return"ルールの使用を検討してください。
例:
cache-store <name>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | - | X | -
http-responseをキャッシュ内に格納します。この段階でレスポンスヘッダーを格納するため、ほかのhttp-responseアクションで、レスポンスの格納前にも格納後にもヘッダーを変更できます。このアクションは、キャッシュ格納フィルターを設定します。
キャッシュの設定については、セクション6.2 を参照してください。
cache-use <name>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
キャッシュ<name>から、キャッシュされたオブジェクトを返すことを試みます。このディレクティブはキャッシュのハッシュ値を計算するため、キャッシュへの保存にも必須です。保存と配信の両方に条件を使いたい場合は、このディレクティブの後に条件を置くのがよい方法です。
キャッシュの設定については、セクション6.2 を参照してください。
capture <sample> [ len <length> | id <id> ]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | X | X
リクエストまたはレスポンスのバッファーからサンプル式<sample>をキャプチャし、最大<len>文字の文字列に変換します。結果の文字列は、次の"capture"スロット(リクエスト用またはレスポンス用)に格納されるため、キャプチャしたHTTPヘッダーの隣に表示される場合があります。その後、自動的にログへ出力されます。また、サンプル取得メソッドで抽出して、ヘッダーなどへ渡すこともできます。このサイズの領域が各キャプチャに対してストリームの存続期間全体にわたって割り当てられるため、長さを制限することを推奨します。長さを指定できるのは"http-request"ルールだけであることに注意してください。このスロットが存在するのは、宣言したセクション内だけです。このルールを、別のフロントエンドのバックエンドとしても使われる"listen"セクションに置いた場合、そのフロントエンドから来るストリームでは無視されます。 詳細は、セクション7.3
(サンプルの取得)、“capture request header”、“capture response header"を参照してください。
“len"の代わりに"id"キーワードを使用すると、アクションはキャプチャした文字列を、すでに宣言されているキャプチャスロットへ格納しようとします。バックエンドでキャプチャを実行する場合に役立ちます。スロットIDは、前の"http-request capture"ディレクティブまたは"declare capture"キーワードで宣言できます。
バックエンドでこのアクションを使用する場合、関連するフロントエンドに必要なキャプチャスロットがあることを十分に確認してください。ない場合、このルールは実行時に無視されます。HAProxyは実行時にバックエンド名を動的に解決できるため、設定の解析時には検出できません。
close
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | X | - | - | -
サーバーとの接続を直ちに閉じるために使用します。これ以降の"tcp-response content"ルールは評価されません。主な目的は、アプリケーションプロトコルが長いタイムアウトの満了を待つことを想定している場合に、やり取りを終えたクライアントとサーバーの接続を強制的に終了させることです。特定のプロトコルでサーバーのリソースを大量に消費する、アイドル接続をなくすことを目指しています。
del-acl(<file-name>) <key fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
ACLからエントリーを削除します。ACLはファイルから読み込まれていなければなりません(ダミーの空ファイルでも構いません)。更新するACLのファイル名を丸括弧内で渡します。引数は<key fmt>の1つです。これはセクション8.2.6
のカスタムログ形式の規則に従い、削除するエントリーの内容を収集します。統計ソケットの"del acl"コマンドに相当しますが、HTTPリクエストまたはレスポンスを契機に実行できます。
del-header <name> [ -m <meth> ]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
<name>で指定した名前を持つHTTPヘッダーフィールドをすべて削除します。<meth>は、ヘッダー名に適用する照合方法です。サポートされる照合方法は、“str”(完全一致)、“beg”(前方一致)、“end”(後方一致)、“sub”(部分文字列一致)、“reg”(正規表現による一致)です。省略した場合は完全一致を使用します。
del-headers-bin <expr> [ -m <meth> ]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
<expr>で指定した名前を持つHTTPヘッダーフィールドをすべて削除します。<expr>は、削除するすべてのヘッダー名をvarintでエンコードしたバイナリー文字列を返さなければなりません。エンコードの説明と例は"add-headers-bin"と"set-headers-bin"を参照してください。<meth>は照合方法で、すべてのヘッダー名に適用します。使用できる照合方法は"str”(完全一致)、“beg”(接頭辞一致)、“end”(接尾辞一致)、“sub”(部分文字列一致)です。“reg”(正規表現一致)は、実行時の性能が予測できないため、使用できません。指定しない場合、完全一致を使用します。
del-map(<map-name>) <key fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
MAPからエントリーを削除します。<map-name>は、マップとACLの名前についてセクション2.7で説明する形式に従わなければなりません。更新するMAPの名前を丸括弧内で渡します。引数は<key fmt>の1つです。これはセクション8.2.6
のカスタムログ形式の規則に従い、削除するエントリーの内容を収集します。引数は"file name"の1つです。統計ソケットの"del map"コマンドに相当しますが、HTTPリクエストまたはレスポンスを契機に実行できます。
deny [ { status | deny_status } <code> ] [ content-type <type> ]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
ルールの評価を停止し、リクエストまたはレスポンスを直ちに拒否します。デフォルトでは、リクエストにはHTTP 403エラー、レスポンスには502を返しますが、返すレスポンスは"return"アクションと同じ構文でカスタマイズできます。詳細は後述の"return"を参照してください。互換性のため、引数を指定しない場合、または"deny_status"だけを指定した場合、“default-errorfiles"引数が暗黙に指定されます。つまり、“deny [deny_status <status>]“は"deny [status <status>] default-errorfiles"の別名です。このアクションは処理を終了させるため、現在のセクションでは、同じルールセットの後続ルールを評価しません。高度な構文については"return"アクションも参照してください。
dgram-drop
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | - | - | - | - | - | - | -
QUIC initialパケットの受信を通知せずに無視します。無視しなければ、新しいQUIC接続のインスタンスが作成され、SSLハンドシェイクが実行されます。
disable-l7-retry
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
接続障害以外の理由でリクエストが失敗した場合、そのリクエストの再試行をすべて無効にします。たとえば、失敗したPOSTリクエストを再試行させないために役立ちます。
do-log [profile <log_profile>]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | X | X | X
このアクションは、プロキシでのログ出力を手動で実行します。つまり、プロキシのログオプション(“log-format"などの形式指定オプションを含む)が考慮されますが、プロキシがトランザクションの処理中に自動生成するログには干渉しません。
“log-profile"を使うと、このアクションを使用できる各コンテキストで、ログをどのように出力するかを詳細に記述できます。具体的には、‘on’キーワードの後に’quic-init’、’tcp-req-conn’、’tcp-req-sess’、’tcp-req-cont’、’tcp-res-cont’、‘http-req’、‘http-res’、‘http-after-res’のいずれかを指定します。
また、"%OG"ログ形式エイリアスを使用した場合にも、正しく報告されます。
省略可能な"profile"引数でlog-profileセクションの名前を指定すると、このdo-logアクション専用に使用できます。その場合、既定で適用される現在のロガーに関連付けられたプロファイルの代わりに使用します。
例:
do-resolve(<var>,<resolvers>[,ipv4|ipv6]) <expr>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
このアクションは、<expr>の出力に対してDNS名前解決を行い、結果を変数<var>に格納します。<resolvers>が指すDNS resolversセクションを使用します。省略可能な引数’ipv4’または’ipv6’を使うと、名前解決で優先するファミリーを選択できます。特定のファミリーの使用を厳密に強制するには、globalキーワード"dns-accept-family"も参照してください。
DNS名前解決の実行中、クライアント側の接続は一時停止し、名前解決の完了を待ちます。IPアドレスが見つかると、<var>へ格納します。何らかのエラーが発生した場合、<var>は設定しません。このアクションを使用すると、リクエスト内の情報(Hostヘッダーなど)に基づいて、実行時にサーバーのIPアドレスを調べることができます。このアクションでサーバーのIPアドレスを調べて"set-dst"アクションで使用する場合、バックエンドのサーバーIPアドレスは0.0.0.0に設定しなければなりません。do-resolveアクションのパラメーターはホストのみを受け取るため、文字列からポートを除去しなければなりません。
例:
注意:HAProxyがネットワークのスキャンに使われたり、さらに悪い場合には自分自身へのループを起こしたりしないように、“protection"ルールを忘れずに設定してください。
early-hint <name> <fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
ほかのどのレスポンスよりも先に、HTTP 103 Early Hintsレスポンスを作成します。このレスポンスに、<name>で指定した名前と、カスタムログ形式の規則に従う<fmt>で定義した値を持つHTTPヘッダーフィールドを追加します(セクション8.2.6
のカスタムログ形式を参照)。HTMLドキュメントの描画に必要なリソースを事前に読み込むため、Linkヘッダーをクライアントへ渡す場合に特に役立ちます。
詳細はRFC 8297を参照してください。
expect-netscaler-cip layer4
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | - | - | - | - | - | -
クライアント側の接続で、ソケットから1バイトも読み取る前にNetScaler Client IP insertionプロトコルのヘッダーを受信するよう設定します。“bind"行に"accept-netscaler-cip"キーワードを指定するのと同等ですが、TCPルールを使用すると、ACLで指定した特定のIPアドレス範囲についてだけPROXYプロトコルを受け入れられます。公開ホストからのトラフィックが複数のロードバランサーの層を通る場合に便利です。
expect-proxy layer4
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | - | - | - | - | - | -
クライアント側の接続を、ソケットから一バイトでも読み取る前にPROXYプロトコルのヘッダーを受信するよう設定します。“bind"行に"accept-proxy"キーワードを指定するのと同じですが、TCPルールを使う場合は、ACLによって特定のIPアドレス範囲からだけPROXYプロトコルを受け入れることができます。公開ホストからのトラフィックが、複数段のロードバランサーを通過する場合に便利です。
normalize-uri <normalizer>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
リクエストのURIを正規化します。
HAProxy 2.4のURI正規化は、現在、実験的な技術プレビューとして利用できます。そのため、呼び出せるようにするには、先にglobalディレクティブ’expose-experimental-directives’を指定する必要があります。問題を修正するために正規化処理の動作が変更され、その結果、利用環境でリクエストを正しく処理できなくなる可能性があることを想定しておくべきです。
各ノーマライザーは1種類の正規化だけを処理するため、対応するバックエンドに適した正規化の程度を細かく選択できます。
たとえば、“path-strip-dotdot"ノーマライザーは、要求されたURIをローカルファイルシステム内のパスへ直接対応付ける静的ファイルサーバーで役立つ場合があります。ただし、パス内のセグメント数が特定の数であることを前提とするAPIでは、ルーティングを壊す可能性があります。
一部の正規化処理は、壊れたURIに対して安全でない変換を行う可能性があることに注意が必要です。また、それぞれは安全な正規化処理でも、組み合わせ方が不適切だと、安全でない変換になる可能性があります。
たとえば、壊れたURIにエスケープされていないパーセント記号が含まれていると、“percent-decode-unreserved"正規化処理が予期しない結果を返すことがあります。そのようなURIの例が”/%%36%36"です。これは”/%66"にデコードされ、さらに”/f"と同等になります。“strict"オプションを指定すれば、このような壊れたURIへのリクエストを安全に拒否できます。
次の正規化処理を使用できます。
-
fragment-encode:”#“を”%23"にエンコードします。
不具合のあるクライアントがパス部分の’#‘を正しくエンコードしないことが分かっている場合を除き、“fragment-strip"ノーマライザーを優先することを推奨します。
例:
- /#foo -> /%23foo
-
fragment-strip:URIの"fragment"コンポーネントを削除します。
RFC 3986#3.5では、URIの"fragment"部分を送信すべきではなく、リソースの取得後にユーザーエージェントが処理すべきとされています。
フラグメントがリクエストのパスの一部と解釈されないように、この正規化処理を最初に適用することを推奨します。
例:
- /#foo -> /
-
path-strip-dot:“path"コンポーネント内の”/./“セグメントを削除します(RFC 3986#6.2.2.3)。
パーセントエンコードされたドット("%2E”)を含むセグメントは検出しません。それが望ましくない場合は、先に"percent-decode-unreserved"正規化処理を使用してください。
例:
- /. -> /
- /./bar/ -> /bar/
- /a/./a -> /a/a
- /.well-known/ -> /.well-known/(変更なし)
-
path-strip-dotdot:“path"部分の”/../“セグメントを正規化します(RFC 3986#6.2.2.3)。
親ディレクトリへのアクセスを試みるセグメントを、その直前のセグメントと統合します。
空のセグメントは特別扱いしません。それが望ましくない場合は、先に"merge-slashes"正規化処理を使用してください。
パーセントエンコードされたドット("%2E”)を含むセグメントは検出しません。それが望ましくない場合は、先に"percent-decode-unreserved"正規化処理を使用してください。
例:
- /foo/../ -> /
- /foo/../bar/ -> /bar/
- /foo/bar/../ -> /foo/
- /../bar/ -> /../bar/
- /bar/../../ -> /../
- /foo//../ -> /foo/
- /foo/%2E%2E/ -> /foo/%2E%2E/
“full"オプションを指定すると、先頭の”../“も削除されます。
例:
- /../bar/ -> /bar/
- /bar/../../ -> /
-
path-merge-slashes:“path"部分で隣り合うスラッシュを単一のスラッシュにまとめます。
例:
- // -> /
- /foo//bar -> /foo/bar
-
percent-decode-unreserved:パーセントエンコードされた非予約文字を、通常の文字表現にデコードします(RFC 3986#6.2.2.2)。
非予約文字には、すべての英字、すべての数字、”-"、”."、”_"、"~“が含まれます。
例:
- /%61dmin -> /admin
- /foo%3Fbar=baz -> /foo%3Fbar=baz(変更なし)
- /%%36%36 -> /%66(安全ではありません)
- /%ZZ -> /%ZZ
“strict"オプションを指定した場合は、無効な並びがあるとHTTP 400 Bad Requestを返します。
例:
- /%%36%36 -> HTTP 400
- /%ZZ -> HTTP 400
-
percent-to-uppercase:パーセントエンコードされた並びの英字を大文字にします(RFC 3986#6.2.2.1)。
例:
- /%6f -> /%6F
- /%zz -> /%zz
“strict"オプションを指定した場合は、無効な並びがあるとHTTP 400 Bad Requestを返します。
例:
- /%zz -> HTTP 400
-
query-sort-by-name: クエリー文字列のパラメーターを名前順に並べ替えます。パラメーターは’&‘で区切られていると想定します。短い名前が長い名前より先になり、同じ名前のパラメーターは相対的な順序を保ちます。
例:
- /?c=3&a=1&b=2 -> /?a=1&b=2&c=3
- /?aaa=3&a=1&aa=2 -> /?a=1&aa=2&aaa=3
- /?a=3&b=4&a=1&b=5&a=2 -> /?a=3&a=1&a=2&b=4&b=5
pause { <timeout> | <expr> }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
指定したミリ秒数だけメッセージの解析を一時停止します。タイムアウトはミリ秒で指定できます。また、このドキュメントの冒頭で説明したように、数値の後ろに単位を付ければほかの単位も使用できます。式を記述することもできます。この式は、ミリ秒単位のタイムアウトとして解釈される数値を返さなければなりません。式の評価に失敗した場合や、不正な値を返した場合、アクションを無視し、評価を続行します。
このアクションはデバッグに使えますが、特定の条件に基づいて一部のクライアントを遅くするためにも使えます。たとえば、“track-sc"ルールで追跡し、リクエストレートが高すぎるクライアントに遅延を加えることができます。
redirect <rule>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
リダイレクトルールに基づいてHTTPリダイレクトを実行します。“redirect"文とまったく同じですが、ほかの"http-request"ルールまたは"http-response"ルールの途中で処理されるリダイレクトルールを挿入し、これらのルールではカスタムログ形式を使用する点が異なります。レスポンスで許可されるリダイレクトは"location"タイプだけです。さらに、レスポンス中にリダイレクトを実行すると、サーバーからHAProxyへの転送を中断するため、ペイロードはクライアントへ転送されません。HTTP/1では、これにより一部の接続が閉じられる場合があります。このアクションは処理を終了させるため、現在のセクションでは、同じルールセットの後続ルールを評価しません。ルールの構文は"redirect"キーワードを参照してください。
reject
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | X | - | -
ルールの評価を停止し、レスポンスを一切送信せずに接続を直ちに閉じます。HTTPルールでは、“tcp-request content reject"ルールと同様に動作します。HTTP/2接続を強制的に直ちに閉じる場合に役立ちます。
“tcp-request connection"ルールで拒否した接続は、セッションになることもないため、統計では"denied connections"として別に集計します。セッションのレート制限の対象にはならず、ログにも記録しません。これらのルールは、大規模なDDoS攻撃中などに見られる、極端に高い接続レートをフィルタリングするためだけに使用すべきだからです。このような極端な状況では、各イベントをログに記録するだけでもシステムが破綻し、フィルタリング能力が大幅に低下します。どうしてもログを記録したい場合は、“tcp-request session"ルールもログを記録しないため、代わりに"tcp-request content"ルールを使用することを推奨します。
“tcp-response content"ルールで使用すると、サーバー接続を閉じ、レスポンスを中止します。一般に、機密情報の漏洩を防ぐために使用します。通常は、“wait-for-body"アクションと組み合わせて内容を検査した後に使用します。
このアクションは"quic-initial"ルールでも使用できます。新しく開いたQUIC接続を、SSLハンドシェイクを一切処理せずに直ちに閉じ、CONNECTION_REFUSEDエラーコードでクライアントに通知します。
replace-header <name> <match-regex> <replace-fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
ヘッダーフィールド<name>のすべての出現箇所について、その値を<match-regex>と照合します。照合では大文字と小文字を区別します。一致した値は、全体を<replace-fmt>に置き換えます。<replace-fmt>では書式指定文字を使用でき、“http-request add-header"の<fmt>引数と同様に動作します。バックスラッシュ(’\’)の後に数値を続ける、標準的な後方参照もサポートされます。
このアクションは、含まれる値の数に関係なく、ヘッダー行全体を対象にします。そのため、If-Modified-SinceやSet-Cookieのように、値にカンマを含むことが自然なヘッダーの処理に適しています。AcceptやCache-Controlのように、カンマで区切った値の一覧を含むヘッダーは、代わりに"replace-value"アクションで処理するべきです。“replace-value"アクションも参照してください。
例:
例:
replace-path <match-regex> <replace-fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
“replace-header"と同様に動作しますが、ヘッダーの代わりにリクエストのパス部分を対象にします。パス部分は、省略可能なスキームとオーソリティーの後に最初に現れる’/‘から始まり、疑問符の直前で終わります。そのため、この置換でスキーム、オーソリティー、クエリー文字列が変わることはありません。
正規表現の評価は、一部のACLより高コストになる場合があります。そのため、置換がまれにしか起きない場合は、条件に一致しなければ評価そのものを行わずに済むよう、条件を付けると有利なことがあります。
例:
replace-pathq <match-regex> <replace-fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
“http-request replace-path"と同じ動作ですが、クエリー文字列がある場合はパスにそれを含む点が異なります。したがって、パスとクエリー文字列の両方を置き換えます。
例:
replace-uri <match-regex> <replace-fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
“replace-header"と同様に動作しますが、ヘッダーの代わりにリクエストのURI部分を対象にします。URI部分には、スキーム、オーソリティー、クエリー文字列が含まれる場合があります。それらも照合対象の値の一部として扱います。
正規表現の評価は、一部のACLより高コストになる場合があります。そのため、置換がまれにしか起きない場合は、条件に一致しなければ評価そのものを行わずに済むよう、条件を付けると有利なことがあります。
重要な注意:HTTP/1.xでは歴史的に、ブラウザーが送信するリクエストの大半は"origin form"を使用します。これはURI部分にスキームもauthorityも含まない点で"absolute form"と異なります。主に、プロキシへ送信するリクエスト、手動で作成したリクエスト、一部のアプリケーションが送信するリクエストだけが絶対形式を使用します。そのため、HTTP/1.xでは、”/“で始まるルールの"replace-uri"は通常、ほとんどの場合に問題なく動作します。しかしHTTP/2では、HTTP/1クライアントがプロキシとの通信に使用するものと同じ形の絶対URIだけを送信することがクライアントに推奨されています。そのため、このような部分的なreplace-uriルールは、HTTP/1では動作してもHTTP/2では失敗する場合があります。スキームとauthorityにも任意で一致できるようにルールを変更するか、replace-pathを使用する必要があります。
例:
replace-value <name> <match-regex> <replace-fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
“replace-header"と同様に動作しますが、ヘッダー全体ではなく、ヘッダーフィールド<name>のカンマで区切られた各値に対して正規表現を照合します。複数の値を持つことが許されるすべてのヘッダーに適しています。たとえば、リクエストのAcceptヘッダーや、リクエストまたはレスポンスのCache-Controlが該当します。
例:
例:
return [ status <code> ] [ content-type <type> ]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
ルールの評価を停止し、レスポンスを直ちに返します。レスポンスに使用するステータスコードは、デフォルトでは200です。“status"の引数として任意で指定できます。レスポンスのcontent-typeも、“content-type"の引数として指定できます。最後に、レスポンス自体を定義できます。使用するerrorfileを指定した完全なHTTPレスポンスでも、使用するファイルまたは文字列を指定したレスポンスペイロードでも構いません。レスポンスは、次の規則に従って作成します。
-
使用するerrorfileもペイロードも定義されていない場合は、ダミーのレスポンスを返します。考慮されるのは"status"引数だけで、[200, 599]の範囲内の任意のコードを指定できます。“content-type"引数は、指定されていても無視されます。
-
“default-errorfiles"引数が指定されている場合は、プロキシのerrorfilesを使用します。“status"引数が定義されている場合、その値はHAProxyが扱うステータスコード(200、400、403、404、405、408、410、413、414、425、429、431、500、501、502、503、504)のいずれかでなければなりません。“content-type"引数は、指定されていても無視されます。
-
“errorfile"引数で特定のerrorfileが定義されている場合は、完全なHTTPレスポンスを含むそのファイルを返します。考慮されるのは"status"引数だけで、その値はHAProxyが扱うステータスコード(200、400、403、404、405、408、410、413、414、425、429、431、500、501、502、503、504)のいずれかでなければなりません。“content-type"引数は、指定されていても無視されます。
-
“errorfiles"引数でhttp-errorsセクションが指定されている場合は、そのセクション内の対応するファイルを返します。このファイルには完全なHTTPレスポンスが含まれます。考慮されるのは"status"引数だけで、その値はHAProxyが扱うステータスコード(200、400、403、404、405、408、410、413、414、425、429、431、500、501、502、503、504)のいずれかでなければなりません。“content-type"引数は、指定されていても無視されます。
-
“file"または"lf-file"引数を指定すると、ファイルの内容をレスポンスペイロードとして使用します。 ファイルが空でない場合、そのcontent-typeを"content-type"の引数として設定しなければなりません。 空の場合、“content-type"引数は無視します。“lf-file"引数では、ファイルの内容をカスタムログ形式として評価します (セクション8.2.6 を参照)。“file"引数では、生の内容として扱います。
-
“string"または"lf-string"引数が指定されている場合は、定義した文字列をレスポンスのペイロードとして使用します。コンテンツタイプは、必ず"content-type"の引数として設定しなければなりません。“lf-string"引数では、文字列をカスタムログ形式として評価します(8.2.6節 を参照)。“string"引数では、そのままの文字列として扱います。
レスポンスがerrorfileに基づいていない場合、“hdr"引数を使ってHTTPヘッダーフィールドを追加できます。それ以外の場合は、すべての"hdr"引数を無視します。各引数のヘッダー名は<name>で指定し、値は<fmt>で定義します。この書式は、8.2.6節
に記載されたカスタムログ形式の規則に従います。
生成されるレスポンスは、バッファーより小さくなければなりません。また、errorfileまたはrawファイルを読み込む際に警告を出さないようにするには、ヘッダー書き換え用に予約されたバッファー領域も空けておくべきです。
このアクションで処理を確定します。つまり、現在のセクションでは、同じルールセットの後続ルールを評価しません。
例:
sc-add-gpc(<idx>,<sc-id>) { <int> | <expr> }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
このアクションは、<sc-id>で指定したスティッキーカウンターに関連付けられた配列の、インデックス<idx>にある汎用カウンターを、整数<int>の値または式<expr>の整数評価結果だけ増やします。整数と式の値は、符号なし32ビット値に制限されます。エラーが発生すると、このアクションは通知せずに失敗し、アクションの評価を続行します。<idx>は0から99まで、<sc-id>は0から2までの整数です。このインデックスにGPCが格納されていない場合も、通知せずに失敗します。値がゼロでも、テーブル内のエントリーをリフレッシュします。‘gpc_rate’は、gpc値の平均増加率を反映するよう自動的に調整されます。
このアクションは、配列のdata_typesである’gpc’と’gpc_rate’にのみ適用されます。従来の’gpc0’、‘gpc1’、‘gpc0_rate’、‘gpc1_rate’には適用されません。従来のデータ型に対応する同等の機能はありませんが、値が常に1であれば、‘sc-inc-gpc()’、‘sc-inc-gpc0()’、‘sc-inc-gpc1()‘を参照してください。値を減らす方法もありませんが、代わりに’sc-set-gpt()‘を使って、汎用タグに正確な値を保存できます。
このアクションの主な用途は、スコアや総量を集計することです(サーバーまたはWAFが報告する送信元IPごとの推定危険度、アップロードした総バイト数など)。
sc-inc-gpc(<idx>,<sc-id>)
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
このアクションは、<sc-id>で指定したスティッキーカウンターに関連付けられた配列の、インデックス<idx>にある汎用カウンターを増やします。エラーが発生すると、このアクションは通知せずに失敗し、アクションの評価を続行します。<idx>は0から99まで、<sc-id>は0から2までの整数です。このインデックスにGPCが格納されていない場合も、通知せずに失敗します。このアクションは、配列の’gpc’および’gpc_rate’というdata_typesだけに適用されます(従来の’gpc0’、‘gpc1’、‘gpc0_rate’、‘gpc1_rate’というdata_typesには適用されません)。
sc-inc-gpc0(<sc-id>)
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
このアクションは、<sc-id>で指定したスティッキーカウンターに対応するGPC0またはGPC1カウンターを増加させます。エラーが発生した場合は通知せずに失敗し、アクションの評価は続行されます。
sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
このアクションは、<sc-id>で指定したスティッキーカウンターに関連付けられた配列の、インデックス<idx>にある32ビット符号なしGPTを、<int>/<expr>の値に設定します。期待される結果は真偽値です。
エラーが発生した場合、このアクションは通知せずに失敗し、アクションの評価は続行されます。<idx>は0から99の整数、<sc-id>は0から2の整数です。そのインデックスにGPTが格納されていない場合も、通知せずに失敗します。
このアクションは’gpt’配列のdata_typeにのみ適用され、従来の’gpt0’ data-typeには適用されません。
sc-set-gpt0(<sc-id>) { <int> | <expr> }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
このアクションは、<sc-id>で指定したスティッキーカウンターと<int>/<expr>の値に従って、32ビット符号なしGPT0タグを設定します。期待される結果は真偽値です。エラーが発生した場合、このアクションは通知せずに失敗し、アクションの評価は続行されます。このアクションは"sc-set-gpt(0,<sc-id>)“の別名です。“sc-set-gpt"アクションも参照してください。
send-retry
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | - | - | - | - | - | - | -
このアクションは、トークンを持たないクライアントのInitialパケットに対して、Retryパケットの送信を強制します。接続を構成する要素を生成してハンドシェイクを開始する前に、クライアントアドレスを確実に検証するために役立ちます。
send-spoe-group <engine-name> <group-name>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -
このアクションは、SPOEメッセージのグループの送信を開始するために使用します。そのためには、メッセージの送信に使うSPOEエンジンと、送信するSPOEグループを定義しなければなりません。当然ながら、SPOEエンジンは既存のSPOEフィルターを参照する必要があります。SPOEフィルター行でエンジン名が指定されていない場合は、SPOEエージェント名を使用しなければなりません。
引数:
set-bandwidth-limit <name> [limit {<expr> | <size>}] [period {<expr> | <time>}]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -
このアクションは、帯域幅制限フィルター<name>を有効にします。フィルターの種類に応じて、アップロード方向またはダウンロード方向に適用されます。<name>がストリーム単位の帯域幅制限フィルターを参照する場合に限り、独自の上限と期間を定義できます。set-bandwidth-limitルールを実行すると、まずフィルターのすべての設定をデフォルト値に戻してから有効にします。そのため、同じフィルターに対して複数の"set-bandwidth-limit"アクションを実行した場合、最後のアクションだけが考慮されます。同じストリームで複数の帯域幅制限フィルターを有効にできます。
帯域制限フィルターはdefaultsセクションで定義できないため、このアクションもdefaultsセクションでは使用できません。また、制限されるのはHTTPペイロードの転送だけで、HTTPヘッダーは対象に含みません。
引数:
例:
帯域制限フィルターの設定については、セクション9.7 を参照してください。
set-bc-mark { <mark> | <expr> }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
対応するプラットフォームで、バックエンド接続(サーバーへ送信するすべてのパケット)のNetfilter/IPFW MARKを、<mark>または<expr>で渡した値に設定します。この値は符号なし32ビット値で、netfilter/ipfw、ルーティングテーブル、またはDTraceによるパケット監視で照合できます。<mark>は10進形式でも16進形式(“0x"接頭辞付き)でも指定できます。代わりに<expr>も使用できます。これはサンプル取得とその後に続くコンバーターで構成される標準のHAProxy式で、整数型に解決されなければなりません。このアクションは、特定のパケットに異なる経路を強制する場合に役立ちます(大量のダウンロードに、より安価なネットワーク経路を使用する場合など)。Linuxカーネル2.6.32以降で動作し、管理者権限が必要です。FreeBSDとOpenBSDでも動作します。マークは、バックエンド/サーバー接続の存続期間全体(接続からクローズまで)にわたって設定されます。
set-bc-tos { <tos> | <expr> }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
対応するプラットフォームで、バックエンド接続(サーバーへ送信するすべてのパケット)のTOSまたはDSCPフィールドを、<tos>または<expr>で渡した値に設定します。この値は、IP TOSフィールドの8ビット全体を表します。DSCPまたはTOSで使用するのは上位6ビットだけで、下位2ビットは常に0であることに注意してください。代わりに<expr>も使用できます。これはサンプル取得とその後に続くコンバーターで構成される標準のHAProxy式で、整数型に解決されなければなりません。このアクションは、リクエスト内の情報に基づいて、内部ルーターのルーティング動作を調整するために使用できます。tosは、バックエンド/サーバー接続の存続期間全体(接続からクローズまで)にわたって設定されます。
詳細はRFC 2474、2597、3260、4594を参照してください。
set-dst <expr>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
宛先IPアドレスを、指定した式の値に設定するために使用します。HAProxyの前段のプロキシが宛先IPを書き換えるものの、正しいIPをHTTPヘッダーで渡す場合や、プライバシーのためにIPをマスクしたい場合に便利です。新しいアドレスとポートに接続するには、バックエンドのサーバーアドレスとして'0.0.0.0:0’を使用してください。
引数:
例:
set-dstは、アドレスファミリーが許す限り、可能であれば元の宛先ポートを保持します。それ以外の場合、宛先ポートは0になります。
set-dst-port <expr>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
宛先ポートを、指定した式の値に設定するために使用します。新しいアドレスとポートに接続するには、バックエンドのサーバーアドレスとして'0.0.0.0:0’を使用してください。
引数:
例:
set-dst-portは、アドレスファミリーがポートをサポートする限り、可能であれば元の宛先アドレスを保持します。そうでなければ、ポートを書き換える前に、宛先アドレスをIPv4の"0.0.0.0"に強制的に設定します。
set-fc-mark { <mark> | <expr> }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -
対応するプラットフォームで、クライアントへ送信するすべてのパケットのNetfilter/IPFW MARKを、<mark>または<expr>で渡した値に設定します。この値は符号なし32ビット値で、netfilter/ipfw、ルーティングテーブル、またはDTraceによるパケット監視で照合できます。<mark>は10進形式でも16進形式(“0x"接頭辞付き)でも指定できます。代わりに<expr>も使用できます。これはサンプル取得とその後に続くコンバーターで構成される標準のHAProxy式で、整数型に解決されなければなりません。このアクションは、特定のパケットに異なる経路を強制する場合に役立ちます(大量のダウンロードに、より安価なネットワーク経路を使用する場合など)。Linuxカーネル2.6.32以降で動作し、管理者権限が必要です。FreeBSDとOpenBSDでも動作します。
set-fc-tos { <tos | <expr> }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -
対応するプラットフォームで、クライアントへ送信するパケットのTOSまたはDSCPフィールドを、<tos>または<expr>で渡した値に設定します。この値は、IP TOSフィールドの8ビット全体を表します。DSCPまたはTOSで使用するのは上位6ビットだけで、下位2ビットは常に0であることに注意してください。代わりに<expr>も使用できます。これはサンプル取得とその後に続くコンバーターで構成される標準のHAProxy式で、整数型に解決されなければなりません。このアクションは、リクエスト内の情報に基づいて、境界ルーターのルーティング動作を調整するために使用できます。
詳細はRFC 2474、2597、3260、4594を参照してください。
set-header <name> <fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
“add-header"アクションと同じですが、ヘッダーがすでに存在する場合は、先に削除します。外部のユーザーにヘッダーを操作させてはならないセキュリティ情報をサーバーに渡す場合や、外部情報を隠すために"Server"などの特定のレスポンスヘッダーを強制的に設定する場合に便利です。新しい値は削除前に計算されるため、既存のヘッダーに値を連結することもできます。
例:
set-headers-bin <expr> [ prefix <str> ]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
“set-header"アクションの変種で、ヘッダーの名前と値をvarintでエンコードしたバイナリー文字列として渡します。varint形式については、“req.hdrs_bin"サンプル取得を参照してください。ヘッダー名を事前に知らなくても、複数のヘッダーを一度に設定したい場合に役立ちます。これらのヘッダーはHTTPパーサーで検証されていないため、不正なメッセージを送信する原因となる可能性があり、最悪の場合はリクエストスマグリング攻撃につながる可能性があります。挿入するヘッダー数も重要です。tune.http.maxhdrによって制限されるためです。オプションのprefixを指定すると、エンコードされた文字列のうち、<str>で始まるヘッダーだけを設定します。
例:
set-log-level <level>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | X
特定の条件を満たしたときに、現在のリクエストのログレベルを変更するために使用します。有効なレベルは、syslogの8レベル(“log"キーワードを参照)と、そのリクエストのログ出力を無効にする特別なレベル"silent"です。このルールは評価を終了しないため、最後に一致したルールが優先されます。ほかの機器から来るヘルスチェックのログ出力を無効にするのに役立ちます。
set-map(<map-name>) <key fmt> <value fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
マップに新しいエントリーを追加します。<map-name>は、マップとACLの名前についてセクション2.7で説明する形式に従わなければなりません。更新するMAPの名前を丸括弧内で渡します。引数は2つです。<key fmt>はセクション8.2.6
で説明するカスタムログ形式の規則に従い、マップのキーを収集します。<value fmt>もカスタムログ形式の規則に従い、新しいエントリーの内容を収集します。値の重複を避けるため、挿入前にマップを検索します。統計ソケットの"set map"コマンドに相当しますが、HTTPリクエストを契機に実行できます。
set-mark <mark> (deprecated)
これは"set-fc-mark"のエイリアスです(代わりにこちらを使用することを推奨します)。
set-method <fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
リクエストメソッドを、書式文字列<fmt>の評価結果で書き換えます。何かを直すより壊す可能性のほうが高いため、これが必要となる妥当な理由はごく少ないはずです。
set-nice <nice>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -
処理中の現在のリクエスト/レスポンスの"nice"値を設定します。同時に処理しているほかのリクエストとの関係にだけ影響します。デフォルト値は0ですが、“bind"行の"nice"設定で変更できます。指定できる範囲は-1024..1024です。値が大きいほど、そのリクエストはほかのリクエストに処理を譲ります。値が小さいほど、ほかのリクエストより優先されます。一部のリクエストの処理を高速化したり、重要でないリクエストの優先度を下げたりする場合に役立ちます。事前に試さずにこの設定を使用すると、大幅な速度低下が発生する可能性があります。
set-path <fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
リクエストのパスを、書式文字列`<fmt>`の評価結果で書き換えます。クエリー文字列があれば、そのまま保持します。パスの前にスキームとオーソリティーがあれば、それらも保持します。リクエストにパスがない場合("*")は、それを書式の評価結果で置き換えます。たとえば、パスの前にディレクトリ要素を追加するために使用できます。"http-request set-query"と"http-request set-uri"も参照してください。
例:
set-pathq <fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
“http-request set-path"と同じですが、クエリー文字列も書き換えます。疑問符を含めてクエリー文字列を削除するために使用できます(“http-request set-query"ではできません)。
set-priority-class <expr>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
現在のリクエストのキュー優先度クラスを設定するために使用します。値には、-2047..2047の範囲の整数に変換されるサンプル式を指定しなければなりません。この範囲を超える結果は切り詰められます。優先度クラスは、キュー内のリクエストを処理する順序を決定します。値が小さいほど優先度が高くなります。
set-priority-offset <expr>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
現在のリクエストの、キュー優先度タイムスタンプのオフセットを設定します。値は、-524287..524287の範囲の整数に変換されるサンプル式でなければなりません。この範囲外の結果は切り詰められます。リクエストをキューに入れると、まず優先度クラスで順序を決め、次に指定したミリ秒単位のオフセットで調整した現在のタイムスタンプで順序を決めます。値が小さいほど優先度が高くなります。結果のタイムスタンプは、524,287ms(8m44s287ms)の範囲を扱える精度でしか追跡しないことに注意してください。リクエストが長時間キュー内で待機し、調整後のタイムスタンプがこの値を超えると、最優先と誤認されます。そのため、オフセットと組み合わせたときにこの上限を超えない値へ"timeout queue"を設定することが重要です。
set-query <fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
最初の疑問符(”?")の後にあるリクエストのクエリー文字列を、形式文字列<fmt>の評価結果で書き換えます。疑問符より前の部分は変更しません。リクエストに疑問符がなく、新しい値が空でない場合、URIの末尾に疑問符を追加し、その後に新しい値を追加します。疑問符がすでにある場合、値が空でも疑問符は決して削除しません。クエリー文字列のパラメーターを追加または削除するために使用できます。
参照:“http-request set-query”、“http-request set-uri”。
例:
set-retries <int> | <epxr>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
このアクションは、現在のストリームに限って、指定済みの"retries"値を上書きします。[0, 100]の範囲の整数値、または式を指定できます。式は[0, 100]の範囲の整数を返さなければなりません。
このアクションはバックエンド側でだけ意味を持つため、このルールを使用できるのはバックエンド機能を持つプロキシだけです。“defaults"セクションでも使用できません。リスナーでこのアクションを使用すると、フロントエンドのコンテキストで評価します。そのため、retriesの値を維持するのは、たとえばuse-backendルールなどによってストリームが別のバックエンドへ振り分けられない場合だけです。振り分けられる場合は、選択したバックエンドのデフォルトのretries値を設定します。
例:
set-src <expr>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
送信元IPアドレスを、指定した式の値に設定するために使用します。HAProxyの前段のプロキシが送信元IPを書き換えるものの、正しいIPをHTTPヘッダーで渡す場合や、プライバシーのために送信元IPをマスクしたい場合に便利です。それ以降の"src"取得処理の呼び出しは、すべてこの値を返します(例を参照)。
引数:
参照:“option forwardfor”。
例:
set-srcは、アドレスファミリーが許す限り、可能であれば元の送信元ポートを保持します。それ以外の場合、送信元ポートは0になります。
set-src-port <expr>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
指定した式の値を送信元ポートアドレスに設定するために使用します。
引数:
例:
set-src-portは、アドレスファミリーがポートをサポートする限り、可能であれば元の送信元アドレスを保持します。そうでなければ、ポートを書き換える前に、送信元アドレスをIPv4の"0.0.0.0"に強制的に設定します。
set-status <status> [reason <str>]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | - | X | X
レスポンスのステータスコードを<status>に置き換えます。この値は100から999の整数でなければなりません。省略可能な<str>で独自の理由句を指定できます。指定しない場合は、そのコードの既定の理由句を使用します。理由句が存在するのはHTTP/1.xだけで、ほかのバージョンのプロトコルでは無視されます。
例:
set-timeout { client | connect | queue | server | tarpit | tunnel } { <timeout> | <expr> }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
このアクションは、指定した"client”、“connect”、“queue”、“server”、“tarpit”、“tunnel"のタイムアウトを、現在のストリームについてだけ上書きします。1つのタイムアウトを変更しても、ほかのタイムアウトには影響しません。設定の解析時に相互に継承される場合も同じです(最後の例を参照)。タイムアウトはミリ秒で指定できます。また、このドキュメントの冒頭で説明したように、数値の後ろに単位を付ければほかの単位も使用できます。式を記述することもできます。この式は、ミリ秒単位のタイムアウトとして解釈される数値を返さなければなりません。
connect、queue、server、tunnelのタイムアウトはバックエンド側でだけ意味を持つため、このルールを使用できるのはバックエンド機能を持つプロキシだけです。同様に、clientタイムアウトはフロントエンド側でだけ意味を持ちます。Tarpitタイムアウトは両側で使用できます。期待する結果を得るには、タイムアウト値はゼロであってはなりません。リスナーでこのアクションを使用すると、フロントエンドのコンテキストで評価します。そのため、バックエンド側のタイムアウトの独自の値を維持するのは、たとえばuse-backendルールなどによってストリームが別のバックエンドへ振り分けられない場合だけです。振り分けられる場合は、選択したバックエンドのデフォルト値を設定します。
例:
例:
例:
set-tos <tos> (deprecated)
これは"set-fc-tos"のエイリアスです(代わりにこちらを使用することを推奨します)。
set-uri <fmt>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
リクエストURIを、形式文字列<fmt>の評価結果で書き換えます。スキーム、authority、パス、クエリー文字列をすべて一度に置き換えます。プロキシの手前でホストを書き換えたり、パスとクエリー文字列の間で一部を移動するなど、URIに複雑な変更を行ったりするために使用できます。絶対URIを設定すると、HTTP/1.1サーバーへそのまま送信します。それが意図した動作でない場合、ホスト、パス、クエリー文字列のいずれか、または複数を個別に設定することを推奨します。“http-request set-path"と"http-request set-query"も参照してください。
set-var(<var-name>[,<cond>...]) <expr>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
変数の内容を設定するために使用します。変数はインラインで宣言されます。
引数:
HTTPルールではすべてのスコープを使用できますが、“tcp-request connection"や"tcp-request session"のように内容へアクセスできないルールセットでは、“proc"と"sess"スコープだけを使用できます。
例:
silent-drop [ rst-ttl <ttl> ]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -
ルールの評価を停止し、クライアントへ通知しないようにするシステム依存の方法で、クライアント側の接続を突然消滅させます。rst-ttl引数なしで呼び出した場合は、TCP_REPAIRを使い、クライアントにFINやRSTパケットを返さずに済むよう試みます。これに失敗した場合(主に権限不足によるもの)は、TTLを1にしたRSTパケットを送る方法に切り替えます。
これにより、HAProxyには接続が存在しなくても、クライアントからは引き続き接続が確立しているように見え、リソースを節約できます。ただし、HAProxyとクライアントの間にあるステートフルな機器(ファイアウォール、プロキシ、ロードバランサー)も、セッションテーブル内に確立済みの接続を維持します。
オプションのrst-ttlは、この動作を変更します。TCP_REPAIRを使用せず、設定可能なTTLを持つRSTパケットを送信します。適切な値を設定すると、RSTパケットはローカルのインフラストラクチャーを通過して、ファイアウォールやほかのシステム内の接続を削除しますが、クライアントに到達する前に消失します。その後のクライアントからのパケットは、手前の機器ですでに破棄されるようになります。これらのローカルRSTはローカルのリソースを保護しますが、クライアントのリソースは保護しません。この操作の影響を十分に理解していない限り、使用してはなりません。
strict-mode { on | off }
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
後続のルールに対して、厳密な書き換えモードを有効または無効にします。これより前に宣言したルールには影響せず、リクエストを書き換えるルールだけに適用されます。厳密モードが有効な場合、書き換えに何らかの失敗があると内部エラーを発生させます。無効な場合、こうしたエラーは通知せずに無視します。厳密な書き換えモードの目的は、一部の書き換えを任意にする一方、リクエスト処理を続行するために必須の書き換えも指定できるようにすることです。
既定では、厳密な書き換えモードが有効です。この値は、ルールセットの評価が終わるとリセットされます。たとえば、フロントエンドでモードを変更しても、HAProxyがバックエンドのルール評価を開始すると、既定のモードに戻ります。
switch-mode http [ proto <name> ]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | - | - | -
このアクションは、接続をアップグレードします。現在対応しているのはHTTPへのアップグレードだけです。プロトコルは任意で指定できます。このアクションを使用できるのは、フロントエンド機能を持つプロキシだけです。接続のアップグレードは直ちに実行され、後続の"tcp-request content"ルールは評価しません。バックエンドのモードに依存する暗黙のアップグレードよりも、この方法を優先することを推奨します。この方法を使用すると、警告を出さずにフロントエンドへHTTPディレクティブを設定できます。これらのディレクティブは、HTTPへのアップグレードが実行された場合に条件付きで評価されます。ただし、HTTPバックエンドを選択しなければならないことに変わりはありません。HTTP接続をTCPサーバーへ振り分けることは、アップグレードしたかどうかにかかわらず、引き続き対応していません。
HTTPアップグレードの詳細は、プロキシに関するセクション4 を参照してください。
tarpit [ { status | deny_status } <code>] [content-type <type>]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
ルールの評価を停止し、“timeout tarpit"で指定した待機時間(未設定の場合は"timeout connect”)の間、応答せずにリクエストを直ちにブロックします。その時間が経過してもクライアントが接続している場合、tarpitの対象になったと気付かれないよう、レスポンスを返します。ログには"PT"フラグを記録します。tarpitルールの目的は、同時リクエスト数に制限のあるロボットを、攻撃中に遅くすることです。非常に単純なロボットに対しては大きな効果が得られる場合があり、“deny"ルールと比べてファイアウォールの負荷を大幅に減らします。しかし、“正しく"開発されたロボットに対しては、HAProxyと手前のファイアウォールに膨大な数の同時接続を処理させることになり、状況が悪化する可能性があります。デフォルトではHTTP 500エラーを返します。ただし、レスポンスは"http-request return"ルールと同じ構文でカスタマイズできます。詳細は"http-request return"を参照してください。
互換性のため、引数が定義されていない場合、または"deny_status"だけが指定されている場合は、“default-errorfiles"引数が暗黙に指定されます。つまり、“http-request tarpit [deny_status <status>]“は"http-request tarpit [status <status>] default-errorfiles"の別名です。これ以降の"http-request"ルールは評価されません。“http-request return"と"http-request silent-drop"も参照してください。
track-sc0 <key> [table <table>]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | X | -
現在のリクエストから、スティッキーカウンターの追跡を有効にします。これらのルールは評価を停止せず、デフォルトのアクションも変更しません。同じ接続で同時に追跡できるカウンター数は、グローバル設定の"tune.stick-counters"で指定します。ビルド時にMAX_SESS_STKCTRを設定している場合、その値がデフォルトになり(haproxy -vvで表示されます)、設定していない場合のデフォルトは3です。そのため、track-scの番号は0から(tune.stick-counters-1)までです。最初に実行する"track-sc0"ルールは、指定したテーブルのカウンターを1番目の組として追跡することを有効にします。最初に実行する"track-sc1"ルールは、指定したテーブルのカウンターを2番目の組として追跡することを有効にします。最初に実行する"track-sc2"ルールは、指定したテーブルのカウンターを3番目の組として追跡することを有効にします。1番目の組をフロントエンド単位のカウンターに、2番目の組をバックエンド単位のカウンターに使用することを推奨します。ただし、これは指針にすぎず、すべての組をどこでも使用できます。
引数:
“track-sc*“ルールを実行すると、テーブル内でキーを検索し、見つからない場合はそのキー用のエントリーを割り当てます。その後、セッションの存続期間全体にわたって、そのエントリーへのポインターを保持します。エントリーのカウンターは、できるだけ頻繁に、セッションのカウンターを更新するたびに更新し、セッションの終了時にも必ず更新します。カウンターを更新するのは、追跡を開始した後に発生したイベントだけです。例外として、接続カウンターとリクエストカウンターは、有用な情報を反映するよう必ず更新します。
エントリーが同時接続数のカウンターを追跡する場合、そのエントリーを追跡している間は一つの接続として数えられ、その間エントリーが期限切れになることはありません。また、カウンターを追跡すると、それを使うすべてのACLチェックに対してテーブル検索が一回だけ行われるため、単にキーを確認する場合よりも性能面で有利です。
unset-var(<var-name>)
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
変数の設定を解除します。<var-name>の詳細は、“set-var"アクションを参照してください。
例:
use-service <service-name>
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
このアクションは、使用するルールセットに応じて、設定済みのTCPサービスまたはHTTPサービスを実行し、リクエストに応答します。このルールは終端となり、同じルールセット内の後続のルールは評価されません。
サービスは、有効なレスポンスを返すことも、何も応答せずに直ちに接続を閉じることもできます。HTTPサービスで有効な応答となるには、有効なHTTPレスポンスでなければなりません。HTTPサービス用のPrometheusエクスポーターなど、組み込みのサービスに加えて、Luaで独自のTCPサービスやHTTPサービスを記述することもできます。
引数:
例:
wait-for-body time <time> [ at-least <bytes> ] [use-large-buffer]
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
次の条件のいずれかが成立するまで、リクエストまたはレスポンスの処理を遅らせます。
- リクエスト本文全体を受信した場合、処理は通常どおり進みます。
- “at-least"引数が指定され、
<bytes>がゼロでない場合に、<bytes>バイトを受信したとき。この場合、処理は通常どおり進みます。 - リクエストバッファーがいっぱいになった場合。この場合、処理は通常どおり進みます。このバッファーのサイズは"tune.bufsize"オプションで決まります。
- リクエストが
<time>ミリ秒を超えて待機した場合。この場合、HAProxyはクライアントに408 “Request Timeout"エラーを返し、リクエストの処理を停止します。ただし、ほかの条件のいずれかが先に成立した場合は、ボディ全体をまだ受信していなくても、このタイムアウトは発生しません。
通常のバッファーではメッセージのボディを格納するには小さすぎる場合、“use-large-buffer"オプションを設定して、大きなバッファーを割り当てることができます。使用するには、globalオプション"tune.bufsize.large"が定義されていなければなりません。
このアクションは、“option http-buffer-request"の代わりに使用できます。
引数:
例:
参照:“option http-buffer-request”、“tune.bufsize.large”。
wait-for-handshake
使用可能なセクション: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
SSLハンドシェイクが完了するまで、リクエストの処理を遅らせます。主に、early dataが有効だと確認できるまでその処理を遅らせるために役立ちます。
14 - 5. bindとserverのオプション
“bind”、“server”、“default-server"キーワードは、ビルドオプションやHAProxyをビルドしたシステムに応じた各種設定をサポートします。各設定は通常、単語一つと、その後に続く場合がある値で構成され、“bind"行または"server"行と同じ行に記述します。このセクションでは、これらのオプションをすべて説明します。
5.1. bindオプション
“bind"キーワードは、いくつかの設定をサポートし、すべて同じ行の引数として指定します。バインドするアドレスより後ろに記述すれば、引数の順序は問いません。すべてのパラメーターは省略可能です。単語一つのもの(真偽値)もあれば、その後ろに値が必要なものもあります。値が必要な場合は、設定名の直後に記述しなければなりません。
現在サポートされている設定は次のとおりです。
accept-netscaler-cip <magic number>
同じ行で宣言したいずれかのTCPソケットで受け入れるすべての接続に、NetScaler Client IP insertionプロトコルの使用を強制します。NetScaler Client IP insertionプロトコルで指定された受け入れた接続のレイヤー3/4のアドレスを、アドレスを使用するあらゆる箇所で使います。唯一の例外は"tcp-request connection"ルールで、実際の接続のアドレスだけを参照します。ログには、プロトコルで指定されたアドレスが記録されます。ただし、プロトコル違反がある場合には、実際のアドレスを使います。外部コンポーネントのサポートとこのキーワードを組み合わせると、常に信頼できるとは限らず、使用できない場合さえあるX-Forwarded-Forの仕組みに代わる、効率的で信頼できる方法として使用できます。このプロトコルを許可するクライアントをより細かく設定するには、“tcp-request connection expect-netscaler-cip"も参照してください。
accept-proxy
同じ行で宣言したいずれかのソケットで受け入れるすべての接続に、PROXYプロトコルの使用を強制します。PROXYプロトコルのバージョン1と2をサポートし、正しく判別します。PROXYプロトコルで指定された受け入れた接続のレイヤー3/4のアドレスを、アドレスを使用するあらゆる箇所で使います。唯一の例外は"tcp-request connection"ルールで、実際の接続のアドレスだけを参照します。ログには、プロトコルで指定されたアドレスが記録されます。ただし、プロトコル違反がある場合には、実際のアドレスを使います。外部コンポーネントのサポートとこのキーワードを組み合わせると、常に信頼できるとは限らず、使用できない場合さえあるX-Forwarded-Forの仕組みに代わる、効率的で信頼できる方法として使用できます。このプロトコルを許可するクライアントをより細かく設定するには、“tcp-request connection expect-proxy"も参照してください。
allow-0rtt
TLSv1.3を使う際、early dataの受信を許可します。セキュリティー上の理由から、デフォルトでは無効です。リプレイ攻撃に弱いため、安全に再実行できるリクエスト、つまり冪等なリクエストだけに許可することを推奨します。early dataで安全に扱えないリクエストには、“wait-for-handshake"アクションを使用できます。QUICでは、QuicTLS、OpenSSL >= 3.5.2、AWS-LCで0rttをサポートしています。TCP/TLSでは、0rttをサポートするのはOpenSSLだけで、クライアントがALPNを送る必要があります。送らない場合、ハンドシェイクが行われるまでearly dataは処理の対象になりません。
alpn <protocols>
TLSのALPN拡張を有効にし、指定したプロトコルリストを、ALPNで選択できる上位プロトコルとして通知します。リストはプロトコル名をカンマで区切ったもので、たとえば"http/1.1,http/1.0”(引用符なし)です。SSLライブラリーを、TLS拡張のサポートを有効にしてビルドしている必要があります(haproxy -vvで確認できます)。ALPN拡張は、当初使われていたNPN拡張に代わるものです。プロトコル上、HTTPSフロントエンドでHTTP/2を有効にする場合と、QUICフロントエンドでHTTP/3を有効にする場合には、ALPNが必要です。ただし、これらのフロントエンドで"npn”、“alpn”、“no-alpn"のいずれも設定していない場合、通常のHTTPSフロントエンドでは"h2,http/1.1”、QUICフロントエンドでは"h3"をデフォルトとして使います。OpenSSL 1.0.2より前のバージョンはALPNをサポートしておらず、現在では廃止されたNPN拡張だけをサポートしていました。執筆時点では、ほとんどのブラウザーがHTTP/2でALPNとNPNの両方を引き続きサポートしているため、しばらくはNPNへのフォールバックが機能する可能性があります。ただし、可能な場合は必ずALPNを使用してください。通知していないプロトコルはネゴシエーションの対象になりません。たとえば、次の設定ではHTTP/2接続だけを受け入れられます。
QUICでサポートするALPNはh3とhq-interopだけです。h3はHTTP/3用で、hq-interopはhttp/0.9およびQUIC interop runnerで使用します(https://interop.seemann.io を参照)。各"alpn"ステートメントは、前の設定を置き換えます。削除するには"no-alpn"を使用してください。
Firefox 88などの古いブラウザーには、H2上のWebSocketで問題が発生するものがありました。このような構成では、“alpn"文字列を"http/1.1"または"no-alpn"に強制してHTTP/2を明示的に無効にするか、グローバルに"h2-workaround-bogus-websocket-clients"を有効にする必要がある場合があります。
backlog <backlog>
ソケットのバックログを指定値に設定します。未指定または0の場合、代わりにフロントエンドのバックログを使用します。そのデフォルトは通常、maxconnの値です。
ca-file <cafile>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。クライアント証明書の検証に使うCA証明書を読み込むPEMファイルを指定します。複数のCAを含むディレクトリを読み込むこともできます。その場合、HAProxyはディレクトリ内のすべての”.pem”、".crt”、".cer”、".crl"ファイルの読み込みを試みます。名前がドットで始まるファイルは無視されます。
警告: serverディレクティブと同様に、cafileの代わりに”@system-ca"パラメーターを使い、システムで信頼されているCAを使用することもできます。ただし、その意味を理解していない限り使用してはなりません。この設定では、実質的にシステム上のいずれかのCAが発行したクライアント証明書をbindがすべて受け入れることになるため、極めて危険です。
ca-ignore-err [all|<errorID>,...]
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。検証時に深さ> 0で無視するerrorIDを、カンマ区切りのリストで設定します。数値のIDか、OpenSSLのドキュメントhttps://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES に記載された定数名(X509_V_ERR)を指定できます。数値は新しいバージョンのOpenSSLで変わる可能性があるため、定数名の使用を推奨します。‘all’を指定すると、すべてのエラーを無視します。エラーを無視した場合、SSLハンドシェイクは中断しません。
ca-sign-file <cafile>
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。サーバー証明書の作成と署名に使うCA証明書とCA秘密鍵の両方を含むPEMファイルを指定します。証明書の動的生成を有効にする場合は必須です。詳細は’generate-certificates’を参照してください。
ca-sign-pass <passphrase>
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。CA秘密鍵のパスフレーズです。省略可能な設定で、証明書の動的生成を有効にする場合だけ使用します。詳細は’generate-certificates’を参照してください。
ca-verify-file <cafile>
この設定は、クライアント証明書の検証に使うCA証明書を読み込むPEMファイルを指定します。ここで指定するのは、server helloメッセージで送信するCA名に含めてはならないCA証明書です。通常、“ca-file"には中間証明書を、“ca-verify-file"にはルートCAのようにチェーンの終端となる証明書を定義する必要があります。
cc <algo>
この設定はTCP_CONGESTIONを定義しているシステムでのみ使用でき、LinuxとFreeBSDで検証されています。TCP輻輳制御アルゴリズムの名前を受け取り、このリスナーが受け入れるすべての接続でそのアルゴリズムを使うよう、リスナーを設定します。代表的な名前に"reno"や"cubic"がありますが、使用できるものはOSによって異なります。システムによっては、特定のアルゴリズムを設定するために特別な権限が必要な場合があります。Linuxでは、利用可能なアルゴリズムの一覧はsysctlの"net.ipv4.tcp_available_congestion_control"で、特権なしで使用を許可されているものは"net.ipv4.tcp_allowed_congestion_control"で確認できます。追加の権限が必要なアルゴリズムを使うには、“cap_net_admin"ケーパビリティーが必要な場合があります(globalセクションの"setcap"を参照)。指定した輻輳制御アルゴリズムを設定できない場合、デフォルトのアルゴリズムをそのまま使い、問題を知らせる警告を出します。serverキーワードの"cc”(セクション5.2 )も参照してください。例:
ciphers <ciphers>
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。TLSv1.2までのSSL/TLSハンドシェイクでネゴシエーションする、暗号アルゴリズムの一覧(“cipher suite”)を記述した文字列を設定します。文字列の形式は、OpenSSLのマニュアルページ"man 1 ciphers"で定義されています。背景や推奨事項については、たとえば(https://wiki.mozilla.org/Security/Server_Side_TLS )と(https://mozilla.github.io/server-side-tls/ssl-config-generator/ )を参照してください。TLSv1.3の暗号設定については、“ciphersuites"キーワードを参照してください。
ciphersuites <ciphersuites>
この設定は、OpenSSLのサポートを組み込み、OpenSSL 1.1.1以降を使ってHAProxyをビルドした場合だけ使用できます。TLSv1.3ハンドシェイクでネゴシエーションする暗号アルゴリズムの一覧(“cipher suite”)を記述した文字列を設定します。文字列の形式は、OpenSSLのマニュアルページ"man 1 ciphers"の"ciphersuites"セクションで定義されています。TLSv1.2以前の暗号設定については、“ciphers"キーワードを参照してください。この設定はTLSv1.2の暗号スイートを受け付ける可能性もありますが、文書化されていない動作であり、動作が一貫しなかったり、不具合があったりする可能性があるため、推奨しません。OpenSSLのデフォルトのTLSv1.3暗号スイートは、“TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"です。
TLSv1.3でサポートされる暗号スイートは5つのみです。
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256
例:
client-sigalgs <sigalgs>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。ネゴシエーションする、クライアント認証に関係する署名アルゴリズムのリストを表す文字列を設定します。文字列の形式は、OpenSSLのmanページ"man 3 SSL_CTX_set1_client_sigalgs"に定義されています。具体的な用途が明らかでない場合、この設定の使用は推奨しません。
crl-file <crlfile>
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。クライアント証明書の検証に使う証明書失効リストを読み込むPEMファイルを指定します。認証局チェーンの各証明書について、証明書失効リストを用意する必要があります。
crt <cert>
この設定は、OpenSSLサポートを組み込んでビルドした場合にのみ使用できます。
HAProxyはキャッシュの仕組みを使い、ファイルを証明書ストレージに読み込むのは一度だけで、その後の各"crt"キーワードではキャッシュしたものを使用します。証明書を"crt-store"で宣言した場合、証明書ストレージはそこから内容を取得し、拡張子の検出による追加ファイルの読み込みは試みません。
必要な証明書と、それに対応する秘密鍵を含むPEMファイルを指定します。このファイルは、複数のPEMファイルを一つに連結して作成できます(例: cat cert.pem key.pem > combined.pem)。CAが中間証明書を必要とする場合は、それもこのファイルに連結できます。中間証明書は、“issuers-chain-path"ディレクティブを使ってディレクトリ内で共有することもできます。
ファイルに秘密鍵が含まれていない場合、HAProxyは同じパスの末尾に”.key"を付けたファイルから鍵の読み込みを試みます。
使用するOpenSSLがDiffie-Hellmanをサポートしている場合、このファイル内のパラメーターが読み込まれます。
PEMファイルの代わりにディレクトリ名を指定すると、そのディレクトリ内のすべてのファイルを名前のアルファベット順に読み込みます。ただし、名前の末尾が予約済みの拡張子’.key’、’.issuer’、’.ocsp’、’.sctl’であるファイルは除きます。ドットで始まるファイルも無視します。このディレクティブは複数回指定でき、複数のファイルやディレクトリから証明書を読み込めます。証明書のCNまたは代替サブジェクトのいずれかに一致する、有効なTLS Server Name Indicationフィールドを送ってきたクライアントに、その証明書を提示します。ホスト名の最初の要素をワイルドカード文字’*‘で置き換えることもできます(たとえば、*.example.orgはwww.example.org に一致しますが、www.sub.example.org には一致しません)。空のディレクトリを指定した場合、“strict-sni"キーワードを使わなければHAProxyは起動しません。
クライアントがSNIを送らない場合、SSLライブラリーがTLS拡張をサポートしていない場合、またはクライアントのSNIホスト名に一致する証明書がない場合には、最初に読み込んだ証明書を提示します。そのため、ディレクトリから証明書を読み込むときは、デフォルトの証明書を先にファイルとして読み込むか、ディレクトリ内で必ず先頭になるようにすることを強く推奨します。複数のデフォルト証明書(rsaを1つ、ecdsaを1つ)を選ぶには、3つの方法があります。
- 複数証明書のバンドルを最初の証明書として設定できます(
foobar.pem.ecdsaとfoobar.pem.rsaが存在する構成ではcrt foobar.pem)。 - または、crt-list行の各証明書に’*‘フィルターを指定します。
- ‘default-crt’キーワードを使用できます。
同じ証明書を複数回読み込んでも副作用はありません。
一部のCA(GoDaddyなど)では、証明書の取得時にサーバーの種類をドロップダウンリストから選びますが、そのリストにHAProxyが含まれていません。その場合は、中間CAが必要だとCAが判断するWebサーバーを必ず選択してください(GoDaddyではApache Tomcatを選ぶと正しいバンドルが得られますが、nginxなどほかの多くの種類では、一部のクライアントで機能しない誤ったバンドルになります)。
HAProxyは各PEMファイルについて、同じパスに”.ocsp"を付けたファイルがあるかを確認します。見つかると、TLS Certificate Status Request拡張(“OCSP stapling"とも呼ばれます)のサポートを自動的に有効にします。このファイルの内容は任意です。空でない場合、DER形式の有効なOCSP Responseを含める必要があります。OCSP Responseが有効とみなされるには、次の規則を満たす必要があります。goodの状態を示していること、PEMファイル内の証明書に対する単一のレスポンスであること、追加した時点で有効であることです。これらを満たさない場合、OCSP Responseを無視して警告を出します。OCSP Responseがどの証明書に適用されるかを特定するには、発行者の証明書が必要です。PEMファイル内に発行者の証明書が見つからなければ、PEMファイルと同じパスに”.issuer"を付けたファイルが存在する場合はそこから読み込み、存在しなければエラーになります。
HAProxyは各PEMファイルについて、同じパスの末尾に”.sctl"を付けたファイルが存在するかどうかも確認します。そのファイルが見つかった場合、Certificate Transparency(RFC6962)TLS拡張のサポートが有効になります。ファイルには、RFCに記載された有効なSigned Certificate Timestamp Listが含まれていなければなりません。ファイルは基本的な構文を確認するために解析されますが、署名の検証は行われません。
クライアントに提示する暗号スイートで、RSAやECDSAなど複数の鍵の種類をサポートしたい場合があります。これにより、EC証明書をサポートするクライアントはEC暗号を使いながら、RSAだけに対応した古いクライアントも同時にサポートできます。
これにはOpenSSL 1.1.1が必要です。証明書の種類ごとに一つのcrtエントリーを指定するか、HAProxy 1.8より前で必要だった"cert bundle"を設定することで、この動作を構成できます。“ssl-load-extra-files"を参照してください。
crt-ignore-err <errors>
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。検証時に深さ== 0で無視するerrorIDを、カンマ区切りのリストで設定します。数値のIDか、OpenSSLのドキュメントhttps://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES に記載された定数名(X509_V_ERR)を指定できます。数値は新しいバージョンのOpenSSLで変わる可能性があるため、定数名の使用を推奨します。‘all’を指定すると、すべてのエラーを無視します。エラーを無視した場合、SSLハンドシェイクは中断しません。
crt-list <file>
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。証明書ごとに任意指定のSSL設定とSNIフィルターを付けた、PEMファイルのリストを指定します。各行は次の形式です。
空行と、ハッシュ(’#’)で始まる行は無視されます。
crt-listは統計ソケット経由で動的に操作できます(管理ガイドの"add ssl crt-list”、“del ssl crt-list”、“show ssl crt-list"を参照)。
crt-listは通常、専用のファイルですが、“crt"ディレクティブで読み込んだディレクトリも、内部ではcrt-listとして表されます。フロントエンドの"ssl-f-use"ディレクティブも、そのフロントエンドに関連付けたcrt-listを宣言します。
crtfile:
sslbindconf:
snifilter:
例:
default-crt <cert>
このオプションは"crt"と同じ動作をしますが、その証明書をデフォルトの証明書としても使用する点が異なります。ECDSA用とRSA用を用意するため、複数のデフォルト証明書を追加できます。それ以上用意しても、あまり有用ではありません。
このオプションは、暗黙のデフォルト証明書を無効にしません。‘default-crt’やほかの’crt’よりも先に’crt’証明書を宣言した場合、その証明書は引き続きデフォルト証明書として使用されます。
bind行で"strict-sni"オプションを使用していない場合、デフォルト証明書を使用します。クライアントがservername拡張を使わなかった場合や、servernameが設定済みのどの証明書にも一致しない場合に、デフォルト証明書を提示します。
例:
“crt"キーワードも参照してください。
curves <curves>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。ECDHEを使用するSSL/TLSハンドシェイク中にネゴシエーションする楕円曲線アルゴリズムのリスト(“curve suite”)を表す文字列を設定します。文字列の形式は、曲線名をコロンで区切ったリストです。例: “X25519:P-256”(引用符なし)。“curves"が設定されている場合、“ecdhe"パラメーターは無視されます。
defer-accept
一部のLinuxカーネルでのみサポートする、省略可能なキーワードです。接続上に何らかのデータが到着するまで接続を受け入れず、遅くとも最初の再送後には受け入れることを指定します。クライアントが先に送信するプロトコル(HTTPなど)だけで使用することを推奨します。接続を受け入れた時点でリクエストの大半がすでに到着しているようにすることで、性能がわずかに改善する場合があります。一方、何も送信しない接続は検出できません。2.6.31までのすべてのカーネルではこのオプションが正しく動作せず、クライアントが送信するまで接続を受け入れないことに注意してください。そのため、手前のファイアウォールでは接続が確立済みに見えるのに、プロキシ側ではSYN_RECVのままに見えて、問題が起きることがあります。このオプションはTCPv4/TCPv6ソケットでのみサポートし、ほかのソケットでは無視します。
ecdhe <named curve>
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。ECDHの一時鍵の生成に使う名前付き曲線(RFC 4492)を設定します。デフォルトで使用する名前付き曲線はprime256v1です。
ech <dir> [ EXPERIMENTAL ]
<dir>内のすべてのECH鍵をbind行に適用します。ファイルの拡張子は.echでなければならず、ECH用のPEMファイル形式を使用する必要があります(https://datatracker.ietf.org/doc/draft-farrell-tls-pemesni/
)。
このキーワードは共有モードでECHを有効にし、HAProxyがTLSエンドポイントとECHエンドポイントの両方として動作します。https://datatracker.ietf.org/doc/draft-ietf-tls-esni/ を参照してください。
これは実験的な機能で、globalセクションの"expose-experimental-directives"オプションが必要です。ECHをサポートするOpenSSLのバージョン(https://github.com/openssl/openssl/tree/feature/ech )も必要で、HAProxyはUSE_ECH=1でコンパイルしなければなりません。AWS-LCのECH APIはサポートしていません。
例:
expose-fd listeners
このオプションは統計ソケットでのみ使用できます。統計ソケットから、別のHAProxyプロセスにリスナーのFDを渡せるようにします。master-workerモードでは、masterとworkerの間の内部socketpairを使ってリスナーを渡すため、この指定は不要です。管理ガイドの”-x"も参照してください。
force-sslv3
このオプションは、このリスナーから作成するSSL接続で、SSLv3だけを使用するよう強制します。接続頻度が高い場合、SSLv3は通常、TLSよりも処理コストが低くなります。グローバル設定の"ssl-default-bind-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
force-tlsv10
このオプションは、このリスナーから作成するSSL接続で、TLSv1.0だけを使用するよう強制します。グローバル設定の"ssl-default-bind-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
force-tlsv11
このオプションは、このリスナーから作成するSSL接続で、TLSv1.1だけを使用するよう強制します。グローバル設定の"ssl-default-bind-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
force-tlsv12
このオプションは、このリスナーから作成するSSL接続で、TLSv1.2だけを使用するよう強制します。グローバル設定の"ssl-default-bind-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
force-tlsv13
このオプションは、このリスナーから作成するSSL接続で、TLSv1.3だけを使用するよう強制します。グローバル設定の"ssl-default-bind-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
generate-certificates
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。SSL証明書の動的生成を有効にします。CA証明書とその秘密鍵が必要です(‘ca-sign-file’を参照)。HAProxyを透過フォワードプロキシとして設定すると、クライアントに提示する証明書のCommon Nameが一致しないため、SSLリクエストでエラーが発生します。このオプションを有効にすると、クライアントがSNIで指定したホスト名を使い、HAProxyが証明書の生成を試みます。実行するのは、SNIのホスト名に一致する証明書がない場合だけです(‘crt-list’を参照)。
証明書の生成時にエラーが起きた場合、接続ではデフォルト証明書にフォールバックします。‘strict-sni’を使用している場合はデフォルト証明書を使用せず、ハンドシェイクの失敗になります。
HAProxyをリバースプロキシとして設定した場合に、多数のバックエンドを持つ構成の導入を容易にするためにも使用できます。
SSL証明書の作成はコストの高い処理なので、生成した証明書の保存にLRUキャッシュを使用します(’tune.ssl.ssl-ctx-cache-size’を参照)。HAProxyのメモリー使用量は増えますが、同じ証明書を何度も使用する場合の遅延を減らします。
gid <gid>
UNIXソケットのグループを、指定したシステムのgidに設定します。globalセクションの"unix-bind"ステートメントでデフォルトを設定することもできます。一部のプラットフォームでは、単に無視されます。グループ名ではなくグループIDを使う点を除き、“group"設定と同じです。UNIX以外のソケットでは無視します。
group <group>
UNIXソケットのグループを、指定したシステムのグループに設定します。globalセクションの"unix-bind"ステートメントでデフォルトを設定することもできます。一部のプラットフォームでは、単に無視されます。gidではなくグループ名を使う点を除き、“gid"設定と同じです。UNIX以外のソケットでは無視します。
guid-prefix <string>
このbind行で割り当てる各リッスンソケットに、大文字と小文字を区別するグローバルで一意のIDを生成します。プレフィックスと、現在のbind行におけるリスナーの位置インデックスを、’-‘を区切り文字として連結します。形式の詳細は、プロキシキーワード"guid"の説明を参照してください。“shm-stats-file"も参照してください。
id <id>
ソケットIDを固定します。デフォルトでは自動的に割り当てますが、監視を容易にするために固定した方が便利な場合があります。値は厳密に正であり、リスナーまたはフロントエンド内で一意でなければなりません。このオプションは、単一のソケットだけを定義する場合にのみ使用できます。
idle-ping <delay>
使用可能なコンテキスト:tcp, http, log
アイドル状態のフロントエンド接続で、定期的に生存確認を行う間隔を定義します。次の確認予定時刻までに相手が応答できない場合、接続を閉じます。応答があれば、クライアントのタイムアウトを更新し、接続を維持します。http-requestとhttp-keep-aliveのタイマーは並行して動作し、idle-pingでは更新しません。
この機能には、基盤となるプロトコルの対応が必要です。現在、実装しているのはH2 muxだけです。ほかのプロトコルでは、idle-pingを単に無視します。
このオプションは、リバースHTTPを使用する場合に特に有用です。bind行に設定すると、能動的に接続を開始する役割を持ち、その接続を通じて着信トラフィックを受け取るピアに役立ちます。
interface <interface>
ソケットの使用を特定のインターフェースに限定します。指定すると、そのインターフェースで受信したパケットだけをソケットが処理します。現在、Linuxでのみサポートしています。インターフェースには、別名のインターフェースではなく、システムのプライマリーインターフェースを指定する必要があります。異なるインターフェースにバインドする場合には、複数のフロントエンドを同じアドレスにバインドすることもできます。ネットワークインターフェースへのバインドにはroot権限が必要です。このパラメーターはTCPv4/TCPv6ソケットにのみ対応します。指定すると、別のインターフェースを通る明示的な経路が設定されていても、戻りのトラフィックは受信時と同じインターフェースと、それに対応するルーティングテーブルを使います。同じクライアントIPアドレスから、異なるインターフェース上のフロントエンドに到達する必要がある場合、非対称ルーティングの問題を解消するのに役立ちます。
ktls <on|off> [ EXPERIMENTAL ]
対象のソケットでktlsを有効または無効にします。有効にした場合、カーネルがサポートし、暗号にも互換性があれば、kTLSを使用します。Linuxカーネル4.17以降でのみ使用できます。ネットワークドライバーやTLSスタックによっては、kTLSの使用がTLS v1.2だけに制限される場合があります。“force-tlsv12"も参照してください。
label <label>
対象のソケットに任意のラベルを設定します。bind行を宣言した場所とは無関係に、ラベルでソケットをまとめるために使用できます。
level <level>
この設定は統計ソケットでのみ使用し、そのソケットで実行できるコマンドの種類を制限します。ほかのソケットでは無視します。<level>には次のいずれかを指定できます。
- “user"は、最も権限の低いレベルです。機密性のない統計情報だけを読み取ることができ、変更は一切許可しません。ソケットへのアクセスを簡単には制限できないシステムに適しています。
- “operator"はデフォルトのレベルで、一般的な用途の大半に適しています。すべてのデータを読み取れますが、影響の小さい変更だけを許可します(最大値カウンターのクリアなど)。
- “admin"は、すべての操作が許可されるため(すべてのカウンターのクリアなど)、慎重に使用することを推奨します。
maxconn <maxconn>
ソケットの同時接続数を指定値に制限します。上限を超える接続は、接続が解放されるまで、システムのバックログに残ります。未指定の場合、上限はフロントエンドのmaxconnと同じです。ポート範囲や複数のアドレスを指定している場合、同じ値を各ソケットに適用します。この設定により、すべてのメモリーを消費しやすいSSLの入り口など、コストの高いソケットに異なる上限を設定できます。
mode <mode>
UNIXソケットのアクセス権限を定義するモードを、八進数で設定します。globalセクションの"unix-bind"ステートメントでデフォルトを設定することもできます。一部のプラットフォームでは、単に無視されます。UNIX以外のソケットでは無視します。
mss <maxseg>
受信接続に対して通知するTCPのMaximum Segment Size(MSS)を設定します。たとえばVPNを通過する接続など、特定のポートに対して小さいMSSを強制するために使えます。これはカーネルの機能に依存します。Linuxでは理論上サポートしていますが、2.6.28より前のすべてのバージョンには不具合がありました。ほかのOSでは、動作する場合もしない場合もあります。また、通知する値は変えず、送出するセグメントの実際のサイズだけを変える場合もあります。Ethernetネットワーク上のTCPv4で一般に通知される値は、1460 = 1500(MTU) - 40(IP+TCP)です。指定値が正の場合、その値をMSSとして通知します。負の場合、受信接続が通知したMSSから、送出セグメント用にどれだけ減らすかを示します。このパラメーターはTCP v4/v6ソケットにのみ対応します。
name <name>
これらのソケットに任意の名前を設定します。名前は統計ページに表示されます。
namespace <name>
Linuxでは、ソケットが属するネットワーク名前空間を指定できます。このディレクティブを使うと、デフォルト以外の名前空間にリスナーを明示的にバインドできます。ネットワーク名前空間の詳細は、OSのドキュメントを参照してください。
nbconn <nbconn> [ EXPERIMENTAL ]
この設定は、リバースHTTPを使用するリスナーのインスタンスでのみ有効です。並列に確立する接続の数を定義します。指定しない場合、デフォルト値の1を使用します。
リバースHTTPは、現在も活発に開発されています。今後、設定の仕組みが変わる可能性があります。そのため、内部では実験的とされており、このディレクティブより前の行に"expose-experimental-directives"を指定しなければなりません。
nice <nice>
ソケットから開始する接続の’niceness’を設定します。値は両端を含む-1024..1024の範囲でなければならず、デフォルトはゼロです。正の値の接続は、ほかの接続に配慮し、スケジューラー内で実行順を譲りやすくなります。反対に、負の値の接続は、ほかの接続よりも高い優先度で実行しようとします。違いが現れるのは、システムが飽和に近い高負荷時だけです。低遅延のサービスや管理用サービスには負の値が適しており、遅延の影響を受けにくいSSL処理や大量転送など、CPUを多く使う処理には一般に大きい値を推奨します。たとえば、SMTPソケットに正の値、RDPソケットに負の値を使うとよい場合があります。
no-alpn
ALPNの処理を無効にします(技術的には、ALPN文字列を通知されない空文字列に設定します)。以前の"alpn"設定を取り消し、アプリケーションプロトコルのネゴシエーションを無効にできます。HTTPSまたはQUICのリスナーがクライアントとALPNをネゴシエーションするのを防ぐためにも使えます。デフォルトでは、HTTPSリスナーは"h2,http/1.1"を、QUICリスナーは"h3"を通知します。上記の"alpn"も参照してください。“crt-list"を使う場合、証明書によって"alpn"設定が上書きされ、処理が再び有効になることがある点に注意してください。
no-ca-names
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。ca-fileを使う場合、server helloメッセージでCA名を送信しないようにします。“no-ca-names"と"ca-file"を組み合わせる代わりに、“ca-verify-file"を使用してください。
no-sslv3
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。SSLがサポートされている場合、リスナーから生成されるすべてのソケットでSSLv3のサポートを無効にします。SSLv2はコード内で強制的に無効にされており、どの設定オプションでも有効にはできません。このオプションは、globalの"ssl-default-bind-options"文でも指定できます。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
no-strict-sni
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。前の"strict-sni"ディレクティブによるstrict-sniの強制を無効にします。“ssl-default-bind-options"でグローバルに強制済みの場合、特定の"bind"行でstrict-sniの使用を無効にするために必要になることがあります。bindの"strict-sni"オプションも参照してください。
no-tls-tickets
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。ステートレスなセッション再開(RFC 5077 TLS Ticket拡張)を無効にし、ステートフルなセッション再開の使用を強制します。ステートレスなセッション再開は、CPU使用量がより多くなります。このオプションは、グローバル設定の"ssl-default-bind-options"でも使用できます。TLSチケットの仕組みを使用するのはTLS 1.2までです。チケットの鍵を定期的にローテーションしない限り(リロード、または"tls-ticket-keys"を使用)、TLSチケットによって前方秘匿性が損なわれます。
no-tlsv10
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。SSLがサポートされている場合、リスナーから生成されるすべてのソケットでTLSv1.0のサポートを無効にします。SSLv2はコード内で強制的に無効にされており、どの設定オプションでも有効にはできません。このオプションは、globalの"ssl-default-bind-options"文でも指定できます。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
no-tlsv11
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。SSLがサポートされている場合、リスナーから生成されるすべてのソケットでTLSv1.1のサポートを無効にします。SSLv2はコード内で強制的に無効にされており、どの設定オプションでも有効にはできません。このオプションは、globalの"ssl-default-bind-options"文でも指定できます。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
no-tlsv12
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。SSLがサポートされている場合、リスナーから生成されるすべてのソケットでTLSv1.2のサポートを無効にします。SSLv2はコード内で強制的に無効にされており、どの設定オプションでも有効にはできません。このオプションは、globalの"ssl-default-bind-options"文でも指定できます。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
no-tlsv13
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。SSLがサポートされている場合、リスナーから生成されるすべてのソケットでTLSv1.3のサポートを無効にします。SSLv2はコード内で強制的に無効にされており、どの設定オプションでも有効にはできません。このオプションは、globalの"ssl-default-bind-options"文でも指定できます。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
npn <protocols>
TLSのNPN拡張を有効にし、指定したプロトコルリストを、NPNで選択できる上位プロトコルとして通知します。リストはプロトコル名をカンマで区切ったもので、たとえば"http/1.1,http/1.0”(引用符なし)です。SSLライブラリーを、TLS拡張のサポートを有効にしてビルドしている必要があります(haproxy -vvで確認できます)。NPN拡張はALPN拡張に置き換えられています(“alpn"キーワードを参照)が、ALPNはOpenSSL 1.0.2以降でしか使用できません。古いバージョンのOpenSSLでHTTP/2を使いたい場合、執筆時点ではほとんどのクライアントがNPNを引き続きサポートしているため、NPNを使用できる可能性があります。NPNとALPNの両方を有効にすることもできますが、試験以外での意味はおそらくありません。
prefer-client-ciphers
暗号スイートの選択時に、クライアントの優先順位を使用します。デフォルトでは、サーバーの優先順位を強制します。グローバル設定の"ssl-default-bind-options"でも使用できます。
OpenSSL >= 1.1.1では、クライアントの暗号リストの先頭がChaCha20-Poly1305の場合、このオプションを設定しなくても、ChaCha20-Poly1305の優先順位が変更されます。
二つのアルゴリズム(RSA + ECDSA)を使う構成では、選択アルゴリズムはRSAとECDSAから選び、常にECDSAを優先します。適切な証明書を選択した後、暗号や曲線などの優先順位付けはSSLライブラリーに委ねます。つまり、このオプションでは、ECDSA証明書よりRSA証明書を優先できません。
proto <name>
受信接続に使用するマルチプレクサーのプロトコルを強制的に指定します。フロントエンドのモード(TCPまたはHTTP)と互換性がなければなりません。また、フロントエンド側で使用できる必要があります。利用可能なプロトコルの一覧はhaproxy -vvで表示されます。プロトコルの属性として、モード(TCP/HTTP)、使用側(FE/BE)、mux名、フラグが表示されます。
一部のプロトコルでは、サーバー側でヘッドオブラインブロッキングが起こります(flag=HOL_RISK)。また、アップグレードをサポートしないプロトコルもあります(flag=NO_UPG)。HTXとの互換性も表示します(flag=HTX)。
bind行の"proto"ディレクティブの引数に使用できるプロトコルは、次のとおりです。
このオプションの目的は、このリッスンソケットから作成するすべての接続について、最適なマルチプレクサーのプロトコルを選ぶ処理を迂回することです。たとえば、bind行に"proto h2"を指定すると、平文TCP上でhttp/2を強制できます。
ALPNまたはNPNの設定を行っている場合、問題を避けるため、指定するプロトコルはマルチプレクサーのプロトコルと互換性のあるものにすることを推奨します。たとえば、“proto h1"を設定した場合、ALPNを"h2"に設定することは推奨しません。
QMuxは、TCP上で動作するQUICのサブセットです。次のプロトコルのドラフトに対応します:https://www.ietf.org/archive/id/draft-ietf-quic-qmux-01.html 。現在、haproxyでは実験的とみなされています。
quic-cc-algo { cubic | newreno | bbr | nocc }[(<args,...>)]
これはQUIC専用の設定で、設定したQUICリスナーへの接続試行に使用する輻輳制御アルゴリズムを選びます。TCPで使うアルゴリズムに似ています。
パケット損失を減らし、スループットを向上させるため、輻輳制御アルゴリズムに加えてペーシングが有効になります。globalキーワード"tune.quic.fe.tx.pacing"で無効にできます。ほとんどの場合、ペーシングは有効にしておくべきです。特にBBRは、想定どおりに動作するためにペーシングに依存します。ペーシングなしでBBRを使うと、転送が遅くなったり、パケット損失率が高くなったりする可能性があります。
デフォルト値:cubic
さらに調整するため、アルゴリズムを示すトークンの後に、パラメーターのリストを指定できます。括弧で囲み、カンマで区切って記述する必要があります。各引数は省略可能で、必要に応じて空にできます。各パラメーターは、必ず次の順序にします。
- バイト単位の最大ウィンドウサイズです。10kを上回り、4gを下回る必要があります。デフォルトでは"tune.quic.fe.cc.max-win-size"の値を使用します。
例:
特別な値"nocc"を使うと、輻輳ウィンドウを常に最大サイズに固定できます。輻輳制御による副作用を取り除く、デバッグ用途専用です。高いパケット損失率などのネットワークの問題をすぐに引き起こす可能性があるため、本番環境で使用してはいけません。
quic-force-retry
これはQUIC専用の設定で、設定したQUICリスナーへのすべての接続試行で、QUIC Retry機能の使用を強制します。新しい接続を開始したときに使ったトランスポートアドレスで、相手がパケットを受信できるかを確認します。そのために、トークンを含むRetryパケットを相手に送ります。相手は、このトークンをRetryパケットの送信者へ返す必要があります。トークンを検証できるのは、その送信者だけです。Retryのしきい値を設定していても、QUIC Retryは常に使用します(“tune.quic.fe.sec.retry-threshold"設定を参照)。
この設定にはクラスターシークレットの設定が必要で、設定されていない場合は起動時にエラーを報告します(“cluster-secret"を参照)。
QUIC Retryの詳細は、https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1.2 を参照してください。
quic-socket [ connection | listener ]
このQUIC専用の設定では、特定のリスナーのソケット割り当てモードを定義できます。各モードの長所と短所の詳しい説明は、“tune.quic.fe.sock-per-conn"を参照してください。
この設定は、globalの"tune.quic.fe.sock-per-conn"オプションと組み合わせて適用されます。グローバル設定で"default-on"モードが有効な場合(これが既定値)、“quic-socket listener"を指定したリスナーを除き、各QUIC接続は専用のソケットを使用します。ただし、グローバルモードが"force-off"に設定されている場合、個々のリスナーの設定は無視されます。
severity-output <format>
この設定は統計ソケット専用で、情報を返すフィードバックメッセージの先頭に付ける重大度の出力を設定します。メッセージの重大度は、syslog rfc5424に従う0から7の範囲です。データを要求する有効なソケットコマンド(“show map”、“get acl foo"など)が正常に実行された場合、その出力に重大度が付くことはありません。ほかのソケットでは無視されます。<format>には、次のいずれかを指定できます。
- “none”(デフォルト):フィードバックメッセージの先頭に重大度を付けません。
- “number”:重大度を数値として先頭に付けます。
- “string”:rfc5424の規約に従った文字列として、重大度を先頭に付けます。
shards { <number> | by-thread | by-group }
マルチスレッドモードで、同じIP:portに複数のリスナーを配置できるOSでは、同じ行に対して、指定した数の同一のリスナーを自動的に作成します。元のリスナーに割り当てたスレッドを均等に分けて、それぞれに割り当てます。スレッド数が非常に多く、単一ソケットに対するカーネル内のロックが大きなオーバーヘッドを生む場合に、役立つことがあります。この場合、受信トラフィックを複数のソケットに分散し、競合を減らします。ただし、多くのスレッドが少しずつ動くようになるため、CPU使用量が増えやすいことに注意してください。
シャード数が使用可能なスレッド数を超える場合、スレッド数まで自動的に減らします(つまり、スレッドごとに一つのシャードになります)。特殊な値"by-thread"も、“bind"行のスレッド数と同じ数のシャードを作成します。システムが受信トラフィックをすべてのシャードへ均等に分散するため、シャード数はスレッド数を割り切れる整数であることが重要です。別の特殊な値"by-group"を使うと、スレッドグループごとに一つのシャードを作成します。多数のスレッドを扱い、ソケットを増やしすぎたくない場合に役立ちます。負荷分散はやや最適さを欠きますが、競合(特にシステム内の競合)は、単一ソケットの場合よりも少なくなります。
同じアドレスへの複数ソケットのバインドをサポートしないOSでは、“by-thread"と"by-group"は、自動的に単一シャードへフォールバックします。“by-group"の場合、単一グループでは何も変わらず、どのみちグループごとにソケットが複製されるため、警告は出しません。一方、“by-thread"では、作成されるリスナー数が想定と異なるため、この状況になると診断用の警告を出します。
sigalgs <sigalgs>
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。TLSv1.2とTLSv1.3のハンドシェイク中にネゴシエーションする署名アルゴリズムのリストを表す文字列を設定します。文字列の形式は、OpenSSLのmanページ"man 3 SSL_CTX_set1_sigalgs"に定義されています。中間装置との互換性が必要な場合を除き、この設定の使用は推奨しません。
ssl
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。このリスナーから生成される接続でSSLの復号を有効にします。証明書が必要です(前述の"crt"を参照)。バッファー内の内容はすべて平文になるため、ACLとHTTPの処理がアクセスするのは復号済みの内容だけです。SSLv3は既定では無効です。有効にするには"ssl-min-ver SSLv3"を使用してください。
ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
このオプションは、このリスナーから作成するSSL接続で、<version>以下のバージョンを使用するよう強制します。今後のHAProxyではssl-min-verのデフォルト値が変わる可能性があるため、“ssl-min-ver"を伴わずにこの設定を使うと、意味が曖昧になることがあります。グローバル設定の"ssl-default-bind-options"でも使用できます。“ssl-min-ver"も参照してください。
ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
このオプションは、このリスナーから作成するSSL接続で、<version>以上のバージョンを使用するよう強制します。デフォルト値は"TLSv1.2"です。グローバル設定の"ssl-default-bind-options"でも使用できます。“ssl-max-ver"も参照してください。
strict-sni
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。クライアントが証明書に一致するSNIを送った場合だけ、SSL/TLSのネゴシエーションを許可します。デフォルトの証明書は使用しません。このオプションを使うと、bind行に証明書がなくても起動できるため、空のディレクトリを指定し、後から統計ソケット経由で追加することができます。グローバル設定の"ssl-default-bind-options"でも使用でき、“bind"行の"no-strict-sni"で個別に無効にできます。詳細は"crt"オプションを参照してください。管理ガイドの"add ssl crt-list"コマンドも参照してください。
tcp-md5sig <password>
このリッスンソケットから作成するすべての受信接続で、TCP MD5署名(RFC 2385 Protection of BGP Sessions via the TCP MD5 Signature Option)を有効にします。このオプションはLinuxでのみ使用できます。有効にすると、<password>文字列を使い、すべてのTCPセグメントに16バイトのMD5ダイジェストで署名します。これにより、TCP接続をなりすましから保護します。主な用途は、偽造されたTCPセグメントが接続ストリームに挿入される攻撃から、BGPを保護することです。ただし、非常に長く存続するTCP接続全般で役立つ場合があります。
tcp-ss <mode>
このリッスンソケットから作成するすべての受信接続に、TCP Save SYNオプションを設定します。このオプションはLinux 4.3以降で使用できます。TCPのSYNフラグを含む受信IPパケットのコピーの保持を試みるよう、カーネルに指示します。後で"fc_saved_syn"サンプル取得関数で調べるためです。このオプションには3つのモードがあります。- 0はSYNパケットの保存を無効にします。これがデフォルトです。- 1はSYNパケットの保存を有効にし、IPとTCPのヘッダーを含めます。- 2はSYNパケットの保存を有効にし、ETH、IP、TCPのヘッダーを含めます。
通常のTCP接続でのみ動作し、UNIXソケットなど、ほかのプロトコルでは無視します。“fc_saved_syn"も参照してください。
tcp-ut <delay>
このリッスンソケットから作成するすべての受信接続に、TCP User Timeoutを設定します。このオプションはLinux 2.6.37以降で使用できます。指定した時間内に確認応答を受け取れないデータを含むソケットに対し、HAProxyがタイムアウトを設定できるようにします。リモート端末やデータベースの接続プールなど、長いアイドル期間のある長時間接続で特に役立ちます。そのような接続では、長いアイドル期間を許容するために、クライアントとサーバーのタイムアウトを長く保つ必要があります。一方、接続(およびサーバーのセッション)に関連するすべてのリソースを解放するため、クライアントが消失したことを検出するのも重要です。引数は時間で、デフォルトの単位はミリ秒です。通常のTCP接続だけに作用し、ほかのプロトコルでは無視します。
tfo
Linuxカーネル>= 3.7でのみサポートする、省略可能なキーワードです。リッスンソケットでTCP Fast Openを有効にします。この機能に対応したクライアントは、二回目の接続から、3ウェイハンドシェイク中にリクエストを送ってレスポンスを受け取れるようになります。そのため、初回接続後は一往復を省略できます。接続頻度が高く、一往復ごとの遅延が重要なプロトコルでのみ意味があります。SYNパケット上のデータを受け付けない多くのファイアウォールで問題が起きる可能性があるため、十分に試験してから有効にすることを推奨します。このオプションはTCPv4/TCPv6ソケットでのみサポートし、ほかのソケットでは無視します。libcがTCP_FASTOPENを定義していない場合、USE_TFO=1を指定してHAProxyをビルドする必要があるかもしれません。
thread [<thread-group>/]<thread-set>[,...]
このリスナーを実行できるスレッドのリストを制限します。特定のスレッドに強制するものではなく、一致しないスレッドを除外します。このリスナーへの受信接続を処理できるスレッドを制限します。
番号の指定方法は二種類あります。デフォルトでは、スレッド番号はプロセス内の絶対番号で、1からglobal.nbthreadの指定値までです。スレッドグループ番号を先に指定し、スラッシュ(’/’)と、そのグループ内での相対スレッド番号を続けることもできます。この場合も番号は1から始まり、プラットフォームに応じて32または64までです。絶対番号を指定した場合、スレッドグループが判明した時点で、自動的に相対番号へ変換します。通常、単純な設定では絶対番号が、CPU配置が性能に影響する複雑な設定では相対番号が適しています。
任意指定のスレッドグループ番号の後に続く"thread-set"は、次の形式で指定しなければなりません。
名前のとおり、“all"は集合内のすべてのスレッドを有効にします(グループを指定していればグループ内のすべて、それ以外はプロセスのすべてのスレッド)。“odd"はプロセスまたはグループの奇数番号のスレッドすべて(1から始めて一つおき)を、“even"は偶数番号のスレッドすべて(2から始めて一つおき)を有効にします。代わりにスレッド番号の範囲を指定した場合は、最初から最後の番号まで、その範囲に含まれるすべてのスレッドを有効にします。番号は、スレッドグループ番号の有無に応じて、グループ内の相対番号または絶対番号になります。最初のスレッド番号を省略すると"1"になり、グループまたはプロセスの最初のスレッドを表します。最後のスレッド番号を省略すると、グループの最後の番号(32または64)、またはプロセスの最後の番号(global.nbthread)を使います。
これらの範囲はカンマで区切って繰り返し指定できるため、連続していないスレッドの集合も指定できます。グループを指定する場合は、新しい範囲ごとにグループを再指定しなければなりません。グループ内の相対指定と絶対指定を混在させることはできません。指定されていないものは解析の最後に解決されるため、“bind"行全体で絶対表記か相対表記のどちらかを使用する必要があります。
“bind"行で記述する各リスナーは、少なくとも一つのファイルディスクリプターで表される、少なくとも一つのソケットを作成する点を理解しておくことが重要です。ファイルディスクリプターは複数のスレッドグループをまたげないため、“bind"行のスレッド範囲が複数のグループにまたがる場合、グループごとに少なくとも一つずつになるよう、複数のファイルディスクリプターを自動的に作成します。技術的には、どれもカーネル内の同じソケットを参照していますが、haproxy内ではそれぞれ別の識別子を持ち、“option socket-stats"を使う場合は、個別の統計エントリーも持ちます。
主な目的は、リスナー内で、IP:portは同じでもスレッドが異なる複数のbind行を用意することです。これにより、システムが受信接続を複数のキューへ分配し、haproxy内部のキューの負荷分散を迂回できます。現在、Linux 3.9以降がこの機能をサポートすることが分かっています。“bind"行の複製と、複数のスレッド群への割り当てを自動化する、上記の"shards"キーワードも参照してください。
このキーワードはリバースHTTPのbindにも対応します。ただし、このようなリスナーでは、複数のスレッドグループにまたがるスレッド集合を指定することは禁止されています。“nbconn"が想定どおりに機能しなくなる可能性があるためです。
tls-tickets
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。ステートレスなセッション再開(RFC 5077 TLS Ticket拡張)を有効にします。これは既定の動作ですが、“ssl-default-bind-options"に指定した"no-tls-tickets"で全体的に無効にした場合、特定の"bind"行でこの機能を再び有効にするために必要になることがあります。bindの"no-tls-tickets"キーワードも参照してください。
tls-ticket-keys <keyfile>
TLSチケットの鍵を読み込むファイルを設定します。鍵の長さは、aes128とaes256のどちらを使うかに応じて48または80バイトでなければなりません。base64でエンコードし、一行に一つの鍵を記述します(例:openssl rand 80 | openssl base64 -A | xargs echo)。最初の鍵によって、それ以降の鍵に使う長さが決まります。aes128とaes256の鍵を混在させることはできません。鍵の数はビルドオプションTLS_TICKETS_NOで指定します(デフォルトは3)。ファイルには、少なくともその数の鍵が必要です。末尾のTLS_TICKETS_NO個の鍵を復号に使い、末尾から二番目の鍵を暗号化に使います。そのため、ファイルに新しい鍵を追加してプロセスをリロードするだけで、簡単に鍵をローテーションできます。鍵は定期的に(たとえば12hごとに)ローテーションしなければなりません。そうしないと、完全前方秘匿性が損なわれます。また、ハードドライブなどの永続ストレージには鍵を置かないことを推奨します(ヒント:tmpfsを使用し、これらのファイルをスワップアウトさせないでください)。有効期間のヒントはtune.ssl.timeoutで変更できます。
transparent
一部のLinuxカーネルでのみサポートする、省略可能なキーワードです。ローカルマシンに属さないアドレスにもバインドし、それらのアドレス宛てのパケットを、ローカルに設定したアドレス宛てのパケットと同じように捕捉することを指定します。通常、IP転送が有効である必要があります。注意:デフォルトのアドレス’*‘と組み合わせないでください。指定ポート宛てのすべてのトラフィックをリダイレクトしてしまいます。このキーワードは、USE_LINUX_TPROXY=1でHAProxyをビルドした場合だけ使用できます。このパラメーターは、カーネルのバージョンに応じてTCPv4およびTCPv6ソケットにのみ対応します。一部のディストリビューションのカーネルには、この機能のバックポートが含まれているため、サポートの有無を提供元に確認してください。
uid <uid>
UNIXソケットの所有者を、指定したシステムUIDに設定します。globalセクションの"unix-bind"文で既定値を設定することもできます。一部のプラットフォームでは、この設定は単に無視されます。ユーザー名の代わりに数値のユーザーIDを使うことを除けば、“user"設定と同じです。UNIX以外のソケットでは無視されます。
user <user>
UNIXソケットの所有者を、指定したシステムのユーザーに設定します。globalセクションの"unix-bind"ステートメントでデフォルトを設定することもできます。一部のプラットフォームでは、単に無視されます。uidではなくユーザー名を使う点を除き、“uid"設定と同じです。UNIX以外のソケットでは無視します。
v4v6
Linuxカーネル >= 2.4.21を含む最新のシステムでのみサポートされる、省略可能なキーワードです。既定のアドレスを使用する場合に、ソケットをIPv4とIPv6の両方にバインドするために使います。既定ではIPv6にのみバインドするシステムでは、この指定が必要になることがあります。IPv6以外のソケットには影響せず、“v6only"オプションが優先されます。
v6only
Linuxカーネル>= 2.4.21を含む最新のシステムでのみサポートされる、省略可能なキーワードです。デフォルトのアドレスを使用する場合に、ソケットをIPv6だけにバインドします。リスナーごとの設定なので、システム全体で設定するより望ましい場合があります。IPv6以外のソケットには効果がなく、“v4v6"オプションより優先されます。
verify [none|optional|required]
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。’none’の場合、クライアント証明書を要求しません。これがデフォルトです。それ以外の場合は、クライアント証明書を要求します。要求に対してクライアントが証明書を送らず、‘verify’が’required’ならハンドシェイクを中断しますが、‘optional’なら成功します。クライアントが送った証明書は、‘ca-file’のCAと、任意指定の’crl-file’のCRLを使って常に検証します。検証に失敗すると、‘verify’の値にかかわらずハンドシェイクを中断します。ただし、エラーコードが’ca-ignore-err’または’crt-ignore-err’に列挙したもののいずれかと完全に一致する場合は例外です。
5.2. serverとdefault-serverのオプション
“server"と"default-server"キーワードは、いくつかの設定をサポートし、すべてserver行の引数として指定します。引数の順序は問わず、どの引数も省略可能です。単語一つのもの(真偽値)もあれば、その後ろに一つ以上の値が必要なものもあります。値が必要な場合は、設定名の直後に記述しなければなりません。default-serverを除き、これらの設定を使う場合は、サーバーのアドレスより後ろに記述する必要があります。
これらの設定はすべて、“server"と"default-server"の両方のキーワードでサポートされます。ただし、“id"は"server"でのみサポートされます。
現在サポートされている設定は次のとおりです。
addr <ipv4|ipv6>
使用可能なコンテキスト:tcp, http, log
“addr"パラメーターを使うと、ヘルスチェックの送信先やagent-checkの確認先に別のIPアドレスを使用できます。サーバーによっては、アプリケーション自体よりもヘルスチェックに適した複雑なテストを実行できる専用コンポーネントに、IPアドレスを割り当てることが望ましい場合があります。このパラメーターは、“check"パラメーターが設定されていない場合は無視されます。“port"パラメーターも参照してください。
agent-check
使用可能なコンテキスト:tcp, http, log
通常のヘルスチェックとは独立して実行する、補助的なエージェントチェックを有効にします。エージェントによるヘルスチェックでは、“agent-port"パラメーターで設定したポートにTCP接続し、最初に現れた’\r’または’\n’で終わるASCII文字列を読み取ります。この文字列は、空白、タブ、カンマで区切られた単語を任意の順序で並べたものです。各単語は次のいずれかで構成されます。
-
“75%“のように、正の整数の百分率をASCIIで表したもの。この形式の値は、HAProxyの起動時に設定したサーバーの初期の重みに対する割合として、重みを設定します。重みゼロは、サーバーに対して同じ効果(負荷分散対象から外すこと)があるため、統計ページでは"DRAIN"と表示します。これはサーバーの重みを設定する従来の方法です。“weight:“接頭辞を使う方法を推奨します。
-
文字列"weight:“の直後に、空白を入れずに正の整数または正の整数の百分率を続けたもの。値が’%‘で終わる場合、新しい重みはサーバーの初期の重みに比例します。それ以外の場合、絶対的な重みとして扱い、0から256までの値でなければなりません。静的な負荷分散アルゴリズムを使うサーバー群に属するサーバーには、より厳しい制限があります。一度設定した重みを変更できないためです。このようなサーバーで受け付ける値は、0と100%(または0と初期の重み)だけです。変更はすぐに反映されますが、一部の負荷分散アルゴリズムでは、変更が反映されるまでに一定数のリクエストが必要です。重みゼロは、サーバーに対して同じ効果(負荷分散対象から外すこと)があるため、統計ページでは"DRAIN"と表示します。
-
文字列"maxconn:“の直後に整数を続けたもの(間に空白は入れません)。この形式の値は、サーバーのmaxconnを設定します。そのサーバーが受け入れる可能性のある接続の総数を求めるには、通知された最大接続数に、このヘルスチェックを使うロードバランサーと異なるバックエンドの数を掛ける必要があります。例: maxconn:30
-
単語"ready”。サーバーの管理状態をREADYモードにし、DRAINまたはMAINTの状態を取り消します。
-
単語"drain”。サーバーの管理状態をDRAINモードにします。その結果、永続性に基づいて受け入れるものを除き、新しい接続は受け入れません。
-
単語"maint”。サーバーの管理状態をMAINTモードにします。その結果、新しい接続を一切受け入れず、ヘルスチェックも停止します。
-
単語"down”、“fail”、“stopped”。必要に応じて、その後ろにシャープ(’#’)と説明文字列を続けられます。いずれもサーバーの稼働状態をDOWNにしますが、統計ページには単語そのものが表示されます。その違いにより、管理者は想定した状況かどうかを判断できます。サービスが意図的に停止されている場合、稼働しているように見えるものの何らかの妥当性の検査に失敗する場合、停止していると判断される場合(プロセスが存在しない、ポートが応答しないなど)を区別できます。
-
単語"up"は、ヘルスチェックでもサービスにアクセス可能と報告していれば、サーバーの稼働状態をUPに戻します。
エージェントが通知しないパラメーターは変更しません。たとえば、CPU使用率を監視し、相対的な重みだけを報告して、稼働状態には一切関与しないエージェントを作れます。同様に、管理者が管理状態だけを変更できる、3つのラジオボタンを持つ利用者向けインターフェースとして設計することもできます。ただし、エージェント自身が行った操作を元に戻せるのは、そのエージェントだけである点が重要です。エージェントでサーバーをDRAINモードやDOWN状態にした場合、サービスを再び稼働させるための、対応する逆の操作もエージェントに実装する必要があります。
接続性は"check"パラメーターで有効にする通常のヘルスチェックで調べるため、エージェントへの接続失敗はエラーとみなしません。ただし、“down"を報告した後にエージェントを停止することは推奨しません。サーバーを再び稼働状態にできるのは、“up"を報告するエージェントだけだからです。必要であれば、不具合のあるエージェントを回避するために、Unix統計ソケットのCLIでエージェントの結果を強制的に設定することもできます。
“agent-port"パラメーターを設定する必要があります。“agent-inter"と"no-agent-check"パラメーターも参照してください。
agent-send <string>
使用可能なコンテキスト:tcp, http, log
このオプションを指定すると、HAProxyは接続時に、指定された文字列をそのままエージェントサーバーに送信します。たとえば、文字列にバックエンド名を埋め込めば、エージェントがバックエンドに応じて異なる応答を返せます。リクエストを改行で終える場合は、必ず’\n’を含めてください。
agent-inter <delay>
使用可能なコンテキスト:tcp, http, log
“agent-inter"パラメーターは、エージェントチェックの間隔を<delay>ミリ秒に設定します。指定しない場合、間隔のデフォルトは2000 msです。
ほかの時間指定パラメーターと同様、{ us, ms, s, m, h, d }のいずれかの単位を明示して入力することもできます。“timeout check"を設定していない場合、“agent-inter"パラメーターはエージェントチェックのタイムアウトも兼ねます。同じハードウェア上で複数のサーバーを稼働させたときの「共振」の影響を減らすため、全サーバーのエージェントチェックとヘルスチェックは、開始時刻を少しずつずらしています。グローバルの"spread-checks"キーワードを使い、エージェントチェックとヘルスチェックの間隔にランダムな揺らぎを加えることもできます。たとえば、多数のバックエンドが同じサーバーを使う場合に有効です。
参照:パラメーター"agent-check”、“agent-port”。
agent-addr <addr>
使用可能なコンテキスト:tcp, http, log
“agent-addr"パラメーターは、エージェントチェックのアドレスを設定します。
agent-checkを別の対象に委ねることができるため、自らを認識して管理するサービスを作成できない場合にも、HAProxyで定義したサーバーの状態や重みを一か所で管理できます。IPアドレスまたはホスト名を指定でき、ホスト名は名前解決されます。
agent-port <port>
使用可能なコンテキスト:tcp, http, log
“agent-port"パラメーターは、エージェントチェックに使用するTCPポートを設定します。
参照:パラメーター"agent-check”、“agent-inter”。
allow-0rtt
使用可能なコンテキスト:tcp, http, log, peers, ring
TLS 1.3を使う場合に、サーバーへのearly dataの送信を許可します。送信するのは、クライアントがearly dataを使った場合、またはバックエンドで"retry-on"の"0rtt-rejected"キーワードを使っている場合だけです。QUICでは、QuicTLS、OpenSSL >= 3.5.2、AWS-LCで0rttをサポートします。TCP/TLSで0rttをサポートするのはOpenSSLだけです。
alpn <protocols>
使用可能なコンテキスト:tcp, http
TLSのALPN拡張を有効にし、指定したプロトコルリストを、ALPNで選択できる上位プロトコルとして通知します。リストはプロトコル名をカンマで区切ったもので、たとえば"http/1.1,http/1.0”(引用符なし)です。SSLライブラリーを、TLS拡張のサポートを有効にしてビルドしている必要があります(haproxy -vvで確認できます)。ALPN拡張は、当初使われていたNPN拡張に代わるものです。HTTP/2サーバーへの接続にはALPNが必要です。QUICサーバー経由でHTTP/3を使うためにも必要で、“alpn"を設定していないQUICサーバーでは"h3"がデフォルト値です。OpenSSL 1.0.2より前のバージョンはALPNをサポートしておらず、現在では廃止されたNPN拡張だけをサポートしていました。HTTP/2とHTTP/1.1の両方をサポートする想定なら、次のように優先順に両方を通知できます。
WebSocketストリームで別のALPNを使うには、“ws"も参照してください。
backup
使用可能なコンテキスト:tcp, http, log
server行に"backup"がある場合、そのサーバーが負荷分散に使われるのは、ほかのバックアップではないサーバーがすべて利用できないときだけです。ただし、そのサーバーを参照する永続性Cookieを伴うリクエストは常に処理されます。既定では、backendに"allbackups"オプションが設定されていない限り、稼働中のバックアップサーバーのうち最初のものだけを使用します。“no-backup"と"allbackups"オプションも参照してください。
ca-file <cafile>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。サーバー証明書の検証に使うCA証明書を読み込むPEMファイルを指定します。複数のCAを含むディレクトリを読み込むこともできます。その場合、HAProxyはディレクトリ内のすべての”.pem”、".crt”、".cer”、".crl"ファイルの読み込みを試みます。名前がドットで始まるファイルは無視されます。
システムで信頼するCAを使うには、cafileの代わりに”@system-ca"パラメーターを使用できます。このディレクトリの場所は、SSL_CERT_DIR環境変数を設定して上書きできます。
cc <algo>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定はTCP_CONGESTIONを定義しているシステムでのみ使用でき、LinuxとFreeBSDで検証されています。TCP輻輳制御アルゴリズムの名前を受け取り、発信接続でそのアルゴリズムを使うよう設定します。代表的な名前に"reno"や"cubic"がありますが、使用できるものはOSによって異なります。システムによっては、特定のアルゴリズムを設定するために特別な権限が必要な場合があります。Linuxでは、利用可能なアルゴリズムはsysctlの"net.ipv4.tcp_available_congestion_control"に、特権なしで使用を許可されているものは"net.ipv4.tcp_allowed_congestion_control"に一覧表示されます。追加の権限が必要なアルゴリズムを使うには、“cap_net_admin"ケーパビリティーが必要な場合があります(globalセクションの"setcap"を参照)。指定した輻輳制御アルゴリズムを設定できない場合、デフォルトのアルゴリズムをそのまま使います。bindキーワードの"cc”(セクション5.1 )も参照してください。
check
使用可能なコンテキスト:tcp, http, log
このオプションは、サーバーのヘルスチェックを有効にします。- 設定しない場合、ヘルスチェックは行わず、サーバーは常に利用可能とみなします。- 設定し、ほかのチェック方式を設定していない場合、設定されている最上位のトランスポート層で接続を確立できれば、サーバーは利用可能とみなします。デフォルトではTCP、“ssl"または"check-ssl"を設定した場合はSSL/TLSです。どちらの場合も、“send-proxy"や"check-send-proxy"を設定した際のPROXYプロトコルヘッダーなど、接続の接頭辞と組み合わせることができます。動的サーバーでは動作が少し異なります。詳細は後続の段落を参照してください。- 設定し、アプリケーション層のヘルスチェックを定義した場合、設定されたトランスポート層の上でアプリケーション層のやり取りを行い、そのすべてが成功すれば、サーバーは利用可能とみなします。
デフォルトでは、サーバーに設定したものと同じアドレスとポートで、同じカプセル化パラメーター(SSL/TLS、proxy-protocolヘッダーなど)を使ってヘルスチェックを行います。送信先アドレスは"addr"で、ポートは"port"で変更できます。変更した場合、サービス用ポートでのチェックではないとみなし、設定済みのカプセル化パラメーターは再利用しません。接続ヘッダーを送るには"check-send-proxy"を、SSL/TLSを使うには"check-ssl"を、明示的に設定する必要があります。
動的サーバーでは、sslとPROXYプロトコルの暗黙の設定は行いません。この場合、チェック用ポートを上書きしていなくても、必要な機能に応じて"check-ssl"と"check-send-proxy"を明示的に使用する必要があります。
server行に"sni"または"alpn"を設定しても、その値はヘルスチェックには使いません。“check-sni"または"check-alpn"を使用する必要があります。
ヘルスチェックのトラフィックのデフォルトの送信元アドレスは、バックエンドで定義したものと同じです。“source"キーワードで変更できます。
チェックの間隔は"inter"キーワードで設定でき、“rise"と"fall"で、サーバーを利用可能または利用不可と判断するために必要なヘルスチェックの成功回数や失敗回数を定義できます。
任意指定のアプリケーションレベルのヘルスチェックは、“option httpchk”、“option mysql-check”、“option smtpchk”、“option pgsql-check”、“option ldap-check”、“option redis-check"で設定できます。
例:
check-reuse-pool
使用可能なコンテキスト:tcp, http
利用可能なアイドル接続がある場合、チェック専用の接続を開く代わりに、その接続を再利用できるようにします。チェックが終わると、接続をプールに戻します。主な目的は、特定のサーバーに対する接続の開始と終了の回数を抑えることです。この機能はhttp-checkルールセットにのみ対応し、ほかのチェック方式では通知なしで無視します。また、チェックの試行ごとに専用セッションを使うため、バックエンドの再利用方針はaggressiveに設定することを推奨します。
設定を簡単にするため、server行または独自のtcp-check connectルールで、チェックの接続に固有のオプションを一つでも定義した場合、このオプションは通知なしで無視します。
パッシブなリバースHTTPゲートウェイとして動作するサーバーでは、再利用による接続だけをサポートするため、このオプションを自動的に有効にします。
参照:“check-pool-conn-name”。
check-send-proxy
使用可能なコンテキスト:tcp, http
サーバーが通常のトラフィックでsend-proxyを使うかどうかにかかわらず、送信するヘルスチェックにPROXYプロトコル行を付けるよう強制します。デフォルトでは、通常のトラフィックでPROXYプロトコルが有効になっており、“port"も"addr"も指定していなければ、ヘルスチェックでも有効になります。ただし、これらのディレクティブを指定している場合は、“check-send-proxy"オプションで使用を強制する必要があります。詳細は"send-proxy"オプションも参照してください。
check-alpn <protocols>
使用可能なコンテキスト:tcp, http
ALPNで通知するプロトコルを定義します。プロトコルのリストは、“http/1.1,http/1.0”(引用符なし)など、プロトコル名のカンマ区切りリストです。設定しない場合、サーバーのALPNを使用します。
check-pool-conn-name <name>
使用可能なコンテキスト:tcp, http
チェックで接続を再利用する場合、<name>を設定していれば接続の識別子として使用し、プール内の対応する接続を探します。serverキーワード"pool-conn-name"に相当します。このオプションを使用していない場合は、“check-sni"もフォールバックとして使用します。
参照:“check-reuse-pool”。
check-proto <name>
使用可能なコンテキスト:tcp, http
サーバーのヘルスチェック接続に使用するマルチプレクサーのプロトコルを強制的に指定します。ヘルスチェックの種類(TCPまたはHTTP)と互換性がなければなりません。また、バックエンド側で使用できる必要があります。利用可能なプロトコルの一覧はhaproxy -vvで表示されます。プロトコルの属性として、モード(TCP/HTTP)、使用側(FE/BE)、mux名、フラグが表示されます。
一部のプロトコルでは、サーバー側でヘッドオブラインブロッキングが起こります(flag=HOL_RISK)。また、アップグレードをサポートしないプロトコルもあります(flag=NO_UPG)。HTXとの互換性も表示します(flag=HTX)。
server行の"check-proto"ディレクティブの引数に使用できるプロトコルは、次のとおりです。
このオプションの目的は、このサーバーに確立するヘルスチェック接続で、最適なマルチプレクサーのプロトコルを選ぶ処理を迂回することです。定義しない場合は、サーバー側の設定があれば、それを使用します。
ALPNまたはNPNの設定を行っている場合、問題を避けるため、指定するプロトコルはマルチプレクサーのプロトコルと互換性のあるものにすることを推奨します。たとえば、“proto h1"を設定した場合、ALPNを"h2"に設定することは推奨しません。
QUICのチェック設定は、まだ完全には実装されていません。まず、QUICチェックを行えるのはQUICサーバーだけです。また、QUICサーバーでチェックに固有の接続パラメーターを一つ以上指定すると、チェックのプロトコルはTCPの使用にフォールバックします。
check-sni-auto
使用可能なコンテキスト:tcp, http, log
このオプションは、まだ値が設定されていなければ、SSLでヘルスチェックを行う際のSNIの自動選択を有効にします。デフォルトで有効ですが、“default-server"ディレクティブからデフォルト値として継承した"no-check-sni-auto"を取り消すため、“server"設定として使うこともできます。また、“default-server"設定として使い、以前の"default-server"の"no-check-sni-auto"設定を取り消すこともできます。
HTTPS接続では、“http-check connect"ルールがない場合に限り、SNIが自動的に選択されます。その場合、“option httpchk"ディレクティブまたは"http-check send"ルールで指定したHostヘッダーの値に基づいてSNIを選択します。“http-check connect"ルールでは自動選択は行われません。ほかのプロトコルでは、このオプションは無視されます。
ヘルスチェックでSNIの自動選択を使い、“check-reuse-pool"を設定している場合、選択した値を接続名に割り当てます。ただし、serverキーワード"check-pool-conn-name"で上書きした場合は除きます。
プロキシするトラフィックでSNIの自動選択を有効にするには、“sni-auto"オプションを参照してください。
check-sni <sni>
使用可能なコンテキスト:tcp, http, log
SSL経由のヘルスチェックで使用するSNIを指定できます。<sni>を設定できるのは文字列だけです。プロキシするトラフィックのSNIを設定する場合は、“sni"を参照してください。
check-ssl
使用可能なコンテキスト:tcp, http, log
サーバーが通常のトラフィックにSSLを使用するかどうかにかかわらず、すべてのヘルスチェックをSSLで暗号化するよう強制します。通常、“port"または"addr"ディレクティブを明示していて、SSLヘルスチェックが継承されない場合に使います。このオプションは、チェックの下にSSLトランスポート層を挿入する点を理解しておくことが重要です。そのため、単純なTCP接続チェックがSSL接続になり、従来のssl-hello-chkに代わるものになります。最も一般的な用途は、“httpchk"とSSLチェックを組み合わせてHTTPSのチェックを送ることです。暗号など、すべてのSSL設定はヘルスチェックとトラフィックに共通です。詳細は"ssl"オプションを、このオプションを無効にする方法は"no-check-ssl"を参照してください。
check-via-socks4
使用可能なコンテキスト:tcp, http, log
アップストリームのsocks4プロキシを使う発信ヘルスチェックを有効にします。デフォルトでは、通常のトラフィックでsocksトンネルを有効にしていても、ヘルスチェックはトンネルを通りません。
ciphers <ciphers>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。サーバーとのSSL/TLSハンドシェイクでネゴシエーションする、暗号アルゴリズムの一覧を記述した文字列を設定します。文字列の形式は、OpenSSLのマニュアルページ"man 1 ciphers"で定義されています。背景や推奨事項については、たとえば(https://wiki.mozilla.org/Security/Server_Side_TLS )と(https://mozilla.github.io/server-side-tls/ssl-config-generator/ )を参照してください。TLSv1.3の暗号設定については、“ciphersuites"キーワードを参照してください。
ciphersuites <ciphersuites>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込み、OpenSSL 1.1.1以降を使ってHAProxyをビルドした場合だけ使用できます。サーバーとのTLS 1.3ハンドシェイクでネゴシエーションする、暗号アルゴリズムの一覧を記述した文字列を設定します。文字列の形式は、OpenSSLのマニュアルページ"man 1 ciphers"の"ciphersuites"セクションで定義されています。TLSv1.2以前の暗号設定については、“ciphers"キーワードを参照してください。
client-sigalgs <sigalgs>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。ネゴシエーションする、クライアント認証に関係する署名アルゴリズムのリストを表す文字列を設定します。文字列の形式は、OpenSSLのmanページ"man 3 SSL_CTX_set1_client_sigalgs"に定義されています。具体的な用途が明らかでない場合、この設定の使用は推奨しません。
cookie <value>
使用可能なコンテキスト: http
“cookie"パラメーターは、サーバーに割り当てるCookie値を<value>に設定します。受信リクエストでこの値を調べ、同じ値を持つ稼働中のサーバーのうち、最初のものを選びます。応答では、Cookieの挿入または書き換えモードの場合、クライアントに送るCookieにこの値を割り当てます。複数のサーバーが同じCookie値を共有しても問題はありません。実際、通常のサーバーとバックアップサーバーの間では、ある程度一般的な使い方です。backendセクションの"cookie"キーワードも参照してください。
crl-file <crlfile>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。サーバー証明書の検証に使う証明書失効リストを読み込むPEMファイルを指定します。
crt <cert>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。証明書と対応する秘密鍵の両方を読み込むPEMファイルを指定します。二つのPEMファイルを一つに連結して作成できます。サーバーがクライアント証明書を要求した場合、この証明書を送ります。
ファイルに秘密鍵が含まれていない場合、HAProxyは同じパスの末尾に”.key"を付けたファイルから鍵の読み込みを試みます(“ssl-load-extra-files"オプションを適切に設定していることが条件です)。
curves <curves>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。ECDHEを使うSSL/TLSハンドシェイクでネゴシエーションする、楕円曲線アルゴリズムの一覧(“curve suite”)を表す文字列を設定します。文字列の形式は、曲線名のコロン区切りリストです。例:“X25519:P-256”(引用符なし)。
disabled
使用可能なコンテキスト:tcp, http, log
“disabled"キーワードは、サーバーを"disabled"状態で起動します。これは、メンテナンスモードで停止扱いとなり、persistモードで許可された接続以外はサーバーに到達しないことを意味します。通常のトラフィックが到達することはなく、force-persistの仕組みを使えばサービスのテストはできるため、新しいサーバーの準備に適しています。“enabled"設定も参照してください。
enabled
使用可能なコンテキスト:tcp, http, log
このオプションは、‘default-server’ディレクティブからデフォルト値として継承した’disabled’設定を取り消すため、‘server’設定として使用できます。また、‘default-server’設定として使い、以前の’default-server’の’disabled’設定を取り消すこともできます。
error-limit <count>
使用可能なコンテキスト:tcp, http, log
正常性の監視を有効にしている場合、“error-limit"パラメーターは、“on-error"で選択したイベントを発生させる連続エラー数を指定します。デフォルトは、連続する10回のエラーです。
参照:“check”、“error-limit”、“on-error”。
fall <count>
使用可能なコンテキスト:tcp, http, log
“fall"パラメーターは、ヘルスチェックが連続して<count>回失敗すると、サーバーを停止とみなすことを指定します。未指定の場合、デフォルトは3です。“check”、“inter”、“rise"パラメーターも参照してください。
force-sslv3
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信でSSLを使用する場合に、SSLv3だけを使うよう強制します。接続頻度が高い場合、SSLv3は通常、TLSより処理コストが低くなります。グローバル設定の"ssl-default-server-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
force-tlsv10
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信でSSLを使用する場合に、TLSv1.0だけを使うよう強制します。グローバル設定の"ssl-default-server-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
force-tlsv11
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信でSSLを使用する場合に、TLSv1.1だけを使うよう強制します。グローバル設定の"ssl-default-server-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
force-tlsv12
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信でSSLを使用する場合に、TLSv1.2だけを使うよう強制します。グローバル設定の"ssl-default-server-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
force-tlsv13
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信でSSLを使用する場合に、TLSv1.3だけを使うよう強制します。グローバル設定の"ssl-default-server-options"でも使用できます。“ssl-min-ver"と"ssl-max-ver"も参照してください。
guid <string>
使用可能なコンテキスト:tcp, http, log
このサーバーに、大文字と小文字を区別するグローバルで一意のIDを指定します。すべてのオブジェクトの種類にわたり、HAProxyの設定全体で一意でなければなりません。形式の詳細は、プロキシキーワード"guid"の説明を参照してください。“shm-stats-file"も参照してください。
hash-key <key>
使用可能なコンテキスト:tcp, http, log
“hash-type consistent"のノードキーの計算方法を指定します。
引数:
“addr"と"addr-port"オプションは、複数のHAProxyプロセスが同じサーバー群にトラフィックを分散する環境で役立つ場合があります。たとえばDNSレコードの解決順序が違うなどの理由で、プロセスごとにサーバーの順序が異なる場合でも、独立した各HAProxyプロセスでルーティングの判断を揃えられます。注意:“balance random"も"hash-type consistent"を使用し、分布のよさはキーの品質に左右されます。
healthcheck <name>
使用可能なコンテキスト:tcp, http
サーバーのチェックに使用するhealth-checkセクションを指定します。
引数:
このオプションにより、プロキシの設定の代わりに、サーバーごとのヘルスチェック設定を使用できます。“healthcheck section"も参照してください。
id <value>
使用可能なコンテキスト:tcp, http, log
サーバーに固定のIDを設定します。IDは32ビットの正の数で、プロキシ内で一意でなければなりません。未指定の場合、未使用のIDを自動的に割り当てます。最初に割り当てる値は1です。現在、このIDが返されるのは統計だけです。また、コンシステントハッシュアルゴリズムを使い、“hash-key"が"id”(デフォルト)の場合に、負荷分散ノードの配置に使います。この場合、値の下位20ビットだけを使用するため(つまり(id % 1048576))、重複を避けるには、1からこの値までの範囲に収めることを推奨します。
idle-ping <delay>
使用可能なコンテキスト:tcp, http, log
アイドル状態のバックエンド接続で、生存確認を定期的に行う間隔を定義します。次の確認予定時刻までに相手が応答できない場合、接続は閉じられます。このキーワードはバックエンド側を対象とするため、アイドル状態の接続がまだ使用できるかを確認するのに役立ちます。ただし、アイドルプールのパージによって接続が破棄されることを防ぐものではありません。
この機能には、基盤となるプロトコルの対応が必要です。現在、実装しているのはH2 muxだけです。ほかのプロトコルでは、idle-pingを単に無視します。
このオプションは、リバースHTTPを使用する場合に特に有用です。server行に設定すると、受信接続を待ち受け、後でトラフィックの転送に再利用できるよう対応するサーバーに関連付けるピアに役立ちます。
init-addr {last | libc | none | <ip>},[...]*
使用可能なコンテキスト:tcp, http, log
サーバーにFQDNを使用する場合に、起動時にどの順序でアドレスを解決するかを指定します。カンマ区切りのリストに記載した方法を順番に適用して解決を試み、最初に成功した方法を使います。有効な方法が見つからないままリストの末尾に達すると、エラーになります。“last"は、状態ファイルにあるアドレスを選ぶ方法です(“server-state-file"を参照)。“libc"は、libc内部のリゾルバーを使います(OSやビルドオプションに応じてgethostbyname()またはgetaddrinfo())。“none"は、有効なIPアドレスを持たず、停止状態でサーバーを起動することを明示します。起動時に一部のDNSの問題を無視し、後で解消されるのを待ちたい場合に役立ちます。最後に、IPv4またはIPv6アドレスを指定することもできます。現在判明しているサーバーのアドレス(設定生成ツールが書き込む場合など)でも、古いセッションを受け止めて適切なエラーメッセージを返すダミーサーバーのアドレスでもかまいません。“first"負荷分散アルゴリズムを使用する場合、このIPアドレスを、新しいインスタンスをその場で作成するきっかけとなる仮のサーバーに向けることもできます。このオプションのデフォルトは"last,libc"で、状態ファイルに以前のアドレスがあればそれを優先し、なければlibcのリゾルバーを使います。これにより従来の動作との互換性を維持します。内部リゾルバーを使用する場合、通常はlibcによる名前解決を無効にするか、明示的に指定することを推奨します(詳細はセクション5.3 を参照)。
例1:
例2:
inter <delay>
使用可能なコンテキスト:tcp, http, log
“inter"パラメーターは、連続するヘルスチェックの間隔を<delay>ミリ秒に設定します。指定しない場合、間隔のデフォルトは2000 msです。“fastinter"と"downinter"を使い、サーバーの状態に応じてチェックの間隔を最適化することもできます。
ほかの時間指定パラメーターと同様、{ us, ms, s, m, h, d }のいずれかの単位を明示して入力することもできます。“timeout check"を設定していない場合、“inter"パラメーターは、サーバーに送るヘルスチェックのタイムアウトも兼ねます。同じハードウェア上で複数のサーバーを稼働させたときの「共振」の影響を減らすため、全サーバーのエージェントチェックとヘルスチェックは、開始時刻を少しずつずらしています。グローバルの"spread-checks"キーワードを使い、エージェントチェックとヘルスチェックの間隔にランダムな揺らぎを加えることもできます。たとえば、多数のバックエンドが同じサーバーを使う場合に有効です。グローバル設定の"tune.max-checks-per-thread"をゼロ以外の値にすると、各スレッドで同時に実行するチェックの数を制限します。この制限に達したスレッドで開始しようとしているチェックは、別のチェックが終わるまでhaproxyがキューに入れて待機させます。その結果、実際のチェック間隔は長くなります。この場合、“inter"を短くしてもキューでの待機時間は短縮できないため、その効果はごく限られます。
init-state { fully-up | up | down | fully-down | none }
使用可能なコンテキスト:tcp, http
使用可能なセクション: defaults | frontend | listen | backend 不可 | 不可 | 可 | 可
“init-state"オプションは、サーバーの初期状態を設定します。- ‘fully-up’の場合、サーバーはすぐに利用可能とみなされます。このサーバーのヘルスチェックが有効なら、すべてのヘルスチェックが失敗するとDOWN状態になります。- ‘up’の場合、サーバーはすぐに利用可能とみなされます。このサーバーのヘルスチェックが有効なら、次のヘルスチェックが失敗すると直ちにDOWN状態になります。- ‘down’の場合、サーバーは初めは利用できないとみなされます。このサーバーのヘルスチェックが有効なら、次のヘルスチェックが成功するとUP状態になることができます。- ‘fully-down’の場合、サーバーは初めは利用できないとみなされます。このサーバーのヘルスチェックが有効なら、すべてのヘルスチェックが成功するとUP状態になります。- ’none’(デフォルト値)の場合、init-stateによる管理を無効にします。‘default-server’ディレクティブからこのパラメーターを継承したとき、デフォルトの動作に戻すために使えます。
サーバーのinit-stateは、HAProxyインスタンスの起動や再起動、新しいサーバーの検出(サービスディスカバリーやDNS解決など)、動的サーバーの稼働開始、サーバーのメンテナンス終了などの際に考慮します。サーバーが別のサーバーを追跡している場合、このディレクティブは使用できません。
例:
参照:“option tcp-check”、“option httpchk”。
ktls <on|off> [ EXPERIMENTAL ]
使用可能なコンテキスト:tcp, http, log, peers, ring
対象のソケットでktlsを有効または無効にします。有効にした場合、カーネルがサポートし、暗号にも互換性があれば、kTLSを使用します。Linux 4.17以降でのみ使用できます。ネットワークドライバーやTLSスタックによっては、kTLSの使用がTLS v1.2だけに制限される場合があります。“force-tlsv12"も参照してください。
log-bufsize <bufsize>
使用可能なコンテキスト:log
“log-bufsize"は、ログバックエンド内のログサーバーに関連付ける、暗黙のリングのバッファーサイズを指定します。未指定の場合はBUFSIZEです。値を大きくするとメモリー使用量は増えますが、バッファーにより多くの未処理メッセージを保持できるため、低速なサーバーでのログメッセージの損失を防ぐのに役立つ場合があります。このキーワードは、“mode log"を指定したログバックエンドセクションでのみ使用できます。
log-proto <logproto>
使用可能なコンテキスト:log, ring
“log-proto"は、logまたはringセクションに設定したサーバーへ、イベントメッセージを転送するプロトコルを指定します。指定できる値は"legacy"と"octet-count"で、rfc6587の"Non-transparent-framing"と"Octet counting"にそれぞれ対応します。デフォルトは"legacy"です。
maxconn <maxconn>
使用可能なコンテキスト:tcp, http
“maxconn"パラメーターは、このサーバーに送る同時接続数の上限を指定します。受信する同時接続数がこの値を超えると、接続をキューに入れ、空きができるまで待機させます。極端な負荷がかかった際に、負荷に弱いサーバーが停止するのを防げるため、非常に重要なパラメーターです。“minconn"を指定すると、上限は動的になります。デフォルト値の"0"は無制限を意味します。“minconn"と"maxqueue"パラメーター、およびバックエンドの"fullconn"キーワードも参照してください。
HTTPモードでは、このパラメーターは接続数ではなく同時リクエスト数を制限します。サーバーへの単一のTCP接続上で、複数のリクエストを多重化する場合があります。たとえばmaxconnに50を指定すると、実際のサーバー接続数は1から50までとなることがありますが、同時リクエスト数は50を超えません。
maxqueue <maxqueue>
使用可能なコンテキスト:tcp, http
“maxqueue"パラメーターは、このサーバーのキューで待機する接続数の上限を指定します。上限に達すると、以降のリクエストは、処理されるまで無期限に待つ代わりに、ほかのサーバーへ再配分されます。永続性は失われますが、接続しようとしているサーバーが停止しかけている場合でも、利用者がすぐに再ログインできることがあります。leastconnなど一部の負荷分散アルゴリズムは、この値をゼロより大きい値に明示的に設定すると考慮し、この上限までサーバーのキューにリクエストを追加します。maxconnが一桁の値の場合、負荷をより均等にできることがよくあります。デフォルト値は"0"で、キューに制限はありません。“maxconn"と"minconn"パラメーター、および"balance leastconn"も参照してください。
max-reuse <count>
使用可能なコンテキスト:http, ring
httpコンテキストで使用する場合:
“max-reuse"引数は、HTTP接続を処理する側に対し、新しいリクエストを送るためにサーバー接続を再利用する回数を、この値までに抑えるよう指示します。指定できる値は、この制限を無効にする-1(デフォルト)か、正の値です。ゼロにすると、実質的にkeep-aliveを無効にします。これは、時間の経過とともにリソースがリークする、一部のサーバーの不具合を回避するためだけに使います。技術的な制限により強制できない場合があるため、下位層が必ずこの引数に従うとは限りません。少なくとも、サーバーへのHTTP/2接続ではこの値が守られます。
ringコンテキストで使用する場合:
“max-reuse"引数は、シンクのTCP接続を処理する側に対し、メッセージ送信のためにサーバー接続を再利用する回数を、この値までに抑えるよう指示します。同じ接続で少なくとも"max-reuse + 1"件のメッセージを処理すると、サーバーへの接続を強制的に破棄します。その後、サーバーへの接続は自動的に作り直されます。マルチスレッド環境で大量のメッセージを扱う場合、リングの負荷を複数のスレッドへ分散しやすくなります。各接続は、その存続期間を通して同じCPUスレッドに結び付いているためです。HTTPとは異なり、syslogにはトランザクションに相当するものがないため、サーバーが接続を閉じず、ネットワークエラーも起きなければ、サーバー接続は無期限に存続する可能性があります。ときどき接続を破棄すれば、ほかのスレッドも順番にメッセージを取得する機会を得られます。また、haproxyとログサーバーの間に別の負荷分散層がある環境では、ログサーバーを円滑に入れ替えるのにも役立つ場合があります。ただし、接続を作り直すたびに、送信元ポートがTIME_WAIT状態で残り、最近のOSでは約一分間再利用できなくなる点に注意してください。そのため、送信元ポートを急速に使い切らないよう、値を小さくしすぎないことが必要です。目安として、接続を閉じる回数を毎秒数回より多くしないでください。できれば、それよりはるかに低い頻度に抑えます。指定できる値は、この制限を無効にする-1(デフォルト)か、正の値です。HTTPの場合とは異なり、シンクサーバーでの"max-reuse"の適用はベストエフォートです。リングのメッセージをバッチで処理するため、上限はバッチの間で確認します。
minconn <minconn>
使用可能なコンテキスト:tcp, http
“minconn"パラメーターを設定すると、maxconnの上限はバックエンドの負荷に応じて変わる動的な上限になります。サーバーは常に少なくとも<minconn>接続を受け入れられ、<maxconn>を超えることはありません。バックエンドの同時接続数が<fullconn>未満の場合、上限は負荷に応じてこの二つの値の間で増加します。そのため、通常時はサーバーの負荷を抑え、高負荷時にはより多く処理させつつ、例外的に負荷が高くなっても過負荷を防げます。“maxconn"と"maxqueue"パラメーター、およびバックエンドの"fullconn"キーワードも参照してください。
namespace <name>
使用可能なコンテキスト:tcp, http, log, peers, ring
Linuxでは、ソケットが属するネットワーク名前空間を指定できます。このディレクティブを使うと、デフォルト以外の名前空間にサーバーを明示的にバインドできます。ネットワーク名前空間の詳細は、OSのドキュメントを参照してください。
no-agent-check
使用可能なコンテキスト:tcp, http, log
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"agent-check"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"agent-check"設定を取り消すこともできます。
no-backup
使用可能なコンテキスト:tcp, http, log
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"backup"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"backup"設定を取り消すこともできます。
no-check
使用可能なコンテキスト:tcp, http, log
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"check"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"check"設定を取り消すこともできます。
no-check-reuse-pool
使用可能なコンテキスト:tcp, http
“default-server"から継承した可能性のある、以前の"check-reuse-pool"設定を取り消します。すべてのチェックを、それぞれの専用接続で行います。
no-check-sni-auto
使用可能なコンテキスト:tcp, http, log
このオプションは、デフォルトで有効なSSLヘルスチェックのSNI自動選択を無効にするため、“server"設定として使用できます。
プロキシするトラフィックでSNIの自動選択を無効にするには、“no-sni-auto"オプションを参照してください。
no-check-ssl
使用可能なコンテキスト:tcp, http, log
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"check-ssl"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"check-ssl"設定を取り消すこともできます。
no-renegotiate
使用可能なコンテキスト:tcp, http, log
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。指定のSSLバックエンドで、従来の安全でない方式も、より新しい"secure renegotiation”(RFC 5746 TLS Renegotiation Indication Extension)も含め、再ネゴシエーションの仕組みを無効にします。このオプションは、グローバル設定の"ssl-default-server-options"でも使用できます。TLS 1.3では再ネゴシエーションはできません。“renegotiate"と"no-renegotiate"のどちらも指定しない場合、SSLライブラリーのデフォルト動作を維持します。たとえば、OpenSSLは安全な再ネゴシエーションをデフォルトで有効にしますが、AWS-LCは無効にします。“renegotiate"も参照してください。
no-send-proxy
使用可能なコンテキスト:tcp, http
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"send-proxy"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"send-proxy"設定を取り消すこともできます。
no-send-proxy-v2
使用可能なコンテキスト:tcp, http
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"send-proxy-v2"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"send-proxy-v2"設定を取り消すこともできます。
no-send-proxy-v2-ssl
使用可能なコンテキスト:tcp, http
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"send-proxy-v2-ssl"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"send-proxy-v2-ssl"設定を取り消すこともできます。
no-send-proxy-v2-ssl-cn
使用可能なコンテキスト:tcp, http
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"send-proxy-v2-ssl-cn"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"send-proxy-v2-ssl-cn"設定を取り消すこともできます。
no-sni-auto
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、デフォルトで有効なSNIの自動選択を無効にするため、“server"設定として使用できます。
SSLヘルスチェックでSNIの自動選択を無効にするには、“no-check-sni-auto"オプションを参照してください。
no-ssl
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"ssl"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"ssl"設定を取り消すこともできます。
default-server ssl設定とサーバーのno-sslを併用した場合も、SSL接続は初期化します。このため、後でランタイムAPIから有効にできます。管理ドキュメントのset serverコマンドを参照してください。
no-ssl-reuse
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信でSSLを使用する場合に、SSLセッションの再利用を無効にします。新しい接続ごとに、サーバーが完全なハンドシェイクを行うよう強制します。おそらく、ベンチマーク、トラブルシューティング、または極めて慎重なユーザーにのみ役立ちます。
no-sslv3
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信でSSLを使用する場合に、SSLv3のサポートを無効にします。SSLv2はコード内で無効にしているため、どの設定オプションを使っても有効にできません。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
default-serverでのサポート:なし
no-tls-tickets
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。ステートレスなセッション再開(RFC 5077 TLS Ticket拡張)を無効にし、ステートフルなセッション再開の使用を強制します。ステートレスなセッション再開は、サーバーのCPU使用量がより多くなります。このオプションは、グローバル設定の"ssl-default-server-options"でも使用できます。TLSチケットの仕組みを使用するのはTLS 1.2までです。チケットの鍵を定期的にローテーションしない限り(リロード、または"tls-ticket-keys"を使用)、TLSチケットによって前方秘匿性が損なわれます。“tls-tickets"も参照してください。
no-tlsv10
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信にSSLを使用する場合にTLSv1.0のサポートを無効にします。SSLv2はコード内で無効にされており、どの設定オプションでも有効にはできません。TLSv1はSSLv3より処理コストが高いため、ローカルサーバーとの通信では無効にすることが適切な場合がよくあります。このオプションは、globalの"ssl-default-server-options"文でも指定できます。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
default-serverでのサポート:なし
no-tlsv11
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信にSSLを使用する場合にTLSv1.1のサポートを無効にします。SSLv2はコード内で無効にされており、どの設定オプションでも有効にはできません。TLSv1はSSLv3より処理コストが高いため、ローカルサーバーとの通信では無効にすることが適切な場合がよくあります。このオプションは、globalの"ssl-default-server-options"文でも指定できます。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
default-serverでのサポート:なし
no-tlsv12
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信にSSLを使用する場合にTLSv1.2のサポートを無効にします。SSLv2はコード内で無効にされており、どの設定オプションでも有効にはできません。TLSv1はSSLv3より処理コストが高いため、ローカルサーバーとの通信では無効にすることが適切な場合がよくあります。このオプションは、globalの"ssl-default-server-options"文でも指定できます。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
default-serverでのサポート:なし
no-tlsv13
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信にSSLを使用する場合にTLSv1.3のサポートを無効にします。SSLv2はコード内で無効にされており、どの設定オプションでも有効にはできません。TLSv1はSSLv3より処理コストが高いため、ローカルサーバーとの通信では無効にすることが適切な場合がよくあります。このオプションは、globalの"ssl-default-server-options"文でも指定できます。代わりに"ssl-min-ver"と"ssl-max-ver"を使用してください。
default-serverでのサポート:なし
no-verifyhost
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"verifyhost"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"verifyhost"設定を取り消すこともできます。
no-tfo
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"tfo"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"tfo"設定を取り消すこともできます。
non-stick
使用可能なコンテキスト:tcp, http
このサーバーに割り当てた接続を、スティックテーブルに決して追加しません。backupと併用すると、バックアップサーバーでスティックテーブルによる永続性を確実に無効にできます。
npn <protocols>
使用可能なコンテキスト:tcp, http
TLSのNPN拡張を有効にし、指定したプロトコルリストを、NPNで選択できる上位プロトコルとして通知します。リストはプロトコル名をカンマで区切ったもので、たとえば"http/1.1,http/1.0”(引用符なし)です。SSLライブラリーを、TLS拡張のサポートを有効にしてビルドしている必要があります(haproxy -vvで確認できます)。NPN拡張はALPN拡張に置き換えられています(“alpn"キーワードを参照)が、ALPNはOpenSSL 1.0.2以降でしか使用できません。
observe <mode>
使用可能なコンテキスト:tcp, http
サーバーとの通信を監視し、その結果に応じて正常性を調整する機能を有効にします。デフォルトでは無効で、有効にするにはヘルスチェックも有効にする必要があります。サポートするモードは"layer4"と"layer7"の二つです。layer4モードでは、TCP接続の成功または失敗だけを考慮します。HTTPプロキシでのみ許可されるlayer7では、HTTPコードの正否、ヘッダーを解析できない状況、タイムアウトなど、サーバーから受信したレスポンスを検証します。有効なステータスコードは100から499まで、および501と505です。
参照:“check”、“on-error”、“error-limit”。
on-error <mode>
使用可能なコンテキスト:tcp, http, log
十分な回数の連続エラーを検出した場合の動作を選択します。現在、次の四つのモードを使用できます。
- fastinter:fastinterを強制します。
- fail-check:チェックの失敗を模擬し、fastinterも強制します(デフォルト)。
- sudden-death: 致命的になる直前のヘルスチェック失敗を模擬し、fastinterを強制します。さらに一度チェックが失敗すると、サーバーをダウンとマークします。
- mark-down:サーバーを直ちにダウンと判定し、fastinterを強制します。
参照:“check”、“observe”、“error-limit”。
on-marked-down <action>
使用可能なコンテキスト:tcp, http, log
サーバーがダウンと判定されたときの動作を変更します。現在、使用可能なアクションは一つです。
- shutdown-sessions: 相手とのストリームを終了します。この設定を有効にすると、サーバーが停止した際、そのサーバーへのすべての接続を直ちに終了します。ヘルスチェックが単純な接続状態より複雑な状況を検出し、長いタイムアウトのためにサービスが長時間応答しないままになる場合に、使用できることがあります。たとえば、データベースが応答不能になり、既存の接続を再利用する見込みがないとヘルスチェックが検出した場合です。この方法で終了した接続は、‘D’(“Down”)の終了コードでログに記録します。
アクションはデフォルトで無効です。
on-marked-up <action>
使用可能なコンテキスト:tcp, http, log
サーバーが稼働中と判定されたときの動作を変更します。現在、使用可能なアクションは一つです。
- shutdown-backup-sessions: すべてのバックアップサーバー上のストリームを終了します。対象のサーバーがバックアップ状態ではなく、無効でもない場合(有効な重みが> 0である必要があります)だけ実行します。LDAPやSQLなどの長時間セッションを扱う場合、復旧した稼働系サーバーにすべてのトラフィックを強制的に戻すために使えることがあります。ただし、未完了のトランザクションなど、解消しようとしたものより大きな問題を引き起こす場合があるため、この機能の使用には細心の注意を払ってください。サーバーの稼働に伴って終了したストリームは、‘U’(“Up”)の終了コードでログに記録します。
アクションはデフォルトで無効です。
pool-conn-name <expr>
使用可能なコンテキスト: http
バックエンド接続を確立すると、この式を評価して接続名を生成します。この名前は、アイドル状態のサーバー接続プール内で、接続を識別する主要なプロパティの一つです。“http-reuse"キーワードを参照してください。リクエストが既存のアイドル接続を探す際には、この式を評価して同一の接続を照合します。
バックエンド接続でSSLのSNIを使用する場合、接続名には"sni"式の結果を自動的に割り当てます。これは最も一般的な使い方に適しています。より高度な設定では、“pool-conn-name"で上書きできます。
参照:“http-reuse”、“sni”。
pool-low-conn <max>
使用可能なコンテキスト: http
サーバーのアイドル接続数の下限を設定します。接続数がこの値を下回ると、スレッドは別のスレッドから接続を取得しようとしません。非常に高速なサーバーを多数使う環境で、CPUの使われ方を改善するのに役立つ場合があります。一つのスレッドに接続が集まり、その後スレッド間を移動するのを防ぎ、すべてのスレッドが常にいくつかのアイドル接続を保持できるようにするためです。一般的にはスレッド数の二倍にすると、応答時間が一ミリ秒未満の場合でも、すでに非常によい性能が得られるようです。デフォルトはゼロで、どのアイドル接続もいつでも使用できます。通常の用途には、この設定を推奨します。“http-reuse"と同じ原則に従って共有できる接続だけが対象です。“tune.idle-pool.shared"でスレッド間の接続共有を無効にした場合、この設定を使って各スレッドに常にいくつかの接続を保持させることが非常に重要になる場合があります。そうしないと、スレッド数が増えるにつれて接続の再利用率が下がります。
pool-max-conn <max>
使用可能なコンテキスト: http
サーバーのアイドル接続数の上限を設定します。-1は無制限、0はアイドル接続を保持しないことを意味します。デフォルトは-1です。アイドル接続を有効にすると、どのクライアントセッションにも属さなくなったアイドル接続を専用プールへ移し、後から来るクライアントが使える状態に保ちます。“http-reuse"と同じ原則に従って共有できる接続だけが対象です。
pool-purge-delay <delay>
使用可能なコンテキスト: http
アイドル接続の削除を開始するまでの時間を設定します。<delay>の間隔ごとに、アイドル接続の半分を閉じます。0は、アイドル接続を一切保持しないことを意味します。デフォルトは5sです。
port <port>
使用可能なコンテキスト:tcp, http, log
“port"パラメーターを使うと、ヘルスチェックやエージェントチェックを別のポートへ送ることができます。サーバーによっては、アプリケーションそのものよりもヘルスチェックに適した複雑な試験を行える、専用のコンポーネントにポートを割り当てたい場合があります。たとえば、inetdで単純なスクリプトを動かす構成は一般的です。“check"パラメーターを設定していない場合、このパラメーターは無視します。“addr"パラメーターも参照してください。
proto <name>
使用可能なコンテキスト:tcp, http
このサーバーへの送信接続に使用するマルチプレクサーのプロトコルを強制的に指定します。バックエンドのモード(TCPまたはHTTP)と互換性がなければなりません。また、バックエンド側で使用できる必要があります。利用可能なプロトコルの一覧はhaproxy -vvで表示されます。プロトコルの属性として、モード(TCP/HTTP)、使用側(FE/BE)、mux名、フラグが表示されます。
一部のプロトコルでは、サーバー側でヘッドオブラインブロッキングが起こります(flag=HOL_RISK)。また、アップグレードをサポートしないプロトコルもあります(flag=NO_UPG)。HTXとの互換性も表示します(flag=HTX)。
server行の"proto"ディレクティブの引数に使用できるプロトコルは、次のとおりです。
このオプションの目的は、このサーバーに確立するすべての接続で、最適なマルチプレクサーのプロトコルを選ぶ処理を迂回することです。
ALPNまたはNPNの設定を行っている場合、問題を避けるため、指定するプロトコルはマルチプレクサーのプロトコルと互換性のあるものにすることを推奨します。たとえば、“proto h1"を設定した場合、ALPNを"h2"に設定することは推奨しません。
WebSocketストリームで別のプロトコルを使用するには、“ws"も参照してください。
QMuxは、TCP上で動作するQUICのサブセットです。次のプロトコルのドラフトに対応します:https://www.ietf.org/archive/id/draft-ietf-quic-qmux-01.html 。現在、haproxyでは実験的とみなされています。
quic-cc-algo { cubic | newreno | bbr | nocc }[(<args,...>)]
このサーバーを宛先とするすべての接続の輻輳制御アルゴリズムを選択する、QUIC固有の設定です。アルゴリズムはTCPで使用するものと似ています。すべてのカスタマイズオプションの詳しい説明は、同様の名前のbindオプションを参照してください。
デフォルト値:cubic
参照:“tune.quic.be.tx.pacing”、“tune.quic.be.cc.max-win-size”。
redir <prefix>
使用可能なコンテキスト: http
“redir"パラメーターは、このサーバー宛てのすべてのGETおよびHEADリクエストでリダイレクトモードを有効にします。HAProxyはリクエストをサーバーへ転送する代わりに、この接頭辞の直後に、要求されたURIのパス部分の先頭の’/‘から始まる文字列を続けた"Location"ヘッダーを付けて、“HTTP 302"レスポンスを送ります。そのため、<prefix>の末尾にはスラッシュを付けないことを推奨します。不正なリクエストはすべて拒否し、GETまたはHEAD以外のリクエストはサーバーが通常どおり処理します。レスポンス全体を生成するため、レスポンスのヘッダーの書き換えやCookieの挿入はできません。ただし、リクエスト内のCookieは引き続き解析するので、ローカルで障害が起きた場合に、ユーザーを離れた場所へ誘導する方法として十分に使用できます。主な用途は、クライアントを静的コンテンツのサーバーへ直接接続させて、帯域幅を増やすことです。注意:ここでは絶対に相対的な場所を指定しないでください。クライアントとHAProxyの間でループが発生します。
例:server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
renegotiate
使用可能なコンテキスト:tcp, http, log
指定のSSLバックエンドで、安全な再ネゴシエーションの仕組み(RFC 5746 TLS Renegotiation Indication Extension)を有効にします。SSLクライアントが再ネゴシエーション要求を送るという意味ではなく、サーバーから要求された場合に、バックエンドが再ネゴシエーションできるようにするだけです。基盤となるSSLライブラリーが、実際に再ネゴシエーションをサポートしている必要もあります。このオプションは、グローバル設定の"ssl-default-server-options"でも使用できます。TLS 1.3では再ネゴシエーションはできません。“renegotiate"と"no-renegotiate"のどちらも指定しない場合、SSLライブラリーのデフォルト動作を維持します。たとえば、OpenSSLは安全な再ネゴシエーションをデフォルトで有効にしますが、AWS-LCは無効にします。
rise <count>
使用可能なコンテキスト:tcp, http, log
“rise"パラメーターは、ヘルスチェックが連続して<count>回成功すると、サーバーを稼働中とみなすことを指定します。未指定の場合、デフォルトは2です。“check”、“inter”、“fall"パラメーターも参照してください。
resolve-opts <option>,<option>,… 使用可能なコンテキスト: tcp, http, log
このサーバーに関連するDNS解決に適用するオプションのカンマ区切りリストです。
使用可能なオプション:
-
allow-dup-ip既定では、実行時のDNS名前解決を使用している場合、HAProxyはバックエンド内でIPアドレスが重複しないようにします。ただし、同じバックエンド内で同じFQDNから名前解決される二つのサーバーが、同じIPアドレスを持つことが適切な場合もあります。その場合は、このオプションを有効にしてください。これはprevent-dup-ipの逆です。
-
ignore-weight SRVレコード内で設定した重みをすべて無視します。“agent-check"やランタイムAPIなど、別の方法で重みを制御したい場合に役立ちます。
-
prevent-dup-ip サーバーでHAProxyのデフォルトの動作を強制します。同じバックエンド内にあり、同じfqdnを共有するサーバーにすでに設定したIPアドレスの再利用を防ぎます。allow-dup-ipの逆です。
例:
allow-dup-ipオプションを設定した場合:
- ネームサーバーが単一のIPアドレスを返した場合、両方のサーバーがそのアドレスを使用します。
- ネームサーバーが2個のIPアドレスを返した場合、各サーバーは異なるアドレスを選びます。
デフォルト値:未設定
resolve-prefer <family>
使用可能なコンテキスト:tcp, http, log
サーバーでDNS名前解決が有効になっており、異なるアドレスファミリーのIPアドレスが複数返された場合、HAProxyは"resolve-prefer"パラメーターで指定したファミリーのIPアドレスを優先して使用します。特定のファミリーの使用を厳密に強制するには、globalキーワード"dns-accept-family"も参照してください。指定できるファミリーは"ipv4"と"ipv6"です。
デフォルト値:ipv6
例:
resolve-net <network>[,<network[,...]]
使用可能なコンテキスト:tcp, http, log
このオプションは、指定したネットワークに一致するIPアドレスを優先して選択します。クラウド環境でローカルIPアドレスを優先する場合に便利です。クラウドの高可用性サービスが、複数の異なるデータセンターにある多数のIPアドレスで公開される場合があります。データセンター間の遅延は無視できないため、このパッチによってローカルのデータセンターを優先できます。設定したネットワークに一致するアドレスがない場合は、別のアドレスを選択します。
例:
resolvers <id>
使用可能なコンテキスト:tcp, http, log
現在のサーバーのホスト名を解決するために、既存の"resolvers"セクションを指定します。resolversを使う場合は、libcによる名前解決を無効にすることが推奨されることが多いですが、例外もあります(5.3.1節 を参照)。いずれの場合も、この点を見落とさないよう、resolversの使用時には"init-addr"を明示的に指定するのがよい方法です。
例:
実装の詳細と注意すべき落とし穴は、セクション5.3 も参照してください。
send-proxy
使用可能なコンテキスト:tcp, http
“send-proxy"パラメーターは、このサーバーに確立するすべての接続でPROXYプロトコルを使用するよう強制します。PROXYプロトコルは、受け入れた接続のレイヤー3/4のアドレスを相手に通知するので、上位層のプロトコルにかかわらず、クライアントのアドレスや、クライアントがアクセスした公開アドレスを相手が把握できます。“accept-proxy"または"accept-netscaler-cip"を指定したリスナーで受け入れた接続では、通知されたアドレスを使います。サポートするアドレスファミリーはTCPv4とTCPv6だけです。Unixソケットなど、ほかのファミリーではUNKNOWNを報告します。このオプションを使うサーバーは、“accept-proxy"を設定してリッスンする別のHAProxyインスタンスに、そのまま連結できます。サーバーがこのプロトコルに対応していない場合、この設定を使用してはいけません。このオプションを設定すると、サーバーに送るヘルスチェックにも自動的にPROXYプロトコルを使います。ただし、“port"または"addr"ディレクティブを明示した場合は例外で、PROXYプロトコルを使うには"check-send-proxy"も明示する必要があります。このセクションの"no-send-proxy"オプションと、“bind"キーワードの"accept-proxy"および"accept-netscaler-cip"オプションも参照してください。
send-proxy-v2
使用可能なコンテキスト:tcp, http
“send-proxy-v2"パラメーターは、このサーバーに確立するすべての接続でPROXYプロトコルのバージョン2を使用するよう強制します。PROXYプロトコルは、受け入れた接続のレイヤー3/4のアドレスを相手に通知するので、上位層のプロトコルにかかわらず、クライアントのアドレスや、クライアントがアクセスした公開アドレスを相手が把握できます。ALPNのネゴシエーションが済んでいれば、その情報も送ります。サーバーがこのバージョンのプロトコルに対応していない場合、この設定を使用してはいけません。このセクションの"no-send-proxy-v2"オプションと、“bind"キーワードのsend-proxyオプションも参照してください。
set-proxy-v2-tlv-fmt(<id>) <fmt>
使用可能なコンテキスト:tcp, http
“set-proxy-v2-tlv-fmt"パラメーターは、PROXYプロトコルのバージョン2で任意のTLVを送るために使います。定義済みのTLV型の型番号(<id>)の範囲については、PROXYプロトコル仕様のセクション2.2.8.を参照してください。一方、値は最大長の65,535バイトを超えない限り、自由に選べます。“fc_pp_tlv"のサンプル取得でフロントエンドが受信したTLVを取り出し、転送するためにも使えます。serverまたはdefault-serverのオプションとして使用できます。PPv2のTLVを実際に送信するため、send-proxy-v2と組み合わせて使う必要があります。
例: server srv1 192.168.1.1:80 send-proxy-v2 set-proxy-v2-tlv-fmt(0x20) %[fc_pp_tlv(0x20)]
この場合、型が0x20のTLVを文字列として取得し、新たに作成する同じく型が0x20のTLVの値に設定します。
proxy-v2-options <option>[,<option>]*
使用可能なコンテキスト:tcp, http
“proxy-v2-options"パラメーターは、“send-proxy-v2"を使用する場合に、PROXYプロトコルのバージョン2で送信するオプションを追加します。使用できるオプションは次のとおりです。
- ssl:“send-proxy-v2-ssl"も参照してください。
- cert-cn:“send-proxy-v2-ssl-cn"も参照してください。
- ssl-cipher:使用する暗号の名前です。
- cert-sig:使用する証明書の署名アルゴリズムです。
- cert-key:使用する証明書の鍵アルゴリズムです。
- authority: クライアントが渡したホスト名の値です(TLS接続のSNIのみサポートします)。
- crc32c:PROXYv2ヘッダーのチェックサムです。
- unique-id: フロントエンドの"unique-id-format"で生成した一意のIDを、PROXYv2ヘッダー内で送ります。この一意のIDは、主に"mode tcp"向けです。生成した一意のIDはKeep-Alive接続内の最初のHTTPリクエストにも使用するため、“mode http"では予期しない結果になることがあります。
send-proxy-v2-ssl
使用可能なコンテキスト:tcp, http
“send-proxy-v2-ssl"パラメーターは、このサーバーに確立するすべての接続でPROXYプロトコルのバージョン2を使用するよう強制します。PROXYプロトコルは、受け入れた接続のレイヤー3/4のアドレスを相手に通知するので、上位層のプロトコルにかかわらず、クライアントのアドレスや、クライアントがアクセスした公開アドレスを相手が把握できます。さらに、PROXYプロトコルのSSL情報拡張を、PROXYプロトコルヘッダーに追加します。サーバーがこのバージョンのプロトコルに対応していない場合、この設定を使用してはいけません。このセクションの"no-send-proxy-v2-ssl"オプションと、“bind"キーワードの"send-proxy-v2"オプションも参照してください。
send-proxy-v2-ssl-cn
使用可能なコンテキスト:tcp, http
“send-proxy-v2-ssl"パラメーターは、このサーバーに確立するすべての接続でPROXYプロトコルのバージョン2を使用するよう強制します。PROXYプロトコルは、受け入れた接続のレイヤー3/4のアドレスを相手に通知するので、上位層のプロトコルにかかわらず、クライアントのアドレスや、クライアントがアクセスした公開アドレスを相手が把握できます。さらに、PROXYプロトコルのSSL情報拡張と、クライアント証明書がある場合はそのsubjectのCommon Nameも、PROXYプロトコルヘッダーに追加します。サーバーがこのバージョンのプロトコルに対応していない場合、この設定を使用してはいけません。このセクションの"no-send-proxy-v2-ssl-cn"オプションと、“bind"キーワードの"send-proxy-v2"オプションも参照してください。
shard <shard>
使用可能なコンテキスト:peers
このパラメーターは、peersプロトコルによるスティックテーブルの同期でのみ使用します。“shard"パラメーターは、分散用ハッシュ値がこのシャードに一致するキーについて、スティックテーブルの更新をすべて受け取るピアを指定します。指定できる値は0から、“peers"セクションの"shards"パラメーターの値までです。デフォルト値の0では、すべてのキーの更新をピアが受け取ります。“shards"より大きい値は無視します。ローカルピアに指定した値も、すべて無視します。
例:
sigalgs <sigalgs>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合にのみ使用できます。TLSv1.2とTLSv1.3のハンドシェイク中にネゴシエーションする署名アルゴリズムのリストを表す文字列を設定します。文字列の形式は、OpenSSLのmanページ"man 3 SSL_CTX_set1_sigalgs"に定義されています。中間装置との互換性が必要な場合を除き、この設定の使用は推奨しません。
slowstart <start_time_in_ms>
使用可能なコンテキスト:tcp, http
サーバーの"slowstart"パラメーターには、復旧したばかりのサーバーが最大速度で動作するまでの時間をミリ秒で指定します。ほかの時間パラメーターと同様に、{ us, ms, s, m, h, d } の別の単位を明示して入力することもできます。この期間中、速度は0から100%まで線形に増加します。この制限は、次の二つのパラメーターに適用されます。
-
maxconn: サーバーが受け入れる接続数は、(minconn,maxconn,fullconn)で定義した通常の動的な上限の1から100%まで増加します。
-
weight: バックエンドが動的な重み付きアルゴリズムを使用する場合、重みは1から100%まで線形に増加します。この場合、ヘルスチェックのたびに重みを更新します。このため、段階数を最大にするには、“inter"パラメーターを"slowstart"より小さくすることが重要です。
HAProxyの起動時にはslowstartを適用しません。適用すると、稼働中のサーバーに問題を引き起こすためです。以前に障害状態と認識したサーバーにのみ適用します。
sni <expression>
使用可能なコンテキスト:tcp, http, log, peers, ring
“sni"パラメーターは、サンプル取得式を評価し、結果を文字列に変換して、サーバーへ送るTLSのSNI拡張のホスト名として使います。代表的な用途は、TCP/SSLを橋渡しする構成で、“ssl_fc_sni"サンプル取得を式に指定し、クライアントから受け取ったSNIを送ることです。HTTPSでは、この方法を使用してはいけません。代わりにreq.hdr(host)を使うことを推奨します。HTTPSのSNIは常にHostフィールドと一致する必要があり、クライアントは同じ接続上で異なるホスト名を使用できるためです。推奨設定の"verify required"を指定すると、結果の名前をサーバー証明書内の名前とも照合します。詳細は"verify"ディレクティブを参照してください。ヘルスチェック用のSNIを設定したい場合は、“check-sni"ディレクティブの説明を参照してください。
デフォルトでは、serverキーワード"pool-conn-name"で上書きしない限り、SNIを"http-reuse"の接続名に割り当てます。
sni-auto
使用可能なコンテキスト:tcp, http, log, peers, ring
“sni-auto"パラメーターは、まだ値が設定されていなければ、SNIの自動選択を有効にします。“sni"式を"req.hdr(host),field(1,:)“に設定し、サーバーに送るリクエストのHost名からポート番号を除いたものを、SNIとして提示します。デフォルトで有効ですが、“default-server"ディレクティブからデフォルト値として継承した"no-sni-auto"を取り消すため、“server"設定として使うこともできます。また、“default-server"設定として使い、以前の"default-server"の"no-sni-auto"設定を取り消すこともできます。
HTTPS接続では、リクエストのhostヘッダーの値が見つかれば、それに基づいてSNIを選択します。見つからない場合は未設定のままです。他のプロトコルでは、このオプションは無視します。
SNIの自動選択を使用する場合、serverキーワード"pool-conn-name"で上書きしない限り、その値を"http-reuse"の接続名に割り当てます。
SSLヘルスチェックでSNIの自動選択を有効にするには、“check-sni-auto"オプションを参照してください。
source <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]
使用可能なコンテキスト:tcp, http, log, peers, ring
“source"パラメーターは、サーバーへの接続時に使用する送信元アドレスを設定します。これを参照するサーバーにだけ適用する点を除き、バックエンドの"source"キーワードとまったく同じパラメーターと原理に従います。詳細は"source"キーワードを参照してください。
さらに、server行の"source"では、下限と上限をダッシュ(’-’)で区切り、送信元ポートの範囲を指定できます。OSによっては、送信元ポートの範囲を指定するときに、有効なIPアドレスが必要な場合があります。複数のサーバーに同じIPアドレスと範囲を指定してもかまいません。これにより、同時接続の総数64kという上限を回避でき、上限はサーバーごとに64k接続になります。
Linux 4.2/libc 2.23以降では、ポートを指定せずに送信元アドレスを指定する接続に、IP_BIND_ADDRESS_NO_PORTを設定します。
ssl
使用可能なコンテキスト:tcp, http, log, peers, ring
サーバーへの発信接続でSSL暗号化を有効にします。SSLでサーバーに接続する場合、“verify"でサーバー証明書を検証することが極めて重要です。検証しないと、通信は容易な中間者攻撃を受けやすくなり、SSLが役に立たなくなります。このオプションを使うと、ヘルスチェックも自動的にSSLで送ります。ただし、“port"または"addr"ディレクティブで、別の場所へチェックを送るよう指定している場合は例外です。“ssl"オプションを無効にするには"no-ssl"を、SSLヘルスチェックを強制するには"check-ssl"を参照してください。
ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信でSSLを使用する場合に、<version>以下のバージョンを使うよう強制します。グローバル設定の"ssl-default-server-options"でも使用できます。“ssl-min-ver"も参照してください。
ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーとの通信でSSLを使用する場合に、<version>以上のバージョンを使うよう強制します。グローバル設定の"ssl-default-server-options"でも使用できます。“ssl-max-ver"も参照してください。
ssl-reuse
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"no-ssl-reuse"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"no-ssl-reuse"設定を取り消すこともできます。
stick
使用可能なコンテキスト:tcp, http
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"non-stick"設定を取り消すため、“server"設定として使用できます。また、“default-server"設定として使い、以前の"default-server"の"non-stick"設定を取り消すこともできます。
strict-maxconn
使用可能なコンテキスト:tcp, http
サーバーのmaxconnという名前は、実際の意味を十分には表していません。実際に設定するのは、サーバーに送るリクエスト数の上限であり、アイドル接続を含めると、サーバーへの接続の総数はそれを超える場合があります。サーバーへの接続数を厳密に制限する必要がある場合は、strict-maxconnを追加できます。指定すると、maxconnを超える数の接続をサーバーに確立することはなく、必要に応じて接続の再利用や終了を試みます。ただし、新しい接続を確立できず、利用可能なアイドル接続もない場合、リクエストが失敗することがあります。認証が行われたことで、特定のセッションだけに結び付いた"private"接続が確立されている場合などに起こり得ます。
socks4 <addr>:<port>
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、サーバーへの発信接続でアップストリームのsocks4トンネルを有効にします。使用しても、デフォルトではヘルスチェックがsocks4を経由するようにはなりません。有効にするには、“check-via-socks4"キーワードを使用する必要があります。
tcp-md5sig <password>
使用可能なコンテキスト:tcp, http, log, peers, ring
このサーバーへのすべての発信接続で、TCP MD5署名(RFC 2385 Protection of BGP Sessions via the TCP MD5 Signature Option)を有効にします。このオプションはLinuxでのみ使用できます。有効にすると、<password>文字列を使い、すべてのTCPセグメントに16バイトのMD5ダイジェストで署名します。これにより、TCP接続をなりすましから保護します。主な用途は、偽造されたTCPセグメントが接続ストリームに挿入される攻撃から、BGPを保護することです。ただし、非常に長く存続するTCP接続全般で役立つ場合があります。
tcp-ut <delay>
使用可能なコンテキスト:tcp, http, log, peers, ring
このサーバーへのすべての発信接続にTCP User Timeoutを設定します。このオプションはLinux 2.6.37以降で使用できます。指定した時間内に確認応答を受け取れないデータを含むソケットに対し、HAProxyがタイムアウトを設定できるようにします。リモート端末やデータベースの接続プールなど、長いアイドル期間のある長時間接続で特に役立ちます。そのような接続では、長いアイドル期間を許容するために、クライアントとサーバーのタイムアウトを長く保つ必要があります。一方、接続(およびクライアントのセッション)に関連するすべてのリソースを解放するため、サーバーが消失したことを検出するのも重要です。ほかの代表的な用途として、ヘルスチェックが遅すぎる場合や、ヘルスチェックが無効になるソフトリロード中に、停止したサーバーへの接続を強制的に終了させることも挙げられます。引数は時間で、デフォルトの単位はミリ秒です。通常のTCP接続だけに作用し、ほかのプロトコルでは無視します。
tfo
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、対応するシステム(現在はLinuxカーネル >= 4.11のみ)で、サーバーへの接続時にTCP Fast Openを使用できるようにします。TCP Fast Openの詳細については、bindの"tfo"オプションを参照してください。tfoを使用する場合は、“retry-on"に"conn-failure”、“empty-response”、“response-timeout"キーワードも指定するべきです。そうしないと、障害時にHAProxyが接続を再試行できません。“no-tfo"も参照してください。
track [<backend>/]<server>
使用可能なコンテキスト:tcp, http, log
このオプションを使うと、別のサーバーを追跡して、対象サーバーの現在の状態を設定できます。追跡の連鎖の最後にあるサーバーでヘルスチェックが有効になっていれば、別のサーバーを追跡しているサーバーを追跡することもできます。<backend>を省略した場合は、現在のバックエンドを使用します。disable-on-404を使う場合は、両方のプロキシで有効にする必要があります。
例:
tls-tickets
使用可能なコンテキスト:tcp, http, log, peers, ring
このオプションは、“default-server"ディレクティブからデフォルト値として継承した"no-tls-tickets"を取り消すため、“server"設定として使用できます。TLSチケットの仕組みを使用するのはTLS 1.2までです。チケットの鍵を定期的にローテーションしない限り(リロード、または"tls-ticket-keys"を使用)、TLSチケットによって前方秘匿性が損なわれます。また、“default-server"設定として使い、以前の"default-server"の"no-tls-tickets"設定を取り消すこともできます。
verify [none|required]
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用できます。’none’の場合、サーバー証明書を検証しません。それ以外の場合、まず証明書のsubjectおよびsubjectAlternateNames属性にある名前が、“sni"ディレクティブで渡した名前、またはそれを指定していなければ"verifyhost"ディレクティブで渡した静的なホスト名と一致することを確認します。その後、‘ca-file’のCAと、任意指定の’crl-file’のCRLを使って、サーバーから渡された証明書を検証します。照合する名前が見つからない場合、証明書内の名前は無視します。このため、SNIを使わない場合には"verifyhost"の使用が重要です。検証に失敗すると、ハンドシェイクを中断します。SSLでサーバーに接続する際、サーバー証明書の検証は極めて重要です。検証しないと、通信は容易な中間者攻撃を受けやすくなり、SSLがまったく役に立たなくなります。globalセクションに"ssl_server_verify"がない限り、“verify"のデフォルトは"required"です。
verifyhost <hostname>
使用可能なコンテキスト:tcp, http, log, peers, ring
この設定は、OpenSSLのサポートを組み込んでビルドした場合だけ使用でき、‘verify required’も指定した場合にだけ有効です。サーバーへの接続にSNIを使わなかった場合に、サーバー証明書との照合に使う、デフォルトの静的なホスト名を設定します。SNIを使わない場合、ホスト名の検証を有効にする唯一の方法です。この静的ホスト名を設定すると、SNI値を指定しないヘルスチェックにも使います。証明書内のどのホスト名も指定したホスト名と一致しない場合、ハンドシェイクを中断します。サーバーが提示する証明書内のホスト名には、ワイルドカードを含められます。“verify”、“sni”、“no-verifyhost"オプションも参照してください。
weight <weight>
使用可能なコンテキスト:tcp, http
“weight"パラメーターは、ほかのサーバーに対する相対的な重みを調整します。各サーバーは、重みの合計に対する自身の重みの割合に応じた負荷を受け取るので、重みが大きいほど負荷も高くなります。デフォルトの重みは1、最大値は256です。0にすると、サーバーは負荷分散に参加しませんが、永続性に基づく接続は引き続き受け入れます。このパラメーターでサーバーの処理能力に応じて負荷を分散する場合、たとえば10から100までのように、後で上下どちらにも十分に調整できる値から始めることを推奨します。
ws { auto | h1 | h2 }
使用可能なコンテキスト:http
このオプションは、WebSocketストリームを中継するときに使用するプロトコルを設定します。特に、RFC8441によるH2 WebSocketをサポートしていないHTTP/2バックエンドを使う場合に有用です。
デフォルトのモードは"auto"です。通常の通信と同じプロトコルを再利用します。ALPNを使う場合だけ動作が異なります。この場合、WebSocketストリームに限り、ALPNを"http/1.1"に下げることを試みます。ただし、設定されたサーバーのALPNにこの値が含まれている場合に限ります。
“h1"を指定すると、WebSocketストリームでHTTP/1.1を強制します。サーバーでSSL ALPNが有効なら、ALPNを通じて指定します。同様に、“h2"はHTTP/2.0 WebSocketを強制します。この値は慎重に使用してください。サーバーがRFC8441をサポートしている必要があり、そうでなければ、WebSocketの中継時にhaproxyがエラーを報告します。
NPNはALPN拡張への移行に伴い非推奨となっているため、考慮されません。
“alpn"と"proto"も参照してください。
5.3. DNSによるサーバーIPアドレスの解決
HAProxyでは、server行にホスト名を指定し、ネームサーバーを使ってそのIPアドレスを取得できます。デフォルトでは、起動時に設定ファイルを解析するときに名前を解決し、プロセスの存続期間中は結果をキャッシュします。ただし、これだけでは不十分な場合があります。たとえばAmazonでは、再起動後にサーバーのIPが変わったり、現在の負荷に応じてELBの仮想IPが変わったりすることがあります。
この章では、実行時にサーバーの名前解決を行うようにHAProxyを設定する方法を説明します。
実行時のサーバー名解決を有効にしているかどうかにかかわらず、“init-addr"パラメーターで無効にしない限り、HAProxyはデフォルトで起動時の設定解析中にlibcを通じて最初の名前解決を行います。
5.3.1. 全体の概要
はじめに説明したとおり、HAProxyの名前解決は、プロセスの存続期間中の異なる二つの段階で行われます。
実行時には、ほかのイベントによっても名前解決が開始されることがあります。
- サーバーのヘルスチェックが接続タイムアウトで終わった場合。サーバーのIPアドレスが変わった可能性があるため、新しいIPを知るには名前解決を開始する必要があります。
resolversを使う場合、サーバー名にはホスト名またはSRVラベルを指定できます。HAProxyは、アンダースコアで始まるものをすべてSRVラベルとみなします。SRVラベルを指定すると、対応するSRVレコードをDNSサーバーから取得し、そこに記載されたホスト名を使用します。SRVラベルは定期的に確認され、サーバーが追加または削除されると、HAProxyも自動的に同じ変更を行います。
次の点に注意してください。
-
すべてのネームサーバーに同時に問い合わせます。HAProxyは最初の有効なレスポンスを処理します。
-
すべてのサーバーがエラーを返すと、名前解決は無効(NX、timeout、refused)とみなされます。
-
HAProxyに実装されたDNSクライアントは非常に基本的なもので、OSのリゾルバーが扱える多数のオプションや高度な構成は理解できません。そのため、FQDNで指定したサーバーが常にちょうど一つのIPアドレスだけを持ち、再起動時などにときどき更新するような極めて単純な構成を除き、libcによる初期化時の名前解決とDNSによる実行時の名前解決を混在させないことを強く推奨します。このような混在構成では、アドレス更新時に障害が起こることが知られています。したがって、自分が何をしているかを正確に理解している場合を除き、server行で"resolvers"を使うときは、常に"init-addr"から"libc"を除外することを推奨します。
5.3.2. resolversセクション
このセクションには、HAProxyの名前解決に関する情報を記述します。resolversセクションは必要なだけ作成でき、各セクションには複数のネームサーバーを含められます。
起動時に、設定内に"default"という名前のresolversセクションがなければ、HAProxyはそのセクションを生成しようとします。このセクションはhttpclientがデフォルトで使うもので、parse-resolv-confキーワードを使用します。自動生成に失敗しても、HAProxyはエラーや警告を出しません。
resolversセクションに複数のネームサーバーが設定されている場合、HAProxyは最初の有効なレスポンスを使います。無効なレスポンスの場合は、最後のものだけを処理します。これは、速いサーバーが誤った、または古いレスポンスを返しても、遅いサーバーに有効な回答を返す機会を与えるためです。
各サーバーが異なる種類のエラーを返す場合、HAProxyは最後のエラーだけを使います。そのエラーに対して次の処理を行います。
たとえば、resolversセクションに2つのネームサーバーを設定している場合、次の状況が考えられます。
-
最初のレスポンスが有効なら、そのまま適用し、次のレスポンスは無視します。
-
最初のレスポンスが無効で次のレスポンスが有効なら、次のレスポンスを適用します。
-
最初のレスポンスがNX domainで次が切り詰められたレスポンスなら、HAProxyはクエリータイプを変更して再試行します。
-
最初のレスポンスがNX domainで次がタイムアウトなら、HAProxyはクエリータイプを変更して再試行します。
-
両方のネームサーバーへのクエリーがタイムアウトした場合、HAProxyは同じクエリータイプで再試行します。
DNSサーバーは、一度のDNSリクエストに対してすべてのIPを返すとは限らないため、HAProxyは以前の回答をキャッシュします。そのIPが返されないまま<hold obsolete>秒が経過すると、その回答は古くなったとみなされます。
resolvers <resolvers id>
<resolvers id>という名前の新しいネームサーバー一覧を作成します。前述のとおり、特別な名前"default"は常に存在し、明示的に宣言しなければ自動作成されます。httpclientなどの内部サービスはこれを使用します。“default"エントリーを宣言すると、これらのサービスの名前解決方法に影響します。
resolversセクションでは、次のパラメーターを指定できます。
accepted_payload_size <nb>
HAProxyが受け付け、このresolversセクションで設定されたすべてのネームサーバーに通知する最大ペイロードサイズを定義します。<nb>の単位はバイトです。未設定の場合、HAProxyは512(RFC 6891で定義された最小値)を通知します。
注意:指定可能な最大値は65535です。UDPでの推奨値は4096です。システムとネットワークが処理できると確信できる場合を除き、8192を超える値は推奨しません(UDPの最大ペイロードサイズは65507なので、それを超えても意味はありません)。大きなDNSレスポンスを処理するためにTCPネームサーバーだけを使う場合は、最大値の65535に設定することを推奨します。
nameserver <name> <address>[:port] [param*]
ネームサーバーを設定します。ネームサーバーの<name>は一意にすることを推奨します。デフォルトでは、<address>はデータグラム型とみなされます。つまり、特別なアドレス接頭辞(11項)を付けずにIPv4またはIPv6を設定すると、UDPプロトコルを使います。ストリームプロトコルのアドレス接頭辞を使うと、ネームサーバーはTCPなどのストリームサーバーとみなされ、5.2項の"server"パラメーターのうちDNS解決に関係するものが適用されます。注意:現在、TCPモードでは同じ接続上で4つのクエリーをパイプライン処理します。アイドル接続は5秒ごとにまとめて削除されます。“maxconn"を設定して同時接続数を制限できます。また、サーバーがサポートしていればTLSも使用できるはずです。
parse-resolv-conf
/etc/resolv.confに記載されたすべてのネームサーバーを、このresolversのネームサーバー一覧に追加します。順序は、/etc/resolv.confの各ネームサーバーを、このディレクティブの位置でresolversセクションに個別に記述した場合と同じです。
hold <status> <period>
DNSレスポンス<status>を受信すると、サーバーの状態をUPからDOWNに変更すべきか判断します。そのために、過去の<period>内に有効なステータスを受信しており、今回受信した無効なステータスを打ち消せるか確認します。
`<status>`:最後の名前解決のステータス。
nx NXDOMAINステータスを受信した後、直近の指定期間内に
有効なステータスを受信したか確認します。
refused REFUSEDステータスを受信した後、直近の指定期間内に
有効なステータスを受信したか確認します。
timeout "timeout retry"が発生した後、直近の指定期間内に
有効なステータスを受信したか確認します。
other その他の無効なステータスを受信した後、直近の指定期間内に
有効なステータスを受信したか確認します。
valid "http-request do-resolve"と
"tcp-request content do-resolve"アクションにのみ適用します。
次の名前解決を開始するまで、サーバーが有効なレスポンスを
保持する期間を定義します。
サーバーの動的な名前解決には影響しません。
obsolete 更新された回答レコードを受信した後、古いDNSレコードを
削除するまでの待機時間を定義します。
SRVレコードに適用します。
`<period>`:有効なレスポンスを受信している必要がある、現在から遡った期間。
HAProxyの時間形式に従い、
デフォルトの単位はミリ秒です。
IPアドレスの特定を動的なDNS解決に依存するサーバーでは、NXDOMAINなどの無効なDNSレスポンスを受信すると、状態がUPからDOWNに変わります。holdディレクティブは、有効なレスポンスを確認するためにどこまで過去に遡るかを定義します。<period>内に有効なレスポンスを受信していれば、今回受信した無効なステータスは無視します。
直近の指定期間内に有効なレスポンスを受信していなければ、サーバーはDOWNとマークされます。たとえば、“hold nx 30s"を設定しており、最後に受信したDNSレスポンスがNXDOMAINの場合、過去30秒以内に有効なレスポンスを受信していなければ、サーバーはDOWNとマークされます。
DOWN状態のサーバーは、DNSサーバーから有効なステータスを受信すると直ちにUPとマークされます。
“hold valid"と"hold obsolete"には、それぞれ別の動作があります。
デフォルト値は、“valid"が10s、“obsolete"が0s、それ以外が30sです。
resolve_retries <nb>
サーバー名の解決を断念するまでに送信するクエリーの数<nb>を定義します。デフォルト値は3です。
ネームサーバーがタイムアウトした場合、またはDNSクエリータイプを切り替える一連の処理がすべて終わり、デフォルトのANYクエリータイプからやり直す必要がある場合に、再試行します。
timeout <event> <time>
名前解決に関するタイムアウトを定義します。<event>は<time>のタイムアウト期間を適用するイベントです。指定可能なイベント:- resolve:ほかの時間設定が適用されない場合に、名前解決を開始するデフォルトの時間。デフォルト値:1s - retry:有効なレスポンスを受信していない場合の、DNSクエリー間の時間。デフォルト値:1s <time>:イベントに関する時間。HAProxyの時間形式に従います。<time>はミリ秒で表します。
例:
15 - 6. キャッシュ
HAProxyは、faviconやcssなどの小さなオブジェクトを対象とするキャッシュを提供します。RAM上で動作する、最小限の保守で済む簡素なキャッシュです。
キャッシュには全スレッドで共有するメモリ領域を使用し、1kBのブロックに分割します。
オブジェクトが使われなくなると、有効期限にかかわらず、新しいオブジェクトを保存するために削除できます。新しいオブジェクトを割り当てる際は、最も古いオブジェクトから削除します。
キャッシュのキーには、hostヘッダーとURIのハッシュを使用します。
Unixソケットの “show cache” コマンドでキャッシュの状態を確認できます。詳細は管理ガイドの第9.3節 「Unixソケットコマンド」を参照してください。
キャッシュからオブジェクトを配信すると、ログのサーバー名は “<CACHE>” に置き換えられます。
6.1. 制約
次の場合、キャッシュはオブジェクトを保存せず、配信もしません。
-
レスポンスが200ではない場合。
-
レスポンスにVaryヘッダーがあり、process-varyオプションが無効になっているか、Varyの値に現在未対応のヘッダーが指定されている場合。現時点で対応しているのはaccept-encoding、referer、originのみです。
-
Content-Lengthとヘッダーサイズの合計が “max-object-size” を超える場合。
-
レスポンスをキャッシュできない場合。
-
レスポンスに明示的な有効期限(Cache-Controlのs-maxageまたはmax-ageディレクティブ、またはExpiresヘッダー)も、検証子(ETagまたはLast-Modifiedヘッダー)もない場合。
-
process-varyオプションが有効で、現在のレスポンスと同じプライマリーキーのエントリーがすでにmax-secondary-entries個存在する場合。
-
process-varyオプションが有効で、クライアントのaccept-encodingヘッダーによってレスポンスが変化する一方、そのエンコーディングが未知の場合。https://www.iana.org/assignments/http-parameters/http-parameters.xhtml に記載されていないエンコーディングが該当します。
-
リクエストがGETではない場合。
-
リクエストのHTTPバージョンが1.1未満の場合。
-
リクエストにAuthorizationヘッダーが含まれる場合。
6.2. 設定
キャッシュを設定するには、cacheセクションを定義し、対応するhttp-requestアクションとhttp-responseアクションを使ってプロキシから利用する必要があります。
6.2.1. cacheセクション
cache <name>
cacheセクションを宣言し、<name> という名前の共有キャッシュメモリを割り当てます。キャッシュサイズの指定は必須です。後述の “total-max-size” キーワードを参照してください。
max-age <seconds>
有効期間の上限を定義します。有効期限には、レスポンスのCache-Controlヘッダーにあるs-maxage、なければmax-ageディレクティブの値と、この設定値のうち小さいほうを使用します。デフォルト値は60秒なので、デフォルトではオブジェクトを60秒より長くキャッシュできません。
max-object-size <bytes>
キャッシュするオブジェクトの最大サイズを定義します。“total-max-size” の半分を超えてはいけません。未設定の場合はキャッシュサイズの256分の一になります。“max-object-size” より大きいオブジェクトは、すべてキャッシュされません。
max-secondary-entries <number>
キャッシュ内で同じプライマリーキーを持つセカンダリーエントリーの同時存在数の上限を定義します。Varyのサポートを有効にする必要があります。デフォルト値は10で、正の整数を指定してください。
process-vary <on/off>
Varyヘッダーの処理を有効または無効にします。無効の場合、このヘッダーを含むレスポンスはキャッシュされません。有効の場合は、すべての受信リクエストについて、リクエストヘッダーの一部から予備的なハッシュを計算し、それを使って各リクエストのセカンダリーキーを構成します(RFC 7234#4.1参照)。これにはCPUコストがかかる場合があります。現在、セカンダリーキーは ‘accept-encoding’、‘referer’、‘origin’ ヘッダーの内容から構成します。RFCでは ‘origin’ と ‘referer’ ヘッダーは単一値とされているため、いずれかを複数含むリクエストは不正な形式とみなすべきです。そのようなリクエストではセカンダリーキーを構成せず、キャッシュからレスポンスを配信することもありません。対処方法をサーバーに判断させるためです。デフォルト値はoff(無効)です。
total-max-size <megabytes>
RAM上のキャッシュサイズをメガバイト単位で定義します。この領域は1kBのブロックに分割され、キャッシュエントリーが使用します。最大値は4095です。
6.2.2. proxyセクション
キャッシュを利用するproxyセクションでは、要求されたオブジェクトをキャッシュから検索するため、“http-request” ルールセットに “cache-use” アクションを含める必要があります。また、取得したオブジェクトをキャッシュに保存または更新するため、“http-response” ルールセットに “cache-store” アクションを含める必要があります。いずれのアクションにも任意で条件を指定できます。たとえば、キャッシュできないことがわかっているサブディレクトリでは “cache-use” を省略したり、キャッシュする価値がないcontent-typeでは “cache-store” を省略したりできます。キャッシュのインデックスキーは “cache-use” アクションの実行時に計算されるため、このアクションを省略すると、レスポンス処理時にキャッシュを更新することもありません。
例:
16 - 7. ACLとサンプル取得
HAProxyは、リクエストやレスポンスのストリーム、クライアントやサーバーの情報、テーブル、環境情報などからデータを抽出できます。このデータ抽出をサンプル取得と呼びます。取得したサンプルはスティックテーブルのキーなど、さまざまな用途に使用できますが、最も一般的な用途は、パターンと呼ばれる定義済みの定数データとの照合です。
7.1. ACLの基本
アクセス制御リスト(ACL)は、任意の情報を定義済みパターンのリストと比較するための、名前付きの方法を宣言するものです。宣言しておくと後から必要に応じて呼び出せるという点で、多くのプログラミング言語の関数と実質的に同等と考えるとよいでしょう。評価の結果は一致または不一致のみで、多くのプログラミング言語の真偽値に相当します。プログラミング言語の関数とは異なり、ACLは同じ名前に照合方法を追加するために、必要なだけ重ねて定義できます。この場合、一致するものが見つかるまで、宣言順にすべて評価されます。
ACLを使用すると、コンテンツに応じた振り分けや、より一般的にはリクエスト、レスポンス、環境の状態から抽出した内容に基づく判断を柔軟に行えます。原理は単純です。
- ストリーム、テーブル、環境からデータサンプルを抽出します
- 必要に応じて、抽出したサンプルの形式を変換します
- サンプルに1つまたは複数のパターン照合方法を適用します
- パターンがサンプルと一致した場合にのみアクションを実行します
アクションは通常、リクエストのブロック、バックエンドの選択、ヘッダーの追加です。
テストを定義するには、“acl"キーワードを使用します。構文は次のとおりです。
これにより、新しいACL <aclname>を作成するか、既存のACLに新しいテストを追加します。これらのテストは、<criterion>で指定したリクエストまたはレスポンスの部分に適用され、省略可能なフラグ[flags]で調整できます。一部の条件は演算子にも対応しており、値の集合の前に指定できます。必要に応じてサンプルに変換演算子を適用することもでき、最初のキーワードの直後にキーワードをコンマ区切りで指定します。値は条件が対応する型で指定し、空白で区切ります。
ACL名は、大文字と小文字の英字、数字、’-’(ダッシュ)、’_’(アンダースコア)、’.’(ドット)、’:’(コロン)で構成する必要があります。ACL名は大文字と小文字を区別するため、“my_acl"と"My_Acl"は異なるACLです。
ACLの数に強制的な上限はありません。使用しないACLは少量のメモリーを消費するだけで、パフォーマンスには影響しません。
条件は通常、サンプル取得方法の名前、またはそのACL専用の派生形です。デフォルトのテスト方法は、サンプル取得方法の出力型によって暗黙的に決まります。ACLの派生形では、同じサンプル取得方法に対して別の照合方法を指定できます。変換に対応しているのは、サンプル取得方法だけです。
サンプル取得方法は、次のいずれかの型のデータを返します。
- 真偽値
- 整数(符号付きまたは符号なし)
- IPv4またはIPv6アドレス
- 文字列
- データブロック
コンバーターは、これらのデータを、いずれかの型のデータに変換します。たとえば、文字列を小文字の文字列に変換するコンバーターもあれば、文字列をIPv4アドレスに変換したり、IPアドレスにネットマスクを適用したりするコンバーターもあります。結果のサンプルの型は、リスト内で最後に適用したコンバーターの型になります。コンバーターを適用しない場合は、サンプル取得方法の型が使用されます。
各サンプルまたはコンバーターは特定の型のデータを返します。その型は、このドキュメントの各キーワードの説明に記載されています。標準のサンプル取得方法を使用してACLを宣言すると、一部の型では自動的にデフォルトの照合方法が適用されます。次の表にまとめます。
バイナリーサンプルを照合するには、照合方法を必ず指定する必要があります。以下を参照してください。
ACLエンジンは、これらの型を次の型のパターンと照合できます。
- 真偽値
- 整数または整数範囲
- IPアドレス/ネットワーク
- 文字列(完全一致、部分文字列、接尾辞、接頭辞、サブディレクトリ、ドメイン)
- 正規表現
- 16進数のブロック
現在、次のACLフラグがサポートされています。
“-f"フラグの後には名前を指定します。この名前は、マップとACLの名前の形式について説明した2.7.の形式に従う必要があります。複数のリストからパターンを読み込む場合は、"-f"引数を複数指定することもできます。既存のファイルを参照する場合、すべての行が個別の値として読み込まれます。空行とシャープ(’#’)で始まる行は無視されます。行頭の空白とタブはすべて削除されます。シャープで始まる有効なパターンをどうしても挿入する必要がある場合は、先頭に空白を付けることで、コメントと見なされないようにできます。データ型と照合方法に応じて、HAProxyは行を二分木に読み込み、非常に高速な検索を可能にすることがあります。IPv4と文字列の完全一致はこれに該当します。この場合、重複は自動的に削除されます。
“-M"フラグを指定すると、ACLでマップを使用できます。このフラグが設定されている場合、リストは2列のエントリーとして解析されます。第1列にはACLが使用するパターン、第2列にはサンプルが含まれます。サンプルは後からマップで使用できます。これは、マッピングを適用する前にマップ内のパターンの有無だけをACLで確認するという、まれなケースで役立ちます。
“-u"フラグは、ACLの一意のIDを強制的に指定します。この一意のIDは、ソケットインターフェースでACLを識別し、その値を動的に変更するために使用します。ファイルは、IDを設定しても常に名前で識別される点に注意してください。
また、"-i"フラグが適用されるのは、それ以降のエントリーです。それより前にファイルから読み込んだエントリーには適用されません。次に例を示します。
この例では、“exact-ua.lst"の各行は、リクエストの"user-agent"ヘッダーと完全一致で照合されます。次に、“generic-ua"の各行は、大文字と小文字を区別せずに照合されます。その後、単語"test"も、大文字と小文字を区別せずに照合されます。
“-m"フラグは、入力サンプルに対する特定のパターン照合方法を選択するために使用します。ACL専用の条件はすべて照合方法を暗黙的に指定するため、通常はこのフラグが不要です。ただし、汎用のサンプル取得方法で、パターンとの照合方法を指定する場合に役立ちます。明確な照合方法がないデータ型(文字列やバイナリーなど)を返すサンプル取得には、この指定が必要です。"-m"の後にパターン照合方法の名前を指定すると、その条件のデフォルトの照合方法に代わって、指定した方法が使用されます。これにより、当初想定されていなかった方法や、文字列を返すサンプル取得方法で内容を照合できます。照合方法は、パターンの解析方法にも影響します。そのため、照合用の接尾辞(_beg、_end、_sub…)が付いたサンプル取得と併用してはいけません。また、"-m"で複数のパターン照合方法を指定することもできません。
“-n"フラグは、DNS解決を禁止します。IPファイルの読み込み時に使用します。デフォルトでは、パーサーがIPアドレスを解析できない場合、解析した文字列をドメイン名の可能性があると見なし、DNS解決を試みます。"-n"フラグは、この名前解決を無効にします。不正なIPリストの検出に役立ちます。DNSサーバーに到達できない場合、タイムアウトを待つためにHAProxyの設定解析に何分もかかることがあります。その間、エラーメッセージは表示されません。"-n"フラグは、この動作を無効にします。また、実行時のACLの動的な変更では、この名前解決機能が無効になっている点にも注意してください。
ただし、いくつか制限があります。すべての照合方法を、すべてのサンプル取得方法で使用できるわけではありません。また、"-m"と”-f"を併用する場合、"-m"を先に指定する必要があります。パターン照合方法は、次のいずれかでなければなりません。
-
“found”: 要求したサンプルがストリーム内に見つかるかどうかだけを確認し、パターンとの比較は行いません。 混乱を避けるため、パターンを指定しないことを推奨します。この照合方法は、ヘッダーやCookieなどの 特定の内容の有無を検出するのに特に役立ちます。内容が空でも検出でき、比較やカウントは不要です。
-
“bool” : 値を真偽値として確認します。真偽値または整数値を返す取得方法にのみ適用でき、 パターンは指定しません。値がゼロまたはfalseの場合は一致せず、それ以外の値はすべて一致します。
-
“int” : 値を整数として照合します。整数と真偽値のサンプルに使用できます。 真偽値のfalseは整数の0、trueは整数の1に相当します。
-
“ip” : 値をIPv4またはIPv6アドレスとして照合します。IPアドレスのサンプルでのみ使用でき、 暗黙的に適用されるため、明示的に指定する必要はありません。
-
“bin” : 内容を、バイナリー列を表す16進文字列と照合します。 バイナリーまたは文字列のサンプルに使用できます。
-
“len” : サンプルの長さを整数として照合します。バイナリーまたは文字列のサンプルに使用できます。
-
“str” : 完全一致:内容を文字列と照合します。 バイナリーまたは文字列のサンプルに使用できます。
-
“sub” : 部分文字列の照合:内容に、指定した文字列パターンの少なくとも1つが含まれるか確認します。 バイナリーまたは文字列のサンプルに使用できます。
-
“reg” : 正規表現の照合:内容を正規表現のリストと照合します。 バイナリーまたは文字列のサンプルに使用できます。
-
“beg” : 接頭辞の照合:内容の先頭が、指定した文字列パターンと一致するか確認します。 バイナリーまたは文字列のサンプルに使用できます。
-
“end” : 接尾辞の照合:内容の末尾が、指定した文字列パターンと一致するか確認します。 バイナリーまたは文字列のサンプルに使用できます。
-
“dir” : サブディレクトリの照合:内容のうちスラッシュで区切られた部分が、指定した文字列パターンの いずれかと完全に一致するか確認します。バイナリーまたは文字列のサンプルに使用できます。
-
“dom” : ドメインの照合:内容のうちドットで区切られた部分が、指定した文字列パターンのいずれかと 完全に一致するか確認します。バイナリーまたは文字列のサンプルに使用できます。
たとえば、HTTPリクエスト内のCookie “JSESSIONID"の有無をすばやく検出するには、次のように指定できます。
バッファー内のデータの先頭500バイトに正規表現を適用するには、次のACLを使用します。
“-i"を使用すると正規表現ライブラリーが大幅に遅くなるシステムでは、次のように照合前にサンプルを小文字に変換できます。
ACL専用の条件には、すべてデフォルトの照合方法が暗黙的に指定されています。これらの条件は通常、元のサンプル取得方法の名前と照合方法を連結した名前になっています。たとえば、“hdr_beg"は、“hdr"取得方法で取得したサンプルに"beg"による照合を適用します。この照合方法を使用できるのは、コンバーターを付けず、キーワードを単独で使用した場合だけです。このようなACLキーワードの後にコンバーターを適用した場合、照合で重要になるのは最後のコンバーターの出力型であるため、ACLキーワードのデフォルトの照合方法は単に無視されます。ACL専用の条件はすべてサンプル取得方法に基づいているため、代わりに元のサンプル取得方法を使用し、"-m"で照合方法を明示的に指定することが常に可能です。
ACL専用の条件に対して”-m"で別の照合方法を指定した場合、その照合方法が基となるサンプル取得方法にそのまま適用されます。たとえば、次のACLはすべて完全に等価です。
次の表は、サンプルまたはコンバーターの型と、照合対象のパターンの型との互換性をまとめたものです。互換性のある組み合わせごとに、使用する照合方法の名前を示しています。その方法がデフォルトで、"-m"なしで動作する場合は、山括弧”>“と”<“で囲んでいます。
7.1.1. 真偽値の照合
真偽値の照合には値が不要で、指定した値はすべて無視されます。型が"boolean"のすべての取得方法では、デフォルトで真偽値による照合を使用します。真偽値による照合では、取得した値をそのまま返します。したがって、真偽値の"true"は常に一致し、“false"は決して一致しません。
整数値を返す取得方法でも、"-m bool"で真偽値による照合を強制できます。この場合、整数値の0は真偽値の"false"に変換され、それ以外のすべての値は"true"に変換されます。
7.1.2. 整数の照合
整数の取得方法では、デフォルトで整数による照合を使用します。真偽値の取得でも、"-m int"で整数による照合を強制できます。この場合、“false"は整数の0に、“true"は整数の1に変換されます。
整数による照合は、整数範囲と演算子にも対応しています。整数による照合が適用されるのは正の値だけである点に注意してください。範囲は、下限と上限をコロンで区切って表す値です。どちらの境界も省略できます。
たとえば、“1024:65535"は非特権ポートの範囲を表す有効な指定で、“1024:“も同様に使用できます。“0:1023"は特権ポートを表す有効な指定で、":1023"も同様に使用できます。
特別なケースとして、一部のACL関数は小数に対応していますが、これは実際にはドットで区切られた2つの整数です。たとえば、一部のバージョン検査で使用されます。範囲や演算子を含め、整数のすべての性質が、この小数にも適用されます。
使いやすくするため、比較演算子もサポートされています。範囲と演算子を併用してもあまり意味がなく、併用を避けることが強く推奨されている点に注意してください。同様に、値の集合に対して大小を比較することにも、あまり意味はありません。
整数の照合で使用できる演算子は次のとおりです。
たとえば、次のACLは、値が負のContent-Lengthヘッダーに一致します。
次のACLは、3.0から3.1まで(両端を含む)のSSLバージョンに一致します。
7.1.3. 文字列の照合
文字列の照合は、文字列またはバイナリーの取得方法に適用され、次の6つの形式があります。
-
完全一致(-m str):抽出した文字列がパターンと完全に一致する必要があります。
-
部分文字列の照合(-m sub):抽出した文字列内でパターンを検索し、 いずれかが見つかるとACLが一致します。
-
接頭辞の照合(-m beg):抽出した文字列の先頭とパターンを比較し、 いずれかが一致するとACLが一致します。
-
接尾辞の照合(-m end):抽出した文字列の末尾とパターンを比較し、 いずれかが一致するとACLが一致します。
-
サブディレクトリの照合(-m dir):抽出した文字列内の任意の位置で、スラッシュ(”/")、 文字列の先頭または末尾を境界としてパターンを検索します。いずれかのパターンが一致すると ACLが一致します。たとえば、文字列”/images/png/logo/32x32.png"は、"/images”、"/images/png”、 “images/png”、"/png/logo”、“logo/32x32.png”、“32x32.png"に一致しますが、“png"や"32x32"には一致しません。
-
ドメインの照合(-m dom):抽出した文字列内の任意の位置で、ドット(”.")、コロン(”:")、 スラッシュ(”/")、疑問符(”?")、文字列の先頭または末尾を境界としてパターンを検索します。 これはURLで使用するためのものです。パターンの先頭と末尾の区切り文字は無視されます。 いずれかのパターンが一致するとACLが一致します。たとえば、文字列 “http://www1.dc-eu.example.com:80/blah “には、“http”、“www1”、".www1”、“dc-eu”、 “example”、“com”、“80”、“dc-eu.example”、“blah”、":www1:"、“dc-eu.example:80"が一致しますが、 “eu"や"dc"には一致しません。フィルタリングやルーティングでドメインの接尾辞を照合する用途には、 一般に適していません。たとえば、別のドメインの前に一致する接頭辞を付けるだけで、 ルーティングを簡単に欺けるためです。
文字列の照合は、渡された文字列をそのまま使用します。ただし、バックスラッシュ(”\")は例外で、空白などの文字をエスケープするために使用できます。最初の文字列の前に”-i"フラグを指定すると、大文字と小文字を区別せずに照合します。文字列”-i"と照合するには、これを2番目に指定するか、最初の文字列の前に”–“フラグを指定します。もちろん、文字列”–“と照合する場合も同様です。
ヌルバイト(0x00)を含む可能性があるバイナリーの取得に、文字列の照合を使用しないでください。最初のヌルバイトが現れた時点で比較が停止するためです。代わりに、まずhexコンバーターで取得したバイナリーを16進文字列に変換してください。
例:
7.1.4. 正規表現(regex)による照合
文字列の照合と同様に、正規表現の照合も渡された文字列をそのまま使用します。ただし、バックスラッシュ(”\")は例外で、空白などの文字をエスケープするために使用できます。最初の正規表現の前に”-i"フラグを指定すると、大文字と小文字を区別せずに照合します。文字列”-i"と照合するには、これを2番目に指定するか、最初の文字列の前に”–“フラグを指定します。もちろん、文字列”–“と照合する場合も同じ原理が適用されます。
7.1.5. 任意のデータブロックの照合
抽出したサンプルを、文字列として安全に表現できないバイナリーブロックと照合することもできます。この場合、照合方法をバイナリーに設定し、偶数個の16進数字の列としてパターンを渡す必要があります。2桁ごとの並びが1バイトを表します。16進数字には、大文字と小文字のどちらも使用できます。
例:
7.1.6. IPv4アドレスとIPv6アドレスの照合
IPv4アドレスの値は、単なるアドレスとして指定することも、末尾にネットマスクを付けて指定することもできます。ネットマスクを付けた場合、IPv4アドレスがそのネットワーク内にあれば一致します。単なるアドレスの代わりに、名前解決可能なホスト名を指定することもできますが、設定が読みにくく、デバッグしにくくなるため、一般に推奨されません。ホスト名を使用する場合は、設定解析時の不確定なDNSの応答に設定が依存しないように、少なくとも/etc/hostsにホスト名が登録されていることを確認することを推奨します。
ドット区切りのIPv4アドレス表記は、通常の形式と、値がすべて0のオクテットを省略した短縮形式の両方に対応しています。
これは、192.168.42/24が192.168.42.0/24と同等になるRFC 4632のCIDRアドレス表記とは異なる点に注意してください。
IPv6は通常の形式で入力でき、ネットマスクの付加は任意です。IPv6のネットマスクにはビット数のみ指定できます。不確定なIPアドレスの名前解決による問題を避けるため、IPv6のパターンにホスト名を指定することは一切できません。
HAProxyは、次の状況ではIPv4アドレスとIPv6アドレスを照合することもできます。
- 検査対象のアドレスがIPv4、パターンのアドレスがIPv4の場合、IPv4で照合します。 マスクが指定されていれば、それを使用します。
- 検査対象のアドレスがIPv6、パターンのアドレスがIPv6の場合、IPv6で照合します。 マスクが指定されていれば、それを使用します。
- 検査対象のアドレスがIPv6、パターンのアドレスがIPv4の場合、IPv6アドレスが2002:IPV4::、::IPV4、 ::ffff:IPV4のいずれかに一致すれば、パターンのマスクを使用してIPv4で照合します。それ以外の場合は失敗します。
- 検査対象のアドレスがIPv4、パターンのアドレスがIPv6の場合、まずIPv4アドレスの先頭に::ffff:を 付けてIPv6に変換し、その後、指定されたIPv6マスクを使用してIPv6で照合します。
7.2. ACLによる条件の構成
一部のアクションは、条件が成立した場合にのみ実行されます。条件は、ACLと演算子を組み合わせたものです。次の3つの演算子がサポートされています。
- AND(暗黙的)
- OR(“or"キーワードまたは”||“演算子で明示的に指定)
- 感嘆符(”!")による否定
条件は、次のような論理和の形式で構成します。
このような条件は通常、“if"または"unless"文の後に記述し、どのような場合にアクションを実行するかを示します。
たとえば、URL “*“への"OPTIONS"以外のメソッドによるHTTPリクエスト、content-lengthのないPOSTリクエスト、content-lengthが0より大きいGETまたはHEADリクエスト、そしてGET/HEAD/POST/OPTIONSのいずれでもないすべてのリクエストをブロックする場合です。
“www"サイトの静的コンテンツへのリクエストと、“img”、“video”、“download”、“ftp"の各ホストへのすべてのリクエストに対して、別のバックエンドを選択する場合は、次のようにします。
“匿名ACL"を使用してルールを構成することもできます。これは、宣言せずにその場で構成する、名前のないACL式です。波括弧で囲み、それぞれの波括弧の前後に空白を入れる必要があります(波括弧を独立した単語として認識させる必要があるためです)。次に例を示します。
この書き方は、設定に誤りを残しやすくなるため、一般には推奨されません。ただし、たとえば送信元IPアドレスを1つだけ照合するような非常に単純なルールでは、任意の名前でACLを宣言するより、この方法のほうが適切な場合があります。次の例も、適切な使い方です。
“http-request deny"キーワードと"use_backend"キーワードの詳細は、セクション4.2 を参照してください。
7.3. サンプルの取得
従来、サンプル取得方法は、ACLを使用してパターンと照合するデータの取得にのみ使われていました。スティックテーブルの登場に伴い、新しい種類のサンプル取得方法が作られました。その多くは、対応するACLと同じ構文を使用します。これらのサンプル取得方法は、“fetch"とも呼ばれます。現在では、ACLとfetchは統合されています。すべてのACL取得方法をfetchとして使用できるようになり、ACLからも任意のサンプル取得方法を使用できます。
このセクションでは、使用できるすべてのサンプル取得方法と、その出力型を詳しく説明します。一部のサンプル取得方法には、既存の設定との互換性を保つための非推奨の別名があります。その場合は非推奨であることを明記しています。新しい構成では使用しないことを推奨します。
サンプルには型があります。型によって、照合できるパターン、適用できるコンバーター、別の型が必要な場合の変換方法が決まります。次の型を使用します。
-
boolean: 条件だけを報告する取得メソッドが返す、真または偽の値です。この型のサンプルは”-m"オプションなしで照合します。整数はゼロ以外なら真とみなし、文字列はまず整数として解析します。
-
integer: 符号付き64ビット整数です。範囲は-2^63から2^63-1(-9223372036854775808から9223372036854775807)です。文字列を整数に変換する場合、先頭の符号文字(’+‘または’-’)を除き、数字でない最初の文字で変換を停止します。読み取った数字から値を作り、数字がなければゼロになります。ただし、空の文字列は変換に失敗します。表現可能な範囲を超える値は、表現可能な最小または最大の整数に制限します。
-
IPv4アドレスとIPv6アドレス: 別々の型ですが、一方を受け入れる場所の多くは他方も受け入れ、単にアドレスを取ると説明しています。IPv4アドレスを整数に変換すると、アドレスの32ビット値になります。IPv6アドレスに変換すると、IPv4-mapped形式(”::ffff:a.b.c.d”)になります。逆方向の変換にはより多くの制限があります。IPv6アドレスには整数表現がなく、IPv4アドレスに変換できるのはIPv4-mapped、IPv4-compatible、6to4アドレスの場合だけです。
-
string: 最初のNUL文字(0x00)で終わるバイト列です。NUL文字自体は文字列に含まれません。途中にNUL文字が必要な場合はbinary型を使用します。エンコーディングは推測しません。HAProxyはこれらのバイトを文字として解釈しようとはせず、そもそもテキストを表すか、どの文字セットか、どう表示するかは、文字列の使用方法だけで決まります。そのため、binaryサンプルを文字列へ変換すると、明示的な変換でも暗黙の変換でも、最初のNUL文字以降を通知せずに破棄します。
-
binary: 長さが既知のバイトのブロックです。各バイトはNULを含む0から255までの任意の値を取れます。リクエストボディやバイナリプロトコルの内容など、生データを抽出する取得メソッドが返す型です。この型のサンプルはboolean、整数、アドレスに変換できません。"-m bin"でバイナリブロックとして照合するか(セクション7.1.5 を参照)、“hex"コンバーターなどで先に表示可能な形式へ変換する必要があります。逆方向の変換には制限がありません。文字列は常に有効なバイナリブロックだからです。
-
method: HTTPメソッドです。HAProxyが認識しているメソッドは識別子で表し、それ以外は元の文字列を保持します。
以下のコンバーターの表では、任意の入力型を受け入れるコンバーターを表すために"any"も使用します。
ACLの派生形がある場合は、それぞれの照合方法とともに示します。これらには、すべて明確なデフォルトのパターン照合方法があるため、ACLによるサンプルの照合方法を示す”-m"オプションを指定する必要はありません(指定することはできます)。
前述のサンプルの型と照合方法の互換性の表に示したように、ACLで汎用のサンプル取得方法を使用する場合、サンプルの型が真偽値、整数、IPv4、IPv6のいずれかでない限り、"-m"オプションが必須です。同じキーワードがACLキーワードと標準の取得方法の両方に存在する場合、ACLエンジンはデフォルトでACL専用のものを自動的に選択します。
これらのキーワードの中には、必須引数と省略可能な引数を、それぞれ単数または複数受け取るものがあります。引数は厳密に型が定められており、設定解析時に検査されるため、不正な引数(名前を解決できないバックエンドなど)で動作する心配はありません。取得関数の引数は丸括弧内に記述し、コンマで区切ります。省略可能な引数は、以下では角括弧(’[ ]’)で囲んで示します。すべての引数が省略可能である場合は、丸括弧も省略できます。
したがって、標準のサンプル取得方法の構文は、次のいずれかになります。
- name
- name(arg1)
- name(arg1,arg2)
7.3.1. コンバーター
サンプル取得方法には、取得したサンプルに適用する変換(“コンバーター"とも呼びます)を組み合わせられます。この組み合わせを"サンプル式"と呼び、その結果が"サンプル"です。当初は"stick on"と"stick store-request"ディレクティブだけが対応していましたが、現在ではサンプルを使用できるすべての場所(ACL、log-format、unique-id-format、add-headerなど)に拡張されています。
これらの変換は、サンプル取得方法の後に、一連の専用キーワードとして列挙します。取得キーワードの引数の直後に、コンマで区切って追加することもできます。これらのキーワードも、ネットマスクなどの引数を受け取る場合があり、その引数は丸括弧内に記述する必要があります。
コンバーターの中には、整数に対する基本的な演算に対応する、ビット演算子や算術演算子があります。ビット演算としてand、or、xor、cplが、算術演算としてadd、sub、mul、div、mod、negがサポートされています。また、odd、even、not、boolという判定用の演算子もあり、ACLを記述せずに一致を返すことができます。
次のキーワードがサポートされています。
以下にコンバーターのキーワードを詳しく説明します。
51d.single(<prop>[,<prop>*])
要求したプロパティの値を文字列として返します。各値は、“51degrees-property-separator"で指定した区切り文字で区切られます。デバイスは、コンバーターに渡されたUser-Agentヘッダーを使用して識別します。この関数には最大五つのプロパティ名を渡せます。プロパティ名が見つからない場合は、値"NoData"を返します。
例:
add(<value>)
符号付き整数型の入力値に<value>を加算し、結果を符号付き整数として返します。<value>には、数値または変数名を指定できます。変数の詳細は、セクション2.8
を参照してください。
add_item(<delim>[,<var>[,<suff>]])
現在のサンプルの後に最少2個、最大3個のフィールドを連結し、サンプルを文字列に変換します。最初のフィールド<delim>は定数文字列で、既存のサンプルが空ではなく、かつ<var>か<suff>のいずれかが空ではない場合に、既存のサンプルの直後に追加します。次のフィールド<var>は変数名です。その変数を検索し、内容を文字列に変換して、<delim>の直後に追加します。変数が見つからない場合は、何も追加しません。これは省略可能で、その後に任意で定数文字列<suff>を指定することもできます。ただし、<var>を省略した場合、<suff>は必須です。このコンバーターはconcatコンバーターに似ており、他の変数を連結して新しい変数を作成できます。主な違いは、区切り文字を追加する意味があるかを確認する点です。たとえば、現在のサンプルが空の場合には、区切り文字の追加は適切ではありません。同じ処理をconcatコンバーターで行うには、2つのルールに分け、最初のルールで現在のサンプル文字列が空かを確認してから区切り文字を追加する必要があります。コンマや閉じ丸括弧を区切り文字に使用する場合、引用符やバックスラッシュで保護し、さらに、その引用符やバックスラッシュが最初の段階のパーサーで除去されないように保護する必要があります(引用とエスケープについてはセクション2.2
を参照してください)。以下の例を参照してください。
例:
aes_cbc_dec(<bits>,<nonce>,<key>[,<aad>])
<bits>パラメーターに応じて、AES128-CBC、AES192-CBC、AES256-CBCのいずれかのアルゴリズムで、生のバイト列の入力を復号します。他のパラメーターはすべてbase64でエンコードする必要があり、結果は生のバイト列で返されます。<aad>パラメーターは省略可能です。<aad>の検証が失敗した場合、コンバーターはデータを返しません。<nonce>、<key>、<aad>には、文字列または変数を指定できます。このコンバーターにはOpenSSL 1.0.1以降が必要です。
例:
aes_cbc_enc(<bits>,<nonce>,<key>[,<aad>])
<bits>パラメーターに応じて、AES128-CBC、AES192-CBC、AES256-CBCのいずれかのアルゴリズムで、生のバイト列の入力を暗号化します。<nonce>、<key>、<aad>パラメーターは、base64でエンコードする必要があります。<aad>パラメーターは省略可能です。結果は生のバイト列で返されます。<nonce>、<key>、<aad>には、文字列または変数を指定できます。このコンバーターにはOpenSSL 1.0.1以降が必要です。
例:
aes_gcm_dec(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])
<bits>パラメーターに応じて、AES128-GCM、AES192-GCM、AES256-GCMのいずれかのアルゴリズムで、生のバイト列の入力を復号します。他のパラメーターはすべてbase64でエンコードする必要があり、結果は生のバイト列で返されます。<aead_tag>または<aad>の検証が失敗した場合、コンバーターはデータを返しません。<aad>パラメーターは省略可能です。<nonce>、<key>、<aead_tag>、<aad>には、文字列または変数を指定できます。このコンバーターにはOpenSSL 1.0.1以降が必要です。
例:
aes_gcm_enc(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])
<bits>パラメーターに応じて、AES128-GCM、AES192-GCM、AES256-GCMのいずれかのアルゴリズムで、生のバイト列の入力を暗号化します。<nonce>、<key>、<aad>パラメーターは、base64でエンコードする必要があります。<aead_tag>パラメーターには変数を指定する必要があります。AEADタグは、base64でエンコードされてその変数に格納されます。<aad>パラメーターは省略可能です。結果は生のバイト列で返されます。<nonce>、<key>、<aad>には、文字列または変数を指定できます。このコンバーターにはOpenSSL 1.0.1以降が必要です。
例:
and(<value>)
<value>と符号付き整数型の入力値とのビット単位の"AND"を計算し、結果を符号付き整数として返します。<value>には、数値または変数名を指定できます。変数の詳細は、セクション2.8
を参照してください。
b64dec
base64でエンコードされた入力文字列を、バイナリー表現に変換(デコード)します。base64()の逆の操作を行います。base64url(RFC 4648の"URLおよびファイル名に安全な文字集合”)の派生形式については、“ub64dec"を参照してください。
base2
バイナリーの入力サンプルを、入力の1バイトにつき8桁の二進数字を含む二進文字列に変換します。ネイティブな表現では接頭辞の照合ができない型(IPプレフィックスなど)に対して、最長接頭辞一致を行えるようにするために使用します。
base64
バイナリーの入力サンプルをbase64文字列に変換します。バイナリーの内容を、確実に転送できる形式でログに記録したり、転送したりするために使用します(たとえば、SSL IDをヘッダーにコピーできます)。base64url(RFC 4648の"URLおよびファイル名に安全な文字集合”)の派生形式については、“ub64enc"を参照してください。
be2dec(<separator>,<chunk_size>[,<truncate>])
ビッグエンディアンのバイナリー入力サンプルを、入力の<chunk_size>バイトごとに符号なし整数を含む文字列に変換します。<separator>を指定した場合、バイナリー入力の<chunk_size>バイトごとに挿入します。<truncate>フラグは、バイナリー入力を<chunk_size>の境界で切り詰めるかどうかを示します。<chunk_size>の最大値は、long long intのサイズ(8バイト)に制限されます。
例:
le2dec(<separator>,<chunk_size>[,<truncate>])
リトルエンディアンのバイナリー入力サンプルを、入力の<chunk_size>バイトごとに符号なし整数を含む文字列に変換します。<separator>を指定した場合、バイナリー入力の<chunk_size>バイトごとに挿入します。<truncate>フラグは、バイナリー入力を<chunk_size>の境界で切り詰めるかどうかを示します。<chunk_size>の最大値は、long long intのサイズ(8バイト)に制限されます。
例:
be2hex([<separator>[,<chunk_size>[,<truncate>]]])
ビッグエンディアンのバイナリー入力サンプルを、入力の1バイトにつき2桁の16進数字を含む16進文字列に変換します。バイナリーの入力データの16進ダンプを、確実に転送できる形式でログに記録したり、転送したりするために使用します(たとえば、SSL IDをヘッダーにコピーできます)。<separator>を指定した場合、バイナリー入力の<chunk_size>バイトごとに挿入します。<truncate>フラグは、バイナリー入力を<chunk_size>の境界で切り詰めるかどうかを示します。
例:
bool
符号付き整数型の入力値が非ゼロであれば真偽値TRUEを返し、それ以外はFALSEを返します。and()と組み合わせると、入力値に対するビット検査(フラグの有無の確認など)の結果をtrue/falseで返すことができます。
bytes(<offset>[,<length>])
バイナリーの入力サンプルからバイト列を抽出します。結果は、元のサンプルのオフセット(バイト単位)から始まるバイナリーサンプルで、任意で指定した長さに切り詰められます。<offset>と<length>には、数値または変数名を指定できます。<offset>または<length>のいずれかが無効な場合、このコンバーターは空のサンプルを返します。無効な<offset>とは、負の値または入力サンプルの長さ以上(>=)の値です。無効な<length>とは、負の値です。
例:
capture-req(<id>)
文字列エントリーをリクエストのスロット<id>にキャプチャーし、そのエントリーをそのまま返します。スロットが存在しない場合、キャプチャーはエラーを報告せずに失敗します。
関連項目:“declare capture”、“http-request capture”、“http-response capture”、“capture.req.hdr”、“capture.res.hdr”(サンプル取得)。
capture-res(<id>)
文字列エントリーをレスポンスのスロット<id>にキャプチャーし、そのエントリーをそのまま返します。スロットが存在しない場合、キャプチャーはエラーを報告せずに失敗します。
関連項目:“declare capture”、“http-request capture”、“http-response capture”、“capture.req.hdr”、“capture.res.hdr”(サンプル取得)。
concat([<start>[,<var>[,<end>]]])
現在のサンプルの後に最大3個のフィールドを連結し、サンプルを文字列に変換します。最初のフィールド<start>は定数文字列で、既存のサンプルの直後に追加します。使用しない場合は省略できます。次のフィールド<var>は変数名です。その変数を検索し、内容を文字列に変換して、<first>部分の直後に追加します。変数が見つからない場合は、何も追加しません。このフィールドも省略できます。最後のフィールド<end>は定数文字列で、変数の後に追加します。これも省略できます。これらの要素を組み合わせることで、既存の変数群に対して、区切り文字を挟んで変数を連結できます。たとえばコロン区切りの値のように、他の変数を連結して新しい変数を作成するために使用できます。コンマや閉じ丸括弧を区切り文字に使用する場合、引用符やバックスラッシュで保護し、さらに、その引用符やバックスラッシュが最初の段階のパーサーで除去されないように保護する必要があります。他の変数から複合変数を作成する用途でよく使用されますが、複数のフィールドを含む書式文字列を使用するほうが便利な場合もあります。以下の例を参照してください。
例:
cpl
符号付き整数型の入力値を受け取り、1の補数(すべてのビットを反転)を求め、結果を符号付き整数として返します。
crc32([<avalanche>])
CRC32 ハッシュ関数を使用してバイナリ入力サンプルを符号なし 32 ビット量にハッシュします。オプションで、<avalanche> 引数が 1 に等しい場合、出力に完全なアバランチハッシュ関数を適用できます。このコンバーターは、さまざまなハッシュベースの負荷分散アルゴリズムで使用される関数と同一であるため、正確に同じ結果を提供します。他のソフトウェアが入力キーに対して CRC32 を計算したい場合の互換性のために提供されています。Ethernet、Gzip、PNG などに見られる一般的な実装に従います。他のアルゴリズムより遅いですが、より良い、あるいは少なくとも予測しにくい分布を提供する可能性があります。32 ビットハッシュは簡単に破られるため、セキュリティ目的には使用してはなりません。また “djb2”、“sdbm”、“wt6”、“crc32c” および “hash-type” ディレクティブを参照してください。
crc32c([<avalanche>])
CRC32C ハッシュ関数を使用してバイナリ入力サンプルを符号なし 32 ビット量にハッシュします。オプションで、<avalanche> 引数が 1 に等しい場合、出力に完全なアバランチハッシュ関数を適用できます。このコンバーターは RFC4960 の付録 B [8] に記載されているものと同じ関数を使用します。他のソフトウェアが入力キーに対して CRC32C を計算したい場合の互換性のために提供されています。他のアルゴリズムより遅く、32 ビットハッシュは簡単に破られるため、セキュリティ目的には使用してはなりません。また “djb2”、“sdbm”、“wt6”、“crc32” および “hash-type” ディレクティブを参照してください。
cut_crlf
入力サンプルの文字列表現を最初に見つかった復帰文字 (’\r’) または改行文字 (’\n’) で切り分けます。文字列長のみが更新されます。
da-csv-conv(<prop>[,<prop>*])
DeviceAtlas コンバーターに、入力で渡された User Agent 文字列を識別させ、引数で列挙されたプロパティを連結して出力するように指示します。区切り文字はグローバルキーワード “deviceatlas-property-separator” で定義されたもの、またはデフォルトではパイプ文字 (’|’) です。HAProxy 設定言語によって 12 種類の異なるプロパティに制限されています。
例:
date
このコンバーターは HTTP ヘッダーからの日付を変換するために使用します。これは IMF 日付、ASCTIME 日付、または RFC850 日付のいずれかです。出力は UNIX タイムスタンプになります。
例:
debug([<prefix][,<destination>])
このコンバーターはデバッグツールとして使用されます。入力サンプルのキャプチャを取得し、イベントシンク <destination> に送信します。シンクは “buf0” のようなリングバッファ、“stdout”、または “stderr” を指定できます。利用可能なシンクは CLI で “show events” を実行することで実行時に確認できます。指定がなければ出力は “buf0” になります。CLI の “show events” コマンドで参照できます。複数の式からの出力を区別しやすくするため、任意のプレフィックス <prefix> を渡すことができます。出力メッセージのコロンの前に表示されます。入力サンプルはそのまま出力されるため、印字できないサンプル型でも、チェーン内のどこにでもデバッグコンバーターを挿入しても安全です。
例:
digest(<algorithm>)
バイナリ入力サンプルをメッセージダイジェストに変換します。結果はバイナリサンプルになります。<algorithm> は OpenSSL メッセージダイジェスト名(例:sha256)でなければなりません。
このコンバーターは HAProxy が USE_OPENSSL でコンパイルされた場合にのみ利用可能です。
div(<value>)
入力値を符号付き整数型として <value> で割り、結果を符号付き整数として返します。<value> がゼロの場合、最大の符号なし整数が返されます(通常は 2^63-1)。<value> は数値または変数名で指定できます。詳細については 2.8節
の変数に関する説明を参照してください。
djb2([<avalanche>])
DJB2 ハッシュ関数を使用してバイナリ入力サンプルを符号なし 32 ビット量にハッシュします。オプションで、<avalanche> 引数が 1 に等しい場合、出力に完全なアバランチハッシュ関数を適用できます。このコンバーターは、さまざまなハッシュベースの負荷分散アルゴリズムで使用される関数と同一であるため、正確に同じ結果を提供します。主にデバッグ用ですが、粗い統計を集めるためのスティックテーブルエントリとしても使用できます。32 ビットハッシュは簡単に破られるため、セキュリティ目的には使用してはなりません。また “crc32”、“sdbm”、“wt6”、“crc32c” および “hash-type” ディレクティブを参照してください。
eth.data
“tcp-ss” バインドオプションを “2” に設定し、“fc_saved_syn” で取得することで返されるバイナリイーサネットフレームを表す入力サンプルと併用します。VLAN を含むすべてのイーサネットヘッダーをスキップし、レイヤ3プロトコル(通常は IPv4 または IPv6)から始まるバイナリデータブロックを返します。また “fc_saved_syn” および “tcp-ss” を参照してください。
eth.dst
“tcp-ss” バインドオプションを “2” に設定し、“fc_saved_syn” で取得することで返されるバイナリイーサネットフレームを表す入力サンプルと併用します。フレームの宛先アドレスに対応する 6 バイトのイーサネットヘッダーをバイナリブロックとして返します。また “fc_saved_syn” および “tcp-ss” を参照してください。
eth.hdr
“tcp-ss” バインドオプションを “2” に設定し、“fc_saved_syn” で取得することで返されるバイナリイーサネットフレームを表す入力サンプルと併用します。イーサネットヘッダーより後の部分をすべて切り落としますが、VLAN があればそれを保持し、ヘッダーをバイナリデータブロックとして返します。また “fc_saved_syn” および “tcp-ss” を参照してください。
eth.proto
“tcp-ss” バインドオプションを “2” に設定し、“fc_saved_syn” で取得することで返されるバイナリイーサネットフレームを表す入力サンプルと併用します。イーサネットヘッダー内で、省略可能な VLAN の後にあるプロトコル番号(EtherType とも呼ばれる)を整数値として返します。通常は IPv4 に対して 0x800、IPv6 に対して 0x86DD になります。また “fc_saved_syn” および “tcp-ss” を参照してください。
eth.src
“tcp-ss” バインドオプションを “2” に設定し、“fc_saved_syn” で取得することで返されるバイナリイーサネットフレームを表す入力サンプルと併用します。フレームの送信元アドレスに対応する 6 バイトのイーサネットヘッダーをバイナリブロックとして返します。また “fc_saved_syn” および “tcp-ss” を参照してください。
eth.vlan
“tcp-ss” バインドオプションを “2” に設定し、“fc_saved_syn” で取得することで返されるバイナリイーサネットフレームを表す入力サンプルと併用します。イーサネットヘッダーに見つかった最後の VLAN ID を整数値として返します。また “fc_saved_syn” および “tcp-ss” を参照してください。
even
入力値が符号付き整数型で偶数の場合に真(TRUE)を返し、それ以外の場合は偽(FALSE)を返します。“not,and(1),bool” と機能的に同等です。
field(<index>,<delimiters>[,<count>])
指定されたインデックス(正のインデックスは先頭から、負のインデックスは末尾から)で、指定された区切り文字を考慮して入力文字列から部分文字列を抽出します。インデックスは 1 または -1 から始まります。区切り文字は、文字のリストを文字列にしたものです。オプションで抽出するフィールド数 <count> を指定できます(デフォルト:1)。0 は残りのすべてのフィールドを抽出することを示します。
例:
fe_exists
入力値としてフロントエンド名を指定し、その名前のフロントエンドが現在の構成に存在する場合に真(TRUE)を返し、それ以外の場合は偽(FALSE)を返します。動的な名前からフロントエンドの存在を確認する必要がある場所(例:マップ照合や外部チェックへの応答)で使用できます。
例:
fix_is_valid
バイナリペイロードを解析し、FIX(Financial Information eXchange)に関する整合性チェックを行います:
- すべてのタグ ID と値が空でなく、タグ ID が適切な数値であることを確認します
- BeginString タグが最初のタグであり、有効な FIX バージョンを示していることを確認します
- BodyLength タグが2番目のタグであり、正しい本文長を示していることを確認します
- MsgType タグが3番目のタグであることを確認します。
- メッセージの最後のタグが CheckSum タグであり、有効なチェックサムであることを確認します。
現在の HAProxy の設計上、クライアントおよびサーバーが送信する最初のメッセージのみが解析可能です。
このコンバーターは真偽値を返し、ペイロードに有効な FIX メッセージが含まれていれば true、それ以外は false になります。
また、fix_tag_value コンバーターも参照してください。
例:
fix_tag_value(<tag>)
FIX (Financial Information eXchange) メッセージを解析し、タグ <tag> から値を抽出します。<tag> は目的のタグを指す文字列または整数です。整数値はすべて許容されますが、以下の文字列のみが整数に変換されます:BeginString、BodyLength、MsgType、SenderCompID、TargetCompID、CheckSum。より多くのタグ名を簡単に追加できます。
現在の HAProxy の設計上、クライアントおよびサーバーが送信する最初のメッセージのみが解析可能です。このコンバーターはメッセージの検証を行いません。まず fix_is_valid コンバーターを使用してメッセージを検証しておくことを強く推奨します。
また、fix_is_valid コンバーターも参照してください。
例:
has_ctl([mask])
入力バイナリーサンプルに、マスク引数で定義された制御文字が含まれているかを検査します。マスクは33ビットの数値(10進数、または “0x” で始まる16進数)で、0x00から0x1Fまでの範囲で検出する各文字に対応するビットを立てます。DEL文字 (0x7F) に一致させるには、ビット32を立てます。マスクを指定しない場合、コンバーターは値0x1FFFFFDFFを使用し、HTTPヘッダーでよく使われるTAB (0x09) を除くすべての制御文字に一致します。特別なマスク “any” は0x1FFFFFFFFに対応し、TABを含むすべての制御文字に一致します。特別なマスク “http” は0x2401に対応し、HTTPヘッダー値で禁止されている制御文字であるCR (0x0D)、LF (0x0A)、NUL (0x00) だけに一致します。
例:
hex
バイナリー入力サンプルを、入力バイトごとに2桁の16進数を含む16進文字列に変換します。バイナリー入力データの16進ダンプを、確実に転送できる形式でログに記録したり転送したりするために使用します(たとえば、SSL IDをヘッダーにコピーできます)。
hex2i
入力バイトごとに2桁の16進数を含む16進文字列を、整数に変換します。入力値に16進数の数字以外の文字が含まれる場合、コンバーターは失敗して何も返しません。これにより、不正な入力と有効なゼロ値を区別できます。
hmac(<algorithm>,<key>)
入力バイナリサンプルを、指定されたキーを使用したメッセージ認証コードに変換します。結果はバイナリサンプルです。<algorithm> は登録済みの OpenSSL メッセージダイジェスト名のいずれかでなければなりません(例:sha256)。<key> パラメーターは base64 エンコードされていなければならず、文字列または変数のいずれかを指定できます。
このコンバーターは HAProxy が USE_OPENSSL でコンパイルされた場合にのみ利用可能です。
host_only
Host ヘッダー値を含む文字列を変換し、ポートを削除します。入力は Host ヘッダー値の形式(rfc9110#section-7.2)に従う必要があります。以下の形式の入力をサポートします:hostname、hostname:80、127.0.0.1、127.0.0.1:80、[::1]、[::1]:80。
このコンバーターは、文字列を小文字に変換します。
また、“port_only” コンバーターも参照してください。これはポートを返します。
htonl
入力整数値をネットワークバイトオーダーでの32ビットバイナリ表現に変換します。サンプル取得は符号付き64ビット整数を扱うため、このコンバーターを使用する場合、入力整数値はまず符号なし32ビット整数にキャストされます。
http_date([<offset[,<unit>]])
エポックからの日付を表す整数値を、HTTPヘッダー項目で使用可能な形式の文字列に変換します。オフセット値が指定された場合、変換前に日付にオフセット値が加算されます。これは、Date ヘッダーフィールドを生成する場合、正のオフセットと組み合わせてレスポンスの Expires 値を生成する場合、負のオフセットと組み合わせて Last-Modified 値を生成する場合に特に便利です。単位値が指定された場合、タイムスタンプを、エポックからの “s”(秒、デフォルト)、“ms”(ミリ秒)、または “us”(マイクロ秒)として扱います。オフセットは入力タイムスタンプと同じ単位であると仮定されます。
iif(<true>,<false>)
入力値が true の場合、<true> 文字列を返します。それ以外の場合は <false> 文字列を返します。
例:
in_table([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブルまたは指定されたスティックテーブル内で照合を行います。キーがテーブルに存在しない場合、論理値 false が返されます。それ以外の場合は論理値 true が返されます。これは、何らかの要素を追跡するテーブルに特定のキーが存在するかを調べるために使用できます(たとえば、送信元IPアドレスやAuthorizationヘッダーが以前に現れたかどうかを確認する場合)。
ip.data
これは、“tcp-ss” バインドオプションを “1” に設定したときに “fc_saved_syn” が返すバイナリイーサネットフレーム、または “eth.data” の出力に使用されます。IPヘッダーおよび任意のオプションまたは拡張をスキップし、トランスポートプロトコル(通常はTCPまたはUDP)から始まるバイナリデータブロックを返します。また、“fc_saved_syn”、“tcp-ss”、“eth.data” を参照してください。
ip.df
これは、“tcp-ss” バインドオプションを “1” に設定したときに “fc_saved_syn” が返すバイナリイーサネットフレーム、または “eth.data” の出力に使用されます。IPヘッダーの DF(フラグメント禁止)フラグが設定されている場合に整数値1を返し、それ以外の場合は0を返します。IPv6にはDFフラグがなく、デフォルトでフラグメントされないため、常に1を返します。また、“fc_saved_syn”、“tcp-ss”、“eth.data” を参照してください。
ip.dst
“tcp-ss” bindオプションを “1” に設定したときに “fc_saved_syn” が返す、バイナリーのイーサネットフレームを表す入力サンプル、または “eth.data” の出力に対して使用します。IPv4/v6ヘッダーから、IPv4またはIPv6の宛先アドレスを返します。“fc_saved_syn”、“tcp-ss”、および “eth.data” も参照してください。
ip.fp([<mode>])
“tcp-ss” bindオプションを “1” に設定したときに “fc_saved_syn” が返す、バイナリーのイーサネットフレームを表す入力サンプル、または “eth.data” の出力に対して使用します。IPヘッダーとTCPヘッダーのさまざまな部分を調べ、外見上は同じ複数のホストを区別するために使える、不変部分のフィンガープリントのようなものを作成します。実際の用途は、共有IPアドレスの背後にある問題のあるホストの識別精度を高め、問題を起こしてブロックすべきホストが1台だけのときに、正当なユーザーをブロックしないようにすることです。このコンバーターは、入力に基づいて最小8バイトのバイナリーブロックを作成します。フィンガープリントのバイトは、次のように配置します。- バイト0: IP TOSフィールド(ip.tosを参照)- バイト1: - ビット7: IPv6 (1) / IPv4 (0) - ビット6: ip.df - ビット5..4: 0:ip.ttl<=32; 1:ip.ttl<=64; 2:ip.ttl<=128; 3:ip.ttl<=255 - ビット3: IPオプションあり (1) / なし (0) - ビット2: TCPデータあり (1) / なし (0) - ビット1: TCP.flagsのCWRが設定済み (1) / クリア済み (0) - ビット0: TCP.flagsのECEが設定済み (1) / クリア済み (0) - バイト2: - ビット7..4: 4バイトワード単位のTCPヘッダー長 - ビット3..0: TCPウィンドウスケーリング + 1 (1..15) / 0(WSの通知なし)- バイト3..4: tcp.win - バイト5..6: tcp.options.mss。存在しない場合はゼロ - バイト7: 存在するTCPオプションごとに1ビット。オプション2から8をそれぞれビット0..6に対応付け、ビット7は9から255までのいずれかのオプションが存在することを示します。
<mode> 引数を使うと、フィンガープリントに情報を追加できます。デフォルトでは、<mode> 引数が未設定またはゼロの場合、フィンガープリントは前述の8バイトだけで構成されます。<mode> に別の値を指定した場合、その値は次の値の合計を表し、対応する要素を以下の順序でフィンガープリントに連結します。- 1: 受信したTTL値をフィンガープリントに追加します(1バイト)。- 2: “tcp.options_list” が返すTCPオプション種別の一覧を、0から40バイトの追加データとしてフィンガープリントに追加します。- 4: 送信元IPアドレスをフィンガープリントに追加します。IPv4では4バイト、IPv6では16バイト増えます。
例:基本のFP、TTL、送信元アドレスを使って、13..25バイトのフィンガープリントを作成します(1+4=5)。
frontend test
mode http
bind :4445 tcp-ss 1
tcp-request connection set-var(sess.syn) fc_saved_syn
http-request return status 200 content-type text/plain lf-string \
"src=%[var(sess.syn),ip.src] fp=%[var(sess.syn),ip.fp(5),hex]\n"
“fc_saved_syn”、“tcp-ss”、“eth.data”、“ip.df”、“ip.ttl”、“tcp.win”、“tcp.options.mss”、および “tcp.options_list” も参照してください。
ip.hdr
“tcp-ss” bindオプションを “1” に設定したときに “fc_saved_syn” が返す、バイナリーのイーサネットフレームを表す入力サンプル、または “eth.data” の出力に対して使用します。IPヘッダーから始まり、最後のオプションまたは拡張の後、トランスポートプロトコルヘッダーの前までのバイナリーデータブロックを返します。“fc_saved_syn”、“tcp-ss”、および “eth.data” も参照してください。
ip.proto
“tcp-ss” bindオプションを “1” に設定したときに “fc_saved_syn” が返す、バイナリーのイーサネットフレームを表す入力サンプル、または “eth.data” の出力に対して使用します。トランスポートプロトコル番号を返します。通常はTCPが6、UDPが17です。“fc_saved_syn”、“tcp-ss”、および “eth.data” も参照してください。
ip.src
“tcp-ss” bindオプションを “1” に設定したときに “fc_saved_syn” が返す、バイナリーのイーサネットフレームを表す入力サンプル、または “eth.data” の出力に対して使用します。IPv4/v6ヘッダーから、IPv4またはIPv6の送信元アドレスを返します。“fc_saved_syn”、“tcp-ss”、および “eth.data” も参照してください。
ip.tos
“tcp-ss” bindオプションを “1” に設定したときに “fc_saved_syn” が返す、バイナリーのイーサネットフレームを表す入力サンプル、または “eth.data” の出力に対して使用します。IPv4ヘッダーのサービス種別 (TOS) フィールド、またはIPv6ヘッダーのトラフィッククラス (TC) フィールドの値に対応する整数を返します。現在のインターネットでは、このフィールドの上位6ビットは通常DSCP (Differentiated Services Codepoint) 値を含み、下位2ビットは未使用か、IP ECNに使用されます。DSCP値についてはRFC2474とRFC8436を、IP ECNフィールドについてはRFC3168を参照してください。“fc_saved_syn”、“tcp-ss”、および “eth.data” も参照してください。
ip.ttl
“tcp-ss” bindオプションを “1” に設定したときに “fc_saved_syn” が返す、バイナリーのイーサネットフレームを表す入力サンプル、または “eth.data” の出力に対して使用します。IPv4/IPv6ヘッダーのTTL (Time To Live) またはHL (Hop Limit) フィールドに対応する整数を返します。この値は通常、固定の値にあらかじめ設定され、パケットが通過するルーターごとに減らされます。初期値が分かれば、クライアントがどれほど遠くから接続しているかを推測するのに役立ちます。最近のほとんどのOSは、初期値64で開始します。“fc_saved_syn”、“tcp-ss”、および “eth.data” も参照してください。
ip.ver
“tcp-ss” bindオプションを “1” に設定したときに “fc_saved_syn” が返す、バイナリーのイーサネットフレームを表す入力サンプル、または “eth.data” の出力に対して使用します。IPヘッダーのIPバージョンを返します。通常は4または6です。上位レイヤーのイーサネットフレーム内のプロトコル番号と一致するかは検査しません。ただし、有効なパケットに対して使用することを想定しているため、この点はOSがすでに検証済みであると想定します。“fc_saved_syn”、“tcp-ss”、および “eth.data” も参照してください。
ipmask(<mask4>[,<mask6>])
IPアドレスにマスクを適用し、結果を検索と保存に使用します。これにより、特定のマスク内のすべてのホストで同じテーブルエントリーを共有し、同じサーバーを使用できます。mask4はドット形式(255.255.255.0など)、またはCIDR形式(24など)で指定できます。mask6は4桁ずつに区切った形式(ffff:ffff::など)、またはCIDR形式(64など)で指定できます。mask6を指定しない場合、後方互換性のため、IPv6アドレスの変換は失敗します。
json([<input-code>])
入力文字列をエスケープし、JSON文字列としてそのまま使用できるASCII出力文字列を生成します。コンバーターは <input-code> パラメーターに従って入力文字列のデコードを試みます。指定できる値は “ascii”、“utf8”、“utf8s”、“utf8p”、“utf8ps” です。“ascii” デコーダーは決して失敗しません。“utf8” デコーダーは3種類のエラーを検出します。
- 不正なUTF-8シーケンス(孤立した継続バイト、継続バイトの数が不正など)
- 無効な範囲(デコードされた値がUTF-8で禁止されている範囲内にある)
- 過長エンコーディング(必要以上に多くのバイトで値がエンコードされている)
UTF-8のJSONエンコードでは、UTF-8文字が0xffffを超える場合に “too long value” エラーが発生することがあります。JSONの文字列エスケープ仕様が、値のエンコードに4桁の16進数しか認めていないためです。UTF-8デコーダーには、2つの接尾辞文字の組み合わせで表す4種類があります。“p” は寛容な処理 (“permissive”)、“s” は通知せずに無視する処理 (“silently ignore”) を表します。各デコーダーの動作は次のとおりです。
- “ascii”: 決して失敗しません。
- “utf8”: エラーを検出すると、種類を問わず失敗します。
- “utf8s”: 決して失敗しませんが、エラーに対応する文字を削除します。
- “utf8p”: 過長エラーは受け入れて修正しますが、それ以外のエラーでは失敗します。
- “utf8ps”: 決して失敗しません。過長エラーは受け入れて修正しますが、それ以外のエラーに対応する文字は削除します。
このコンバーターは、JSON形式のトラフィックログを処理するサーバーへのログ出力用に、適切にエスケープされたJSONを作成する際に特に便利です。
例:
クライアント127.0.0.1からのリクエスト:
出力ログ:
json_query(<json_path>[,<output_type>])
json_queryコンバーターは、JSONのstring、boolean、number、array型をサポートします。浮動小数点数は文字列として返します。output_typeに ‘int’ を指定すると、値を整数に変換します。配列は、先頭と末尾を角かっこで囲んだ文字列として返します。内容はCSV形式です。データ型によって、配列の値を引用符で囲む場合があります。配列の値が複合型の場合、各値の完全なJSON表現をコンマで区切って文字列に含めます。JWTに対するrolesクエリの結果の例を示します。
変換できない場合、json_queryコンバーターは失敗します。
<json_path> は https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/
で定義された有効な JSON Path 文字列でなければなりません。
注意:コンテキストや下位実装によっては、重複する JSON キーの抽出が未定義であり、入力コンテンツから同じキーの最初、最後、または任意の出現を返す可能性があります。また、キー名がエンコードされた形で渡された場合、常に一致するとは限りません。要するに、このコンバーターはコンテンツのサニタイズには適していません。
例:
jwt_decrypt_cert(<cert>)
入力されたJSON Web Tokenについて、JSON Web Encryption形式(RFC 7516を参照)に従って署名を検証し、指定した証明書で復号した内容を返します。<cert> パラメーターは、すでに読み込まれた証明書へのパスでなければなりません(CLIコマンド “dump ssl cert” でダンプできます)。証明書の “jwt” オプションは、明示的に “on” に設定されていなければなりません(crt-listの “jwt” オプションを参照してください)。直接指定することも、変数を介して指定することもできます。現在扱えるのは、Compact Serialization形式(base64-urlでエンコードした5つの文字列をドットで区切った形式)を使用するトークンだけです。
このコンバーターは、JOSE ヘッダーの “alg” フィールドに以下のアルゴリズムが含まれるトークンで使用できます:RSA-OAEP、RSA-OAEP-256、ECDH-ES、ECDH-ES+A128KW、ECDH-ES+A192KW、ECDH-ES+A256KW。RSA1_5 アルゴリズムは実装されていますが、RFC 8725 の 3.2節 に従ってデフォルトで無効になっています。必要に応じて ‘jwt.decrypt_alg_list’ グローバルオプションで再有効化できます。
サポートされるアルゴリズムおよび暗号化アルゴリズム(それぞれ JOSE ヘッダーの “alg” および “enc” フィールド)は、‘jwt.decrypt_alg_list’ および ‘jwt.decrypt_enc_list’ グローバルオプションによって変更できます。
JWEトークンは、base64urlエンコードした形式で渡さなければなりません。出力は “raw” 形式で返します。トークンのパース、署名検証、または内容の復号中にエラーが発生した場合、空文字列が返されます。
例:
jwt_decrypt_jwk(<jwk>)
入力された JSON Web Token に対して、JSON Web Encryption 形式(RFC 7516 参照)に従った署名検証を行い、提供された JSON Web Key (RFC7517) を使って内容を復号して返します。<jwk> パラメーターは、‘oct’、‘EC’、または ‘RSA’ 型(JSON キーの ‘kty’ フィールド)の有効な JWK でなければなりません。JWK は文字列として、または変数経由で提供できます。
現在扱えるのは、Compact Serialization形式(base64-urlでエンコードした5つの文字列をドットで区切った形式)を使用するトークンだけです。
このコンバーターは、JOSE ヘッダーの “alg” フィールドに以下の対称型アルゴリズムが含まれるトークンのデコードに使用できます:A128KW、A192KW、A256KW、A128GCMKW、A192GCMKW、A256GCMKW、dir。この場合、提供された JWK は ‘oct’ 型であることを想定しています。
このコンバーターは、JOSEヘッダーの “alg” フィールドに指定したアルゴリズムに応じて、‘RSA’ JWK が提供された場合はRSA ファミリー(RSA-OAEP または RSA-OAEP-256)のアルゴリズムを、‘EC’ JWK が提供された場合、ECDH ファミリー(ECDH-ES、ECDH-ES+A128KW、ECDH-ES+A192KW、ECDH-ES+A256KW)のアルゴリズムを処理します。RSA1_5 アルゴリズムは実装されていますが、RFC 8725 の 3.2節 に従ってデフォルトで無効になっています。必要に応じて ‘jwt.decrypt_alg_list’ グローバルオプションで再有効化できます。
AWS-LC では A128KW および A192KW アルゴリズムが利用できないため、A128KW、A192KW、ECDH-ES+A128KW、ECDH-ES+A192KW アルゴリズムは動作しません。
サポートされるアルゴリズムおよび暗号化アルゴリズム(それぞれ JOSE ヘッダーの “alg” および “enc” フィールド)は、‘jwt.decrypt_alg_list’ および ‘jwt.decrypt_enc_list’ グローバルオプションによって変更できます。
JWEトークンは、base64urlエンコードした形式で渡さなければなりません。出力は “raw” 形式で返します。トークンのパース、署名検証、または内容の復号中にエラーが発生した場合、空文字列が返されます。
構成におけるクォート、コンマ、ダブルクォートの取り扱いの都合上、JWK の内容はこのコンバーターが正しく動作するためには適切にエスケープされている必要があります(詳細は 2.2節 を参照)。
例:
jwt_decrypt_secret(<secret>)
入力されたJSON Web Tokenについて、JSON Web Encryption形式(RFC 7516を参照)に従って署名を検証し、指定したbase64エンコード済みシークレットで復号した内容を返します。シークレットは、文字列として、または変数を介して指定できます。現在扱えるのは、Compact Serialization形式(base64-urlでエンコードした5つの文字列をドットで区切った形式)を使用するトークンだけです。
このコンバーターは、JOSE ヘッダーの “alg” フィールドに以下のアルゴリズムが含まれるトークンで使用できます:A128KW、A192KW、A256KW、A128GCMKW、A192GCMKW、A256GCMKW、dir。ただし、A128KW および A192KW アルゴリズムは AWS-LC では利用できないため、復号できません。
JWEトークンは、base64urlエンコードした形式で渡さなければなりません。出力は “raw” 形式で返します。トークンのパース、署名検証、または内容の復号中にエラーが発生した場合、空文字列が返されます。
例:
jwt_header_query([<json_path>[,<output_type>]])
入力された JSON Web Token (JWT) に対して、パラメーターが指定されていない場合はトークンのデコードされたヘッダー部分(JWT の最初の base64-url エンコードされた部分)を返します。パラメーターが指定されている場合は、デコードされたヘッダー部分に対して json_query を実行します。受け入れられる json_path および output_type パラメーターの詳細については “json_query” コンバーターを参照してください。このコンバーターは、コンパクトシリアライゼーション形式の JWS または JWE トークンで使用できます。
このコンバーターは HAProxy が USE_OPENSSL でコンパイルされた場合にのみ利用可能です。
jwt_payload_query([<json_path>[,<output_type>]])
入力された JSON Web Signed (JWS) 形式の JSON Web Token (JWT) に対して、パラメーターが指定されていない場合はトークンのデコードされたペイロード部分(JWT の2番目の base64-url エンコードされた部分)を返します。パラメーターが指定されている場合は、デコードされたペイロード部分に対して json_query を実行します。受け入れられる json_path および output_type パラメーターの詳細については “json_query” コンバーターを参照してください。
このコンバーターは HAProxy が USE_OPENSSL でコンパイルされた場合にのみ利用可能です。
jwt_verify(<alg>,<key>)
入力されたJSON Web Token (JWT) の署名を、<alg> アルゴリズムと <key> パラメーターを使って検証します。現在処理できるのは、Compact Serialization形式(base64-urlでエンコードした3つの文字列をドットで区切った形式)を使用するJWSトークンだけです。このコンバーターはトークンの署名だけを検証し、RFC7519の7.2節
で規定された完全なJWT検証は行いません。たとえば、デコード後のヘッダーとペイロードの内容が、完全に有効なJSONであることは保証せず、それぞれの内容に対するチェックも行いません。
-
<alg>は、検証に使用するアルゴリズムの名前を保持する文字列、または変数名にできます(“set-var” も参照してください)。RFC7518の3.1節 に記載されたアルゴリズムに対応しています。
RFC8725のセクション3.2 の推奨に従い、“none"アルゴリズムはデフォルトでは許可しません。明示的に許可するには、globalオプション’jwt.allow_none_alg’を設定してください。
-
<key>は、シークレットまたは公開鍵のパスを保持する文字列、または変数名にできます(“set-var” も参照してください)。シークレットは、HMACアルゴリズムを使用する場合にのみ適用できます。
公開鍵は、PKCS#1形式(RSA鍵用で、BEGIN RSA PUBLIC KEYで始まります)、またはSPKI形式(Subject Public Key Infoで、BEGIN PUBLIC KEYで始まります)でなければなりません。公開鍵は設定の解析時に利用できなければならず、実行時に更新したり読み込んだりすることはできません。完全なPEM証明書に基づくJWTトークンの検証については、“jwt_verify_cert” コンバーターを参照してください。
JWTの検証に使用する可能性があるすべての公開鍵は、初期化時に分かっていなければなりません。専用のキャッシュに追加し、実行時のディスクアクセスを不要にするためです。
検証に成功すると1、検証に失敗すると0、それ以外のエラーでは厳密に負の値を返します。このようにゼロでないエラー戻り値があるため、このコンバーターの結果を決して真偽値に変換すべきではありません。取り得る戻り値の完全な一覧は、以下を参照してください。
可能な戻り値は以下の通りです:
このコンバーターは HAProxy が USE_OPENSSL でコンパイルされた場合にのみ利用可能です。
例:
jwt_verify_cert(<alg>,<cert>)
入力されたJSON Web Token (JWT) の署名を、<alg> アルゴリズムと <cert> パラメーターを使って検証します。現在処理できるのは、Compact Serialization形式(base64-urlでエンコードした3つの文字列をドットで区切った形式)を使用するJWSトークンだけです。このコンバーターはトークンの署名だけを検証し、RFC7519の7.2節
で規定された完全なJWT検証は行いません。たとえば、デコード後のヘッダーとペイロードの内容が、完全に有効なJSONであることは保証せず、それぞれの内容に対するチェックも行いません。
-
<alg>は、検証に使用するアルゴリズムの名前を保持する文字列、または変数名にできます(“set-var” も参照してください)。“jwt_verify” コンバーターとは異なり、このコンバーターは第2パラメーターとして証明書だけを想定するため、HMACアルゴリズムを使用するトークンには使用すべきではありません。RFC7518の3.1節 に記載されたアルゴリズムに、HMACを除いて対応しています。
-
<key>は、証明書のパスを保持する文字列、または変数名にできます(“set-var” も参照してください)。証明書は、標準のPEM証明書(BEGIN CERTIFICATEで始まるもの)でなければなりません。パスをコンバーターに直接渡すか、変数を介して参照できます。変数を使う場合、対応する証明書は、crt-storeで宣言することも、統計ソケット経由で動的に読み込むこともできます。パスを直接指定した場合、対応する証明書が内部の証明書ストアにまだ読み込まれていなければ、設定の解析中に読み込みます。そのため、証明書はすでに存在していなければならず、存在しない場合はエラーが発生します。
JWTの検証に使用できると明示的に定義した証明書だけを使用できます。crt-storeの “jwt” オプションを参照してください。
統計ソケットを使って、証明書を動的に更新したり、新しい証明書を追加したりできます。管理ガイドの “set ssl cert” と “new ssl cert” も参照してください。
検証に成功すると1、検証に失敗すると0、それ以外のエラーでは厳密に負の値を返します。このようにゼロでないエラー戻り値があるため、このコンバーターの結果を決して真偽値に変換すべきではありません。取り得る戻り値の完全な一覧は、以下を参照してください。
可能な戻り値は以下の通りです:
このコンバーターは HAProxy が USE_OPENSSL でコンパイルされた場合にのみ利用可能です。
例:
language(<value>[,<default>])
“accept-language” ヘッダーから “req.fhdr” を使用して抽出されたリストから、q-factor が最大の値を返します。q-factor を持たない値の q-factor は 1 とみなされ、q-factor が 0 の値は除外されます。半角セミコロン区切りの <values> に含まれる値のみを対象とします。引数 <value> の構文は “lang[;lang[;lang[;…]]]” です。指定されたリストに一致する値が存在せず、デフォルト値が提供されている場合、そのデフォルト値が返されます。言語名にはダッシュ(’-’)の後にバリアントが付くことがあります。バリアントがリストに含まれている場合は一致しますが、含まれていない場合はベース言語のみがチェックされます。一致は大文字小文字を区別し、出力文字列は常に引数で提供されたものの中から選ばれます。引数の順序には意味がなく、リクエスト内の値の順序だけが有効です。同じq-factorを持つ値が複数ある場合、その中で最初の値を使用します。
例:
length
文字列の長さを取得します。これは文字列のサンプル取得関数の直後、または文字列型を返す変換キーワードの直後にのみ配置できます。結果の型は整数です。
lower
文字列のサンプルを小文字に変換します。これは文字列のサンプル取得関数の直後、または文字列型を返す変換キーワードの直後にのみ配置できます。結果の型は文字列です。
ltime(<format>[,<offset>])
エポックからの日付を表す整数を、<format> 文字列で定義されたフォーマット(strftime(3) を使用)に従ってローカル時間の文字列に変換します。ログに任意の日付フォーマットを使用できるようにする目的があります。入力日付にオプションの <offset>(秒単位、正または負)を適用できます。使用するOSがサポートする書式は、strftime()のmanページを参照してください。utime コンバーターも参照してください。
例:
ltrim(<chars>)
入力サンプルの文字列表現の先頭から、<chars> に含まれる文字をすべてスキップします。
map(<map_name>[,<default_value>])
<match_type> の照合方法を使って <map_name> から入力値を検索し、対応する値を <output_type> 型に変換して返します。入力値が <map_name> に存在しない場合、コンバーターは <default_value> を返します。<default_value> が設定されていない場合、コンバーターは失敗し、入力値が取得できなかったものとして動作します。<match_type> が設定されていない場合、デフォルトは “str” です。同様に、<output_type> が設定されていない場合、デフォルトは “str” です。便宜上、“map” キーワードは “map_str” のエイリアスであり、文字列を別の文字列にマップします。<map_name> は 2.7 節のマップおよび ACL の名前形式に従う必要があります。
キーの範囲が重ならないようにすることが重要です。IPアドレスと文字列はツリーに格納するため、最も具体的な一致のうち、最初のものを使用します。それ以外のキーはリストに格納するため、最初に一致したものを使用します。
次の表に、使用できるすべてのマップ関数を、入力型、照合方式、出力型の順に並べて示します。
特殊なマップ “map_regm” は、正規表現にキャプチャーグループがあることを想定し、後方参照(”\1” など)を対応する一致テキストに置き換えて、出力を変更します。
出力型 “key” は、値ではなく、一致したエントリのキー(マップファイルに記載されたもの)を文字列として返すことを意味します。この出力型を使用する場合、オプションの <default_value> 引数はサポートされません。
<map_name> で参照されるファイルには、1行に1つのキーと値が含まれます。’#’ で始まる行は無視され、空行と同じ扱いになります。先頭のタブや空白は削除されます。キーは最初の「単語」(スペースとタブ以外の文字の並び)です。値は、その後に続くスペースとタブの並びの後から行末までの部分で、末尾のスペースとタブを除きます。
例:
mod(<value>)
入力値(符号付き整数型)を <value> で割り、その余りを符号付き整数として返します。<value> がゼロの場合、ゼロを返します。<value> は数値または変数名です。詳細は 2.8節
の変数についてを参照してください。
mqtt_field_value(<packettype>,<fieldname_or_property_ID>)
入力された <packettype> 型のMQTTペイロードにある、<fieldname> の値を返します。<packettype> は文字列(大文字小文字を区別しないマッチング)またはパケットの種類に対応する数値です。サポートされる文字列および整数は以下の通りです:
https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718021
https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901022
<fieldname> は <packettype> に依存し、以下のいずれかになります。(<fieldname> のマッチングは大文字小文字を区別しません。)<property id> は MQTT v5.0 ストリームでのみ見つかります。以下の表を確認してください: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901029
- CONNECT (または 1): flags, protocol_name, protocol_version, client_identifier, will_topic, will_payload, username, password, keepalive または任意のプロパティ ID を数値として指定(MQTT v5.0 パケットのみ):
まだサポートされていません:
- CONNACK (または 2): flags, protocol_version, reason_code または任意のプロパティ ID を数値として指定(MQTT v5.0 パケットのみ):
まだサポートされていません:
現在の HAProxy の設計上、クライアントおよびサーバーが送信する最初のメッセージのみが解析可能です。したがって、このコンバーターは CONNECT および CONNACK パケット型からのみデータを抽出できます。CONNECT はクライアントが最初に送信するメッセージであり、CONNACK はサーバーが最初に送信する応答です。
例:
mqtt_is_valid
バイナリ入力が有効な MQTT パケットかどうかを確認します。ブール値を返します。
現在の HAProxy の設計上、クライアントおよびサーバーが送信する最初のメッセージのみが解析可能です。したがって、このコンバーターは CONNECT および CONNACK パケット型からのみデータを抽出できます。CONNECT はクライアントが最初に送信するメッセージであり、CONNACK はサーバーが最初に送信する応答です。
MQTT 3.1、3.1.1 および 5.0 のみがサポートされています。
例:
ms_ltime(<format>[,<offset>])
“ltime” と同様に動作しますが、入力がミリ秒単位であることを想定しています。また、date(1) に由来する %N 変換指定子もサポートしています。エポックからの日付を表す整数を、<format> 文字列で定義されたフォーマットに従って strftime(3) を使用してローカル時間の文字列に変換します。目的は、ログで任意の日付フォーマットを使用可能にすることです。入力日付に、オプションの <offset>(ミリ秒単位、正または負の値)を適用できます。使用するOSがサポートする書式は、strftime()のmanページを参照してください。
%N 変換指定子を使用すると、日付のナノ秒部分を出力できます。入力がミリ秒単位であるため、精度は制限されています(000000000..999000000)。%N は % と N の間に幅引数を取ることができます。ミリ秒(%3N)やマイクロ秒(%6N)を表示するのに有用です。デフォルトおよび最大幅は 9(%N = %9N)です。
utime コンバーター(UTC 用)および “ltime” と “us_ltime” コンバーターについても参照してください。
例:
ms_utime(<format>[,<offset>])
“utime” と同様に動作しますが、入力がミリ秒単位であることを想定しています。また、date(1) に由来する %N 変換指定子もサポートしています。エポックからの日付を表す整数を、<format> 文字列で定義されたフォーマットに従って strftime(3) を使用して UTC 時間の文字列に変換します。目的は、ログで任意の日付フォーマットを使用可能にすることです。入力日付に、オプションの <offset>(ミリ秒単位、正または負の値)を適用できます。使用するOSがサポートする書式は、strftime()のmanページを参照してください。
%N 変換指定子を使用すると、日付のナノ秒部分を出力できます。入力がミリ秒単位であるため、精度は制限されています(000000000..999000000)。%N は % と N の間に幅引数を取ることができます。ミリ秒(%3N)やマイクロ秒(%6N)を表示するのに有用です。デフォルトおよび最大幅は 9(%N = %9N)です。
ltime コンバーター(ローカル時間用)および “utime” と “us_utime” コンバーターについても参照してください。
例:
mul(<value>)
入力値(符号付き整数型)を <value> で乗算し、その積を符号付き整数として返します。オーバーフローした場合、その符号で表現できる限界値を返し、演算結果のラップアラウンドを防ぎます。<value> は数値または変数名として指定できます。変数の詳細については 2.8節
を参照してください。
nbsrv
入力値(文字列型)をバックエンド名として解釈し、そのバックエンドに利用可能なサーバー数を返します。動的名前(たとえばマップ検索の結果など)からバックエンドを参照する場所で使用できます。
neg
符号付き整数型の入力値の符号を反転した値を計算し、それを符号付き整数として返します。0は変化しません。この演算子は、逆向きの減算のために用意されています。定数から入力値を引くには、“neg,add(value)” を実行するだけです。
not
符号付き整数型の入力値がゼロでなければ、真偽値FALSEを返し、それ以外はTRUEを返します。and()と併用すると、入力値のビットテスト(たとえば、フラグがないことの確認)について、真または偽を返すために使用できます。
odd
入力値(符号付き整数型)が奇数の場合、論理値 TRUE を返し、それ以外(偶数)の場合、論理値 FALSE を返します。これは “and(1),bool” と機能的に同等です。
or(<value>)
<value> と入力値(符号付き整数型)のビット単位の “OR” を実行し、その結果を符号付き整数として返します。<value> は数値または変数名として指定できます。変数の詳細については 2.8節
を参照してください。
param(<name>[,<delim>])
入力文字列からパラメーター <name> の最初の出現を抽出します。パラメータは <delim> で区切られ、デフォルトでは “&” が使用されます。パラメーター名と値は “=” で区切られます。パラメーターセグメントの末尾までに “=” と値が存在しない場合、空文字列とみなされます。
クエリ文字列や、場合によってはx-www-form-urlencodedの本文から、パラメーターを抽出するのに役立ちます。特に、query,param(<name>) は urlp(<name>) の代わりに使用でき、区切り文字として “&” だけを使用します。一方、“urlp” は “?” と “;” も使用します。
このコンバーターは URL エンコードされた文字に対して特別な処理を行いません。値をデコードしたい場合は、出力に対して url_dec コンバーターを使用してください。入力内のパラメーター名にエンコードされた文字が含まれる可能性がある場合、“param” を呼び出す前に入力を正規化することを推奨します。これは “http-request normalize-uri” を使用して行うことができ、特に percent-decode-unreserved および percent-to-uppercase オプションを利用できます。
例:
port_only
Host ヘッダー値を含む文字列を、そのポート番号として整数に変換します。入力は Host ヘッダー値の形式(rfc9110#section-7.2)に従う必要があります。以下のような入力をサポートします:hostname、hostname:80、127.0.0.1、127.0.0.1:80、[::1]、[::1]:80。
入力にポートが指定されていない場合、0 を返します。
関連項目: ホストを返す “host_only” コンバーター。
protobuf(<field_number>[,<field_type>])
Protocol Buffersメッセージのバイナリー表現である入力サンプルから、<field_number>(ドット表記)で指定したフィールドを抽出します。<field_type> を指定しない場合は生データとして、指定した場合は整数サンプルとして抽出します(後述の “ungrpc” も参照してください)。使用できる型は、“varint” ワイヤータイプ0では “int32”、“int64”、“uint32”、“uint64”、“sint32”、“sint64”、“bool”、“enum”、64ビットのワイヤータイプ1では “fixed64”、“sfixed64”、“double”、ワイヤータイプ5では “fixed32”、“sfixed32”、“float” です。“string” は長さ区切りの型として扱うため、抽出に <field_type> 引数は必要ありません。Protocol Buffersメッセージのフィールド型の詳細は、https://developers.google.com/protocol-buffers/docs/encoding
を参照してください。
regsub(<regex>,<subst>[,<flags>])
入力文字列に、正規表現による置換を適用します。よく知られた “sed” ユーティリティーの “s/<regex>/<subst>/” と同じ操作を行います。デフォルトでは、入力文字列の中で、正規表現 <regex> に一致する最長の部分が最初に現れる箇所を、置換文字列 <subst> で置き換えます。第3引数 <flags> にフラグ “g” を追加すると、すべての一致箇所を置換することもできます。また、<flags> にフラグ “i” を追加すると、大文字と小文字を区別せずに正規表現を照合できます。<flags> は文字列なので、必要なすべてのフラグを連結して指定します。そのため、“i” と “g” の両方が必要な場合、“gi” と “ig” は同じ効果になります。このコンバーターの主な用途は、特定の文字や文字の並びを、ほかのものに置き換えることです。
正規表現部分を保護されたクォートで囲むことを強く推奨します。これにより、明確性が向上し、正規表現の閉じカッコが関数のカッコと混同されるのを防げます。Bourneシェルと同様に、1段階目のクォートは行上の単語グループを区切る際に処理され、2段階目のクォートは引数に使用可能です。外側にシングルクォートを使用することを推奨します。これは、バックスラッシュやドル記号の解決を試みないためです。
例:
reverse
入力文字列をバイト単位で逆順にします。
このコンバーターはエンコーディングに依存せず、文字ではなくバイトを逆順にします。UTF-8でエンコードされた、人が読むためのテキストを逆順にするには適していません。
これにより、元の文字列の接尾辞照合を逆順文字列の接頭辞照合に変換でき、“map_beg” などのインデックス付き接頭辞マッチャーを大規模なマップで使用できるようになります。
例:
reverse_dom
FQDNのようなホスト名を含む文字列を、ラベルを逆順にした形式に変換します。入力に末尾のドットが1つある場合は無視されます。空のラベルがあると、コンバーターは失敗します。
このコンバーターは入力を小文字に変換せず、ポートも削除しません。必要に応じて “lower” や “host_only” などの既存のコンバーターと組み合わせて使用することを想定しています。
末尾のドットのポリシーは意図的に呼び出し元に任されています。これにより、呼び出し元がアペックスもマッチさせたいか、サブドメインのみをマッチさせたいかを決定できるようになります。
逆順ラベル形式は、大規模なドメインマップで有用です。ドメインの接尾辞照合を接頭辞照合に変換でき、“map_beg” などのインデックス付き接頭辞マッチャーの使用が可能になります。
例:
rfc7239_field(<field>)
RFC 7239準拠のヘッダー値入力から1つのフィールド/パラメーターを抽出します。
サポートされるフィールドは以下の通りです。 - proto: ‘http’ または ‘https’ - host: HTTP準拠のホスト - for: RFC7239 ノード - by: RFC7239 ノード
詳細は以下を参照してください:
例:
rfc7239_is_valid
入力ヘッダーが RFC 7239準拠のヘッダー値の場合に true を返し、それ以外の場合は false を返します。
例:
rfc7239_n2nn
‘for’ または ‘by’ 7239ヘッダーフィールドから提供された RFC7239 ノードを、対応するノード名の最終形式に変換します。 - IPv4アドレス - IPv6アドレス - ‘unknown’ - ‘_obfs’ 識別子
例:
rfc7239_n2np
‘for’ または ‘by’ 7239ヘッダーフィールドから提供された RFC7239 ノードを、対応するノードポートの最終形式に変換します。 - 無符号整数 - ‘_obfs’ 識別子
例:
rfc7239_nn
提供されたアドレス/文字列入力を RFC7239 互換のノード名に変換します。手動で ‘for’ または ‘by’ 7239ヘッダーフィールドを構築する際に使用できます。
入力が文字列の場合、難読化された識別子を表すために自動的に ‘_’ 文字が前置されます。文字列は RFC7239 文字セットに準拠している必要があります。文字列が空の場合、“unknown” 識別子に変換されます。
例:
関連項目: “rfc7239_np”
rfc7239_np
提供された無符号整数/文字列入力を RFC7239 互換のノードポートに変換します。手動で ‘for’ または ‘by’ 7239ヘッダーフィールドを構築する際に使用できます。
入力が文字列の場合、難読化された識別子を表すために自動的に ‘_’ 文字が前置されます。文字列は RFC7239 文字セットに準拠している必要があり、空であってはなりません。
例:
関連項目: “rfc7239_nn”
rtrim(<chars>)
入力サンプルの文字列表現の末尾から <chars> の文字をすべてスキップします。
sdbm([<avalanche>])
SDBMハッシュ関数を使用して、バイナリ入力サンプルを無符号32ビット量にハッシュします。省略可能な <avalanche> 引数が1の場合、出力に完全なアバランチハッシュ関数を適用できます。このコンバーターは、さまざまなハッシュベースの負荷分散アルゴリズムで使用される関数と同一であるため、正確に同じ結果を提供します。主にデバッグ用途を想定していますが、大まかな統計を収集するためのスティックテーブルエントリーとしても使用できます。セキュリティ目的には使用しないでください。32ビットハッシュは簡単に破られるためです。関連項目: “crc32”, “djb2”, “wt6”, “crc32c”, および “hash-type” ディレクティブ。
secure_memcmp(<var>)
<var> の内容と入力値を比較します。両方の値はバイナリ文字列として扱われます。両方のバイナリ文字列が一致するかどうかを示すブール値を返します。
バイナリ文字列の長さが同じである場合、比較は一定の時間で行われます。
このコンバーターは HAProxy が USE_OPENSSL でコンパイルされた場合にのみ利用可能です。
例:
set-var(<var>[,<cond>...])
指定されたすべての条件が真である場合に限り、入力内容を変数に設定し、出力としてそのまま内容を返します(指定できる条件の一覧は以下を参照)。変数は値と、それに対応する入力の型を保持します。変数の詳細については 2.8節 を参照してください。
次の条件の中から、最大4つの条件をコンバーターに渡せます。
- “ifexists”/“ifnotexists”:
- “ifempty”/“ifnotempty”:
- “ifset”/“ifnotset”:
- “ifgt”/“iflt”:
sha1
バイナリ入力サンプルを SHA-1 ダイジェストに変換します。結果は長さ 20 バイトのバイナリサンプルです。
sha2([<bits>])
バイナリ入力サンプルを SHA-2 シリーズのダイジェストに変換します。結果は長さ <bits>/8 バイトのバイナリサンプルです。
<bits> の有効な値は 224、256、384、512 であり、それぞれ SHA-<bits> に対応します。デフォルト値は 256 です。
このコンバーターは HAProxy が USE_OPENSSL でコンパイルされた場合にのみ利用可能です。
srv_is_up
文字列型の入力値(サーバー名または <backend>/<server> 形式)を取得し、指定されたサーバーが現在 UP である場合に true を返します。動的な名前(たとえばCookieの値(req.cook(SRVID),srv_is_up))からサーバー状態を照会し、リクエストを別の場所に転送する判断に使用できます。使用する前に、制御されていないデータに対してこのコンバーターを使用すると、外部の観測者が構成内の任意のサーバーの状態を照会できる可能性があることに注意してください。これは一部の環境では許容されない場合があります。
srv_queue
文字列型の入力値(サーバー名または <backend>/<server> 形式)を取得し、そのサーバーにキューされたストリーム数を返します。動的な名前(たとえばCookieの値(req.cook(SRVID),srv_queue))からキューされたストリームを照会し、接続先の固定を解除するか、リクエストを別の場所に転送する判断に使用できます。使用する前に、制御されていないデータに対してこのコンバーターを使用すると、外部の観測者が構成内の任意のサーバーの状態を照会できる可能性があることに注意してください。これは一部の環境では許容されない場合があります。
strcmp(<var>)
<var> の内容を文字列型の入力値と比較します。結果は strcmp(3) と互換性のある符号付き整数として返されます。両方の文字列が同一の場合、0 を返します。左の文字列が辞書的に右の文字列より小さい場合、または左の文字列が短い場合、0 より小さい値を返します。それ以外の場合は 0 より大きい値を返します(右の文字列が左の文字列より大きい場合、または右の文字列が短い場合)。
2つのバイナリ文字列を一定の時間で比較する必要がある場合は、secure_memcmpコンバーターも参照してください。
例:
sub(<value>)
符号付き整数型の入力値から <value> を減算し、結果を符号付き整数として返します。注意:定数から入力値を減算するには、単に “neg,add(value)” を実行してください。<value> は数値または変数名です。詳細については 2.8節
を参照してください。
table_bytes_in_rate([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値 0 を返します。存在する場合、指定されたテーブル内の入力サンプルに関連するクライアントからサーバーへの平均バイト転送速度を、テーブルで設定した期間のバイト数で返します。sc_bytes_in_rate サンプル取得キーワードも参照してください。
table_bytes_out_rate([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値 0 を返します。存在する場合、指定されたテーブル内の入力サンプルに関連するサーバーからクライアントへの平均バイト転送速度を、テーブルで設定した期間のバイト数で返します。sc_bytes_out_rate サンプル取得キーワードも参照してください。
table_clr_gpc(<idx>[,<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。gpc配列のインデックス <idx> にある汎用カウンターをクリアし、それまでの値を返します。<idx> は 0 から 99 の整数です。エントリが存在しない場合、エントリが作成され、0 が返されます。このコンバーターは ‘gpc’ 配列の data_type にのみ適用されます(従来の ‘gpc0’ や ‘gpc1’ の data_type には適用されません)。sc_clr_gpc サンプル取得キーワードも参照してください。
table_clr_gpc0([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。最初の汎用カウンター ‘0’ をクリアし、その前の値を返します。エントリが存在しない場合、エントリが作成され、0 が返されます。これは通常、最初のACLを満たした場合に接続へ印を付けるために、式内の第2の ACL として使用されます:
例:
sc_clr_gpc0 サンプル取得キーワードも参照してください。
table_clr_gpc1([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。最初の汎用カウンター ‘1’ をクリアし、その前の値を返します。エントリが存在しない場合、エントリが作成され、0 が返されます。これは通常、最初のACLを満たした場合に接続へ印を付けるために、式内の第2の ACL として使用されます。sc_clr_gpc1 サンプル取得キーワードも参照してください。
table_conn_cnt([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値 0 を返します。存在する場合、指定されたテーブル内の入力サンプルに関連する着信接続の累積数を返します。sc_conn_cnt サンプル取得キーワードも参照してください。
table_conn_cur([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値 0 を返します。存在する場合、指定されたテーブル内の入力サンプルに関連する現在追跡している同時接続数を返します。sc_conn_cur サンプル取得キーワードも参照してください。
table_conn_rate([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値 0 を返します。存在する場合、指定されたテーブル内の入力サンプルに関連する着信接続の平均発生速度を返します。sc_conn_rate サンプル取得キーワードも参照してください。
table_expire([<table>[,<default_value>]])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、コンバーターは失敗しますが、<default_value> が設定されている場合は、コンバーターは成功し、<default_value> を返します。キーがテーブルに存在する場合、コンバーターは入力されたサンプルに対応するキーの有効期限までの時間を、指定されたテーブルから返します。また、table_idle サンプル取得キーワードも参照してください。
table_glitch_cnt([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応するフロント側の接続の異常発生回数の累計値を、指定されたテーブルから返します。sc_glitch_cnt サンプル取得キーワードと、現在のフロント側の接続で測定した値を取得する fc_glitches も参照してください。
table_glitch_rate([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応するフロント側の接続の異常発生率の平均値を、指定されたテーブルから返します。また、sc_glitch_rate サンプル取得キーワードも参照してください。
table_gpc(<idx>[,<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応する配列のインデックス <idx> における汎用カウンターの現在値を、指定された <table> から返します。<idx> は 0 から 99 の整数です。このインデックスに GPC が格納されていない場合も、整数値0を返します。これは ‘gpc’ 配列データ型だけに適用します(従来の ‘gpc0’ や ‘gpc1’ データ型には適用しません)。また、sc_get_gpc サンプル取得キーワードも参照してください。
table_gpc0([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応する最初の汎用カウンターの現在値を、指定されたテーブルから返します。また、sc_get_gpc0 サンプル取得キーワードも参照してください。
table_gpc0_rate([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは、指定したテーブル内で入力サンプルに関連付けられたgpc0カウンターが、テーブルで設定した期間内に増加した頻度を返します。また、sc_get_gpc0_rate サンプル取得キーワードも参照してください。
table_gpc1([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応する2番目の汎用カウンターの現在値を、指定されたテーブルから返します。また、sc_get_gpc1 サンプル取得キーワードも参照してください。
table_gpc1_rate([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは、指定したテーブル内で入力サンプルに関連付けられたgpc1カウンターが、テーブルで設定した期間内に増加した頻度を返します。また、sc_get_gpc1_rate サンプル取得キーワードも参照してください。
table_gpc_rate(<idx>[,<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは、指定したスティックテーブル <table> 内で入力サンプルに関連付けられた配列の、インデックス <idx> にある汎用カウンターが、設定した期間内に増加した頻度を返します。<idx> は 0 から 99 の整数です。このインデックスに gpc_rate が格納されていない場合も、整数値0を返します。これは ‘gpc_rate’ 配列データ型だけに適用します(従来の ‘gpc0_rate’ や ‘gpc1_rate’ データ型には適用しません)。また、sc_gpc_rate サンプル取得キーワードも参照してください。
table_gpt(<idx>[,<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応する配列のインデックス <idx> における汎用タグの現在値を、指定された <table> から返します。<idx> は 0 から 99 の整数です。このインデックスに GPT が格納されていない場合も、整数値0を返します。これは ‘gpt’ 配列データ型だけに適用します(従来の ‘gpt0’ データ型には適用しません)。また、sc_get_gpt サンプル取得キーワードも参照してください。
table_gpt0([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応する最初の汎用タグの現在値を、指定されたテーブルから返します。また、sc_get_gpt0 サンプル取得キーワードも参照してください。
table_http_err_cnt([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応する HTTP エラーの累計数を、指定されたテーブルから返します。また、sc_http_err_cnt サンプル取得キーワードも参照してください。
table_http_err_rate([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは、指定したテーブル内で入力サンプルに関連付けられたHTTPエラーの平均レートを返します。テーブルで設定した期間内のエラー数で測定します。また、sc_http_err_rate サンプル取得キーワードも参照してください。
table_http_fail_cnt([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応する HTTP失敗の累計数を、指定されたテーブルから返します。また、sc_http_fail_cnt サンプル取得キーワードも参照してください。
table_http_fail_rate([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは、指定したテーブル内で入力サンプルに関連付けられたHTTP失敗の平均レートを返します。テーブルで設定した期間内の失敗数で測定します。また、sc_http_fail_rate サンプル取得キーワードも参照してください。
table_http_req_cnt([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは入力されたサンプルに対応する HTTP リクエストの累計数を、指定されたテーブルから返します。また、sc_http_req_cnt サンプル取得キーワードも参照してください。
table_http_req_rate([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、整数値ゼロが返されます。それ以外の場合、コンバーターは、指定したテーブル内で入力サンプルに関連付けられたHTTPリクエストの平均レートを返します。テーブルで設定した期間内のリクエスト数で測定します。また、sc_http_req_rate サンプル取得キーワードも参照してください。
table_idle([<table>[,<default_value>]])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。キーがテーブルに存在しない場合、コンバーターは失敗しますが、<default_value> が設定されている場合は、コンバーターは成功し、<default_value> を返します。キーが存在する場合、コンバーターは入力されたサンプルに対応するキーのエントリーが、最後に更新されてからどれだけの時間アイドル状態であったかを、指定されたテーブルから返します。また、table_expire サンプル取得キーワードも参照してください。
table_inc_gpc(<idx>[,<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。配列のインデックス <idx> における汎用カウンターをインクリメントし、その新しい値を返します。<idx> は 0 から 99 の整数です。エントリーが存在しない場合、エントリーが作成され、1 が返されます。このコンバーターは ‘gpc’ 配列データタイプにのみ適用されます(従来の ‘gpc0’ や ‘gpc1’ データタイプには適用されません)。また、sc_inc_gpc も参照してください。
table_inc_gpc0([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。汎用カウンター ‘0’ をインクリメントし、その新しい値を返します。エントリーが存在しない場合、エントリーが作成され、1 が返されます。sc0/sc2/sc2_inc_gpc0 も参照してください。通常は、式の2番目のACLとして使用し、最初のACLを満たした場合に、接続へ印を付けます:
例:
table_inc_gpc1([<table>])
入力サンプルを使用して、現在のプロキシのスティックテーブル、または指定したスティックテーブルを検索します。汎用カウンター「1」をインクリメントし、その新しい値を返します。エントリーが見つからない場合、エントリーを作成して1を返します。sc0/sc2/sc2_inc_gpc1も参照してください。通常は、式の2番目のACLとして使用し、最初のACLを満たした場合に、接続へ印を付けます。
table_kbytes_in([<table>])
入力されたサンプルを、現在のプロキシのスティックテーブルまたは指定されたスティックテーブルで照合します。キーがテーブルに存在しない場合、整数値ゼロを返します。それ以外の場合、コンバーターは指定されたテーブルにおける入力サンプルに関連するクライアントからサーバーへのデータの累計値をキロバイト単位で返します。現在、テストは32ビット整数で行われており、値は4テラバイトまでに制限されています。参照: sc_kbytes_inサンプル取得キーワード。
table_kbytes_out([<table>])
入力されたサンプルを、現在のプロキシのスティックテーブルまたは指定されたスティックテーブルで照合します。キーがテーブルに存在しない場合、整数値ゼロを返します。それ以外の場合、コンバーターは指定されたテーブルにおける入力サンプルに関連するサーバーからクライアントへのデータの累計値をキロバイト単位で返します。現在、テストは32ビット整数で行われており、値は4テラバイトまでに制限されています。参照: sc_kbytes_outサンプル取得キーワード。
table_server_id([<table>])
入力されたサンプルを、現在のプロキシのスティックテーブルまたは指定されたスティックテーブルで照合します。キーがテーブルに存在しない場合、整数値ゼロを返します。それ以外の場合、コンバーターは指定されたテーブルにおける入力サンプルに関連するサーバーIDを返します。サーバーIDは、接続が成功した際に「stick」ルールによってサンプルに関連付けられます。サーバーIDがゼロの場合は、このキーに関連するサーバーが存在しないことを意味します。
table_sess_cnt([<table>])
入力されたサンプルを、現在のプロキシのスティックテーブルまたは指定されたスティックテーブルで照合します。キーがテーブルに存在しない場合、整数値ゼロを返します。それ以外の場合、コンバーターは指定されたテーブルにおける入力サンプルに関連する受信セッションの累計数を返します。ここでセッションとは、「tcp-request connection」ルールセットによって受け入れられた受信接続を指します。参照: sc_sess_cntサンプル取得キーワード。
table_sess_rate([<table>])
入力されたサンプルを、現在のプロキシのスティックテーブルまたは指定されたスティックテーブルで照合します。キーがテーブルに存在しない場合、整数値ゼロを返します。それ以外の場合、コンバーターは指定されたテーブルにおける入力サンプルに関連する平均受信セッションレートを返します。ここでセッションとは、「tcp-request connection」ルールセットによって受け入れられた受信接続を指します。参照: sc_sess_rateサンプル取得キーワード。
table_trackers([<table>])
入力されたサンプルを、現在のプロキシのスティックテーブルまたは指定されたスティックテーブルで照合します。キーがテーブルに存在しない場合、整数値ゼロを返します。それ以外の場合、コンバーターは指定されたテーブルにおける入力サンプルと同じキーを追跡している現在の同時接続数を返します。これはtable_conn_curとは異なり、保存された情報に依存せず、テーブルの参照カウント(CLIの"show table"で返される「use」値)に依存します。これは、layer7の追跡に適している場合があります。たとえば、特定のアドレスからの同時接続数をサーバーに通知するのに使用できます。参照: sc_trackersサンプル取得キーワード。
tcp.dst
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。このコンバーターはTCPヘッダーに含まれる宛先ポートを表す整数を返します。参照: “fc_saved_syn”、「tcp-ss」、および"ip.data”。
tcp.flags
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。このコンバーターはTCPヘッダー内のTCPフラグを表す整数を返します。FINからCWRまでの8フラグすべてが取得されます。各フラグは「and()」コンバーターでテストできます。各フラグの値についてはRFC9293を参照してください。参照: “fc_saved_syn”、「tcp-ss」、および"ip.data”。
tcp.options.mss
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。TCPオプションの種類「MSS」を検索し、見つかった場合、そのオプションに含まれる通知された値に対応する整数値を返します。見つからない場合、ゼロを返します。MSSは最大セグメントサイズを意味し、ピアが受信できる最大セグメントサイズ(バイト単位)を示します。参照: “fc_saved_syn”、「tcp-ss」、および"ip.data”。
tcp.options.sack
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。TCPオプションの種類「Sack-Permitted」を検索し、見つかった場合、1を返します。見つからない場合、ゼロを返します。参照: “fc_saved_syn”、「tcp-ss」、および"ip.data”。
tcp.options.tsopt
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。TCPオプションの種類「Timestamp」を検索し、見つかった場合、1を返します。見つからない場合、ゼロを返します。参照: “fc_saved_syn”、「tcp-ss」、および"ip.data”。
tcp.options.tsval
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。TCPオプションの種類「Timestamp」を検索し、見つかった場合、ピアが発行したタイムスタンプ値を返します。見つからない場合、何も返しません。タイムスタンプは32ビット符号なし値です。単位は決まっておらず、ピアだけが決定します。また、異なる接続間では互いに独立していることが期待されます。参照: “fc_saved_syn”、「tcp-ss」、および"ip.data”。
tcp.options.wscale
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。TCPオプションの種類「Window Scale」を検索し、見つかった場合、ピアが発行したウィンドウスケーリング値を返します。見つからない場合、ゼロを返します。値は14を超えないことが想定されていますが、14を超える値の送信を妨げる技術的な制限はありません。ウィンドウスケールオプションが使用されたかどうかを検出するには、“tcp.options.wsopt"を使用してください。参照: 「tcp-ss」、“fc_saved_syn”、“ip.data”、および"tcp.options.wsopt”。
tcp.options.wsopt
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。TCPオプションの種類「Window Scale」を検索し、見つかった場合、1を返します。見つからない場合、0を返します。参照: “fc_saved_syn”、「tcp-ss」、“ip.data”、“tcp.options.wscale”。
tcp.options_list
「ip.data」が返すような、バイナリのTCPヘッダーを表す入力サンプルに対して使用します。TCPヘッダーに出現する順序で、すべてのTCPオプション種別からなるバイナリ列を作成します。生成する長さは0~60バイト(最悪の場合)です。End-of-optionsは出力しません。「fc_saved_syn」、「tcp-ss」、「ip.data」も参照してください。
tcp.seq
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。TCPヘッダーに使用されたピアのシーケンス番号を表す整数を返します。シーケンス番号は32ビット符号なし値です。参照: “fc_saved_syn”、「tcp-ss」、および"ip.data”。
tcp.src
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。TCPヘッダーに含まれる送信元ポートを表す整数を返します。参照: “fc_saved_syn”、「tcp-ss」、および"ip.data”。
tcp.win
入力サンプルが"ip.data"によって返されたバイナリTCPヘッダーを表している場合に使用します。TCPヘッダーでピアが通知したウィンドウサイズを表す整数を返します。値はそのまま16ビット符号なし量として提供され、ウィンドウスケーリング係数は適用されません。参照: “fc_saved_syn”、「tcp-ss」、および"ip.data”。
ub64dec
このコンバーターはb64decコンバーターのbase64url版です。base64urlエンコーディングは、URLやファイル名で安全に使える文字セットを使用するbase64エンコーディングの一種です。これはJWT(JSON Web Token)標準で使用されるエンコーディングでもあります。
例:
ub64enc
このコンバーターはbase64コンバーターのbase64url版です。
ungrpc(<field_number>[,<field_type>])
gRPCメッセージを表す入力バイナリサンプルから、<field_number>で指定したフィールド番号(ドット表記)のProtocol Buffersメッセージフィールドを抽出します。<field_type>を指定しない場合は生データとして、指定した場合は整数サンプルとして抽出します。使用できる型は、“varint"のワイヤータイプ0では"int32”、“int64”、“uint32”、“uint64”、“sint32”、“sint64”、“bool”、“enum”、64ビットのワイヤータイプ1では"fixed64”、“sfixed64”、“double”、ワイヤータイプ5では"fixed32”、“sfixed32”、“float"です。“string"は長さで区切られる型と見なされるため、抽出に<field_type>引数は不要です。Protocol Buffersメッセージのフィールド型の詳細は、次を参照してください:
https://developers.google.com/protocol-buffers/docs/encoding
例:
リクエストボディーが"Rectangle"オブジェクトの値(2つのPPointのProtocol Buffersメッセージ)で構成されているとします。4つのProtocol Buffersフィールドは、次の"ungrpc"ディレクティブで抽出できます:
中間の48.59フィールドを、次のようにバイナリサンプルとして抽出することもできます:
gRPCメッセージは常にgRPCヘッダーにProtocol Buffersメッセージが続く構造であるため、前の例の最初のPPointである"lo"の"latitude"は、次の同等のディレクティブで抽出できます:
最初の変換は"ungrpc”、残りの変換は"protobuf"でなければなりません。直前のバイナリサンプルを解釈するための2番目の引数は、最後の変換だけが指定してもしなくてもかまいません。
unset-var(<var>)
入力コンテンツが定義されている場合、変数を解除します。変数名はそのスコープを示す接頭辞で始まります。詳細についてはセクション2.8 を参照してください。
upper
文字列サンプルを大文字に変換します。これは文字列サンプル取得関数の後にのみ配置でき、または文字列型を返す変換キーワードの後にのみ配置できます。結果の型は文字列です。
url_dec([<in_form>])
入力としてURLエンコードされた文字列を受け取り、デコードされたバージョンを出力として返します。入力と出力はともに文字列型です。<in_form>引数が非ゼロの整数値に設定されている場合、入力文字列はフォームまたはクエリ文字列の一部とみなされ、’+‘文字はスペース(’ ‘)に変換されます。それ以外の場合は、クエリ文字列を示す疑問符の後にのみ変換が行われます(’?’)。
url_enc([<enc_type>])
入力として文字列を受け取り、エンコードされたバージョンを出力として返します。入力と出力はともに文字列型です。デフォルトではエンコーディングのタイプはquery用に想定されています。現時点では他のタイプはサポートされていませんが、オプション引数は将来の変更のために用意されています。
us_ltime(<format>[,<offset>])
“ltime"と同様に動作しますが、入力はマイクロ秒単位です。date(1)に由来する%N変換指定子もサポートしています。エポックからの日時を表すと想定した整数を、<format>文字列で定義されたフォーマットに従ってstrftime(3)を使用してローカル時間の文字列に変換します。目的は、ログで任意の日付フォーマットを使用できるようにすることです。入力日付にオプションの<offset>(マイクロ秒単位)を適用できます(正または負)。使用しているオペレーティングシステムがサポートする形式は、strftime()のマニュアルページを参照してください。
%N変換指定子を使用すると、日付のナノ秒部分を出力できます。入力がマイクロ秒単位であるため、精度は制限されています(000000000..999999000)。%Nは%とNの間に幅引数を取ることができます。ミリ秒(%3N)やマイクロ秒(%6N)を表示するのに有用です。デフォルトおよび最大幅は9です(%N = %9N)。
UTC用の"utime"コンバーター、および"ltime"と"ms_ltime"コンバーターも参照してください。
例:
us_utime(<format>[,<offset>])
“utime"と同様に動作しますが、入力はマイクロ秒単位です。date(1)に由来する%N変換指定子もサポートしています。エポックからの日時を表すと想定した整数を、<format>文字列で定義されたフォーマットに従ってstrftime(3)を使用してUTC時間の文字列に変換します。目的は、ログで任意の日付フォーマットを使用できるようにすることです。入力日付にオプションの<offset>(マイクロ秒単位)を適用できます(正または負)。使用しているオペレーティングシステムがサポートする形式は、strftime()のマニュアルページを参照してください。
%N変換指定子を使用すると、日付のナノ秒部分を出力できます。入力がマイクロ秒単位であるため、精度は制限されています(000000000..999999000)。%Nは%とNの間に幅引数を取ることができます。ミリ秒(%3N)やマイクロ秒(%6N)を表示するのに有用です。デフォルトおよび最大幅は9です(%N = %9N)。
ローカル時刻用の"ltime"コンバーター、および"utime"と"ms_utime"コンバーターも参照してください。
例:
utime(<format>[,<offset>])
エポックからの日時を表すと想定した整数を、<format>文字列で定義されたフォーマットに従ってstrftime(3)を使用してUTC時間の文字列に変換します。目的は、ログで任意の日付フォーマットを使用できるようにすることです。入力日付にオプションの<offset>(秒単位)を適用できます(正または負)。使用しているオペレーティングシステムがサポートする形式は、strftime()のマニュアルページを参照してください。また"ltime"コンバーターおよび"ms_utime”、“us_utime"についても参照してください。
例:
when(<condition>[,<args>...])
条件を評価し、真の場合は入力サンプルをそのまま出力に渡し、それ以外の場合は何も返しません。エラー発生時のデバッグ情報など、まれにしか必要にならず、特定の条件下でのみ出力すべき情報を扱うために設計されています。
条件は以下のリストのキーワードからなります。任意で感嘆符(’!’)を前に付けて否定でき、条件固有の引数を後ろに付けることもできます:
- "error"は、リクエストまたはストリームの処理中にエラーが発生した場合に真を返します。"dontlog-normal"と同じルールを使用します(たとえば、再ディスパッチが成功した場合もエラーとみなされます)。
- "forwarded"は、リクエストがバックエンドサーバーに転送された場合に真を返します。
- "normal"は、エラーが発生しなかった場合に真を返します("!error"と同等です)。
- "processed"は、リクエストがバックエンドサーバーに転送された場合、またはアプレットによって処理された場合に真を返します。
- "stopping"は、ルールを評価した時点でプロセスが停止中の場合に真を返します。
- "toapplet"は、リクエストがアプレットによって処理された場合に真を返します。
- "acl"は、次の引数で指定したACLの評価結果が真の場合に真を返します。ACLはコンバーター内でインライン評価されるため、参照する内容はそのコンテキストで有効でなければなりません。たとえば、合計転送時間が長すぎるかどうかを評価してから、異常に長い転送の詳細をログに記録するかどうかを決める用途があります。
内容はどの場合でも評価されるため、この方法でその情報の生成を回避することはできません。あくまで、その情報を出力しないためのものです。
たとえば、処理中にエラーが発生した場合にだけバックエンドストリームのデバッグ情報をログに追加する、停止時に追加情報をログに記録するといった用途があります。
例:
例
例
条件が真でない場合は式の評価を打ち切るため、後続のコンバーターが呼び出されないようにすることもできます。たとえば、エラー発生時にだけdebug()コンバーターを呼び出し、どうしても必要な場合にだけ要素をログに記録できます。
例:
debugコンバーターも参照してください。
word(<index>,<delimiters>[,<count>])
入力文字列から指定された区切り文字を用いて、先頭(正のインデックス)または末尾(負のインデックス)から数えたn番目の単語を抽出します。インデックスは1または-1から始まり、区切り文字は、文字のリストを文字列にしたものです。空の単語はスキップされます。つまり、入力文字列の先頭または末尾にある区切り文字は無視され、入力文字列内に連続する区切り文字は1つの区切り文字として扱われます。オプションで抽出する単語数を<count>で指定できます(デフォルト:1)。値0は残りのすべての単語を抽出することを示します。
例:
wt6([<avalanche>])
WT6ハッシュ関数を使用して、バイナリ入力サンプルを符号なし32ビット量にハッシュします。オプションで、<avalanche>引数が1に等しい場合に、出力に完全なアバランチハッシュ関数を適用できます。このコンバーターは、さまざまなハッシュベースの負荷分散アルゴリズムで使用される関数と同一であるため、正確に同じ結果を提供します。主にデバッグ用途に使用されますが、スティックテーブルエントリーとして粗い統計情報を収集する用途にも使用できます。32ビットハッシュは簡単に破られるため、セキュリティ目的には使用してはなりません。参照: “crc32”, “djb2”, “sdbm”, “crc32c”,および"hash-type"ディレクティブ。
x509_v_err_str
数値を対応するX509_V_ERR定数名に変換します。OpenSSLの複数バージョンに対応した設定をACLで作成する際に有用です。バージョンを変更すると一部のコードが変わる可能性があるためです。
対応する定数名が見つからない場合、数値を文字列として出力します。
OpenSSLが提供する定数の一覧はhttps://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES にあります。OpenSSLの正しいバージョンのページを確認してください。
例:
xor(<value>)
<value>と入力値(符号付き整数型)の間でビット単位の「XOR」(排他的論理和)を実行し、結果を符号付き整数として返します。<value>は数値または変数名として指定できます。詳細についてはセクション2.8
の変数に関する記述を参照してください。
xxh3([<seed>])
XXH3 64ビットバージョンのXXhashハッシュ関数を使用して、バイナリ入力サンプルを符号付き64ビット量にハッシュします。このハッシュはシードをサポートしており、デフォルトは0ですが、<seed>引数で異なる値を指定できます。このハッシュは非常に優れており高速であるため、URLおよび/またはURLパラメータをスティックテーブルのキーとしてハッシュして、低衝突率で統計情報を収集する用途に使用できますが、アルゴリズムが暗号的に安全とは見なされていないため注意が必要です。
xxh32([<seed>])
XXHashハッシュ関数の32ビットバージョンを使用して、バイナリ入力サンプルを符号なし32ビット量にハッシュします。このハッシュはシードをサポートしており、デフォルトは0ですが、<seed>引数で異なる値を指定できます。このハッシュは非常に優れており高速であるため、URLおよび/またはURLパラメータをスティックテーブルのキーとしてハッシュして、低衝突率で統計情報を収集する用途に使用できますが、アルゴリズムが暗号的に安全とは見なされていないため注意が必要です。
xxh64([<seed>])
XXHashハッシュ関数の64ビットバージョンを使用して、バイナリ入力サンプルを符号付き64ビット量にハッシュします。このハッシュはシードをサポートしており、デフォルトは0ですが、<seed>引数で異なる値を指定できます。このハッシュは非常に優れており高速であるため、URLおよび/またはURLパラメータをスティックテーブルのキーとしてハッシュして、低衝突率で統計情報を収集する用途に使用できますが、アルゴリズムが暗号的に安全とは見なされていないため注意が必要です。
7.3.2. 内部状態からのサンプル取得
最初のサンプル取得メソッド群は、クライアント情報とはまったく関係のない内部情報に適用されます。これらは、外部監視者に内部ステータスを報告するために"monitor fail"ディレクティブと併用されることがあります。このセクションで説明するサンプル取得メソッドは、どこでも使用可能です。
このセクションのサンプル取得メソッドと、それぞれの型の一覧:
詳細一覧:
acl([!]<name>[,...]): boolean
指定されたACLの評価がすべて真の場合に真を返し、それ以外の場合は偽を返します。最大12個のACLを指定でき、それぞれをコンマで区切ります。各名前付きACLは”!“で前置することで結果を反転できます。評価のいずれかでエラーが発生した場合、サンプルもエラーを返します。HAProxyは参照されたACLに対して、たとえばHTTPリクエストサンプルを使用するACLがレスポンスコンテキストで使用されているかどうかなどの検証チェックを行いません。この動作は将来変更される可能性があります。
act_conn: integer プロセス上のアクティブな同時接続の総数を返します。
always_false: boolean 常にブール値"false"を返します。設定調整中に別のACLの一時的な置き換えとしてACLと併用できます。
always_true: boolean 常にブール値"true"を返します。設定調整中に別のACLの一時的な置き換えとしてACLと併用できます。
avg_queue([<backend>]): integer
指定されたバックエンドのキュー済み接続数を、アクティブなサーバー数で割った値を返します。バックエンドが指定されない場合は現在のバックエンドが使用されます。これは"queue"と似ていますが、ファームのサイズを考慮することで、新しい接続が処理されるまでの時間をより正確に測定できます。主な用途は、ACLと併用して、新規ユーザーに提供するサービスの品質が低下することが確実になった場合にお詫びページを返すことです。また、この値をヘッダーでバックエンドサーバーに渡し、機能を制限したモードで動作するか、一部の機能を無効にして処理を少し高速化するかをサーバー自身が決められるようにする用途もあります。すべてのアクティブなサーバーが停止した場合、キュー済み接続数の2倍を測定値として扱います。これは妥当な推定であり、いずれかのサーバーがすぐに復帰すると予想されるためですが、別のバックエンドがより良好な状態であれば、新規トラフィックをそちらに送信することを優先します。参照: “queue”, “be_conn”, “be_sess_rate"サンプル取得。
be_conn([<backend>]): integer
バックエンド上の現在確立された接続数に適用され、評価中の接続を含む可能性があります。バックエンド名が指定されない場合は現在のバックエンドが使用されます。別のバックエンドを確認することも可能です。通常のファームが満杯の場合に、特定のファームを使用する用途に使用できます。参照: “fe_conn”, “queue”, “be_conn_free”, “be_sess_rate"指定子。
be_conn_free([<backend>]): integer
バックエンド内の利用可能なサーバー上の利用可能な接続数に相当する整数値を返します。キューのスロットは含まれません。バックアップサーバーも含まれませんが、他のすべてのサーバーが停止している場合を除きます。バックエンド名が指定されない場合は現在のバックエンドが使用されます。別のバックエンドを確認することも可能です。通常のファームが満杯の場合に、特定のファームを使用する用途に使用できます。参照: “be_conn”, “connslots”, “srv_conn_free"指定子。
その他の注意点と備考:いずれかのサーバーのmaxconnまたはmaxqueueが0(無制限)の場合、この取得は明らかに意味をなさないため、返される値は-1になります。
be_sess_rate([<backend>]): integer
バックエンドでのセッション生成レートを、1秒あたりの新規セッション数を表す整数値として返します。処理負荷が高い、または障害に弱いバックエンドのセッションレートが高くなりすぎた場合に、ACLと併用して別のバックエンドへ切り替えたり、サービスの乱用を制限したりするために使用します(たとえば、オンライン辞書の内容を丸ごと取得されることを防ぎます)。log-formatディレクティブでこの値をログに追加する用途にも役立ちます。
例:
bin(<hex>): bin
バイナリ列を返します。入力には、文字列の16進表現を指定します。
bool(<bool>): bool
ブール値を返します。<bool>には’true’、‘false’、‘1’、‘0’を指定できます。‘false’と'0’は同じ値です。’true’と'1’も同じ値です。
connslots([<backend>]): integer
すべてのサーバーの最大接続数と最大キューサイズを合計し、バックエンドでまだ利用可能な接続スロット数に対応する整数値を返します。おそらくACLとの併用に限られます。
基本的な考え方は、まだ利用可能な接続「スロット」数(接続+キュー)を測定できるようにし、それを超える接続を別のバックエンドへリダイレクトできるようにすることです(想定用途については"use_backend"キーワードを参照してください)。
‘connslots’=利用可能なサーバー接続スロット数+利用可能なサーバーキュースロット数。
“fe_conn"も使用できますが、単一のIPアドレスに届いたトラフィックを複数のバックエンドへ振り分ける場合(たとえば、ACLで名前に基づく負荷分散を行う場合)に、各バックエンドと、その利用可能な"connslots"を区別したいときは、“connslots"が特に役立ちます。また、“nbsrv"が実際に停止中のサーバーだけを測定するのに対して、この取得はより細かく、利用可能な接続スロット数も調べます。“queue"と"avg_queue"も参照してください。
その他の注意点と備考: 現時点のコードは動的な接続を考慮しません。また、いずれかのサーバーのmaxconnまたはmaxqueueが0の場合、この取得は明らかに意味をなさないため、-1を返します。
cpu_calls: integer ストリームまたは現在のリクエストを処理するタスクが、割り当てられてから呼び出された回数を返します。HTTP keep-aliveの場合、同じ接続の新しいリクエストごとにこの値をリセットします。通常、この値は小さく安定しているはずです(典型的な単純なリクエストでは約2回)が、処理(圧縮、キャッシュ、解析)によっては大きくなることがあります。純粋にパフォーマンス監視を目的とした値です。
cpu_ns_avg: integer ストリームまたは現在のリクエストを処理するタスクの、1回の呼び出しに費やした平均ナノ秒数を返します。HTTP keep-aliveの場合、同じ接続の新しいリクエストごとにこの値をリセットします。この値は、各呼び出しでリクエストまたは接続を処理する全体的なコストを示します。値に良い悪いはありませんが、呼び出しに費やす時間は必然的に他の処理に遅延を生じさせ(後述のlat_ns_avgを参照)、他の接続の見かけの応答時間に影響することがあります。圧縮、複雑な正規表現の照合、負荷の高いLua処理などがこの値に直接影響する場合があり、ログに記録しておくと、適切なパフォーマンスを取り戻すために修正すべき問題のある処理を見つけやすくなります。注: この値はcpu_ns_totをcpu_callsで割った値そのものです。
cpu_ns_tot: integer ストリームまたは現在のリクエストを処理するタスクの各呼び出しに費やした合計ナノ秒数を返します。HTTP keep-aliveの場合、同じ接続の新しいリクエストごとにこの値をリセットします。この値は、各呼び出しでリクエストまたは接続を処理する全体的なコストを示します。値に良い悪いはありませんが、呼び出しに費やす時間は必然的に他の処理に遅延を生じさせ(後述のlat_ns_avgを参照)、マシン上のCPUコストを生じさせ、他の接続の見かけの応答時間に影響することがあります。圧縮、複雑な正規表現の照合、負荷の高いLua処理などがこの値に直接影響する場合があり、ログに記録しておくと、適切なパフォーマンスを取り戻すために修正すべき問題のある処理を見つけやすくなります。たとえば、多数のHTTPチャンクを処理してcpu_callsが大きくなると、この値が見かけ上大きくなる場合があります。そのため、代わりにcpu_ns_avgをログに記録することがよくあります。
cpu_usage_grp: integer 最後のポーリングループで測定したCPU使用率を、現在のスレッドグループの全スレッドの平均として、0~100の値で返します。トラブルシューティングやログ記録に使用できます。この測定値は変動が非常に激しいものの、各スレッドが数十~数百のリクエストにわたって測定するため、持続的な負荷に対しては正確さを保ちます。
cpu_usage_proc: integer 最後のポーリングループで測定したCPU使用率を、実行中の全スレッドの平均として、0~100の値で返します。トラブルシューティングやログ記録に使用できます。この測定値は変動が非常に激しいものの、各スレッドが数十~数百のリクエストにわたって測定するため、持続的な負荷に対しては正確さを保ちます。統計ページおよび"show info"で報告されるアイドル率を100から引いた値です。
cpu_usage_thr: integer 最後のポーリングループで測定したCPU使用率を、呼び出し元スレッドについて、0~100の値で返します。トラブルシューティングやログ記録に使用できます。この測定値は変動が非常に激しいものの、数十~数百のリクエストにわたって測定するため、持続的な負荷に対しては正確さを保ちます。グリッチ数が多すぎる場合の接続強制切断を有効にするか、圧縮を無効にするかの判断に使う値と同じです。“tune.glitches.kill.cpu-usage"と"maxcompcpuusage"も参照してください。
date([<offset>[,<unit>]]): integer
現在の日時をエポック(01/01/1970からの秒数)として返します。
オフセット値を指定した場合、現在の日時に加算してから値を返します。正負どちらのオフセットも使用できるため、相対的な日時の計算に特に役立ちます。http_dateコンバーターとの併用に適しています。
<unit>は任意です。秒を表す"s”(デフォルトの動作)、ミリ秒を表す"ms”、マイクロ秒を表す"us"を指定できます。単位を指定した場合、エポックからの秒数、ミリ秒数、マイクロ秒数のいずれかに、オフセットを加えた整数値を返します。1秒未満の時間分解能が必要な場合に役立ちます。
例:
date_us: integer 日時のマイクロ秒部分を返します(「秒」の部分はdateサンプルが返します)。同じtimeval構造体から取得するため、このサンプルはdateサンプルと整合しています。
env(<name>): string
環境変数<name>の値を含む文字列を返します。環境変数はプロセスごとに存在し、プロセスの起動時に取得される点に注意してください。情報を次のホップのサーバーへ渡したり、ACLと併用して、特定の方法でプロセスを起動した場合に特定の動作を行ったりする用途に役立ちます。
例:
fe_conn([<frontend>]): integer
フロントエンドで現在確立されている接続数を返します。評価中の接続を含む場合もあります。フロントエンド名を指定しない場合は現在のフロントエンドを使用します。別のフロントエンドを調べることもできます。完全に遮断する前にお詫びページを返したり、サーバー群が満杯と判断された場合に特定のバックエンドを使用して新しいリクエストをそちらへ流したりできます。主にACLと併用しますが、HTTPヘッダーで統計情報をサーバーへ渡す用途にも使用できます。“dst_conn”、“be_conn”、“fe_sess_rate"取得も参照してください。
fe_req_rate([<frontend>]): integer
フロントエンドに送られる1秒あたりのHTTPリクエスト数に対応する整数値を返します。クライアント側のkeep-aliveが有効な場合、この数は"fe_sess_rate"と異なることがあります。
fe_sess_rate([<frontend>]): integer
フロントエンドでのセッション生成レートを、1秒あたりの新規セッション数を表す整数値として返します。サービスの乱用をできるだけ早期に防ぐため、ACLと併用して、受信セッションレートを許容範囲に制限します。たとえば、他のレイヤー4のACLと組み合わせて、レートが制限値を下回るまでクライアントを少し待たせることができます。log-formatディレクティブでこの値をログに追加する用途にも役立ちます。フロントエンドで使用する"rate-limit sessions"ディレクティブも参照してください。
例:
hostname: string システムのホスト名を返します。
int(<integer>): signed integer
符号付き整数を返します。
ipv4(<ipv4>): ipv4
ipv4値を返します。
ipv6(<ipv6>): ipv6
ipv6値を返します。
last_entity: string ストリーム解析中に最後に評価されたエンティティーの識別情報を返します。最後に一致した終端ルール、または処理を中断したフィルターである場合があります。
終端ルールとは、ルールセットの評価を終了させるルールです(“accept”、“deny”、“redirect"など)。“content"ルールセットに作用するTCPリクエストおよびレスポンスルールと、“http-request”、“http-response”、“http-after-response"ルールセットのHTTPルールで動作します。従来の"redirect"ルールセットはサポートしません(この情報を保存していないためです)。また、この情報はストリームレベルで保存され、“tcp-request connection"や"tcp-request session"のルールの実行中にはストリームが存在しないため、これらのルールセットもサポートしません。この場合、返される値は"last_rule_file:last_rule_line"と同等です。“last_rule_file"と"last_rule_line"も参照してください。
フィルターの場合は、開発者が定義した識別子を返します。その識別子を定義していなければ、一意の内部識別子に対応する16進数の値を返します。
この関数の主な目的は、処理を中断した最後のエンティティーをログに記録できるようにし、問題のデバッグに役立てることです。エンティティーについて返される情報は時間とともに変わる可能性があるため、デバッグ以外の用途に使用してはなりません。
例:
last_rule_file: string ストリーム解析中に最後に一致した終端ルールを含む設定ファイル名を返します。終端ルールとは、ルールセットの評価を終了させるルールです(“accept”、“deny”、“redirect"など)。“content"ルールセットに作用するTCPリクエストおよびレスポンスルールと、“http-request”、“http-response”、“http-after-response"ルールセットのHTTPルールで動作します。従来の"redirect"ルールセットはサポートしません(この情報を保存していないためです)。また、この情報はストリームレベルで保存され、“tcp-request connection"や"tcp-request session"のルールの実行中にはストリームが存在しないため、これらのルールセットもサポートしません。主な目的は、最終判断を下したルールの場所をログに記録できるようにし、たとえばリクエストが拒否された理由を調べやすくすることです。“last_rule_line"も参照してください。
last_rule_line: integer ストリーム解析中に最後に一致した終端ルールが、設定ファイル内で何行目にあるかを返します。終端ルールとは、ルールセットの評価を終了させるルールです(“accept”、“deny”、“redirect"など)。“content"ルールセットに作用するTCPリクエストおよびレスポンスルールと、“http-request”、“http-response”、“http-after-response"ルールセットのHTTPルールで動作します。従来の"redirect"ルールセットはサポートしません(この情報を保存していないためです)。また、この情報はストリームレベルで保存され、“tcp-request connection"や"tcp-request session"のルールの実行中にはストリームが存在しないため、これらのルールセットもサポートしません。主な目的は、最終判断を下したルールの場所をログに記録できるようにし、たとえばリクエストが拒否された理由を調べやすくすることです。“last_rule_file"も参照してください。
lat_ns_avg: integer ストリームを処理するタスクが起こされてから、実際に呼び出されるまでに費やした平均ナノ秒数を返します。HTTP keep-aliveの場合、同じ接続の新しいリクエストごとにこの値をリセットします。この値は、並行して処理する他のすべてのリクエストによって、現在のリクエストに生じる全体的な遅延を示し、負荷の高い他の処理による体感性能の低下を直接示す指標です。この値を低く保つには、“tune.runqueue-depth"でスケジューラーの実行キューの深さを減らす、“tune.maxpollevents"で一度に処理する同時イベント数を減らす、“bind"行またはフロントエンドの"nice"オプションでストリームのnice値を下げる、“tune.sched.low-latency"で低遅延スケジューリングを有効にする、ログから処理の調整や修正が必要な他の重いリクエスト(“cpu_ns_avg"が大きいもの)を探すといった方法があります。大きいバッファーの圧縮、負荷の高い正規表現、長い正規表現リストが原因になる場合があります。注: この値はlat_ns_totをcpu_callsで割った値そのものです。
lat_ns_tot: integer ストリームを処理するタスクが起こされてから、実際に呼び出されるまでに費やした合計ナノ秒数を返します。HTTP keep-aliveの場合、同じ接続の新しいリクエストごとにこの値をリセットします。この値は、並行して処理する他のすべてのリクエストによって、現在のリクエストに生じる全体的な遅延を示し、負荷の高い他の処理による体感性能の低下を直接示す指標です。この値を低く保つには、“tune.runqueue-depth"でスケジューラーの実行キューの深さを減らす、“tune.maxpollevents"で一度に処理する同時イベント数を減らす、“bind"行またはフロントエンドの"nice"オプションでストリームのnice値を下げる、“tune.sched.low-latency"で低遅延スケジューリングを有効にする、ログから処理の調整や修正が必要な他の重いリクエスト(“cpu_ns_avg"が大きいもの)を探すといった方法があります。大きいバッファーの圧縮、負荷の高い正規表現、長い正規表現リストが原因になる場合があります。注: 合計遅延が転送時間に加わるように直感的には思えますが、ほぼ常にそうではありません。タスクがCPUを待っている間もネットワークバッファーは満たされ続け、次の呼び出しで一度により多く処理するためです。たとえば、多数のHTTPチャンクを処理してcpu_callsが大きくなると、この値が見かけ上大きくなる場合があります。そのため、より適切なパフォーマンス指標であるlat_ns_avgを代わりにログに記録することがよくあります。
meth(<method>): method
メソッドを返します。
nbsrv([<backend>]): integer
現在のバックエンド、または指定したバックエンドで、使用可能なサーバーの数を整数で返します。主にACLで使用しますが、ログに追加しても役立ちます。通常は、ある負荷を処理するにはサーバー数が少なすぎる場合に、別のバックエンドへ切り替えるために使用します。“monitor fail” と組み合わせると、障害の報告に役立ちます。
pid: integer 現在のプロセスのPIDを返します。ほとんどの場合、ワーカープロセスのPIDです。
prio_class: integer HTTPモードでは現在のストリーム、TCPモードでは現在の接続の、優先度クラスを返します。値は、“http-request set-priority-class” または “tcp-request content set-priority-class” の、最後の呼び出しで設定したものです。
prio_offset: integer HTTPモードでは現在のストリーム、TCPモードでは現在の接続の、優先度オフセットを返します。値は、“http-request set-priority-offset” または “tcp-request content set-priority-offset” の、最後の呼び出しで設定したものです。
proc: integer 常に値1を返します(以前は、呼び出し元のプロセス番号を返していました)。
queue([<backend>]): integer
指定したバックエンドのキューで待機している接続の総数を、サーバーのキュー内のすべての接続も含めて返します。バックエンド名を指定しない場合は、現在のバックエンドを使用しますが、別のバックエンドを調べることもできます。ACLで使用したり、バックエンドサーバーに統計を渡したりするのに役立ちます。キューでの待機が、既知の水準を超えた場合に、アクションを実行するために使用できます。通常は、トラフィックの急増や、サーバーの大幅な速度低下を示します。考えられるアクションの例は、既存のユーザーは引き続き受け入れながら、新しいユーザーを拒否することです。取得関数 “avg_queue”、“be_conn”、“be_sess_rate” も参照してください。
quic_enabled: boolean QUICトランスポートプロトコルへの対応を有効にしてコンパイルし、かつglobalの “tune.quic.listen” オプションでQUICリスナーを無効にしていなければ、trueを返します。globalの “tune.quic.listen” オプションも参照してください。
rand([<range>]): integer
ゼロから始まる、<range> 個の値の範囲内で、ランダムな整数を返します。範囲を指定しなければ、デフォルトは2^32で、0から4294967295までの数値を返します。たとえば、ルーティングを決定するために必要な値を渡す場合や、単にデバッグを行う場合に役立ちます。この乱数は、セキュリティー目的に使用してはいけません。
srv_conn([<backend>/]<server>): integer
指定したサーバーで、現在確立している接続の数を、整数で返します。評価している接続も含む場合があります。<backend> を省略すると、現在のバックエンド内でサーバーを探します。あるサーバーがいっぱいの場合に、特定のサーバーファームを使用したり、サーバーとのアクティブな接続数について、HAProxy側から見た情報をサーバーへ通知したりするために使用できます。取得メソッド “fe_conn”、“be_conn”、“queue”、“srv_conn_free” も参照してください。
srv_conn_free([<backend>/]<server>): integer
指定したサーバーで、利用できる接続の数を、整数で返します。評価している接続も含む場合があります。値には、キューの空き枠を含めません。<backend> を省略すると、現在のバックエンド内でサーバーを探します。あるサーバーがいっぱいの場合に、特定のサーバーファームを使用したり、サーバーとのアクティブな接続数について、HAProxy側から見た情報をサーバーへ通知したりするために使用できます。取得メソッド “be_conn_free” と “srv_conn” も参照してください。
その他の注意事項: サーバーのmaxconnが0の場合、この取得関数は明らかに意味を持たないため、-1を返します。
srv_is_up([<backend>/]<server>): boolean
指定したサーバーがUPならtrue、DOWNまたはメンテナンスモードならfalseを返します。<backend> を省略すると、現在のバックエンド内でサーバーを探します。主に、ヘルスチェックで報告した外部の状態(たとえば、地理的に離れたサイトの可用性)に応じて、アクションを実行するために使用します。別の、やや技巧的な用途として、ダミーのサーバーを、CLIから有効または無効にできるブール変数として使用し、そのACLに依存するルールを、リアルタイムで調整することもできます。
srv_iweight([<backend>/]<server>): integer
サーバーの初期重みを、整数で返します。<backend> を省略すると、現在のバックエンド内でサーバーを探します。“srv_weight” と “srv_uweight” も参照してください。
srv_queue([<backend>/]<server>): integer
指定したサーバーのキューで、現在待機している接続の数を、整数で返します。<backend> を省略すると、現在のバックエンド内でサーバーを探します。“use-server” ディレクティブと組み合わせて、速いことが分かっているサーバーの負荷が低いときに、そのサーバーを強制的に使用するために使える場合があります。サンプル取得メソッド “srv_conn”、“avg_queue”、“queue” も参照してください。
srv_sess_rate([<backend>/]<server>): integer
指定したサーバーでのセッション作成速度を、毎秒の新しいセッション数を表す整数で返します。<backend> を省略すると、現在のバックエンド内でサーバーを探します。主にACLで使用しますが、ログでも意味を持つ場合があります。高コストの、または負荷に弱いバックエンドのセッション作成速度が高くなりすぎた場合に、別のバックエンドへ切り替えたり、サービスの悪用を制限したりするために使用します(たとえば、遅延するリクエストによって、サーバーに過負荷がかかるのを防ぎます)。
例:
srv_uweight([<backend>/]<server>): integer
ユーザーから見えるサーバーの重みを、整数で返します。<backend> を省略すると、現在のバックエンド内でサーバーを探します。“srv_weight” と “srv_iweight” も参照してください。
srv_weight([<backend>/]<server>): integer
現在の(または実効的な)サーバーの重みを、整数で返します。<backend> を省略すると、現在のバックエンド内でサーバーを探します。“srv_iweight” と “srv_uweight” も参照してください。
stopping: boolean 関数を呼び出したプロセスが、現在、停止処理中であれば、TRUEを返します。ログの記録や、正常なシャットダウンの際に、一部のチェックを緩めたり、特定の接続を閉じやすくしたりするために役立ちます。
str(<string>): string
文字列を返します。
table_avl([<table>]): integer
現在のプロキシのスティックテーブル、または指定したスティックテーブルで、使用可能なエントリーの総数を返します。“table_cnt” も参照してください。
table_cnt([<table>]): integer
現在のプロキシのスティックテーブル、または指定したスティックテーブルで、現在使用中のエントリーの総数を返します。エントリー数を数えるほかの方法については、“table_conn_cnt” とtable_avlも参照してください。
term_events: string ストリームに関連付けられた、クライアント側とサーバー側のすべての実体について、既知の終了イベントをすべて返します。次の情報を含む、7要素のタプルを返します。
- フロントエンド接続の終了イベント
- フロントエンドのマルチプレクサー接続の終了イベント
- フロントエンドのストリームエンドポイント記述子の終了イベント
(マルチプレクサーのストリーム、またはアプレット)
- ストリームの終了イベント
- バックエンドのストリームエンドポイント記述子の終了イベント
(マルチプレクサーのストリーム、またはアプレット)
- バックエンドのマルチプレクサー接続の終了イベント
- バックエンド接続の終了イベント
各階層について、最初の4つのイベントを報告します。特定の階層で、まだイベントを報告していなければ、空文字列を返します。終了イベントに対応していなければ、”-” を返します。
デバッグ目的にのみ使用しなければなりません。開発者の要件に応じて変わる可能性があるため、正確な形式は文書化していません。
tgroup: integer 関数を呼び出したスレッドグループの位置を、0から (global.thread-groups - 1) までの整数で返します。ログの記録やデバッグに役立ちます。
thread: integer 関数を呼び出したスレッドの位置を、0から (global.nbthread-1) までの整数で返します。ログの記録やデバッグに役立ちます。
txn.id32: integer 内部のトランザクションIDを返します。32ビットの整数です。そのため、厳密には一意ではなく、トランザクションIDは一巡する場合があります。一巡するまでの時間は、リクエストの頻度によって決まります。実際には、問題にはならないはずです。完全に一意なIDについては、“unique-id-format” ディレクティブを参照してください。
txn.sess_term_state: string ログに報告する、TCPまたはHTTPストリームの終了状態を返します。2文字の文字列で、ストリームの最終状態に、終了の原因となったイベントが続きます。発生し得るイベントの一覧は、切断時のストリーム状態についての8.5節 を参照してください。サンプル取得関数を評価した時点の値を返します。この値は変わる可能性があります。“http-after-response” ルールセットのACL、またはログメッセージで使用する場合を除き、常に “–” になります。
例:
uptime: integer 現在のHAProxyワーカーの稼働時間を、秒単位で返します。
uuid([<version>]): string
RFC 9562標準に従うUUIDを返します。バージョンを指定しなければ、バージョン4のUUID(完全にランダム)を返します。
バージョン4と7に対応しています。
var(<var-name>[,<default>]): undefined
格納した型のまま、変数を返します。変数を設定していなければ、サンプル取得は失敗します。ただし、デフォルト値を指定している場合は、それを文字列として返します。空文字列も使用できます。詳細は、変数についての2.8節 を参照してください。
dump_all_vars([<scope>][,<prefix>][,<delimiter>]): string
指定したスコープのすべての変数を、一覧で返します。任意で名前の接頭辞による絞り込みができ、区切り文字も変更できます。
出力形式: var1=value1<delim>var2=value2<delim>…
型ごとの値のエンコーディング:
- 文字列: 引用符で囲み、エスケープします (”, \, \r, \n, \b, \0)。例: txn.name=“John \“Doe\””
- バイナリ: ‘x’ 接頭辞を付けた16進エンコーディングで、引用符は付けません。例: txn.data=x48656c6c6f
- 整数: 引用符なしの10進数です。例: txn.count=42
- ブール値: 引用符なしの “true” または “false” です。例: txn.active=true
- アドレス: 引用符なしのIPアドレス文字列です。例: txn.client=192.168.1.1
- HTTPメソッド: 引用符で囲んだ文字列です。例: req.method=“GET”
引数:
-
<scope>(省略可能): sess、txn、req、res、procです。省略すると、ここに示した順に、すべてのスコープを調べます。 -
<prefix>(省略可能): スコープの接頭辞を取り除いた後の名前が、指定した接頭辞で始まる変数を絞り込みます。性能に関する注意: 接頭辞で絞り込む場合も、スコープ内のすべての変数を調べます。数千の変数を含む設定では、使用すべきではありません。 -
<delimiter>(省略可能): 変数を区切る文字列です。デフォルトは “, “(コンマとスペース)です。任意の文字列に変更できます。なお、関数の引数にコンマやスペースを渡すには、シングルクォートかダブルクォートで囲む必要があります(式自体をすでに引用符で囲んでいる場合は、もう一方を使用します)。
戻り値:
- 成功時: 一致したすべての変数を含む文字列
- 失敗時: 出力バッファーが小さすぎる場合は空になります(サンプル取得は失敗します)。出力を切り詰めることはありません。不完全なデータを避けるため、処理全体が失敗します。
デバッグ、ログの記録、変数の状態のエクスポートに、特に役立ちます。
例:
wait_end: boolean 検査期間が終わった場合にtrueを返し、そうでなければ取得しません。ACLでのみ、内容の解析と組み合わせて使用し、早すぎる段階で誤った判定を返すことを防ぎます。特定のアドレスを遅延させて拒否するなど、一部のアクションを遅らせるために使用することもできます。ルールの評価を停止するか、直ちにtrueを返すかのどちらかなので、ルールの最後のACLとして使用することを推奨します。デフォルトのACL “WAIT_END” は、事前の宣言なしで、常に使用できる点に注意してください。このテストは、TCPリクエストの内容検査で使用するために設計しています。
例:
waiting_entity: string エラーまたはタイムアウトが発生したときに、処理を続行できるのを待っていた実体の識別情報を返します。たとえば、ルールやフィルターの場合があります。ただし、この一覧は網羅的なものではなく、すべての実体の形式を必ず文書化しているわけではありません。
実体がルールの場合は、その場所を返します。ルールを含む設定ファイルと、そのファイル内でルールを定義した行を、コロンで区切ったものです。
フィルターの場合は、開発者が定義した識別子を返します。その識別子を定義していなければ、一意の内部識別子に対応する16進数の値を返します。
この関数の主な目的は、エラーまたはタイムアウトによって処理を中断したときに、ストリームの解析をブロックしていた実体をログに報告し、問題のデバッグに役立てることです。実体について返す情報は、時とともに変わる可能性があり、デバッグ以外の目的に使用してはいけません。
例:
7.3.3. レイヤー4でのサンプル取得
レイヤー4は、通常、トランスポート層だけを指します。HAProxyでは接続に最も近く、まだ内容を利用できない層です。ここで説明する取得メソッドは、後で得られる情報を必要とする場合を除き、“tcp-request connection” ルールセットという早い段階から使用できます。通常は、TCP/IPのアドレスとポート、および着信接続に関係するスティックテーブルの要素などを取得します。スティックカウンターから値を取得するには、定義済みの接頭辞 “sc0_"、“sc1_"、“sc2_” で、カウンター番号を0、1、2と明示できます。これら3つの定義済みの接頭辞は、globalの “tune.stick-counters” の値が3を超えない場合にのみ使用できます。それ以外の場合は、“sc_” 接頭辞を使用し、最初の整数引数としてカウンター番号を指定できます。“sc_0” から “sc_N” までで、Nは (tune.stick-counters-1) です。“sc*” 形式では、任意でテーブルを指定できます。その場合、現在追跡しているキーを、現在追跡しているテーブルの代わりに、指定した別のテーブルで検索します。
この節のサンプル取得メソッドと、それぞれの型の一覧:
詳細な一覧:
accept_date([<unit>]): integer
HAProxyが接続を受け付けた、正確な日時です(システムのバックログ内で待機していた場合、ネットワーク上で観測した日時とは、わずかに異なることがあります)。通常は、上流のファイアウォールのログに現れる日時と同じです。HTTPモードでは、accept_dateフィールドを、接続が新しいリクエストを受信できるようになった最初の時点にリセットします(HTTP/1では前のレスポンスの終了時、HTTP/2では前のリクエストの直後)。
エポックからの秒数を返します。
<unit> は省略可能で、秒を表す “s”(デフォルトの動作)、ミリ秒を表す “ms”、マイクロ秒を表す “us” を指定できます。単位を指定した場合、戻り値は、エポックからの秒数、ミリ秒数、またはマイクロ秒数を表す整数です。秒未満の時間分解能が必要な場合に役立ちます。
bc.timer.connect: integer サーバーへのTCP接続を確立するための、合計時間です。log-formatの%Tcに相当します。ミリ秒 (ms) 単位で報告します。詳細は、8.4節 「タイミングイベント」を参照してください。
bc_be_queue: integer 対象バックエンドの接続枠を待っている間に、キューから取り出されたストリーム数です。log-formatの%bqに相当します。
bc_dst: ip サーバー側の接続の宛先IPアドレス、つまり、HAProxyが接続したサーバーのアドレスです。IP型で、IPv4とIPv6の両方のテーブルで使用できます。IPv6テーブルでは、RFC 4291に従って、IPv4アドレスを、対応するIPv6アドレスにマッピングします。
bc_dst_port: integer サーバー側の接続の宛先TCPポート、つまり、HAProxyが接続したポートを、整数で返します。
bc_err: integer 現在のバックエンド接続で発生した可能性がある、エラーのIDを返します。エラーコードと、対応するエラーメッセージの完全な一覧は、取得関数 “fc_err_str” を参照してください。
bc_err_name: string バックエンド接続で発生し、接続を失敗させた問題を示す、内部のエラー名を返します。この文字列は単一の単語からなり、エラーがなければ空です。“fc_err_str” キーワードに示した表の、“name” 列に対応します。
bc_err_str: string 現在のバックエンド接続で発生し、接続を失敗させた問題を示す、エラーメッセージを返します。エラーコードと、対応するエラーメッセージの完全な一覧は、取得関数 “fc_err_str” を参照してください。
bc_glitches: integer バックエンド接続で数えた、プロトコル上の異常の回数を返します。通常は、プロトコル違反や小さな異常を含み、不具合がある、または不正な動作をするサーバーを示します。そのようなサーバーは、インフラに問題を引き起こす可能性があります(たとえば、接続を早く中止させ、TLSの再ネゴシエーションを頻発させます)。単一のバッファーに収まらない、大きすぎるレスポンスによって生じる場合もあり、HTTP 502エラーの原因を説明します。理想的にはゼロのままであるべきですが、総リクエスト数に比べて非常に少なければ、通常は問題ありません。急増はどこかに異常があることを示す場合がありますが、通常、特に小さい値は、警戒すべきものとは考えません。すべてのプロトコル・マルチプレクサーが、この指標を測定するわけではありません。イベントの詳細を知る唯一の方法は、トレースを有効にし、すべてのやり取りを記録することです。
bc_http_major: integer バックエンド接続で使用する、HTTPのメジャーバージョンのエンコーディングを返します。HTTP/0.9からHTTP/1.1では1、HTTP/2では2です。リクエストヘッダー内のバージョンではなく、通信路上のエンコーディングに基づく点に注意してください。
bc_nb_streams: integer バックエンド接続で開いたストリーム数を返します。
bc_reused: boolean 再利用したバックエンド接続で転送した場合、trueを返します。
bc_rtt(<unit>): integer
バックエンド接続について、カーネルが測定した往復時間 (RTT) を返します。<unit> は省略可能で、デフォルトの単位はミリ秒です。<unit> には、ミリ秒を表す “ms”、またはマイクロ秒を表す “us” を指定できます。サーバー接続を確立していない場合、接続がTCPではない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
bc_rttvar(<unit>): integer
バックエンド接続について、カーネルが測定した往復時間 (RTT) の分散を返します。<unit> は省略可能で、デフォルトの単位はミリ秒です。<unit> には、ミリ秒を表す “ms”、またはマイクロ秒を表す “us” を指定できます。サーバー接続を確立していない場合、接続がTCPではない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
bc_settings_streams_limit: integer バックエンド接続で許可する、ストリーム数の上限を返します。TCPとHTTP/1.1の接続では、常に1です。ほかのプロトコルでは、サーバーとネゴシエートした設定によって決まります。
bc_src: ip サーバー側の接続の送信元IPアドレス、つまり、HAProxyが接続を開始した側のサーバーアドレスです。IP型で、IPv4とIPv6の両方のテーブルで使用できます。IPv6テーブルでは、RFC 4291に従って、IPv4アドレスを、対応するIPv6アドレスにマッピングします。
bc_src_port: integer サーバー側の接続の送信元TCPポート、つまり、HAProxyが接続を開始した側のポートを、整数で返します。
bc_srv_queue: integer 対象サーバーの接続枠を待っている間に、キューから取り出されたストリーム数です。log-formatの%sqに相当します。
be_id: integer 現在のバックエンドのIDを含む整数を返します。フロントエンドでレスポンスとともに使用し、どのバックエンドがリクエストを処理したかを確認できます。フロントエンドで使用し、バックエンドを使用していなければ、現在のフロントエンドのIDを返します。tcp-checkまたはhttp-checkルールセットでも使用できます。
be_connect_timeout: integer 現在のバックエンドの接続タイムアウトについて、設定値をミリ秒単位で返します。このタイムアウトは、“set-timeout” ルールで上書きできます。“cur_connect_timeout” も参照してください。
be_name: string 現在のバックエンドの名前を含む文字列を返します。フロントエンドでレスポンスとともに使用し、どのバックエンドがリクエストを処理したかを確認できます。フロントエンドで使用し、バックエンドを使用していなければ、現在のフロントエンドの名前を返します。tcp-checkまたはhttp-checkルールセットでも使用できます。
be_queue_timeout: integer 現在のバックエンドのキュータイムアウトについて、設定値をミリ秒単位で返します。このタイムアウトは、“set-timeout” ルールで上書きできます。“cur_queue_timeout” も参照してください。
be_server_timeout: integer 現在のバックエンドのサーバータイムアウトについて、設定値をミリ秒単位で返します。このタイムアウトは、“set-timeout” ルールで上書きできます。“cur_server_timeout” も参照してください。
be_tarpit_timeout: integer 現在のバックエンドのキュータイムアウトについて、設定値をミリ秒単位で返します。このタイムアウトは、“set-timeout” ルールで上書きできます。“cur_tarpit_timeout” も参照してください。
be_tunnel_timeout: integer 現在のバックエンドのトンネルタイムアウトについて、設定値をミリ秒単位で返します。このタイムアウトは、“set-timeout” ルールで上書きできます。“cur_tunnel_timeout” も参照してください。
bytes_in: integer “req.bytes_in” を参照してください。
bytes_out: integer “res.bytes_in” を参照してください。
cur_connect_timeout: integer ストリームに現在適用している接続タイムアウトを、ミリ秒単位で返します。デフォルトでは、“set-timeout” ルールを適用していなければ、be_connect_timeoutと同じ値になります。“be_connect_timeout” も参照してください。
cur_client_timeout: integer ストリームに現在適用しているクライアントタイムアウトを、ミリ秒単位で返します。デフォルトでは、“set-timeout” ルールを適用していなければ、fe_client_timeoutと同じ値になります。“fe_client_timeout” も参照してください。
cur_queue_timeout: integer ストリームに現在適用しているキュータイムアウトを、ミリ秒単位で返します。デフォルトでは、“set-timeout” ルールを適用していなければ、be_queue_timeoutと同じ値になります。“be_queue_timeout” も参照してください。
cur_server_timeout: integer ストリームに現在適用しているサーバータイムアウトを、ミリ秒単位で返します。デフォルトでは、“set-timeout” ルールを適用していなければ、be_server_timeoutと同じ値になります。“be_server_timeout” も参照してください。
cur_tarpit_timeout: integer ストリームに現在適用しているtarpitタイムアウトを、ミリ秒単位で返します。デフォルトでは、“set-timeout” ルールを適用していなければ、fe_tarpit_timeout/be_tarpit_timeoutと同じ値になります。“fe_tarpit_timeout” と “be_tarpit_timeout” も参照してください。
cur_tunnel_timeout: integer ストリームに現在適用しているトンネルタイムアウトを、ミリ秒単位で返します。デフォルトでは、“set-timeout” ルールを適用していなければ、be_tunnel_timeoutと同じ値になります。“be_tunnel_timeout” も参照してください。
dst: ip クライアント側の接続の宛先IPアドレス、つまり、クライアントが接続したアドレスです。どのtcp/httpルールでも、このアドレスを変更できます。透過モードでの実行時に役立つ場合があります。IP型で、IPv4とIPv6の両方のテーブルで使用できます。IPv6テーブルでは、RFC 4291に従って、IPv4アドレスを、対応するIPv6アドレスにマッピングします。着信接続が、接続追跡を伴うアドレス変換やリダイレクトを経由した場合は、リダイレクト前の元の宛先アドレスを報告します。Linuxシステムでは、nf_conntrack_tcp_loose sysctlを設定している場合、まれに送信元と宛先が逆に見えることがあります。遅れて届いたレスポンスが、タイムアウトした接続を再び開き、送信元と宛先とみなす側を入れ替える可能性があるためです。
dst_conn: integer 同じソケット上で現在確立している接続の数を、評価している接続も含めて、整数で返します。通常はACLで使用しますが、HTTPヘッダーやログで、その情報をサーバーに渡すためにも使用できます。完全にブロックする前に、お詫びのページを返したり、ソケットが飽和していると判断した場合に、特定のバックエンドへ新しいリクエストを流したりするために使用できます。これにより、待ち受けるポートやアドレスごとに、異なる上限を割り当てられます。取得関数 “fe_conn” と “be_conn” も参照してください。
dst_is_local: boolean 着信接続の宛先アドレスが、システムのローカルアドレスならtrue、システムに存在しないアドレスならfalseを返します。後者は、透過モードで捕捉したことを意味します。転送するトラフィックと、マシンの実際のアドレス宛てのトラフィックに対して、それぞれ別のデフォルトルールを適用するのに役立ちます。たとえば、そのアドレスでのみ統計ページを提供したり、SSHアクセスをローカルにリダイレクトしたりできます。チェックには、いくつかのシステムコールが必要なため、接続ごとに1回だけ実行する方がよい点に注意してください。
dst_port: integer クライアント側の接続の宛先TCPポート、つまり、クライアントが接続したポートを、整数で返します。どのtcp/httpルールでも、このアドレスを変更できます。透過モードでの実行時、アプリケーションのセッション全体について、一部のクライアントに動的なポートを割り当てる場合、すべてのユーザーを同じサーバーに固定する場合、またはHTTPヘッダーでサーバーへ宛先ポート情報を渡す場合に、使用できます。
fc.timer.handshake: integer TCP接続の受け付けと、下位プロトコルのハンドシェイクの実行にかかった、合計時間です。現在の対象プロトコルは、proxy-protocolとSSLです。log-formatの%Thに相当します。ミリ秒 (ms) 単位で報告します。詳細は、8.4節 「タイミングイベント」を参照してください。
fc.timer.total: integer プロキシが受け付けた時点から、両端を閉じた時点までの、ストリームの合計存続時間です。log-formatの%Ttに相当します。ミリ秒 (ms) 単位で報告します。詳細は、8.4節 「タイミングイベント」を参照してください。
fc_dst: ip クライアント側の接続の、元の宛先IPアドレスです。“tcp-request connection” ルールだけが、このアドレスを変更できます。詳細は “dst” を参照してください。
fc_dst_is_local: boolean 着信接続の元の宛先アドレスが、システムのローカルアドレスならtrue、システムに存在しないアドレスならfalseを返します。詳細は “dst_is_local” を参照してください。
fc_dst_port: integer クライアント側の接続の、元の宛先TCPポートを、整数で返します。“tcp-request connection” ルールだけが、このアドレスを変更できます。詳細は “dst-port” を参照してください。
fc_err: integer 現在の接続で発生した可能性がある、エラーのIDを返します。戻り値が厳密に正である場合は、接続が成功しておらず、エラーログを出力することを意味します(8.2.5節 で説明しています)。エラーコードと、対応するエラーメッセージの完全な一覧は、取得関数 “fc_err_str” を参照してください。
fc_err_name: string フロントエンド接続で発生し、接続を失敗させた問題を示す、内部のエラー名を返します。この文字列は単一の単語からなり、エラーがなければ空です。“fc_err_str” キーワードに示した表の、“name” 列に対応します。
fc_err_str: string 現在の接続で発生し、接続を失敗させた問題を示す、エラーメッセージを返します。この文字列は、エラーログ形式の “message” 部分に対応します(8.2.5節 を参照)。エラーコードと、対応するエラーメッセージの完全な一覧は、以下を参照してください。
fc_fackets: integer クライアント接続について、カーネルが測定したfackカウンターを返します。サーバー接続を確立していない場合、接続がTCPではない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
fc_glitches: integer フロントエンド接続で数えた、プロトコル上の異常の回数を返します。通常は、プロトコル違反や小さな異常を含み、不具合がある、または不正な動作をするクライアントを示します。そのようなクライアントは、ログ内の過剰なエラーや、多数の接続の早期中止によるTLSの再ネゴシエーションの頻発など、インフラに問題を引き起こす可能性があります。単一のバッファーに収まらない、大きすぎるリクエストによって生じる場合もあり、HTTP 400エラーの原因を説明します。理想的にはゼロのままであるべきですが、プロトコルの境界的な動作を試すブラウザーが、ときどき発生させることもあり得ます。急増はどこかに異常があることを示す場合がありますが、通常、特に小さい値は、警戒すべきものとは考えません。大きい値(接続ごとに数百から数千、またはリクエスト数と同程度)は、プロトコルスタックの特徴を調べたり、攻撃したりするために、意図的に作られたクライアントを示す場合があります。すべてのプロトコル・マルチプレクサーが、この指標を測定するわけではありません。イベントの詳細を知る唯一の方法は、トレースを有効にし、すべてのやり取りを記録することです。
fc_http_major: integer フロント側の接続で使用する、HTTPのメジャーバージョンのエンコーディングを報告します。HTTP/0.9からHTTP/1.1では1、HTTP/2では2です。リクエストヘッダー内のバージョンではなく、通信路上のエンコーディングに基づく点に注意してください。
fc_lost: integer 接続がTCPでもQUICでもなければ、サンプル取得に失敗します。QUICでは、クライアント接続で失われたQUICパケット数を返します。TCPでは、クライアント接続について、カーネルが測定したlostカウンターを返します。サーバー接続を確立していない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
fc_nb_streams: integer フロントエンド接続で開いたストリーム数を返します。
fc_pp_authority: string クライアントがPROXYプロトコルヘッダーで送信した、最初のauthority TLVがあれば、それを返します。
fc_pp_tlv(<id>): string
指定したTLV IDに対応するTLVの値を返します。IDは、0から255までの数値、または、PPv2仕様のTLV定数の接尾辞に対応する、次のシンボル名のいずれかでなければなりません: “ALPN”: PP2_TYPE_ALPN, “AUTHORITY”: PP2_TYPE_AUTHORITY, “CRC32”: PP2_TYPE_CRC32C, “NETNS”: PP2_TYPE_NETNS, “NOOP: PP2_TYPE_NOOP”, “SSL”: PP2_TYPE_SSL, “SSL_CIPHER”: PP2_SUBTYPE_SSL_CIPHER, “SSL_CN”: PP2_SUBTYPE_SSL_CN, “SSL_KEY_ALG”: PP2_SUBTYPE_SSL_KEY_ALG, “SSL_SIG_ALG”: PP2_SUBTYPE_SSL_SIG_ALG, “SSL_VERSION”: PP2_SUBTYPE_SSL_VERSION, “UNIQUE_ID”: PP2_TYPE_UNIQUE_ID.
受信する値は、1024バイト以下でなければなりません。潜在的なDoS攻撃を防ぐためです。256バイト以下の値は、メモリープールを使用できます。そのため、最適な性能を得るには、送信する値の長さを256バイトまでに抑えるようにしてください。
fc_pp_authorityとfc_pp_unique_idとは異なり、fc_pp_tlvは、TLV IDが重複する場合、要求したTLVのすべての出現箇所を、反復して取得できる点に注意してください。反復の順序は、PROXYプロトコルヘッダー内の位置に対応します。ただし、通常、TLVは一意とみなすため、重複への依存は、原則として避けるべきです。一般に、TLV IDの重複は、PROXYプロトコルヘッダーの送信側に、誤りがあることを示します。
fc_pp_unique_id: string クライアントがPROXYプロトコルヘッダーで送信した、最初のunique ID TLVがあれば、それを返します。
fc_rcvd_proxy: boolean クライアントがPROXYプロトコルヘッダーで接続を開始した場合、trueを返します。
fc_reordering: integer 接続がTCPでもQUICでもなければ、サンプル取得に失敗します。QUICでは、クライアント接続で順序が入れ替わった、QUICパケットの数を返します。TCPでは、クライアント接続について、カーネルが測定したreorderingカウンターを返します。サーバー接続を確立していない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
fc_retrans: integer クライアント接続について、カーネルが測定したretransmitsカウンターを返します。サーバー接続を確立していない場合、接続がTCPではない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
fc_rtt(<unit>): integer
接続がTCPでもQUICでもなければ、サンプル取得に失敗します。QUICでは、クライアント接続の平滑化した往復時間を返します。TCPでは、クライアント接続について、カーネルが測定した往復時間 (RTT) を返します。<unit> は省略可能で、デフォルトの単位はミリ秒です。<unit> には、ミリ秒を表す “ms”、またはマイクロ秒を表す “us” を指定できます。サーバー接続を確立していない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
fc_rttvar(<unit>): integer
接続がTCPでもQUICでもなければ、サンプル取得に失敗します。QUICでは、クライアント接続の平滑化した往復時間の分散を返します。TCPでは、クライアント接続について、カーネルが測定した往復時間 (RTT) の分散を返します。<unit> は省略可能で、デフォルトの単位はミリ秒です。<unit> には、ミリ秒を表す “ms”、またはマイクロ秒を表す “us” を指定できます。サーバー接続を確立していない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
fc_sacked: integer クライアント接続について、カーネルが測定したsackedカウンターを返します。サーバー接続を確立していない場合、接続がTCPではない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
fc_saved_syn: binary 着信接続の確立中に、システムが保存したSYNパケットのコピーを返します。“bind” 行に “tcp-ss” オプションがあり、Linuxカーネルが4.3以上である必要があります。“tcp-ss” が1の場合、IPヘッダーとTCPヘッダーだけが含まれます。“tcp-ss” が2の場合、IPヘッダーの前にEthernetヘッダーも含まれ、たとえば、送信元MACアドレスやVLANの制御やログ記録に使用できます。SYNの保存を保証するものではない点に注意してください。たとえば、SYN Cookieを使用する場合、SYNパケットは保存せず、一致するACKパケットによって接続を確立します。また、システムは、最初の読み取り後まで、コピーを保持することを保証しません。そのため、“tcp-request connection” ルールで、“sess” スコープの変数にコピーし、その後の操作では、その変数だけを使用することを強く推奨します。ループバックインターフェイスでは、システムがダミーの14バイトのEthernetヘッダーを作成する点にも注意してください。送信元と宛先のアドレスは両方ともゼロで、プロトコルだけを設定します。デバッグ時には、“hex” コンバーターを使用して、このようなサンプルを16進数に変換すると便利です。例(以下では、フィールドを手動で分け、コメントを付けています):
“bytes()” コンバーターは、パケットから特定のフィールドを抽出するのに役立ちます。be2dec()も、データの一部を読み取り、整数の形式で出力できます。より正確な抽出については、“eth.XXX” コンバーターを参照してください。
IPv4入力の例:
“set-var” アクションと、“be2dec”、“bytes”、“hex”、“eth.XXX”、“ip.XXX”、“tcp.XXX” コンバーターも参照してください。
fc_settings_streams_limit: integer フロントエンド接続で許可する、ストリーム数の上限を返します。TCPとHTTP/1.1の接続では、常に1です。ほかのプロトコルでは、クライアントとネゴシエートした設定によって決まります。
fc_src: ip クライアント側の接続の、元の送信元IPアドレスです。“tcp-request connection” ルールだけが、このアドレスを変更できます。詳細は “src” を参照してください。
fc_src_is_local: boolean 着信接続の送信元アドレスが、システムのローカルアドレスならtrue、システムに存在しないアドレスならfalseを返します。詳細は “src_is_local” を参照してください。
fc_src_port: integer クライアント側の接続の送信元TCPポートを、整数で返します。“tcp-request connection” ルールだけが、このアドレスを変更できます。詳細は “src-port” を参照してください。
fc_unacked: integer クライアント接続について、カーネルが測定したunackedカウンターを返します。サーバー接続を確立していない場合、接続がTCPではない場合、または、2.4より前のLinuxカーネルなど、OSがTCP_INFOに対応していない場合は、サンプル取得に失敗します。
fe_client_timeout: integer 現在のフロントエンドのクライアントタイムアウトについて、設定値をミリ秒単位で返します。このタイムアウトは、“set-timeout” ルールで上書きできます。
fe_defbe: string フロントエンドのデフォルトのバックエンド名を含む、文字列を返します。フロントエンドで、デフォルトではどのバックエンドがリクエストを処理するかを、確認するために使用できます。
fe_id: integer 現在のフロントエンドのIDを含む、整数を返します。バックエンドで、どのフロントエンドから呼び出されたかを確認したり、同じフロントエンドを経由するすべてのユーザーを、同じサーバーに固定したりするために使用できます。
fe_name: string 現在のフロントエンドの名前を含む、文字列を返します。バックエンドで、どのフロントエンドから呼び出されたかを確認したり、同じフロントエンドを経由するすべてのユーザーを、同じサーバーに固定したりするために使用できます。
fe_tarpit_timeout: integer 現在のフロントエンドのtarpitタイムアウトについて、設定値をミリ秒単位で返します。このタイムアウトは、“set-timeout” ルールで上書きできます。
req.bytes_in: integer クライアントから受信したバイト数を返します。値は、HAProxyが受信したデータに対応し、一部のヘッダーと、内部エンコーディングのオーバーヘッドを含みます。リクエストの圧縮は、ここで報告する値に影響しません。
req.bytes_out: integer サーバーへ送信したバイト数を返します。値は、HAProxyが送信したデータに対応し、一部のヘッダーと、内部エンコーディングのオーバーヘッドを含みます。リクエストの圧縮は、ここで報告する値に影響します。
res.bytes_in: integer サーバーから受信したバイト数を返します。値は、HAProxyが受信したデータに対応し、一部のヘッダーと、内部エンコーディングのオーバーヘッドを含みます。レスポンスの圧縮は、ここで報告する値に影響しません。
res.bytes_out: integer クライアントへ送信したバイト数を返します。値は、HAProxyが送信したデータに対応し、一部のヘッダーと、内部エンコーディングのオーバーヘッドを含みます。レスポンスの圧縮は、ここで報告する値に影響します。
res.timer.data: integer レスポンスのペイロードを、最後のバイトまでクライアントへ送信する、合計転送時間です。HTTPでは、レスポンスの最後のヘッダーの後(Trの後)から始まります。log-formatの%Tdに相当し、ミリ秒 (ms) 単位で報告します。詳細は、8.4節 「タイミングイベント」を参照してください。
sc_bytes_in_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターから、クライアントからサーバーへの、平均バイト転送速度を返します。テーブルで設定した期間のバイト数で測定します。“table_bytes_in_rate” も参照してください。
sc_bytes_out_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターから、サーバーからクライアントへの、平均バイト転送速度を返します。テーブルで設定した期間のバイト数で測定します。“table_bytes_out_rate” も参照してください。
sc_clr_gpc(<idx>,<ctr>[,<table>]): integer
現在のプロキシのスティックテーブル、または指定したスティックテーブル <table> で、ID <ctr> の追跡カウンターに関連付けられた配列の、インデックス <idx> にある汎用カウンターをクリアし、それまでの値を返します。<idx> は0から99まで、<ctr> は0から2までの整数です。最初の呼び出し前に格納している値はゼロなので、最初の呼び出しは常にゼロを返します。この取得関数は、‘gpc’ 配列のdata_typeだけに適用します(従来の ‘gpc0’ や ‘gpc1’ のdata_typeには適用しません)。
sc_clr_gpc0(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた、最初の汎用カウンターをクリアし、それまでの値を返します。最初の呼び出し前に格納している値はゼロなので、最初の呼び出しは常にゼロを返します。通常は、式の2番目のACLとして使用し、最初のACLを満たした場合に、接続へ印を付けます。
例:
sc_clr_gpc1(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた、2番目の汎用カウンターをクリアし、それまでの値を返します。最初の呼び出し前に格納している値はゼロなので、最初の呼び出しは常にゼロを返します。通常は、式の2番目のACLとして使用し、最初のACLを満たした場合に、接続へ印を付けます。
sc_conn_cnt(<ctr>[,<table>]): integer
現在追跡しているカウンターから、着信接続の累積数を返します。“table_conn_cnt” も参照してください。
sc_conn_cur(<ctr>[,<table>]): integer
同じ追跡カウンターを追跡している、現在の同時接続数を返します。追跡を開始すると自動的に増え、終了すると減ります。“table_conn_cur” も参照してください。
sc_conn_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターから、平均接続レートを返します。テーブルで設定した期間内の接続数で測定します。“table_conn_rate” も参照してください。
sc_get_gpc(<idx>,<ctr>[,<table>]): integer
現在のプロキシのスティックテーブル、または指定したスティックテーブル <table> で、ID <ctr> の現在追跡しているカウンターに関連付けられたGPC配列の、インデックス <idx> にある汎用カウンターの値を返します。<idx> は0から99まで、<ctr> は0から2までの整数です。このインデックスにgpcが格納されていなければ、ゼロを返します。この取得関数は、‘gpc’ 配列のdata_typeだけに適用します(従来の ‘gpc0’ や ‘gpc1’ のdata_typeには適用しません)。“table_gpc” と “sc_inc_gpc” も参照してください。
sc_get_gpc0(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた、最初の汎用カウンターの値を返します。“table_gpc0” と sc/sc0/sc1/sc2_inc_gpc0 も参照してください。
sc_get_gpc1(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた、2番目の汎用カウンターの値を返します。“table_gpc1” と sc/sc0/sc1/sc2_inc_gpc1 も参照してください。
sc_get_gpt(<idx>,<ctr>[,<table>]): integer
現在のプロキシのスティックテーブル、または指定したスティックテーブル <table> で、ID <ctr> の追跡カウンターに関連付けられた配列の、インデックス <idx> にある最初の汎用タグの値を返します。<idx> は0から99まで、<ctr> は0から2までの整数です。このインデックスにGPTが格納されていなければ、ゼロを返します。この取得関数は、‘gpt’ 配列のdata_typeだけに適用します(従来の ‘gpt0’ のdata-typeには適用しません)。“table_gpt” も参照してください。
sc_get_gpt0(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた、最初の汎用タグの値を返します。“table_gpt0” も参照してください。
sc_glitch_cnt(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた接続で観測した、フロント側接続の異常の累積数を返します。通常、これらの異常によって、リクエストや接続が中止されるため、返却値は過去の接続に対応することがよくあります。良い値や悪い値という基準はありませんが、品質の低いクライアントでは、接続ごとに、時折いくつかの異常が発生することがあります。一方、極端に不正なクライアントや悪意のあるクライアントでは、接続で、短時間に何千ものイベントが追加されることがあります。現在の接続に影響する異常の数については fc_glitches、送信元ごとの参照については src_glitch_cnt、イベントレートの測定については sc_glitch_rate も参照してください。
sc_glitch_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターについて、フロント側接続の異常を観測した平均レートを返します。テーブルで設定した期間内のイベント数で測定します。通常、これらの異常によって、リクエストや接続が中止されるため、返却値は過去の接続に関係することがよくあります。良い値や悪い値という基準はありませんが、品質の低いクライアントでは、接続ごとに、時折いくつかの異常が発生することがあるため、通常は低いレートが想定されます。ただし、極端に不正なクライアントや悪意のあるクライアントでは、接続ごとに、短時間に何千ものイベントが追加され、高いレートが続くことがあります。“table_glitch_rate” と “sc_glitch_cnt” も参照してください。
sc_gpc_rate(<idx>,<ctr>[,<table>]): integer
現在のプロキシのテーブル、または指定したスティックテーブル <table> で、ID <ctr> の追跡カウンターに関連付けられた配列の、インデックス <idx> にある汎用カウンターの、平均増加レートを返します。設定した期間内に、gpcカウンターが増加した頻度を報告します。<idx> は0から99まで、<ctr> は0から2までの整数です。値を返すには、スティックテーブルに ‘gpc_rate’ カウンター配列を格納しておく必要があります。‘gpc’ が保持するのは、イベント数だけだからです。この取得関数は、‘gpc_rate’ 配列のdata_typeだけに適用します(従来の ‘gpc0_rate’ や ‘gpc1_rate’ のdata_typeには適用しません)。“table_gpc_rate”、“sc_get_gpc”、“sc_inc_gpc” も参照してください。
sc_gpc0_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた、最初の汎用カウンターの平均増加レートを返します。設定した期間内に、gpc0カウンターが増加した頻度を報告します。src_gpc0_rate、sc/sc0/sc1/sc2_get_gpc0、sc/sc0/sc1/sc2_inc_gpc0 も参照してください。値を返すには、スティックテーブルに “gpc0_rate” カウンターを格納しておく必要があります。“gpc0” が保持するのは、イベント数だけだからです。
sc_gpc1_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた、2番目の汎用カウンターの平均増加レートを返します。設定した期間内に、gpc1カウンターが増加した頻度を報告します。src_gpc1_rate、sc/sc0/sc1/sc2_get_gpc1、sc/sc0/sc1/sc2_inc_gpc1 も参照してください。値を返すには、スティックテーブルに “gpc1_rate” カウンターを格納しておく必要があります。“gpc1” が保持するのは、イベント数だけだからです。
sc_http_err_cnt(<ctr>[,<table>]): integer
現在追跡しているカウンターから、HTTPエラーの累積数を返します。リクエストエラーと4xxエラーレスポンスの両方を含みます。“table_http_err_cnt” も参照してください。
sc_http_err_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターから、HTTPエラーの平均レートを返します。テーブルで設定した期間内のエラー数で測定します。リクエストエラーと4xxエラーレスポンスの両方を含みます。src_http_err_rate も参照してください。
sc_http_fail_cnt(<ctr>[,<table>]): integer
現在追跡しているカウンターから、HTTPレスポンスの失敗の累積数を返します。レスポンスエラーと、501および505を除く5xxステータスコードの両方を含みます。“table_http_fail_cnt” も参照してください。
sc_http_fail_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターから、HTTPレスポンスの失敗の平均レートを返します。テーブルで設定した期間内の失敗数で測定します。レスポンスエラーと、501および505を除く5xxステータスコードの両方を含みます。“table_http_fail_rate” も参照してください。
sc_http_req_cnt(<ctr>[,<table>]): integer
現在追跡しているカウンターから、HTTPリクエストの累積数を返します。有効かどうかにかかわらず、開始したすべてのリクエストを含みます。src_http_req_cnt も参照してください。
sc_http_req_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターから、HTTPリクエストの平均レートを返します。テーブルで設定した期間内のリクエスト数で測定します。有効かどうかにかかわらず、開始したすべてのリクエストを含みます。src_http_req_rate も参照してください。
sc_inc_gpc(<idx>,<ctr>[,<table>]): integer
現在のプロキシのスティックテーブル、または指定したスティックテーブル <table> で、ID <ctr> の指定した追跡カウンターに関連付けられた配列の、インデックス <idx> にある汎用カウンターを増加させ、新しい値を返します。<idx> は0から99まで、<ctr> は0から2までの整数です。最初の呼び出し前に格納している値はゼロなので、最初の呼び出しは値を1に増やし、1を返します。この取得関数は、‘gpc’ 配列のdata_typeだけに適用します(従来の ‘gpc0’ や ‘gpc1’ のdata_typeには適用しません)。
sc_inc_gpc0(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた、最初の汎用カウンターを増加させ、新しい値を返します。最初の呼び出し前に格納している値はゼロなので、最初の呼び出しは値を1に増やし、1を返します。通常は、式の2番目のACLとして使用し、最初のACLを満たした場合に、接続へ印を付けます:
例:
sc_inc_gpc1(<ctr>[,<table>]): integer
現在追跡しているカウンターに関連付けられた、2番目の汎用カウンターを増加させ、新しい値を返します。最初の呼び出し前に格納している値はゼロなので、最初の呼び出しは値を1に増やし、1を返します。通常は、式の2番目のACLとして使用し、最初のACLを満たした場合に、接続へ印を付けます。
sc_kbytes_in(<ctr>[,<table>]): integer
現在追跡しているカウンターから、クライアントからサーバーへのデータの合計量を、キロバイト単位で返します。現在、テストは32ビット整数で行うため、値の上限は4テラバイトです。“table_kbytes_in” も参照してください。
sc_kbytes_out(<ctr>[,<table>]): integer
現在追跡しているカウンターから、サーバーからクライアントへのデータの合計量を、キロバイト単位で返します。現在、テストは32ビット整数で行うため、値の上限は4テラバイトです。“table_kbytes_out” も参照してください。
sc_key(<ctr>): any sc0_key: any sc1_key: any sc2_key: any 現在追跡しているカウンターとの照合に使用するキーを返します。
sc_sess_cnt(<ctr>[,<table>]): integer
現在追跡しているカウンターから、セッションへ移行した着信接続の累積数を返します。これは、“tcp-request connection” ルールで受け入れた接続を意味します。クライアントとの接続でHTTPキープアライブを使用する場合、各接続から多くのバックエンドセッションが生じることがあるため、バックエンドでは、接続数よりも多くのセッションを数える場合があります。“table_sess_cnt” も参照してください。
sc_sess_rate(<ctr>[,<table>]): integer
現在追跡しているカウンターから、平均セッションレートを返します。テーブルで設定した期間内のセッション数で測定します。セッションとは、初期の “tcp-request connection” ルールを通過した接続です。クライアントとの接続でHTTPキープアライブを使用する場合、各接続から多くのバックエンドセッションが生じることがあるため、バックエンドでは、接続数よりも多くのセッションを数える場合があります。“table_sess_rate” も参照してください。
sc_tracked(<ctr>[,<table>]): boolean
指定したセッションカウンターを、現在のセッションが現在追跡していれば、trueを返します。サーバーへ渡すヘッダーに、値を設定するかどうかを判断するときに便利です。
sc_trackers(<ctr>[,<table>]): integer
同じ追跡カウンターを追跡している、現在の同時接続数を返します。追跡を開始すると自動的に増え、終了すると減ります。sc0_conn_curとは異なり、格納した情報を使用せず、テーブルの参照カウント(CLIで “show table” を実行すると返される “use” の値)を使用します。このため、レイヤー7の追跡に、より適している場合があります。たとえば、特定のアドレスからの同時接続数を、サーバーへ通知するために使用できます。
so_id: integer 現在のリスニングソケットのIDを含む整数を返します。多数の “bind” 行があるフロントエンドや、同じソケットを経由するすべてのユーザーを、同じサーバーに固定する場合に便利です。
so_name: string “bind” 行のnameで定義した、現在のリスニングソケットの名前を含む文字列を返します。so_idと同じ目的に使用できますが、整数の代わりに文字列を使用します。
src: ip セッションのクライアントの送信元IPアドレスです。どのtcp/httpルールでも、このアドレスを変更できます。IP型で、IPv4とIPv6の両方のテーブルで使用できます。IPv6テーブルでは、RFC 4291に従い、IPv4アドレスを対応するIPv6アドレスにマッピングします。使用するのは、TCPレベルの送信元アドレスであり、プロキシの背後にあるクライアントのアドレスではない点に注意してください。ただし、bindディレクティブ “accept-proxy” または “accept-netscaler-cip” を使用する場合、実際のアドレスを参照する “tcp-request connection” を除くすべてのルールセットでは、別のPROXYプロトコル対応コンポーネントの背後にあるクライアントのアドレスになることがあります。着信接続が、接続追跡を伴うアドレス変換やリダイレクトを通過した場合、リダイレクト前の元の宛先アドレスを報告します。Linuxシステムでは、nf_conntrack_tcp_loose sysctlを設定していると、送信元と宛先がまれに逆に見えることがあります。遅れて届いたレスポンスが、タイムアウトした接続を再び開き、送信元と宛先と認識する対象を入れ替えることがあるためです。
例:
src_bytes_in_rate([<table>]): integer
“table_bytes_in_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_bytes_in_rate([<table>])
src_bytes_out_rate([<table>]): integer
“table_bytes_out_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_bytes_out_rate([<table>])
src_clr_gpc(<idx>[,<table>]): integer
“table_clr_gpc” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_clr_gpc(<idx>[,<table>])
src_clr_gpc0([<table>]): integer
“table_clr_gpc0” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_clr_gpc0([<table>])
src_clr_gpc1([<table>]): integer
“table_clr_gpc1” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_clr_gpc1([<table>])
src_conn_cnt([<table>]): integer
“table_conn_cnt” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_conn_cnt([<table>])
src_conn_cur([<table>]): integer
“table_conn_cur” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_conn_cur([<table>])
src_conn_rate([<table>]): integer
“table_conn_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_conn_rate([<table>])
src_get_gpc(<idx>[,<table>]): integer
“table_gpc” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_gpc(<idx>[,<table>])
src_get_gpc0([<table>]): integer
“table_gpc0” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_gpc0([<table>])
src_get_gpc1([<table>]): integer
“table_gpc1” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_gpc1([<table>])
src_get_gpt(<idx>[,<table>]): integer
“table_gpt” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_gpt(<idx>[,<table>])
src_get_gpt0([<table>]): integer
“table_gpt0” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_gpt0([<table>])
src_glitch_cnt([<table>]): integer
“table_glitch_cnt” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_glitch_cnt([<table>])
src_glitch_rate([<table>]): integer
“table_glitch_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_glitch_rate([<table>])
src_gpc_rate(<idx>[,<table>]): integer
“table_gpc_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_gpc_rate(<idx>[,<table>])
src_gpc0_rate([<table>]): integer
“table_gpc0_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_gpc0_rate([<table>])
src_gpc1_rate([<table>]): integer
“table_gpc1_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_gpc1_rate([<table>])
src_http_err_cnt([<table>]): integer
“table_http_err_cnt” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_http_err_cnt([<table>])
src_http_err_rate([<table>]): integer
“table_http_err_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_http_err_rate([<table>])
src_http_fail_cnt([<table>]): integer
“table_http_fail_cnt” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_http_fail_cnt([<table>])
src_http_fail_rate([<table>]): integer
“table_http_fail_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_http_fail_rate([<table>])
src_http_req_cnt([<table>]): integer
“table_http_req_cnt” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_http_req_cnt([<table>])
src_http_req_rate([<table>]): integer
“table_http_req_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_http_req_rate([<table>])
src_inc_gpc(<idx>[,<table>]): integer
“src_inc_gpc” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_inc_gpc(<idx>[,<table>])
src_inc_gpc0([<table>]): integer
“src_inc_gpc0” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_inc_gpc0([<table>])
src_inc_gpc1([<table>]): integer
“src_inc_gpc1” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_inc_gpc1([<table>])
src_is_local: boolean 着信接続の送信元アドレスが、システムのローカルアドレスならtrue、システムに存在しないアドレス、つまりリモートマシンからの接続ならfalseを返します。UNIXアドレスは、ローカルとみなす点に注意してください。クライアントの接続元に応じて、アクセス制限を適用するときに便利です(たとえば、リモートマシンには認証やhttpsを要求する場合)。このチェックは、いくつかのシステムコールを伴うので、接続ごとに1回だけ実行することを推奨します。
src_kbytes_in([<table>]): integer
“table_kbytes_in” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_kbytes_in([<table>])
src_kbytes_out([<table>]): integer
“table_kbytes_out” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_kbytes_out([<table>])
src_port: integer クライアント側の接続のTCP送信元ポートに対応する整数値を返します。これは、クライアントが接続元として使用したポートです。どのtcp/httpルールでも、このアドレスを変更できます。現在のプロトコルでは、送信元ポートをあまり重視しないため、この関数の用途は非常に限られます。
src_sess_cnt([<table>]): integer
“table_sess_cnt” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_sess_cnt([<table>])
src_sess_rate([<table>]): integer
“table_sess_rate” コンバーターと同じですが、キーには着信接続の送信元アドレスを使用します。
次と同等です: src,table_sess_rate([<table>])
src_updt_conn_cnt([<table>]): integer
現在のプロキシのスティックテーブル、または指定したスティックテーブルで、着信接続の送信元アドレスに対応するエントリーを作成または更新します。このテーブルは、“conn_cnt” データ型を格納するように設定しておく必要があります。そうでなければ、マッチングを無視します。現在のカウントを1増やし、有効期限のタイマーを更新します。更新後のカウントを返すため、このマッチングはゼロを返すことはありません。これは、送信元アドレスに基づいて、サービスを濫用する利用者を拒否するために使用していました。注意: 代わりに、“tcp-request” ルールで、より機能が充実した “track-sc*” アクションを使用することを推奨します。
例:
srv_id: integer レスポンスを処理するときに、サーバーのIDを含む整数を返します。ほぼACLでのみ使用しますが、ログ記録やデバッグにも使用できます。また、tcp-checkやhttp-checkのルールセットでも使用できます。
srv_name: string レスポンスを処理するときに、サーバーの名前を含む文字列を返します。ほぼACLでのみ使用しますが、ログ記録やデバッグにも使用できます。また、tcp-checkやhttp-checkのルールセットでも使用できます。
txn.conn_retries: integer このストリームが、サーバーへの接続を試みた際に経験した、接続の再試行回数を返します。接続を完全に確立するまでは、この値は変わる可能性があります。HTTP接続では、レイヤー7の再試行が、この値に影響することがあります。
txn.redispatched: boolean “option redispatch” の設定に従い、再試行時に接続の再振り分けが発生した場合、trueを返します。接続を完全に確立するまでは、この値は変わる可能性があります。HTTP接続では、レイヤー7の再試行が、この値に影響することがあります。
7.3.4. レイヤー5でのサンプル取得
レイヤー5は通常、セッション層そのものを指します。HAProxyでは、接続のすべてのハンドシェイクを終え、まだコンテンツを利用できない段階のセッションに、最も近い概念です。ここで説明する取得メソッドは、後で得られる情報を必要としない限り、早ければ “tcp-request content” ルールセットから使用できます。通常は、SSLネゴシエーションの結果などを含みます。
この節のサンプル取得メソッドと、それぞれの型の一覧:
詳細一覧:
51d.all(<prop>[,<prop>*]): string
要求したプロパティーの値を、文字列で返します。値は、“51degrees-property-separator” で指定した区切り文字で区切ります。リクエスト内の重要なHTTPヘッダーをすべて使用して、デバイスを識別します。この関数には、最大5つのプロパティー名を渡すことができ、プロパティー名が見つからない場合は、値 “NoData” を返します。
例:
bs.aborted: boolean 現在のストリームについて、サーバーから中止を受信した場合はtrue、それ以外はfalseを返します。
bs.debug_str([<bitmap>]): string
この関数は、開発者が複雑な問題を調査するときに使用するためのものです。バックエンドのストリームと接続の下位層から内部状態を抽出し、通常はスペースで区切った一連の “name=value” という形式の文字列にまとめます。省略可能な引数 <bitmap> は、情報を抽出する層を指定し、次の値の算術OR(または合計)です: - ソケット層: 16 - 接続層: 8 - トランスポート層(SSLなど): 4 - マルチプレクサー接続: 2 - マルチプレクサーストリーム: 1
これらの値は、バージョンによって変わる可能性があります。デフォルトのゼロは特別な値で、すべての層を有効にします。本番環境の長期的な監視では、この関数の出力に依存しないでください。より詳細な情報が必要になれば、安定版ブランチ内でも変更することを想定しています。代表的な用途は、fs.debug_str()とともに、この情報をlog-formatの末尾に連結することです。例:
bs.id: integer サーバー側のマルチプレクサーのストリームIDを返します。適切な情報を返す責任は、マルチプレクサーにあります。
bs.rst_code: integer 現在のストリームについて、サーバーから受信したリセットコードを返します。サーバーから受信したH2 RST_STREAMフレーム、またはQUIC STOP_SENDINGフレームのコードを返します。中止を受信していない場合、またはサーバー側のストリームがH2/QUICストリームではない場合は、サンプル取得に失敗します。
fs.aborted: boolean 現在のストリームについて、クライアントから中止を受信した場合はtrue、それ以外はfalseを返します。
fs.debug_str([<bitmap>]): string
この関数は、開発者が複雑な問題を調査するときに使用するためのものです。フロントエンドのストリームと接続の下位層から内部状態を抽出し、通常はスペースで区切った一連の “name=value” という形式の文字列にまとめます。省略可能な引数 <bitmap> は、情報を抽出する層を指定し、次の値の算術OR(または合計)です: - ソケット層: 16 - 接続層: 8 - トランスポート層(SSLなど): 4 - マルチプレクサー接続: 2 - マルチプレクサーストリーム: 1
これらの値は、バージョンによって変わる可能性があります。デフォルトのゼロは特別な値で、すべての層を有効にします。本番環境の長期的な監視では、この関数の出力に依存しないでください。より詳細な情報が必要になれば、安定版ブランチ内でも変更することを想定しています。代表的な用途は、bs.debug_str()とともに、この情報をlog-formatの末尾に連結することです。例:
fs.id: integer クライアント側のマルチプレクサーのストリームIDを返します。適切な情報を返す責任は、マルチプレクサーにあります。たとえば、生のTCPではストリームがないため、常に0を返します。
fs.rst_code: integer 現在のストリームについて、クライアントから受信したリセットコードを返します。クライアントから受信したH2 RST_STREAMフレーム、またはQUIC STOP_SENDINGフレームのコードを返します。中止を受信していない場合、またはクライアント側のストリームがH2/QUICストリームではない場合は、サンプル取得に失敗します。
ssl_bc: boolean バック側の接続がSSL/TLSトランスポート層を使用し、ローカルで復号する場合にtrueを返します。これは、“ssl” オプションを指定したサーバーに発信接続したことを意味します。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_alg_keysize: integer 発信接続がSSL/TLSトランスポート層を使用する場合に、対称暗号がサポートする鍵のサイズをビット単位で返します。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_alpn: string TLSトランスポート層を使用した発信接続から、Application Layer Protocol Negotiationフィールドを抽出します。結果は、サーバーとネゴシエートしたプロトコル名を含む文字列です。SSLライブラリーは、TLS拡張のサポートを有効にしてビルドしておく必要があります(haproxy -vvで確認してください)。“server” 行の “alpn” キーワードでプロトコルのリストを指定しなければ、TLS ALPN拡張を通知しない点に注意してください。また、このリストからプロトコルを選ぶことをサーバーに強制するものではなく、ほかのプロトコルを要求することもできます。TLS ALPN拡張は、TLS NPN拡張を置き換えるためのものです。“ssl_bc_npn” も参照してください。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_cipher: string 発信接続がSSL/TLSトランスポート層を使用する場合に、使用している暗号の名前を返します。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_client_early_traffic_secret: string 発信接続がTLS 1.3トランスポート層を使用する場合に、バック側の接続のCLIENT_EARLY_TRAFFIC_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_bc_client_handshake_traffic_secret: string 発信接続がTLS 1.3トランスポート層を使用する場合に、バック側の接続のCLIENT_HANDSHAKE_TRAFFIC_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_bc_client_random: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、バック側の接続のクライアントランダム値を返します。一時鍵を使う暗号で送信したトラフィックを復号するのに役立ちます。OpenSSL >= 1.1.0、またはBoringSSLが必要です。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_client_traffic_secret_0: string 発信接続がTLS 1.3トランスポート層を使用する場合に、バック側の接続のCLIENT_TRAFFIC_SECRET_0を16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_bc_curve: string 発信接続がSSL/TLSトランスポート層を使用する場合に、鍵共有に使用した曲線の名前を返します。OpenSSL >= 3.0.0、またはAWS-LC >= 1.57.0が必要です。
ssl_bc_early_exporter_secret: string 発信接続がTLS 1.3トランスポート層を使用する場合に、バック側の接続のEARLY_EXPORTER_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_bc_err: integer 発信接続がSSL/TLSトランスポート層を使用する場合に、バックエンド側で発生した最初のエラースタックの、最後のエラーのIDを返します。ハンドシェイクのエラーのほか、接続の存続期間中に発生した読み取りや書き込みのエラーも報告できます。このエラーコードの説明をテキストで取得するには、“ssl_bc_err_str” サンプル取得関数、または “openssl errstr” コマンド(16進表記のエラーコードを引数に取ります)を使用できます。エラーコードの完全な一覧については、使用するSSLライブラリーのドキュメントを参照してください。
ssl_bc_err_str: string 発信接続がSSL/TLSトランスポート層を使用する場合に、バックエンドの観点から接続で発生した最初のエラースタックの、最後のエラーを文字列で返します。“ssl_fc_err” も参照してください。
ssl_bc_exporter_secret: string 発信接続がTLS 1.3トランスポート層を使用する場合に、バック側の接続のEXPORTER_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_bc_is_resumed: boolean バック側の接続がSSL/TLSトランスポート層を使用し、新しく作成したSSLセッションを、キャッシュ済みのセッションまたはTLSチケットで再開した場合に、trueを返します。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_npn: string TLSトランスポート層を使用した発信接続から、Next Protocol Negotiationフィールドを抽出します。結果は、サーバーとネゴシエートしたプロトコル名を含む文字列です。SSLライブラリーは、TLS拡張のサポートを有効にしてビルドしておく必要があります(haproxy -vvで確認してください)。“server” 行の “npn” キーワードでプロトコルのリストを指定しなければ、TLS NPN拡張を通知しない点に注意してください。また、このリストからプロトコルを選ぶことをサーバーに強制するものではなく、ほかのプロトコルを使用することもできます。TLS NPN拡張は、ALPNに置き換えられた点に注意してください。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_protocol: string 発信接続がSSL/TLSトランスポート層を使用する場合に、使用しているプロトコルの名前を返します。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_server_handshake_traffic_secret: string 発信接続がTLS 1.3トランスポート層を使用する場合に、バック側の接続のSERVER_HANDSHAKE_TRAFFIC_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_bc_server_random: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、バック側の接続のサーバーランダム値を返します。一時鍵を使う暗号で送信したトラフィックを復号するのに役立ちます。OpenSSL >= 1.1.0、またはBoringSSLが必要です。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_server_traffic_secret_0: string 発信接続がTLS 1.3トランスポート層を使用する場合に、バック側の接続のSERVER_TRAFFIC_SECRET_0を16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_bc_session_id: binary 発信接続がSSL/TLSトランスポート層を使用する場合に、バック側の接続のSSL IDを返します。セッションが再利用されたかどうかを確認したい場合、ログに記録すると役立ちます。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_session_key: binary 発信接続がSSL/TLSトランスポート層を使用する場合に、バック側の接続のSSLセッションのマスター鍵を返します。一時鍵を使う暗号で送信したトラフィックを復号するのに役立ちます。OpenSSL >= 1.1.0、またはBoringSSLが必要です。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_sni: string サーバーへの接続で使用した、Server Name Indication TLS拡張(SNI)のフィールドを取得します。結果が存在する場合、通常はHTTPSホスト名に一致する文字列(253文字以下)です。主な用途は、ログ記録とデバッグです(たとえば、接続の確立時に使用したSNIを調べ、サーバーが認識したものと照合する場合)。
ssl_bc_unique_id: binary 発信接続がSSL/TLSトランスポート層を使用する場合に、RFC5929の3節 で定義するTLSの一意なIDを返します。このIDは、コンバーター “ssl_bc_unique_id,base64” を使用して、base64にエンコードできます。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_bc_use_keysize: integer 発信接続がSSL/TLSトランスポート層を使用する場合に、使用している対称暗号の鍵のサイズをビット単位で返します。tcp-checkやhttp-checkのルールセットでも使用できます。
ssl_c_ca_err: integer 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアント証明書の検証中に、深さ > 0で検出した最初のエラーのIDを返します。この検証処理でエラーが発生しなかった場合は0を返します。エラーコードの完全な一覧については、使用するSSLライブラリーのドキュメントを参照してください。
ssl_c_ca_err_depth: integer 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアント証明書の検証中に検出した最初のエラーについて、CAチェーン内での深さを返します。エラーが発生しなかった場合は0を返します。
ssl_c_chain_der: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアントが提示した証明書チェーンをDER形式で返します。ACLで使用する場合、照合する値は16進形式で渡すことができます。ASN.1 DERデータを受け付けるライブラリーであれば、どれでも結果を解析できます。現在、再開したセッションには対応していません。
ssl_c_der: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアントが提示した証明書をDER形式で返します。ACLで使用する場合、照合する値は16進形式で渡すことができます。
ssl_c_err: integer 着信接続がSSL/TLSトランスポート層を使用する場合に、深さ0での検証中に検出した最初のエラーのIDを返します。この検証処理でエラーが発生しなかった場合は0を返します。エラーコードの完全な一覧については、使用するSSLライブラリーのドキュメントを参照してください。
ssl_c_i_dn([<entry>[,<occ>[,<format>]]]): string
着信接続がSSL/TLSトランスポート層を使用する場合に、<entry> を指定しなければ、クライアントが提示した証明書の発行者の完全な識別名を返します。指定した場合は、そのエントリーをDNの先頭から検索し、最初に見つかったエントリーの値を返します。省略可能な2番目の引数として出現番号を指定すると、正の場合はDNの先頭から、負の場合は末尾から数えてn番目の、指定したエントリーの値を返します。たとえば、“ssl_c_i_dn(OU,2)” は2番目の組織単位を、“ssl_c_i_dn(CN)” はコモンネームを取得します。<format> パラメーターを使用すると、各プロトコルで使用するのに適したDNを取得できます。現在は、LDAP v3向けのrfc2253に対応しています。形式だけを変更したい場合は、最初の2つのパラメーターに、空文字列とゼロを指定できます。例: ssl_c_i_dn(,0,rfc2253) 要求したエントリーのASN.1値(<entry> を指定しなかった場合は、DN内のいずれかのエントリー)に、後続のデータを伴う埋め込みNULバイトがあると、不正な形式とみなし、データを返しません。
ssl_c_key_alg: string 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアントが提示した証明書の鍵の生成に使用したアルゴリズム名を返します。
ssl_c_notafter: string 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアントが提示した終了日時を、YYMMDDhhmmss[Z]形式の文字列で返します。
ssl_c_notbefore: string 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアントが提示した開始日時を、YYMMDDhhmmss[Z]形式の文字列で返します。
ssl_c_r_dn([<entry>[,<occ>[,<format>]]]): string
着信接続がSSL/TLSトランスポート層を使用し、設定したca-fileで正常に検証した場合に、<entry> を指定しなければ、クライアントが提示した証明書のルートCAの完全な識別名を返します。指定した場合は、そのエントリーをDNの先頭から検索し、最初に見つかったエントリーの値を返します。省略可能な2番目の引数として出現番号を指定すると、正の場合はDNの先頭から、負の場合は末尾から数えてn番目の、指定したエントリーの値を返します。たとえば、“ssl_c_r_dn(OU,2)” は2番目の組織単位を、“ssl_c_r_dn(CN)” はコモンネームを取得します。<format> パラメーターを使用すると、各プロトコルで使用するのに適したDNを取得できます。現在は、LDAP v3向けのrfc2253に対応しています。形式だけを変更したい場合は、最初の2つのパラメーターに、空文字列とゼロを指定できます。例: ssl_c_r_dn(,0,rfc2253) 要求したエントリーのASN.1値(<entry> を指定しなかった場合は、DN内のいずれかのエントリー)に、後続のデータを伴う埋め込みNULバイトがあると、不正な形式とみなし、データを返しません。
ssl_c_s_dn([<entry>[,<occ>[,<format>]]]): string
着信接続がSSL/TLSトランスポート層を使用する場合に、<entry> を指定しなければ、クライアントが提示した証明書のサブジェクトの完全な識別名を返します。指定した場合は、そのエントリーをDNの先頭から検索し、最初に見つかったエントリーの値を返します。省略可能な2番目の引数として出現番号を指定すると、正の場合はDNの先頭から、負の場合は末尾から数えてn番目の、指定したエントリーの値を返します。たとえば、“ssl_c_s_dn(OU,2)” は2番目の組織単位を、“ssl_c_s_dn(CN)” はコモンネームを取得します。<format> パラメーターを使用すると、各プロトコルで使用するのに適したDNを取得できます。現在は、LDAP v3向けのrfc2253に対応しています。形式だけを変更したい場合は、最初の2つのパラメーターに、空文字列とゼロを指定できます。例: ssl_c_s_dn(,0,rfc2253) 要求したエントリーのASN.1値(<entry> を指定しなかった場合は、DN内のいずれかのエントリー)に、後続のデータを伴う埋め込みNULバイトがあると、不正な形式とみなし、データを返しません。
ssl_c_san: string 着信接続がSSL/TLSトランスポート層を使用し、クライアント証明書を受け取った場合に、その証明書に含まれるSubject Alt Nameフィールドを、カンマ区切りの文字列で返します。
クライアント証明書の検査に使用できます。
例:
次の結果になります:
ssl_c_serial: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアントが提示した証明書のシリアル番号を返します。ACLで使用する場合、照合する値は16進形式で渡すことができます。
ssl_c_sha1: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアントが提示した証明書のSHA-1フィンガープリントを返します。クライアントを特定のサーバーに固定したり、この情報をサーバーへ渡したりするために使用できます。出力はバイナリーなので、この署名をサーバーへ渡す場合は、次の例のように、16進数またはbase64にエンコードする必要があります:
例:
ssl_c_sig_alg: string 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアントが提示した証明書の署名に使用したアルゴリズム名を返します。
ssl_c_used: boolean 現在のSSLセッションがクライアント証明書を使用していれば、現在の接続でSSLセッションの再開を使用している場合でも、trueを返します。“ssl_fc_has_crt” も参照してください。
ssl_c_verify: integer 着信接続がSSL/TLSトランスポート層を使用する場合に、検証結果のエラーIDを返します。エラーが発生しなかった場合はゼロを返します。エラーコードの完全な一覧については、使用するSSLライブラリーのドキュメントを参照してください。
ssl_c_version: integer 着信接続がSSL/TLSトランスポート層を使用する場合に、クライアントが提示した証明書のバージョンを返します。
ssl_f_der: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンドが提示した証明書をDER形式で返します。ACLで使用する場合、照合する値は16進形式で渡すことができます。
ssl_f_i_dn([<entry>[,<occ>[,<format>]]]): string
着信接続がSSL/TLSトランスポート層を使用する場合に、<entry> を指定しなければ、フロントエンドが提示した証明書の発行者の完全な識別名を返します。指定した場合は、そのエントリーをDNの先頭から検索し、最初に見つかったエントリーの値を返します。省略可能な2番目の引数として出現番号を指定すると、正の場合はDNの先頭から、負の場合は末尾から数えてn番目の、指定したエントリーの値を返します。たとえば、“ssl_f_i_dn(OU,2)” は2番目の組織単位を、“ssl_f_i_dn(CN)” はコモンネームを取得します。<format> パラメーターを使用すると、各プロトコルで使用するのに適したDNを取得できます。現在は、LDAP v3向けのrfc2253に対応しています。形式だけを変更したい場合は、最初の2つのパラメーターに、空文字列とゼロを指定できます。例: ssl_f_i_dn(,0,rfc2253) 要求したエントリーのASN.1値(<entry> を指定しなかった場合は、DN内のいずれかのエントリー)に、後続のデータを伴う埋め込みNULバイトがあると、不正な形式とみなし、データを返しません。
ssl_f_key_alg: string 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンドが提示した証明書の鍵の生成に使用したアルゴリズム名を返します。
ssl_f_notafter: string 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンドが提示した終了日時を、YYMMDDhhmmss[Z]形式の文字列で返します。
ssl_f_notbefore: string 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンドが提示した開始日時を、YYMMDDhhmmss[Z]形式の文字列で返します。
ssl_f_s_dn([<entry>[,<occ>[,<format>]]]): string
着信接続がSSL/TLSトランスポート層を使用する場合に、<entry> を指定しなければ、フロントエンドが提示した証明書のサブジェクトの完全な識別名を返します。指定した場合は、そのエントリーをDNの先頭から検索し、最初に見つかったエントリーの値を返します。省略可能な2番目の引数として出現番号を指定すると、正の場合はDNの先頭から、負の場合は末尾から数えてn番目の、指定したエントリーの値を返します。たとえば、“ssl_f_s_dn(OU,2)” は2番目の組織単位を、“ssl_f_s_dn(CN)” はコモンネームを取得します。<format> パラメーターを使用すると、各プロトコルで使用するのに適したDNを取得できます。現在は、LDAP v3向けのrfc2253に対応しています。形式だけを変更したい場合は、最初の2つのパラメーターに、空文字列とゼロを指定できます。例: ssl_f_s_dn(,0,rfc2253) 要求したエントリーのASN.1値(<entry> を指定しなかった場合は、DN内のいずれかのエントリー)に、後続のデータを伴う埋め込みNULバイトがあると、不正な形式とみなし、データを返しません。
ssl_f_serial: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンドが提示した証明書のシリアル番号を返します。ACLで使用する場合、照合する値は16進形式で渡すことができます。
ssl_f_sha1: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンドが提示した証明書のSHA-1フィンガープリントを返します。SNIによって、どの証明書を選択したかを確認するために使用できます。
ssl_f_sig_alg: string 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンドが提示した証明書の署名に使用したアルゴリズム名を返します。
ssl_f_version: integer 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンドが提示した証明書のバージョンを返します。
ssl_fc: boolean フロント側の接続がSSL/TLSトランスポート層を使用し、ローカルで復号する場合にtrueを返します。これは、“ssl” オプションを指定した “bind” 行で宣言したソケットに一致したことを意味します。
例:
ssl_fc_alg_keysize: integer 着信接続がSSL/TLSトランスポート層を使用する場合に、対称暗号がサポートする鍵のサイズをビット単位で返します。
ssl_fc_alpn: string TLSトランスポート層を使用し、HAProxyがローカルで復号する着信接続から、Application Layer Protocol Negotiationフィールドを抽出します。結果は、クライアントが通知したプロトコル名を含む文字列です。SSLライブラリーは、TLS拡張のサポートを有効にしてビルドしておく必要があります(haproxy -vvで確認してください)。“bind” 行の “alpn” キーワードでプロトコルのリストを指定しなければ、TLS ALPN拡張を通知しない点に注意してください。また、このリストからプロトコルを選ぶことをクライアントに強制するものではなく、ほかのプロトコルを要求することもできます。TLS ALPN拡張は、TLS NPN拡張を置き換えるためのものです。“ssl_fc_npn” も参照してください。
ssl_fc_cipher: string 着信接続がSSL/TLSトランスポート層を使用する場合に、使用している暗号の名前を返します。
ssl_fc_cipherlist_bin([<filter_option>]): binary
Client Helloの暗号リストを、バイナリー形式で返します。返却値の長さの上限は、“tune.ssl.capture-buffer-size” 設定で制御する、共有キャプチャーバッファーのサイズによって制限します。<filter_option> を設定すると、返すデータをフィルターできます。指定できる値:
例:
ssl_fc_cipherlist_hex([<filter_option>]): string
Client Helloの暗号リストのバイナリー形式を、16進数にエンコードして返します。返却値の長さの上限は、“tune.ssl.capture-buffer-size” 設定で制御する、共有キャプチャーバッファーのサイズによって制限します。<filter_option> を設定すると、返すデータをフィルターできます。指定できる値:
ssl_fc_cipherlist_str([<filter_option>]): string
Client Helloの暗号リストを、デコードしたテキスト形式で返します。返却値の長さの上限は、“tune.ssl.capture-buffer-size” 設定で制御する、共有キャプチャーバッファーのサイズによって制限します。<filter_option> を設定すると、返すデータをフィルターできます。指定できる値:
このサンプル取得関数は、OpenSSL >= 1.0.2でのみ使用できます。この機能が有効でない場合は、“ssl_fc_cipherlist_xxh” と同様にハッシュを返します。
ssl_fc_cipherlist_xxh: integer 暗号リストのxxh64を返します。“tune.ssl.capture-buffer-size” の値を0より大きく設定している場合にのみ、このハッシュを返せます。ただし、ハッシュの計算では、暗号リストのすべてのデータを考慮します。
ssl_fc_client_early_traffic_secret: string 着信接続がTLS 1.3トランスポート層を使用する場合に、フロント側の接続のCLIENT_EARLY_TRAFFIC_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_fc_client_handshake_traffic_secret: string 着信接続がTLS 1.3トランスポート層を使用する場合に、フロント側の接続のCLIENT_HANDSHAKE_TRAFFIC_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_fc_client_random: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、フロント側の接続のクライアントランダム値を返します。一時鍵を使う暗号で送信したトラフィックを復号するのに役立ちます。OpenSSL >= 1.1.0、またはBoringSSLが必要です。
ssl_fc_client_traffic_secret_0: string 着信接続がTLS 1.3トランスポート層を使用する場合に、フロント側の接続のCLIENT_TRAFFIC_SECRET_0を16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_fc_crtname: string 着信SSL/TLS接続で選択した証明書の名前を返します。これは、“show ssl cert” に表示する名前です。設定内での証明書の宣言方法によって、相対パスまたは絶対パスを含むファイル名の場合と、別名の場合があります。
例:
ssl_fc_curve: string 着信接続がSSL/TLSトランスポート層を使用する場合に、鍵共有に使用した曲線の名前を返します。OpenSSL >= 3.0.0が必要です。
ssl_fc_early_rcvd: boolean 接続上で早期データを観測した場合、その後にハンドシェイクが完了したかどうかにかかわらず、trueを返します。トラフィックの処理には実用的な用途がありませんが、クライアントが0-RTTを使用して早期データを送信したことを確認する、ほぼ唯一の方法であり、デバッグに役立つ場合があります。ほかの方法は、ネットワークトラフィックをキャプチャーするか、フロント側の接続のフラグをログに記録して、コードと照合することだけだからです。クライアントの機能に関する統計を得るためにも役立つ場合があります。“ssl_fc_has_early” も参照してください。
ssl_fc_early_exporter_secret: string 着信接続がTLS 1.3トランスポート層を使用する場合に、フロント側の接続のEARLY_EXPORTER_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_fc_ecformats_bin: binary Client Helloで示す、対応する楕円曲線の点の形式を、バイナリー形式で返します。返却値の長さの上限は、“tune.ssl.capture-buffer-size” 設定で制御する、共有キャプチャーバッファーのサイズによって制限します。
例:
ssl_fc_eclist_bin([<filter_option>]): binary
Client Helloで示す、対応する楕円曲線を、バイナリー形式で返します。返却値の長さの上限は、“tune.ssl.capture-buffer-size” 設定で制御する、共有キャプチャーバッファーのサイズによって制限します。<filter_option> を設定すると、返すデータをフィルターできます。指定できる値:
例:
ssl_fc_err: integer 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンド側で発生した最初のエラースタックの、最後のエラーのIDを返します。エラーが発生しなかった場合は0を返します。検証以外のハンドシェイク関連のエラー(暗号の不一致など)や、接続の存続期間中に発生する読み取りや書き込みのエラーを識別するために使用できます。クライアント証明書の検証処理で発生したエラーは、この取得関数では報告せず、既存の “ssl_c_err”、“ssl_c_ca_err”、“ssl_c_ca_err_depth” 取得関数で報告します。このエラーコードの説明をテキストで取得するには、“ssl_fc_err_str” サンプル取得関数、または “openssl errstr” コマンド(16進表記のエラーコードを引数に取ります)を使用できます。エラーコードの完全な一覧については、使用するSSLライブラリーのドキュメントを参照してください。
ssl_fc_err_str: string 着信接続がSSL/TLSトランスポート層を使用する場合に、フロントエンド側で発生した最初のエラースタックの、最後のエラーを文字列で返します。クライアント証明書の検証処理で発生したエラーは、この取得関数では報告しません。“ssl_fc_err” も参照してください。
ssl_fc_exporter_secret: string 着信接続がTLS 1.3トランスポート層を使用する場合に、フロント側の接続のEXPORTER_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_fc_extlist_bin([<filter_option>]): binary
Client Helloの拡張リストを、バイナリー形式で返します。返却値の長さの上限は、“tune.ssl.capture-buffer-size” 設定で制御する、共有キャプチャーバッファーのサイズによって制限します。<filter_option> を設定すると、返すデータをフィルターできます。指定できる値:
例:
ssl_fc_has_crt: boolean SSL/TLSトランスポート層を使用する着信接続に、クライアント証明書が存在する場合にtrueを返します。‘verify’ 文を ‘optional’ に設定している場合に便利です。注意: Session IDまたはTLSチケットを使ってSSLセッションを再開する場合、現在の接続にはクライアント証明書が存在しませんが、キャッシュやチケットから取得できることがあります。そのため、現在のSSLセッションがクライアント証明書を使用しているかどうかを確認するには、“ssl_c_used” の使用を推奨します。
ssl_fc_has_early: boolean 早期データを送信し、まだハンドシェイクを完了していない場合にtrueを返します。セキュリティーに影響するため、このようなデータを拒否したり、“wait-for-handshake” アクションでハンドシェイクの完了を待ったりするのに便利です。“ssl_fc_early_rcvd” も参照してください。
ssl_fc_has_sni: boolean SSL/TLSトランスポート層を使用する着信接続に、Server Name Indication TLS拡張(SNI)が存在するかを確認します。着信接続にTLS SNIフィールドがある場合にtrueを返します。SSLライブラリーは、TLS拡張のサポートを有効にしてビルドしておく必要があります(haproxy -vvで確認してください)。
ssl_fc_is_resumed: boolean SSL/TLSトランスポート層を使用する着信接続で、SSLセッションキャッシュまたはTLSチケットを使用してSSL/TLSセッションを再開した場合にtrueを返します。
ssl_fc_npn: string TLSトランスポート層を使用し、HAProxyがローカルで復号する着信接続から、Next Protocol Negotiationフィールドを抽出します。結果は、クライアントが通知したプロトコル名を含む文字列です。SSLライブラリーは、TLS拡張のサポートを有効にしてビルドしておく必要があります(haproxy -vvで確認してください)。“bind” 行の “npn” キーワードでプロトコルのリストを指定しなければ、TLS NPN拡張を通知しない点に注意してください。また、このリストからプロトコルを選ぶことをクライアントに強制するものではなく、ほかのプロトコルを要求することもできます。TLS NPN拡張は、ALPNに置き換えられた点に注意してください。
ssl_fc_protocol: string 着信接続がSSL/TLSトランスポート層を使用する場合に、使用しているプロトコルの名前を返します。
ssl_fc_protocol_hello_id: integer Client Helloメッセージで示す、クライアントがセッション中の通信に使用したいTLSプロトコルのバージョンです。“tune.ssl.capture-buffer-size” の値を0より大きく設定している場合にのみ、この値を返せます。
例:
ssl_fc_server_handshake_traffic_secret: string 着信接続がTLS 1.3トランスポート層を使用する場合に、フロント側の接続のSERVER_HANDSHAKE_TRAFFIC_SECRETを16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_fc_server_random: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、フロント側の接続のサーバーランダム値を返します。一時鍵を使う暗号で送信したトラフィックを復号するのに役立ちます。OpenSSL >= 1.1.0、またはBoringSSLが必要です。
ssl_fc_server_traffic_secret_0: string 着信接続がTLS 1.3トランスポート層を使用する場合に、フロント側の接続のSERVER_TRAFFIC_SECRET_0を16進文字列で返します。OpenSSL >= 1.1.1が必要です。これは、SSLKEYLOGFILEを生成するために、OpenSSLのkeylogコールバックが出力する鍵の1つです。グローバルセクションで “tune.ssl.keylog on” を指定し、SSLの鍵のログ記録を有効にしておく必要があります。“tune.ssl.keylog” も参照してください。
ssl_fc_session_id: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、フロント側の接続のSSL IDを返します。特定のクライアントをサーバーに固定するのに役立ちます。ブラウザーによっては、数分ごとにセッションIDを更新する点に注意してください。
ssl_fc_session_key: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、フロント側の接続のSSLセッションのマスター鍵を返します。一時鍵を使う暗号で送信したトラフィックを復号するのに役立ちます。OpenSSL >= 1.1.0、またはBoringSSLが必要です。
ssl_fc_sigalgs_bin([<filter_option>]): binary
Client Helloで提示したsignatures_algorithms (13) TLS拡張の内容を返します。TLSのRFCで定義する、2バイトのアルゴリズムのバイナリーリストを提供します: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.3 。
“tune.ssl.capture-buffer-size” の値を0より大きく設定している場合にのみ、この値を返せます。<filter_option> を設定すると、返すデータをフィルターできます。指定できる値: 0: 暗号の完全なリストを返します(デフォルト) 1: 出力からGREASE (RFC8701) の値を除外します
ssl_fc_sni: string SSL/TLSトランスポート層を使用し、HAProxyがローカルで復号する着信接続から、Server Name Indication TLS拡張(SNI)のフィールドを抽出します。結果が存在する場合、通常はHTTPSホスト名に一致する文字列(253文字以下)です。SSLライブラリーは、TLS拡張のサポートを有効にしてビルドしておく必要があります(haproxy -vvで確認してください)。
この取得関数は、前述の “req.ssl_sni” とは異なり、SSLの内容をそのまま転送する接続ではなく、HAProxyが復号する接続に適用します。後述の “ssl_fc_sni_end” と “ssl_fc_sni_reg” も参照してください。SSLライブラリーは、TLS拡張のサポートを有効にしてビルドしておく必要があります(haproxy -vvで確認してください)。
注意! ごく特殊な条件を除き、通常、このフィールドをHTTPの “Host” ヘッダーフィールドの代わりに使用するのは適切ではありません。たとえば、HTTPS接続をサーバーへ転送する場合、SNIフィールドは、フロント側のSNIの値からではなく、“req.hdr(host)” を使用して、HTTP Hostヘッダーフィールドから設定する必要があります。SNIは、サーバー側が提示する証明書の選択にのみ使用し、クライアントは、その証明書に含まれる名前に一致する限り、異なるHostの値を持つリクエストを送信できるためです。そのため、バックエンドがTCPモードで動作する場合を除き、通常は、“ssl_fc_sni” をサーバーの “sni” キーワードの引数に使用すべきではありません。
派生ACL:
ssl_fc_supported_versions_bin([<filter_option>]): binary
Client Helloで提示したsupported_versions (43) TLS拡張の内容を返します。2バイトのバージョンのバイナリーリストを提供します。TLSv1.3 (0x0304)、TLSv1.2 (0x0303) です。
“tune.ssl.capture-buffer-size” の値を0より大きく設定している場合にのみ、この値を返せます。<filter_option> を設定すると、返すデータをフィルターできます。指定できる値: 0: 暗号の完全なリストを返します(デフォルト) 1: 出力からGREASE (RFC8701) の値を除外します
ssl_fc_unique_id: binary 着信接続がSSL/TLSトランスポート層を使用する場合に、RFC5929の3節 で定義するTLSの一意なIDを返します。このIDは、コンバーター “ssl_fc_unique_id,base64” を使用して、base64にエンコードできます。
ssl_fc_use_keysize: integer 着信接続がSSL/TLSトランスポート層を使用する場合に、使用している対称暗号の鍵のサイズをビット単位で返します。
ssl_s_chain_der: binary 発信接続がSSL/TLSトランスポート層を使用する場合に、サーバーが提示した証明書チェーンをDER形式で返します。ACLで使用する場合、照合する値は16進形式で渡すことができます。ASN.1 DERデータを受け付けるライブラリーであれば、どれでも結果を解析できます。現在、再開したセッションには対応していません。
ssl_s_der: binary 発信接続がSSL/TLSトランスポート層を使用する場合に、サーバーが提示した証明書をDER形式で返します。ACLで使用する場合、照合する値は16進形式で渡すことができます。
ssl_s_i_dn([<entry>[,<occ>[,<format>]]]): string
発信接続がSSL/TLSトランスポート層を使用する場合に、<entry> を指定しなければ、サーバーが提示した証明書の発行者の完全な識別名を返します。指定した場合は、そのエントリーをDNの先頭から検索し、最初に見つかったエントリーの値を返します。省略可能な2番目の引数として出現番号を指定すると、正の場合はDNの先頭から、負の場合は末尾から数えてn番目の、指定したエントリーの値を返します。たとえば、“ssl_s_i_dn(OU,2)” は2番目の組織単位を、“ssl_s_i_dn(CN)” はコモンネームを取得します。<format> パラメーターを使用すると、各プロトコルで使用するのに適したDNを取得できます。現在は、LDAP v3向けのrfc2253に対応しています。形式だけを変更したい場合は、最初の2つのパラメーターに、空文字列とゼロを指定できます。例: ssl_s_i_dn(,0,rfc2253) 要求したエントリーのASN.1値(<entry> を指定しなかった場合は、DN内のいずれかのエントリー)に、後続のデータを伴う埋め込みNULバイトがあると、不正な形式とみなし、データを返しません。
ssl_s_key_alg: string 発信接続がSSL/TLSトランスポート層を使用する場合に、サーバーが提示した証明書の鍵の生成に使用したアルゴリズム名を返します。
ssl_s_notafter: string 発信接続がSSL/TLSトランスポート層を使用する場合に、サーバーが提示した終了日時を、YYMMDDhhmmss[Z]形式の文字列で返します。
ssl_s_notbefore: string 発信接続がSSL/TLSトランスポート層を使用する場合に、サーバーが提示した開始日時を、YYMMDDhhmmss[Z]形式の文字列で返します。
ssl_s_s_dn([<entry>[,<occ>[,<format>]]]): string
発信接続がSSL/TLSトランスポート層を使用する場合に、<entry> を指定しなければ、サーバーが提示した証明書のサブジェクトの完全な識別名を返します。指定した場合は、そのエントリーをDNの先頭から検索し、最初に見つかったエントリーの値を返します。省略可能な2番目の引数として出現番号を指定すると、正の場合はDNの先頭から、負の場合は末尾から数えてn番目の、指定したエントリーの値を返します。たとえば、“ssl_s_s_dn(OU,2)” は2番目の組織単位を、“ssl_s_s_dn(CN)” はコモンネームを取得します。<format> パラメーターを使用すると、各プロトコルで使用するのに適したDNを取得できます。現在は、LDAP v3向けのrfc2253に対応しています。形式だけを変更したい場合は、最初の2つのパラメーターに、空文字列とゼロを指定できます。例: ssl_s_s_dn(,0,rfc2253) 要求したエントリーのASN.1値(<entry> を指定しなかった場合は、DN内のいずれかのエントリー)に、後続のデータを伴う埋め込みNULバイトがあると、不正な形式とみなし、データを返しません。
ssl_s_serial: binary 発信接続がSSL/TLSトランスポート層を使用する場合に、サーバーが提示した証明書のシリアル番号を返します。ACLで使用する場合、照合する値は16進形式で渡すことができます。
ssl_s_sha1: binary 発信接続がSSL/TLSトランスポート層を使用する場合に、サーバーが提示した証明書のSHA-1フィンガープリントを返します。SNIによって、どの証明書を選択したかを確認するために使用できます。
ssl_s_sig_alg: string 発信接続がSSL/TLSトランスポート層を使用する場合に、サーバーが提示した証明書の署名に使用したアルゴリズム名を返します。
ssl_s_version: integer 発信接続がSSL/TLSトランスポート層を使用する場合に、サーバーが提示した証明書のバージョンを返します。
txn.timer.user: integer アイドル時間を除き、プロキシが受け入れた時点から、両端を閉じた時点までの、クライアントから見た合計推定時間です。log-formatの%Tuに相当し、ミリ秒 (ms) 単位で報告します。詳細は、8.4節 「タイミングイベント」を参照してください。
7.3.5. バッファーの内容からのサンプル取得(レイヤー6)
バッファーの内容からのサンプル取得は、上記の取得方法とは少し異なります。取得対象のデータが一時的なものだからです。このデータは、存在する間しか使用できず、転送すると失われます。そのため、たとえば、リクエスト中にバッファーの内容から取得したサンプルを、レスポンスで使用することはできません。データは、取得している最中にも変わる可能性があります。必要なデータが完全に揃い、使用できるようにするため、たとえばTCPリクエストの内容検査で、待ち時間を設定したり、複数のサンプル取得メソッドを組み合わせたりする必要がある場合があります。詳しくは、“tcp-request content” キーワードを参照してください。
警告: 次のサンプル取得関数は、HTTPプロキシで使用すると無視されます。これらは、バッファー内の生の内容だけを扱います。一方、HTTPプロキシは構造化した内容を使用するため、そのデータの生の表現には意味がありません。ACLが次のサンプル取得関数のいずれかに依存していれば、警告を出します。ただし、不正な使用をすべて検出できるわけではありません(カスタムログ形式やサンプル式の中で使用する場合など)。注意してください。
この節のサンプル取得メソッドと、それぞれの型の一覧:
詳細一覧:
distcc_body(<token>[,<occ>]): binary
distccメッセージを解析し、トークン <token> の出現番号 #<occ> に対応するボディーを返します。出現番号は1から始まります。指定しなければ、どの出現箇所にも一致できますが、現在の実装では、最初の出現箇所だけを確認します。HAProxyを経由してdistccでビルドするファイルから、ファイル名や引数を抽出するために使用できます。対応するトークンの完全な一覧については、distccのプロトコルのドキュメントを参照してください。
distcc_param(<token>[,<occ>]): integer
distccメッセージを解析し、トークン <token> の出現番号 #<occ> に対応するパラメーターを返します。出現番号は1から始まります。指定しなければ、どの出現箇所にも一致できますが、現在の実装では、最初の出現箇所だけを確認します。HAProxyを経由してdistccでビルドするファイルから、プロトコルのバージョン、ファイルサイズ、引数などの情報を抽出するために使用できます。ほかの用途として、アイドル状態の接続を保持しないよう、前処理済みのファイルの内容が始まるまで待ってから、サーバーに接続することもできます。対応するトークンの完全な一覧については、distccのプロトコルのドキュメントを参照してください。
例:
payload(<offset>,<length>): binary (deprecated)
リクエストの文脈(“stick on” や “stick match” など)で使用する場合は “req.payload” の別名であり、“stick store response” などのレスポンスの文脈で使用する場合は “res.payload” の別名です。
payload_lv(<offset1>,<length>[,<offset2>]): binary (deprecated)
リクエストの文脈(“stick on” や “stick match” など)で使用する場合は “req.payload_lv” の別名であり、“stick store response” などのレスポンスの文脈で使用する場合は “res.payload_lv” の別名です。
req.len: integer req_len: integer (非推奨) リクエストバッファー内のバイト数に対応する整数値を返します。主にACLで使用します。バッファーが変化している間は、このテストがfalseを返さないことを理解してください。つまり、ゼロと等しいかどうかを確認すると、セッションの開始時に、ほぼ常に即座に一致します。一方、より多くのデータを求めるテストでは、そのデータが届くのを待ち、それ以上データが届かないとHAProxyが確信した場合にのみ、falseを返します。このテストは、TCPリクエストの内容検査で使用するために設計しています。
req.payload(<offset>,<length>): binary
リクエストバッファーの、バイト位置 <offset> から始まる、<length> バイトのバイナリーブロックを抽出します。特別な場合として、<length> 引数がゼロの場合は、<offset> から末尾までのバッファー全体を抽出します。ACLとともに使用すると、バッファー内の任意の位置に、特定の内容が存在するかを確認できます。
派生ACL:
req.payload_lv(<offset1>,<length>[,<offset2>]): binary
リクエストバッファー内の、<offset1> の位置にある <length> バイトのフィールドでサイズを指定する、バイナリーブロックを抽出します。ブロックの開始位置は、<offset2> を指定した場合はその位置、指定しなかった場合は長さのフィールドの直後です。<offset2> パラメーターは、先頭に ‘+’ または ‘-’ 符号を付けた相対オフセットにも対応します。
派生ACL:
例: “stick store-response” キーワードの例を参照してください。
req.proto_http: boolean req_proto_http: boolean (非推奨) リクエストバッファー内のデータがHTTPのように見え、HTTPとして正しく解析できる場合にtrueを返します。通常のHTTPリクエストの解析と同じパーサーを使用するため、意外な結果は生じないはずです。リクエストが完了、失敗、またはタイムアウトするまでは、このテストは一致しません。TCPログでプロトコルを報告するためにも使用できますが、主な用途は、たとえばヘッダーを追跡するために、完全なHTTPリクエストがバッファーに存在するまで、TCPリクエストの解析を停止することです。
例:
req.rdp_cookie([<name>]): string
リクエストバッファーがRDPプロトコルのように見える場合に、RDP Cookie <name> を抽出します。名前を指定しなければ、任意のCookieを抽出します。パーサーは、RDPプロトコルの仕様に示すとおり、最初のCookieだけを確認します。Cookie名の大文字と小文字は区別しません。通常は、“MSTS” というCookie名を使用します。クライアントで適切に設定すれば、サーバーへ接続するクライアントのユーザー名を格納できるためです。サーバーへのセッションの固定には、“MSTSHASH” Cookieもよく使用します。
“balance rdp-cookie” とは異なり、任意の負荷分散アルゴリズムを使用できるため、クライアントのバックエンドサーバーへの分散は、RDP Cookieのハッシュと連動しません。“balance roundrobin” や “balance leastconn” などの負荷分散アルゴリズムを使用すると、“balance rdp-cookie” のハッシュよりも、クライアントをバックエンドサーバーへ均等に分散できると考えられます。
派生ACL:
例:
“balance rdp-cookie”、“persist rdp-cookie”、“tcp-request”、“req.rdp_cookie” ACLも参照してください。
req.rdp_cookie_cnt([name]): integer
リクエストバッファーをRDPプロトコルとして解析することを試み、見つかったRDP Cookieの数に対応する整数を返します。省略可能なCookie名を渡した場合は、その名前に一致するCookieだけを対象にします。主にACLで使用します。
派生ACL:
req.ssl_alpn: string クライアントがSSL ClientHelloメッセージ内で送信した、Application-Layer Protocol Negotiation(ALPN)TLS拡張 (RFC7301) の値を含む文字列を返します。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。次の例のように、TLSクライアントのALPNの優先設定に基づいて、ACLでルーティングを判断する場合に便利です。“ssl_fc_alpn” も参照してください。この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。この制限による影響(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)の詳細については、“req.ssl_sni” キーワードのドキュメントを参照してください。
例:
req.ssl_cipherlist binary
TLS ClientHelloの内容で報告する、クライアントが対応する対称暗号の選択肢のリストを、バイナリー形式で返します。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。“ssl” オプションを指定した場合に使用できる、SSL bind用の同等の取得関数 “ssl_fc_cipherlist_bin” を参照してください。この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。この制限による影響(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)の詳細については、“req.ssl_sni” キーワードのドキュメントを参照してください。
例:
req.ssl_ec_ext: boolean クライアントがSSL ClientHelloメッセージ内で、RFC4492の5.1節 で定義するSupported Elliptic Curves Extensionを送信したかどうかを、ブール値で返します。同じIPアドレスで、ECC対応のクライアントにはEC証明書を提示し、それ以外のすべてのクライアントにはRSAを使用するために利用できます。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。この制限による影響(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)の詳細については、“req.ssl_sni” キーワードのドキュメントを参照してください。
req.ssl_hello_type: integer req_ssl_hello_type: integer (非推奨) リクエストバッファーに、完全なSSL(v3以上)のClient Helloメッセージとして解析できるデータが含まれている場合、そのバッファー内のSSL Helloメッセージの型を含む整数値を返します。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。主にACLで、接続先の固定に使用できるSSLセッションIDを含むと想定する、SSL Helloメッセージの存在を検出するために使用します。この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。この制限による影響(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)の詳細については、“req.ssl_sni” キーワードのドキュメントを参照してください。
req.ssl_keyshare_groups binary
TLS ClientHelloで報告する、クライアントが対応する鍵交換用の暗号パラメーターのリストを、バイナリー形式で返します。TLS v1.3では、keyshareはClientHelloメッセージの一部で、最後のClient Hello拡張です。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。この制限による影響(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)の詳細については、“req.ssl_sni” キーワードのドキュメントを参照してください。
例:
req.ssl_sigalgs binary
TLS ClientHelloで報告する、クライアントが対応する署名アルゴリズムのリストを、バイナリー形式で返します。この情報は、Client Hello拡張として提供します。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。“ssl” オプションを指定した場合に使用できる、SSL bind用の同等の取得関数 “ssl_fc_sigalgs_bin” を参照してください。この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。この制限による影響(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)の詳細については、“req.ssl_sni” キーワードのドキュメントを参照してください。
例:
req.ssl_sni: string req_ssl_sni: string (非推奨) リクエストバッファーに、完全なSSL(v3以上)のClient Helloメッセージとして解析できるデータが含まれている場合、バッファーを通過するTLSストリームでクライアントが送信した、Server Name TLS拡張の値を含む文字列を返します。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。HTTPS (443)、IMAPS (993)、SMTPS (465) など、実際に暗黙的なTLSを使用するプロトコルでのみ機能し、SMTP (25/587) やIMAP (143) など、明示的なTLSを使用するプロトコルでは機能しません。最近のブラウザーでは、SNIは通常、クライアントが接続しようとするホストの名前を含みます。このテストは、TCPリクエストの内容検査で使用するために設計しています。内容に応じた振り分けが必要な場合は、次の例のように、まず完全なClient Hello(型1)を待つことを推奨します。“ssl_fc_sni” も参照してください。後述の理由(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)により、この取得関数の返却値は、特定のホストへのアクセスの許可や拒否を単独で判断するには、信頼性が不十分な点に注意してください。
この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。クライアントが同じTCPストリーム内で複数のClientHelloメッセージを送信する場合でも、最初のClientHelloが持つSNIだけを返し、それ以降のClientHelloの内容はすべて無視します。このような送信は、たとえば、サーバーがTLS 1.3の処理の一部としてHelloRetryRequest (HRR) を要求した場合や、クライアントがTLSの再ネゴシエーションを開始した場合に発生します。再ネゴシエーションでは、同じTCPストリーム内で後から新しいClientHelloを送信し、異なるSNIを含むことがあります。
Encrypted Client Hello (ECH) を使用する場合、通信路上で見えるClientHelloは、実際の暗号化した “Inner” ClientHelloを埋め込んだ、“Outer” ClientHelloだけです。この場合、この取得関数が抽出するSNIは、Outer ClientHelloのSNIであり、おとりのSNIです。クライアントが実際に到達したいホストではありません。現在、この取得関数は、Inner ClientHelloを復号することも解析することもできません。そのため、ECHを使用する場合、ルーティングやアクセス制御の判断を、この取得関数に依存させてはいけません。
派生ACL:
例:
req.ssl_st_ext: integer クライアントがSessionTicket TLS拡張 (RFC5077) を送信しなかった場合は0を返します。クライアントがSessionTicket TLS拡張を送信した場合は1を返します。クライアントが、長さがゼロではないTLS SessionTicketも送信した場合は2を返します。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。たとえば、クライアントがSessionTicketを送信したかどうかを検出し、それに応じて接続先を固定するために使用できます。SessionTicketがなければSessionIDに基づいて固定します。あるいは、SessionTicketを使用する場合はサーバー側に状態が存在しないため、固定しないようにできます。この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。この制限による影響(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)の詳細については、“req.ssl_sni” キーワードのドキュメントを参照してください。
req.ssl_supported_groups binary
TLS ClientHelloで報告する、クライアントが対応するグループのリストを、バイナリー形式で返します。これらのグループは鍵交換に使用し、楕円曲線を使用する鍵交換と、使用しない鍵交換の両方を含むことがあります。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。“ssl” オプションを指定した場合に使用できる、SSL bind用の同等の取得関数 “ssl_fc_eclist_bin” を参照してください。この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。この制限による影響(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)の詳細については、“req.ssl_sni” キーワードのドキュメントを参照してください。
例:
req.ssl_ver: integer req_ssl_ver: integer (非推奨) リクエストバッファー内のストリームの、SSL/TLSプロトコルのバージョンを含む整数値を返します。SSLv2 HelloメッセージとSSLv3メッセージの両方に対応します。TLSv1はSSLバージョン3.1として通知します。値は、メジャーバージョンに65536を掛け、マイナーバージョンを加えたものです。リクエストバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “bind” 行では機能しない点に注意してください。このテストのACL版は、MAJOR.MINOR形式の10進表記(3.1など)と照合します。この取得関数は主にACLで使用します。この取得関数が解析するのは、リクエストバッファー内で見つかった最初のClientHelloメッセージだけです。この制限による影響(HelloRetryRequest、再ネゴシエーション、Encrypted Client Hello)の詳細については、“req.ssl_sni” キーワードのドキュメントを参照してください。
派生ACL:
res.len: integer レスポンスバッファー内のバイト数に対応する整数値を返します。主にACLで使用します。バッファーが変化している間は、このテストがfalseを返さないことを理解してください。つまり、ゼロと等しいかどうかを確認すると、ストリームの開始時に、ほぼ常に即座に一致します。一方、より多くのデータを求めるテストでは、そのデータが届くのを待ち、それ以上データが届かないとHAProxyが確信した場合にのみ、falseを返します。このテストは、TCPレスポンスの内容検査で使用するために設計しています。ただし、tcp-checkのexpectルールでも使用できます。
res.payload(<offset>,<length>): binary
レスポンスバッファーの、バイト位置 <offset> から始まる、<length> バイトのバイナリーブロックを抽出します。特別な場合として、<length> 引数がゼロの場合は、<offset> から末尾までのバッファー全体を抽出します。ACLとともに使用すると、バッファー内の任意の位置に、特定の内容が存在するかを確認できます。tcp-checkのexpectルールでも使用できます。
res.payload_lv(<offset1>,<length>[,<offset2>]): binary
レスポンスバッファー内の、<offset1> の位置にある <length> バイトのフィールドでサイズを指定する、バイナリーブロックを抽出します。ブロックの開始位置は、<offset2> を指定した場合はその位置、指定しなかった場合は長さのフィールドの直後です。<offset2> パラメーターは、先頭に ‘+’ または ‘-’ 符号を付けた相対オフセットにも対応します。tcp-checkのexpectルールでも使用できます。
例: “stick store-response” キーワードの例を参照してください。
res.ssl_hello_type: integer rep_ssl_hello_type: integer (非推奨) レスポンスバッファーに、完全なSSL(v3以上)のHelloメッセージとして解析できるデータが含まれている場合、そのバッファー内のSSL Helloメッセージの型を含む整数値を返します。レスポンスバッファー内の生の内容だけに適用し、SSLデータ層で復号した内容には適用しないため、“ssl” オプションを指定した “server” 行では機能しない点に注意してください。主にACLで、接続先の固定に使用できるSSLセッションIDを含むと想定する、SSL Helloメッセージの存在を検出するために使用します。
7.3.6. HTTPサンプルの取得(レイヤー7)
HTTPの内容、リクエスト、レスポンスからサンプルを取得できます。このアプリケーション層は、レイヤー7とも呼びます。この節のデータを取得できるのは、それぞれのリクエストバッファーまたはレスポンスバッファーから、完全なHTTPリクエストまたはレスポンスを解析した場合だけです。HTTP専用のすべてのルールと、“mode http” で動作するセクションでは、常にこの条件を満たします。TCPの内容検査を使用する場合は、まずリクエストやレスポンスが到着できるように、検査の待ち時間を設ける必要がある場合があります。これらの取得関数は、レイヤー4の取得関数よりも、CPUリソースを少し多く必要とすることがあります。ただし、リクエストとレスポンスには索引を付けているため、大きな差はありません。
注意: tcp-request contentルールでのHTTP処理は、HTTPプロキシからであれば、すべて想定どおりに動作します。ただし、TCPプロキシからで、HTTPへのアップグレードを行っていない場合は、HTTP/1の内容に対してのみ機能します。HTTP/2の内容では、プリフェイスだけが見えます。そのため、使用できるサンプル取得関数は “req.proto_http”、“req.ver”、場合によっては “method” だけです。それ以外のレイヤー7のサンプル取得関数は、すべて失敗します。HTTPへのアップグレード後は、HTTPプロキシからの場合と同じように動作します。
この節のサンプル取得メソッドと、それぞれの型の一覧:
詳細一覧:
base: string 最初のHostヘッダーと、リクエストのパス部分を連結して返します。パス部分は、最初のスラッシュから始まり、疑問符の直前で終わります。仮想ホスティング環境でURLの濫用を検出したり、共有キャッシュの効率を改善したりする場合に役立ちます。サイズを制限したスティックテーブルと組み合わせると、ホストとパスごとに、最もよく要求されるオブジェクトの統計を収集することもできます。ACLでは、"www.example.com/favicon.ico ” のように、ホストとパスの両方を使った簡単な内容振り分けルールを作成できます。“path” と “uri” も参照してください。
派生ACL:
注意: 派生ACLの後にコンバーターを続けたり、"-m” パターンマッチングメソッドを指定したACLで使用したりしてはいけません。
base32: integer 前述の “base” 取得メソッドが返す値の、32ビットのハッシュを返します。すべてのURLを保存することなく、トラフィックの多いサイトで、URLごとの活動を追跡するのに便利です。代わりに短いハッシュを保存するため、多くのメモリーを節約できます。出力型は符号なし整数です。使用するハッシュ関数はSDBMで、出力に完全なアバランシェ処理を適用します。技術的には、base32は “base,sdbm(1)” と完全に同じです。
base32+src: binary 前述のbase32取得関数と、後述のsrc取得関数の結果を連結して返します。結果の型はバイナリーで、送信元アドレスのファミリーによって、サイズは8バイトまたは20バイトです。IPとURLの組み合わせごとに、カウンターを追跡するために使用できます。
baseq: string 最初のHostヘッダーと、リクエストのクエリー文字列を含むパス部分を連結して返します。パス部分は、最初のスラッシュから始まります。“base” の代わりに使用すると、統計やキャッシュの用途で、対象のリソースを適切に識別できます。“path”、“pathq”、“base” も参照してください。
capture.req.hdr(<idx>): string
“capture request header” でキャプチャーしたヘッダーの内容を抽出します。idxは、設定内のcaptureキーワードの位置です。最初のエントリーのインデックスは0です。“capture request header” も参照してください。
capture.req.method: string HTTPリクエストのMETHODを抽出します。リクエストとレスポンスの両方で使用できます。“method” とは異なり、保存用の領域を割り当てるため、リクエストとレスポンスの両方で使用できます。
capture.req.uri: string リクエストのURIを抽出します。URIは、リクエスト内の最初のスラッシュから始まり、最初のスペースの直前で終わります(ホスト部分は含みません)。“path” や “url” とは異なり、保存用の領域を割り当てるため、リクエストとレスポンスの両方で使用できます。
capture.req.ver: string リクエストのHTTPバージョンを抽出し、“HTTP/<major>.<minor>” 形式で返します。保持される情報を使用するため、リクエスト、レスポンス、ログで使用できます。リクエストのバージョンが無効な場合、このサンプル取得は失敗します。
capture.res.hdr(<idx>): string
“capture response header” でキャプチャーしたヘッダーの内容を抽出します。idxは、設定内のcaptureキーワードの位置です。最初のエントリーのインデックスは0です。“capture response header” も参照してください。
capture.res.ver: string レスポンスのHTTPバージョンを抽出し、“HTTP/<major>.<minor>” 形式で返します。保持される情報を使用するため、ログで使用できます。レスポンスのバージョンが無効な場合、このサンプル取得は失敗します。
cookie([<name>]): string (deprecated)
リクエストの “Cookie” ヘッダー行、またはレスポンスの “Set-Cookie” ヘッダーから、Cookie名 <name> の最後の出現箇所を抽出し、その値を文字列で返します。代表的な用途は、同じプロファイルを共有する複数のクライアントが、同じサーバーを使用するようにすることです。“appsession” の “request-learn” 文と似たことを実現できますが、複数ピア間の同期と、再起動をまたいだ状態の保持に対応します。名前を指定しなければ、最初のCookieの値を返します。この取得関数は、使用する文脈によって方向が曖昧に決まるため、今後は使用せず、代わりにreq.cook()またはres.cook()へ置き換えるべきです。
hdr([<name>[,<occ>]]): string
リクエストで使用する場合はreq.hdr()と、レスポンスで使用する場合はres.hdr()と同じです。詳細は、それぞれの取得関数を参照してください。取得の方向が不明な場合は、方向を明示した取得関数を使用してください。hdr()サンプル取得メソッドとは異なり、hdr_* ACLキーワードは、明確にリクエストヘッダーに適用する点に注意してください。
http_auth(<userlist>): boolean
クライアントから受信した認証データが、指定したuserlistに格納したユーザー名とパスワードに一致するかどうかを、ブール値で返します。この取得関数は、ACL以外ではあまり役立ちません。現在は、HTTP Basic認証だけに対応します。
http_auth_bearer([<header>]): string
Bearer方式を使用する場合(JSON Web Tokenを送信する場合など)に、認証データ内で見つかった、クライアントが提供したトークンを返します。クライアントが送信したデータは、一切検査しません。特定の <header> を指定した場合は、Authorizationヘッダーの代わりに、そのヘッダーを解析します。
http_auth_group(<userlist>): string
指定したuserlistに照らして、ユーザー名とパスワードの両方が有効な場合、クライアントから受信した認証データ内のユーザー名に対応する文字列を返します。主な用途はACLでの使用で、ユーザーがリスト内のいずれかのグループに所属しているかを確認します。この取得関数は、ACL以外ではあまり役立ちません。現在は、HTTP Basic認証だけに対応します。
派生ACL:
http_auth_pass: string クライアントから受信した認証データ内のユーザーのパスワードを、Authorizationヘッダーで指定されたとおりに返します。このサンプル取得関数は、一切検査しません。Basic認証だけに対応します。
http_auth_type: string クライアントから受信した認証データ内の認証方式を、Authorizationヘッダーで指定されたとおりに返します。このサンプル取得関数は、一切検査しません。Basic認証だけに対応します。
http_auth_user: string クライアントから受信した認証データ内のユーザー名を、Authorizationヘッダーで指定されたとおりに返します。このサンプル取得関数は、一切検査しません。Basic認証だけに対応します。
http_first_req: boolean 処理中のリクエストが、その接続の最初のリクエストである場合にtrueを返します。最初のリクエストでない場合に、一部のリクエストで欠ける可能性があるヘッダーを追加または削除したり、ログでリクエストをグループ化したりするために使用できます。
method: integer + string HTTPリクエストのメソッドに対応する整数値を返します。たとえば、“GET” は1に相当します(対応関係はソースを確認してください)。値9は “other method” を意味し、ストリームから抽出した文字列に変換できます。これをサンプルとして直接使用すべきではありません。ACLからの使用だけを想定しており、ACLは、パターン内のメソッドを、これらの整数と文字列の値へ透過的に変換します。よく使うメソッドの多くは、定義済みACLですでに検査できます。
派生ACL:
例:
path: string リクエストのURLパスを抽出します。パスは最初のスラッシュから始まり、疑問符の直前で終わります(ホスト部分は含みません)。代表的な用途は、プリフェッチ対応のキャッシュや、データベースから複数の情報を集約してキャッシュに保持する必要があるポータルです。外向きのキャッシュでは、代わりに “url” を使用する方が適切です。ACLでは、通常、ファイル名に完全一致させる場合("/login.php” など)や、派生形式を使用してディレクトリー部分と照合する場合に使用します。“url” と “base” 取得メソッドも参照してください。URI内のフラグメント参照(パスの後の ‘#’)は、HTTP標準で厳格に禁止しており、拒否する点に注意してください。ただし、リクエストを受信するフロントエンドで “option accept-unsafe-violations-in-http-request” を指定している場合、このフラグメント部分を受け入れ、パスにも含めます。
派生ACL:
注意: 派生ACLの後にコンバーターを続けたり、"-m” パターンマッチングメソッドを指定したACLで使用したりしてはいけません。
pathq: string クエリー文字列を含む、リクエストのURLパスを抽出します。最初のスラッシュから始まります。このサンプル取得関数は、スキームやオーソリティー部分があれば除外し、常に相対URIを取得するのに便利です。相対URIは、HTTP/1.1のリクエストターゲットで一般的な表現ですが、HTTP/2では絶対URIを使用することがよくあります。このサンプル取得関数は、どちらの場合も同じ結果を返します。URI内のフラグメント参照(パスの後の ‘#’)は、HTTP標準で厳格に禁止しており、拒否する点に注意してください。ただし、リクエストを受信するフロントエンドで “option accept-unsafe-violations-in-http-request” を指定している場合、このフラグメント部分を受け入れ、パスにも含めます。
query([<options>]): string
リクエストのクエリー文字列を抽出します。最初の疑問符の後から始まります。疑問符が存在しなければ、この取得関数は何も返しません。疑問符が存在しても、その後に何もなければ、空文字列を返します。そのため、“found” マッチングメソッドを使用すると、クエリー文字列が存在するかどうかを簡単に確認できます。この取得関数は、疑問符の直前で終わる “path” と、疑問符を含む “query_string” を補完します。
省略可能なパラメーターで、返却値をカスタマイズできます。次のオプションに対応します:
- with_qm: クエリー文字列が空でなければ、先頭に疑問符を含めます。
req.body: binary HTTPリクエストの、利用可能なボディーをデータブロックとして返します。リクエストのボディーを、できる限り確実に待つために、“option http-buffer-request” の使用を推奨します。
req.body_len: integer HTTPリクエストの、利用可能なボディーの長さをバイト単位で返します。ボディーがバッファーより大きい場合、通知した長さより小さくなることがあります。リクエストのボディーを、できる限り確実に待つために、“option http-buffer-request” の使用を推奨します。
req.body_param([<name>[,i]]): string
この取得関数は、POSTリクエストのボディーがURLエンコードされていると想定します。“content-type” に “application/x-www-form-urlencoded” という値が含まれるかを、ユーザーが確認できます。ボディー内のパラメーター <name> の最初の出現箇所を抽出します。値は ‘&’ の直前で終わります。2番目の引数に “i” を追加しない限り、パラメーター名の大文字と小文字を区別します。名前を指定しなければ、任意のパラメーターに一致し、最初のものを返します。結果は、リクエストボディーに記載されたとおりの、パラメーター <name> の値に対応する文字列です(URLデコードは行いません)。この取得関数のACL版は、複数のパラメーターを順に処理し、名前を指定しなければ、すべてのパラメーターの値を順に報告する点に注意してください。
req.body_size: integer HTTPリクエストのボディーについて、通知した長さをバイト単位で返します。通知したContent-Lengthヘッダーの値、またはチャンクエンコーディングの場合は、利用可能なデータのサイズを表します。
req.cook([<name>]): string
リクエストの “Cookie” ヘッダー行から、Cookie名 <name> の最後の出現箇所を抽出し、その値を文字列で返します。名前を指定しなければ、最初のCookieの値を返します。ACLで使用する場合は、一致するすべてのCookieを評価します。Cookieヘッダーの仕様 (RFC6265) に従い、名前と値の周囲のスペースを無視します。Cookie名の大文字と小文字は区別します。空のCookieも有効なので、空のCookieが存在する場合は、空の値を返すことがあります。存在の検出には、“found” マッチングを使用してください。サーバーが送信したレスポンスのCookieには、res.cook()版を使用してください。
派生ACL:
注意: 派生ACLの後にコンバーターを続けたり、"-m” パターンマッチングメソッドを指定したACLで使用したりしてはいけません。
req.cook_cnt([<name>]): integer
リクエスト内のCookie <name> の出現数を表す整数値を返します。<name> を指定しなかった場合は、すべてのCookieの数を返します。
req.cook_names([<delim>]): string
ルールを評価した時点で、リクエストのCookieヘッダーにあるすべてのCookie名を、その出現どおりに連結した文字列を作成します。デフォルトの区切り文字はカンマ (’,’) ですが、省略可能な引数 <delim> で上書きできます。その場合、<delim> の最初の文字だけを使用します。
req.cook_val([<name>]): integer
リクエストの “Cookie” ヘッダー行から、Cookie名 <name> の最後の出現箇所を抽出し、その値を整数に変換して返します。名前を指定しなければ、最初のCookieの値を返します。ACLで使用する場合は、値が一致するまで、名前が一致するすべてのCookieを順に処理します。
req.fhdr(<name>[,<occ>]): string
HTTPリクエスト内のヘッダー <name> の、最後の出現箇所の完全な値を返します。req.hdr()とは異なり、値に含まれるカンマもそのまま返し、区切り文字として使用しません。User-Agentなどのヘッダーで役立つ場合があります。
ACLから使用する場合は、一致が見つかるまで、すべての出現箇所を順に処理します。
省略可能な位置番号を指定して、特定の出現箇所を選ぶこともできます。正の値は、最初の出現箇所から数えた位置を示し、1が最初です。負の値は、最後の出現箇所からの相対位置を示し、-1が最後です。
req.fhdr_cnt([<name>]): integer
リクエストヘッダーフィールド名 <name> の出現数を表す整数値を返します。<name> を指定しなかった場合は、ヘッダーフィールドの総数を返します。req.fhdr()と同様に、カンマでヘッダーを分割しない点が、res.hdr_cnt()とは異なります。
req.hdr([<name>[,<occ>]]): string
HTTPリクエスト内のヘッダー <name> の、カンマで区切った最後の値を返します。この取得関数は、すべてのカンマを、別々の値を区切る文字として扱います。AcceptやX-Forwarded-Forなど、値のリストとして定義するヘッダーを処理する場合に便利です。代わりにヘッダーの行全体が必要な場合は、req.fhdr()を使用してください。特定のヘッダーをどのように解析すべきかについては、RFC 7231を注意深く確認してください。また、Connectionなど、大文字と小文字を区別しないヘッダーもあります。
ACLから使用する場合は、一致が見つかるまで、すべての出現箇所を順に処理します。
省略可能な位置番号を指定して、特定の出現箇所を選ぶこともできます。正の値は、最初の出現箇所から数えた位置を示し、1が最初です。負の値は、最後の出現箇所からの相対位置を示し、-1が最後です。
代表的な用途は、X-Forwarded-ForヘッダーをIPに変換して、IP型のスティックテーブルと組み合わせることです。
派生ACL:
注意: 派生ACLの後にコンバーターを続けたり、"-m” パターンマッチングメソッドを指定したACLで使用したりしてはいけません。
req.hdr_cnt([<name>]): integer
リクエストヘッダーフィールド名 <name> の出現数を表す整数値を返します。<name> を指定しなかった場合は、ヘッダーフィールドの値の総数を返します。req.hdr()と同様に、ヘッダーの値をカンマで区切った各部分を数えます。ヘッダーの行全体の数を数えたい場合は、代わりにreq.fhdr_cnt()を使用すべきです。
ACLでは、特定のヘッダーの存在、不在、濫用を検出したり、特定のヘッダーが複数あるリクエストを拒否して、リクエストスマグリング攻撃を防いだりするために使用できます。
ヘッダーのマッチングの詳細については、req.hdr()を参照してください。
req.hdr_ip([<name>[,<occ>]]): ip
HTTPリクエスト内のヘッダー <name> の最後の出現箇所を抽出し、IPv4またはIPv6アドレスに変換して、そのアドレスを返します。ACLで使用する場合は、すべての出現箇所を検査し、<name> を省略した場合は、すべてのヘッダーのすべての値を検査します。パーサーはRFC7239で説明する形式に厳密に従います。ただし、IPv4アドレスの後に、コロン (’:’) と、有効な10進数のポート番号(0から65535)を任意で付けられる拡張があります。このポート番号は、通知せずに取り除きます。それ以外の形式はすべて一致せず、そのアドレスを無視します。
<occ> パラメーターは、req.hdr()と同じように処理します。
代表的な用途は、X-Forwarded-ForおよびX-Client-IPヘッダーでの使用です。
req.hdr_names([<delim>]): string
ルールを評価した時点で、リクエストにあるすべてのヘッダー名を、その出現どおりに連結した文字列を作成します。デフォルトの区切り文字はカンマ (’,’) ですが、省略可能な引数 <delim> で上書きできます。その場合、<delim> の最初の文字だけを使用します。
req.hdr_val([<name>[,<occ>]]): integer
HTTPリクエスト内のヘッダー <name> の最後の出現箇所を抽出し、整数値に変換します。ACLで使用する場合は、すべての出現箇所を検査し、<name> を省略した場合は、すべてのヘッダーのすべての値を検査します。
<occ> パラメーターは、req.hdr()と同じように処理します。
代表的な用途は、X-Forwarded-Forヘッダーでの使用です。
req.hdrs: string 現在のリクエストヘッダーを、ヘッダーとリクエストボディーを区切る最後の空行を含む文字列で返します。この最後の空行は、途中で切れたヘッダーブロックの検出に使用できます。このサンプル取得関数は、一部のSPOEヘッダー解析器や、高度なログ記録に役立ちます。
req.hdrs_bin: binary 現在のリクエストヘッダーを、解析済みのバイナリー形式で返します。SPOEに処理の一部を委譲する場合に便利です。各文字列は、長さと、それに続く、長さで指定したバイト数のデータで表します。長さは、SPOEのドキュメントで詳述する、可変長整数のエンコーディングで表します。リストの終わりは、空のヘッダー名と値の組(両方の長さが0)で示します。
*(<str:header-name>``<str:header-value>)<empty string>``<empty string>
int: エンコーディングについては、SPOEのドキュメントを参照してください。str: <int:length>``<bytes>
req.timer.hdr: integer クライアントのリクエストを取得するまでの合計時間です(HTTPモードのみ)。最初のバイトを受信してから、HTTPヘッダーの終わりを示す空行をプロキシが受信するまでの経過時間です。ミリ秒 (ms) 単位で報告し、log-formatの%TRに相当します。詳細は、8.4節 「タイミングイベント」を参照してください。
req.timer.idle: integer HTTPリクエストの前のアイドル時間です(HTTPモードのみ)。ハンドシェイクの終了から、HTTPリクエストの最初のバイトまでの時間を数えます。ミリ秒単位で報告し、log-formatの%Tiに相当します。詳細は、8.4節 「タイミングイベント」を参照してください。
req.timer.queue: integer 接続スロットを待つために、キュー内で費やした合計時間です。ミリ秒単位で報告し、log-formatの%Twに相当します。詳細は、8.4節 「タイミングイベント」を参照してください。
req.timer.tq: integer 接続を受け入れた時点、または前のレスポンスの最後のバイトを送信した時点から、クライアントのリクエストを取得するまでの合計時間です。ミリ秒単位で報告し、log-formatの%Tqに相当します。詳細は、8.4節 「タイミングイベント」を参照してください。
req.ver: string req_ver: string (非推奨) HTTPリクエストのバージョン文字列を、"<major>.<minor>” 形式で返します。ACLで役立つ場合があります。一般的なバージョンは、定義済みACLですでに検査できます。保持される情報を使用するため、リクエスト、レスポンス、ログで使用できます。リクエストのバージョンが無効な場合、このサンプル取得は失敗します。
一般的な値は、“1.0”、“1.1”、“2.0”、“3.0” です。
派生ACL:
request_date([<unit>]): integer
HAProxyがHTTPリクエストの最初のバイトを受信した正確な日時です(log-formatのエイリアス%tr)。accept_date+ハンドシェイク時間(%Th)+アイドル時間(%Ti)から計算します。
エポックからの秒数を返します。
<unit>は任意です。秒を表す"s”(デフォルトの動作)、ミリ秒を表す"ms”、マイクロ秒を表す"us"を指定できます。単位を指定した場合、エポックからの秒数、ミリ秒数、マイクロ秒数のいずれかを表す整数値を返します。1秒未満の時間分解能が必要な場合に役立ちます。
res.body: binary HTTPレスポンスの利用可能なボディーをデータブロックとして返します。リクエスト側とは異なり、レスポンスボディーを待つディレクティブはありません。このサンプル取得は、ヘルスチェックのコンテキストで特に有用であり、使用可能です。
tcp-checkに基づくexpectルールで使用できます。
res.body_len: integer HTTPレスポンスの利用可能なボディーの長さをバイト単位で返します。リクエスト側とは異なり、レスポンスボディーを待つディレクティブはありません。このサンプル取得は、ヘルスチェックのコンテキストで特に有用であり、使用可能です。
tcp-checkに基づくexpectルールで使用できます。
res.body_size: integer HTTPレスポンスボディーの通知された長さをバイト単位で返します。Content-Lengthヘッダーで通知された長さ、またはチャンクエンコーディングの場合は利用可能なデータのサイズを表します。リクエスト側とは異なり、レスポンスボディーを待つディレクティブはありません。このサンプル取得は、ヘルスチェックのコンテキストで特に有用であり、使用可能です。
tcp-checkに基づくexpectルールで使用できます。
res.cache_hit: boolean レスポンスがHTTPキャッシュのエントリーから作成された場合はブール値"true"を返し、それ以外の場合はブール値"false"を返します。
res.cache_name: string res.cache_hitが真の場合、HTTPレスポンスの作成に使用したHTTPキャッシュの名前を含む文字列を返し、それ以外の場合は空文字列を返します。
res.comp: boolean レスポンスがHAProxyによって圧縮された場合はブール値"true"を返し、それ以外の場合はブール値"false"を返します。ログに情報を追加する用途に使用できます。
res.comp_algo: string レスポンスがHAProxyによって圧縮された場合、使用したアルゴリズムの名前を含む文字列を返します。たとえば、“deflate"です。ログに情報を追加する用途に使用できます。
res.cook([<name>]): string
レスポンスの"Set-Cookie"ヘッダー行から、名前<name>のCookieの最後の出現を抽出し、その値を文字列として返します。名前を指定しない場合、最初のCookieの値を返します。
tcp-checkに基づくexpectルールで使用できます。
派生ACL:
res.cook_cnt([<name>]): integer
レスポンスに含まれるCookie<name>の出現回数を表す整数値を返します。<name>を指定しない場合は、すべてのCookieの数を返します。主にACLと併用して、不審なレスポンスを検出する用途に役立ちます。
tcp-checkに基づくexpectルールで使用できます。
res.cook_names([<delim>]): string
ルールを評価した時点で、レスポンス(Set-Cookieヘッダー)に出現順にすべてのCookie名を連結した文字列を作成します。デフォルトの区切り文字はカンマ(’,’)ですが、任意の引数<delim>で変更できます。この場合、<delim>の最初の文字だけを使用します。
tcp-checkに基づくexpectルールで使用できます。
res.cook_val([<name>]): integer
レスポンスの"Set-Cookie"ヘッダー行から、名前<name>のCookieの最後の出現を抽出し、その値を整数に変換して返します。名前を指定しない場合、最初のCookieの値を返します。
tcp-checkに基づくexpectルールで使用できます。
res.fhdr([<name>[,<occ>]]): string
req.fhdr()取得と同様に動作しますが、HTTPレスポンス内のヘッダーに作用する点が異なります。
req.fhdr()と同様に、res.fhdr()取得は値全体を返します。ヘッダーがリストとして定義されている場合は、res.hdr()の使用を推奨します。
DateやExpiresなどのヘッダーに対して役立つ場合があります。
tcp-checkに基づくexpectルールで使用できます。
res.fhdr_cnt([<name>]): integer
req.fhdr_cnt()取得と同様に動作しますが、HTTPレスポンス内のヘッダーに作用する点が異なります。
req.fhdr_cnt()と同様に、res.fhdr_cnt()取得は値全体に作用します。ヘッダーがリストとして定義されている場合は、res.hdr_cnt()の使用を推奨します。
tcp-checkに基づくexpectルールで使用できます。
res.hdr([<name>[,<occ>]]): string
req.hdr()取得と同様に動作しますが、HTTPレスポンス内のヘッダーに作用する点が異なります。
req.hdr()と同様に、res.hdr()取得はカンマを区切り文字として扱います。この動作が望ましくない場合は、res.fhdr()の使用を推奨します。
tcp-checkに基づくexpectルールで使用できます。
派生ACL:
注意:派生ACLの後にコンバーターを続けたり、"-m"パターンマッチングメソッドを指定したACLで使用したりしてはいけません。
res.hdr_cnt([<name>]): integer
req.hdr_cnt()取得と同様に動作しますが、HTTPレスポンス内のヘッダーに作用する点が異なります。
req.hdr_cnt()と同様に、res.hdr_cnt()取得はカンマを区切り文字として扱います。この動作が望ましくない場合は、res.fhdr_cnt()の使用を推奨します。
tcp-checkに基づくexpectルールで使用できます。
res.hdr_ip([<name>[,<occ>]]): ip
req.hdr_ip()取得と同様に動作しますが、HTTPレスポンス内のヘッダーに作用する点が異なります。
スティックテーブルにデータを学習させる用途に役立ちます。
tcp-checkに基づくexpectルールで使用できます。
res.hdr_names([<delim>]): string
ルールを評価した時点で、レスポンスに出現順にすべてのヘッダー名を連結した文字列を作成します。デフォルトの区切り文字はカンマ(’,’)ですが、任意の引数<delim>で変更できます。この場合、<delim>の最初の文字だけを使用します。
tcp-checkに基づくexpectルールで使用できます。
res.hdr_val([<name>[,<occ>]]): integer
req.hdr_val()取得と同様に動作しますが、HTTPレスポンス内のヘッダーに作用する点が異なります。
スティックテーブルにデータを学習させる用途に役立ちます。
tcp-checkに基づくexpectルールで使用できます。
res.hdrs: string 現在のレスポンスヘッダーを、ヘッダーとリクエストボディーを区切る最後の空行も含めて文字列として返します。最後の空行は、ヘッダーブロックの切り詰めを検出するために使用できます。一部のSPOEヘッダー解析や高度なログ記録に役立つサンプル取得です。
tcp-checkに基づくexpectルールでも使用できます。
res.hdrs_bin: binary 事前解析済みのバイナリ形式で格納された現在のレスポンスヘッダーを返します。SPOEで一部の処理を外部へ委譲する用途に役立ちます。tcp-checkに基づくexpectルールで使用できます。各文字列は、長さと、それに続く、長さで指定したバイト数のデータで表します。長さはSPOEのドキュメントで詳述する可変長整数エンコーディングで表します。リストの終わりは、空のヘッダー名と空の値の組(両方の長さが0)で示します。
*(<str:header-name>``<str:header-value>)<empty string>``<empty string>
int: エンコーディングについては、SPOEのドキュメントを参照してください。str: <int:length>``<bytes>
res.timer.hdr: integer サーバーへのTCP接続が確立した時点から、サーバーがレスポンスヘッダー全体を送信した時点までの経過時間です。ミリ秒単位で報告し、log-formatの%Trに相当します。詳細はセクション8.4 「タイミングイベント」を参照してください。
res.ver: string resp_ver: string (非推奨) HTTPレスポンスのバージョン文字列を、"<major>.<minor>“という形式で返します。ログに役立つ場合もありますが、主にACL用です。レスポンスのバージョンが無効な場合、このサンプル取得は失敗します。
tcp-checkに基づくexpectルールで使用できます。
派生ACL:
server_status: integer サーバーから受信したHTTPステータスコードを含む整数を返します。サーバーからレスポンスを受信しなかった場合、このサンプル取得は失敗します。
set-cookie([<name>]): string (deprecated)
レスポンスの"Set-Cookie"ヘッダー行から、名前<name>のCookieの最後の出現を抽出し、対応する値を照合に使用します。“appsession"がデフォルトのオプションで行っていた処理に相当しますが、複数ピア間の同期と、再起動をまたいだ状態保持をサポートします。
この取得関数は非推奨で、“res.cook"取得に置き換えられています。このキーワードはまもなく削除されます。
status: integer HTTPレスポンスのHTTPステータスコードを含む整数を返します。たとえば、302です。主にACLと整数範囲の照合に使用し、たとえばレスポンスが3xxでない場合にLocationヘッダーを削除する用途があります。‘set-status’アクションなどで変更しなければ、クライアントが受信するステータスコードになります。
tcp-checkに基づくexpectルールで使用できます。
txn.status: integer ログに報告されるトランザクションのHTTPステータスコードを含む整数を返します。
txn.timer.total: integer HTTPリクエストの総アクティブ時間です。プロキシがリクエストヘッダーの最初のバイトを受信した時点から、レスポンスボディーの最後のバイトを送信した時点までの時間を指します。log-formatの%Taに相当し、ミリ秒(ms)単位で報告します。詳細はセクション8.4 「タイミングイベント」を参照してください。
unique-id: string リクエストに付与されたunique-idを返します。“unique-id-format"ディレクティブを設定しなければなりません。設定していない場合、unique-idサンプル取得は失敗します。unique-idは通常HTTPリクエストで使用しますが、このサンプル取得は他のプロトコルでも使用できます。HTTP以外のプロトコルで使用する場合、unique-id-formatディレクティブにHTTPの要素を含めてはいけません。unique-id-formatとunique-id-headerを参照してください。
url: string リクエストのURLを、リクエストに記載された形のまま抽出します。典型的な用途は、プリフェッチに対応するキャッシュや、データベースから複数の情報を集約してキャッシュに保持する必要があるポータルです。ACLでは、“url"より"path"の使用を推奨します。クライアントは、通常プロキシに対して行うように、完全なURLを送信する場合があるためです。実質的な用途は、“path"では一致しない”*“との照合だけであり、この用途にはすでに定義済みのACLがあります。“path"と"base"も参照してください。URI内のフラグメント参照(パスの後の’#’)はHTTP標準で厳密に禁止されており、拒否されます。ただし、リクエストを受信するフロントエンドに"option accept-unsafe-violations-in-http-request"がある場合、このフラグメント部分は受け入れられ、urlにも含まれます。
派生ACL:
注意:派生ACLの後にコンバーターを続けたり、"-m"パターンマッチングメソッドを指定したACLで使用したりしてはいけません。
url32: integer 最初のHostヘッダーと、パラメーターを含むURL全体を連結した値の32ビットハッシュを返します(前述の"base32"取得のように、リクエストのパス部分だけではありません)。URLごとの活動を追跡する用途に役立ちます。短いハッシュを保存するため、大幅にメモリーを節約できます。出力型は符号なし整数です。
url32+src: binary “url32"取得と"src"取得を連結した値を返します。結果はバイナリ型で、送信元アドレスファミリーに応じて8バイトまたは20バイトになります。IPごと、URLごとのカウンターを追跡する用途に使用できます。
url_ip: ip ホスト部分がIPアドレスとして記載されている場合、リクエストのURLからIPアドレスを抽出します。ホスト部分が名前の場合、名前解決を行わないため取得は失敗します。用途は非常に限られています。たとえば、監視システムが、特定の送信元アドレスがどの経路をたどるかを試すために、または特定の送信元アドレスのエントリーをテーブルに強制的に作成するために、送信元IPの代わりにこのフィールドを使用する場合があります。‘http-request set-dst’と組み合わせて、従来の’option http_proxy’を再現できます。
url_port: integer リクエストのURLからポート部分を抽出します。リクエストでポートを指定しない場合、ポート80とみなします。“url_ip"と同様、URLのauthorityがアドレスとして記載されている場合だけ動作します。ホスト名の場合は、ここでは名前解決を行わないため取得が失敗します。
urlp([<name>[,<delim>[,i]]]): string
クエリー文字列内で、パラメーター<name>の最初の出現を抽出します。パラメーターは’?‘または<delim>の後から始まり、’&’、’;’、<delim>のいずれかの前で終わります。3番目の引数に"i"を追加しない限り、パラメーター名は大文字と小文字を区別します。名前を指定しない場合、どのパラメーターも一致し、最初のものを返します。結果は、リクエストに記載されたパラメーター<name>の値に対応する文字列です(URLデコードは行いません)。クライアントIDに基づくセッション維持、URLパラメーターとして渡されたアプリケーションCookieの抽出、ACLでの検査に使用できます。この取得のACL版は複数のパラメーターを順に処理し、名前を指定しない場合は、すべてのパラメーターの値を順に返します。
派生ACL:
注意:派生ACLの後にコンバーターを続けたり、"-m"パターンマッチングメソッドを指定したACLで使用したりしてはいけません。
例:
urlp_val([<name>[,<delim>[,i]]]): integer
前述の"urlp"を参照してください。リクエスト内のURLパラメーター<name>を抽出し、整数値に変換します。たとえば、ユーザーIDに基づくセッション維持や、ACLでページ番号または価格を照合する用途に使用できます。
7.3.7. 開発者向けのサンプル取得
このサンプル取得メソッド群は開発者専用です。開発者の依頼に基づくデバッグ用途を除き、本番環境で決して使用してはなりません。また、後方互換性には特別な配慮を行いません。以下のサンプル取得を変更、改名、削除しないという保証はありません。使用が必要な場合は、十分に注意してください。曖昧さを避けるため、これらのサンプル取得は専用の"internal"スコープに置かれています。たとえば、“internal.strm.is_htx"です。
この節のサンプル取得メソッドと、それぞれの型の一覧:
詳細一覧:
internal.htx.data: integer チャネルに関連付けられたHTXメッセージ内で、データが使用するサイズをバイト単位で返します。チャネルはサンプルの方向に応じて選択します。
internal.htx.free: integer チャネルに関連付けられたHTXメッセージ内の空き領域(size - used)をバイト単位で返します。チャネルはサンプルの方向に応じて選択します。
internal.htx.free_data: integer チャネルに関連付けられたHTXメッセージ内の、データ用の空き領域をバイト単位で返します。チャネルはサンプルの方向に応じて選択します。
internal.htx.has_eom: boolean チャネルに関連付けられたHTXメッセージにメッセージ終端フラグ(EOM)が含まれている場合はtrueを返し、それ以外の場合はfalseを返します。チャネルはサンプルの方向に応じて選択します。
internal.htx.nbblks: integer チャネルに関連付けられたHTXメッセージ内のブロック数を返します。チャネルはサンプルの方向に応じて選択します。
internal.htx.size: integer チャネルに関連付けられたHTXメッセージの合計サイズをバイト単位で返します。チャネルはサンプルの方向に応じて選択します。
internal.htx.used: integer チャネルに関連付けられたHTXメッセージ内で使用する合計サイズ(データ+メタデータ)をバイト単位で返します。チャネルはサンプルの方向に応じて選択します。
internal.htx_blk.size(<idx>): integer
チャネルに関連付けられたHTXメッセージ内の、位置<idx>にあるブロックのサイズを返します。存在しない場合は0を返します。チャネルはサンプルの方向に応じて選択します。<idx>には任意の正の整数、または次の特殊な値を指定できます: * head : 最も古く挿入されたブロック * tail : 最も新しく挿入されたブロック * first: 解析を開始または再開する最初のブロック
internal.htx_blk.type(<idx>): string
チャネルに関連付けられたHTXメッセージ内の、位置<idx>にあるブロックの型を返します。存在しない場合は"HTX_BLK_UNUSED"を返します。チャネルはサンプルの方向に応じて選択します。<idx>には任意の正の整数、または次の特殊な値を指定できます: * head : 最も古く挿入されたブロック * tail : 最も新しく挿入されたブロック * first: 解析を開始または再開する最初のブロック
internal.htx_blk.data(<idx>): binary
チャネルに関連付けられたHTXメッセージ内の、位置<idx>にあるDATAブロックの値を返します。存在しない場合、またはDATAブロックでない場合は、空文字列を返します。チャネルはサンプルの方向に応じて選択します。<idx>には任意の正の整数、または次の特殊な値を指定できます:
* head : 最も古く挿入されたブロック
* tail : 最も新しく挿入されたブロック
* first: 解析を開始または再開する最初のブロック
internal.htx_blk.hdrname(<idx>): string
チャネルに関連付けられたHTXメッセージ内の、位置<idx>にあるHEADERブロックのヘッダー名を返します。存在しない場合、またはHEADERブロックでない場合は、空文字列を返します。チャネルはサンプルの方向に応じて選択します。<idx>には任意の正の整数、または次の特殊な値を指定できます:
* head : 最も古く挿入されたブロック
* tail : 最も新しく挿入されたブロック
* first: 解析を開始または再開する最初のブロック
internal.htx_blk.hdrval(<idx>): string
チャネルに関連付けられたHTXメッセージ内の、位置<idx>にあるHEADERブロックのヘッダー値を返します。存在しない場合、またはHEADERブロックでない場合は、空文字列を返します。チャネルはサンプルの方向に応じて選択します。<idx>には任意の正の整数、または次の特殊な値を指定できます:
* head : 最も古く挿入されたブロック
* tail : 最も新しく挿入されたブロック
* first: 解析を開始または再開する最初のブロック
internal.htx_blk.start_line(<idx>): string
チャネルに関連付けられたHTXメッセージ内の、位置<idx>にあるREQ_SLまたはRES_SLブロックの値を返します。存在しない場合、またはSLブロックでない場合は、空文字列を返します。チャネルはサンプルの方向に応じて選択します。<idx>には任意の正の整数、または次の特殊な値を指定できます:
* head : 最も古く挿入されたブロック
* tail : 最も新しく挿入されたブロック
* first: 解析を開始または再開する最初のブロック
internal.strm.is_htx: boolean 現在のストリームがHTXストリームの場合はtrueを返します。これは、チャネルバッファー内のデータを内部HTX表現で格納していることを意味します。それ以外の場合はfalseを返します。
7.4. 定義済みACL
一部の定義済みACLはハードコードされているため、必要とするフロントエンドごとに宣言する必要はありません。混同を避けるため、名前はすべて大文字です。等価な定義を以下に示します。
17 - 8. ログ
HAProxyの強みの一つは、間違いなく詳細なログです。この種の製品で得られる情報としては、おそらく最もきめ細かく、複雑な環境の問題解決に非常に重要です。通常のログには、クライアントのポート、TCP/HTTPの状態タイマー、終了時の正確なストリーム状態と終了理由、トラフィックをサーバーへ振り向けた判断に関する情報を含み、任意のヘッダーを取得することもできます。
管理者が素早く対応できるよう、発生した内部・外部の問題を明確に示し、異なるレベルのフィルターを使って、複数の送信先へ同時にログを送れます。
- グローバルなプロセス単位のログ(システムエラー、起動・停止など)
- インスタンスごとのシステムエラーと内部エラー(リソース不足、不具合など)
- インスタンスごとの外部の問題(サーバーの稼働・停止、接続数の上限)
- インスタンスごとの活動(クライアント接続)。接続確立時または終了時に記録します。
- リクエストごとのログレベル制御。たとえばhttp-request set-log-level silent if sensitive_request
レベルの異なるログを別々のログサーバーへ振り分けることで、複数の運用チームが連携し、問題をできるだけ早く修正できます。たとえば、システム担当はシステム全体のエラーを監視し、アプリケーション担当はサーバーの稼働・停止をリアルタイムで監視し、セキュリティ担当は一時間遅れで活動ログを分析できます。
8.1. ログレベル
TCP接続とHTTP接続について、日付、時刻、送信元IPアドレス、宛先アドレス、接続時間、応答時間、HTTPリクエスト、HTTP応答コード、転送バイト数、ストリームの終了条件、さらには交換したCookieの値まで記録できます。たとえば、特定のユーザーの問題を追跡できます。すべてのメッセージを、最大二つのsyslogサーバーへ送れます。ログのfacilityの詳細は、セクション4.2 の"log"キーワードを参照してください。
8.2. ログ形式
HAProxyは5種類のログ形式をサポートします。複数の形式で共通するフィールドは、以下の節で詳しく説明します。一部は、特定のオプションに固有の指標により、設定に応じて少し変わる場合があります。次の形式をサポートします。
-
デフォルト形式は、非常に基本的で、ほとんど使われません。着信接続を受け入れた時点で、送信元IP:port、宛先IP:port、フロントエンド名という、ごく基本的な情報だけを記録します。このモードはいずれなくなるため、詳しくは説明しません。
-
TCP形式は、より高度です。フロントエンドで"option tcplog"を設定すると有効になります。通常、HAProxyは接続の終了を待ってから記録します。タイマー、接続数、キューサイズなど、はるかに豊富な情報を記録します。純粋なTCPプロキシには、この形式を推奨します。
-
HTTP形式は、HTTPプロキシ用として最も高度です。フロントエンドで"option httplog"を設定すると有効になります。TCP形式と同じ情報に加え、リクエスト、ステータスコード、取得したヘッダーとCookieなど、HTTP固有のフィールドを含みます。HTTPプロキシには、この形式を推奨します。
-
CLF HTTP形式は、HTTP形式と同等ですが、フィールドをCLF形式と同じ順序で並べます。共通フィールドの後に、すべてのタイマー、取得項目、フラグなどを、標準HTTP形式と同じ順序で、一つずつ独立したフィールドに記録します。
-
カスタムログ形式では、独自のログ行を作成できます。
以下の節では、各形式をさらに詳しく説明します。形式は「フィールド」単位で規定します。別途説明がない限り、フィールドは任意の数の空白で区切ったテキストの一部分です。syslogサーバーが行頭にフィールドを挿入する場合があるため、最初のフィールドは、常にプロセス名と識別子を含むものとみなします。
注意:ログ行は非常に長くなることがあるため、以下の例では複数行に分割する場合があります。例のログ行は3つの閉じ山括弧(’>>>’)で始めます。複数行に分ける場合、最後以外の行はバックスラッシュ(’\’)で終え、次の行を二文字分インデントします。
8.2.1. デフォルトのログ形式
特定のオプションを設定しない場合に使う形式です。接続を受け入れると直ちにログを出力します。現在、リクエストの宛先IPとポートを記録する唯一の形式である点に注意してください。
例:
フィールド 形式 上記の例からの抜粋
各フィールドの詳細:
- “source_ip"は、接続を開始したクライアントのIPアドレスです。
- “source_port"は、接続を開始したクライアントのTCPポートです。
- “destination_ip"は、クライアントが接続したIPアドレスです。
- “destination_port"は、クライアントが接続したTCPポートです。
- “frontend_name"は、接続を受信して処理したフロントエンド(またはリスナー)の名前です。
- “mode"は、フロントエンドの動作モード(TCPまたはHTTP)です。
UNIXソケットの場合、送信元と宛先のアドレスは"unix:“と表示し、ポートは接続を受け入れたソケットの内部IDを表します(統計で報告するものと同じIDです)。
この非推奨の形式はいずれなくなるため、新規導入で使わないことを推奨します。
8.2.2. TCPログ形式
フロントエンドで"option tcplog"を指定するとTCP形式を使います。純粋なTCPプロキシに推奨する形式で、問題解決に有用な情報を豊富に含みます。タイマーとバイト数を含むため、通常はセッションの終了時にログを出力します。“option logasap"を指定すると早めに出力でき、リモート端末など、長いセッションを使う多くの環境で意味があります。“monitor"ルールにマッチするセッションは、決して記録しません。フロントエンドに"option dontlognull"を指定すると、クライアントとサーバーの間でデータを交換しなかったセッションのログを出さないようにもできます。“option dontlog-normal"を指定すると、成功した接続は記録しません。
TCPログ形式は、内部では次の正確な文字列に基づくカスタムログ形式として定義しています。必要なら、これを基に形式を拡張できます。また、代わりにHAPROXY_TCP_LOG_FMT変数も使えます。使い方は、セクション8.2.6 「カスタムログ形式」を参照してください。
CLFログ形式も、内部では次の正確な文字列に基づくカスタムログ形式として定義しています。
設定オプションによって、一部のフィールドが少し変わる場合があります。以下では、そのフィールド名の後にアスタリスク(’*’)を付けています。
例:
フィールド 形式 上記の例からの抜粋
各フィールドの詳細:
-
“client_ip"は、HAProxyへのTCP接続を開始したクライアントのIPアドレスです。UNIXソケットで接続を受け入れた場合は、IPアドレスを"unix"という語に置き換えます。“accept-proxy"を設定したソケットでPROXYプロトコルを正しく使った場合、または"accept-netscaler-cip"を設定したソケットでNetScaler Client IP挿入プロトコルを正しく使った場合、ログには転送された接続の情報が反映されます。
-
“client_port"は、接続を開始したクライアントのTCPポートです。UNIXソケットで受け入れた場合は、そのソケットのIDに置き換えます。このIDは統計インターフェースでも報告します。
-
“accept_date"は、HAProxyが接続を受信した正確な日時です。システムのバックログで待ちがあった場合、ネットワーク上で観測した日時とはわずかに異なることがあります。通常は、上流のファイアウォールのログに現れる日時と同じです。HTTPモードでは、新しいリクエストを受信できるようになった最初の時点(HTTP/1では前のレスポンスの終了時、HTTP/2では前のリクエストの直後)に、このフィールドをリセットします。
-
“frontend_name"は、接続を受信して処理したフロントエンド(またはリスナー)の名前です。
-
“backend_name"は、サーバーへの接続を管理するために選ばれたバックエンド(またはリスナー)の名前です。切り替えルールを適用していない場合、フロントエンドと同じ名前になります。TCPアプリケーションではよくある構成です。
-
“server_name"は、最後に接続を送ったサーバーの名前です。接続エラーによる再振り分けがあれば、最初のサーバーと異なる場合があります。このサーバーは、リクエストを処理したバックエンドに属します。サーバーに到達する前に接続を中止した場合は、サーバー名の代わりに”
<NOSRV>“を示します。 -
“Tw"は、各種キューで待った合計時間をミリ秒で表します。キューに到達する前に接続を中止した場合は、"-1"になることがあります。詳細は後述の「タイマー」を参照してください。
-
“Tc"は、最後のサーバーへの接続確立を待った合計時間を、再試行も含めてミリ秒で表します。接続を確立する前に中止した場合は、"-1"になることがあります。詳細は後述の「タイマー」を参照してください。
-
“Tt"は、接続の受け入れから最後のクローズまでの合計経過時間をミリ秒で表します。すべての処理を含みます。ただし、“option logasap"を指定した場合は例外で、ログを出力した時点で計測を止めます。その場合、最終値はこれより大きくなることを示す’+‘を、値の前に付けます。詳細は後述の「タイマー」を参照してください。
-
“bytes_read"は、ログ出力時点でサーバーからクライアントへ転送した総バイト数です。“option logasap"を指定した場合は、最終値がこれより大きくなる可能性を示す’+‘を、値の前に付けます。64ビットカウンターなので、ログ解析ツールはオーバーフローせずに扱えなければなりません。
-
“termination_state"は、セッション終了時の状態です。セッションの状態、どちら側が終了を引き起こしたか、その理由(タイムアウト、エラーなど)を示します。正常なフラグは”–“で、バッファーにデータを残さず、どちらかの側がセッションを閉じたことを示します。詳細は後述の「切断時のストリーム状態」を参照してください。
-
“actconn"は、セッションを記録した時点の、プロセス全体の同時接続数です。プロセス単位のシステム上限に達したことを検出するのに便利です。たとえば、複数の接続エラーが起きたときにactconnが512に近ければ、システムがプロセスのファイルディスクリプター数を1024に制限し、すべて使い切っている可能性が高いと考えられます。システムの調整方法は、セクション3 「グローバルセクション」を参照してください。
-
“feconn"は、セッションを記録した時点の、フロントエンドの同時接続数です。高負荷を維持するための必要リソース量を見積もり、フロントエンドの"maxconn"に達したことを検出するのに便利です。この値が急増する原因は、ほとんどの場合バックエンドサーバーの混雑ですが、サービス拒否攻撃の場合もあります。
-
“beconn"は、セッションを記録した時点で、バックエンドが扱う同時接続の総数です。サーバー上で有効な同時接続の総数と、キューで待機中の接続数を含みます。アプリケーションの高負荷に対応するため、追加で必要なサーバー数を見積もるのに便利です。この値が急増する原因は、ほとんどの場合バックエンドサーバーの混雑ですが、サービス拒否攻撃の場合もあります。
-
“srv_conn"は、セッションを記録した時点で、そのサーバー上にまだ残る有効な同時接続の総数です。サーバーに設定した"maxconn"を超えることはありません。この値が頻繁に"maxconn"に近づくか等しくなる場合、トラフィック調整が多く発生しています。つまり、サーバーのmaxconnが低すぎるか、最適な応答時間で負荷を処理するだけのサーバー数がありません。一台だけ"srv_conn"が高い場合、通常は、そのサーバーに問題があり、接続の処理が他のサーバーより長くかかっています。
-
“retries"は、このセッションがサーバーへの接続を試みたときの再試行回数です。接続試行と同時にサーバーを停止している場合を除き、通常はゼロでなければなりません。再試行が多い場合、一般にはHAProxyとサーバーの間のネットワーク問題、または新しい接続をキューに入れられないサーバーのシステムバックログの設定不備を示します。このフィールドの前に’+‘が付く場合があり、最初のサーバーで最大再試行回数に達した後、セッションを再振り分けしたことを示します。その場合、ログのサーバー名は最初のサーバーではなく、再振り分け先です。ただし、ハッシュなどによって両者が同じになる場合もあります。したがって、一般的な目安として、再試行回数の前に’+‘がある場合、その回数をログに記載されたサーバーのものとみなすべきではありません。
-
“srv_queue"は、サーバーのキューで、このリクエストより前に処理したリクエストの総数です。サーバーのキューを通らなければゼロです。キューで過ごした時間をキュー内のリクエスト数で割ると、サーバーのおおよその応答時間を見積もれます。セッションを再振り分けして二つのサーバーキューを通った場合、その位置を合算します。再振り分けがない限り、リクエストがサーバーキューとバックエンドキューの両方を通ることはないはずです。
-
“backend_queue"は、バックエンドのグローバルキューで、このリクエストより前に処理したリクエストの総数です。グローバルキューを通らなければゼロです。平均キュー長を見積もることができ、サーバーの"maxconn"で割れば、不足するサーバー数に容易に換算できます。再振り分けがあると、セッションがバックエンドのキューを二度通る場合があり、その位置を合算します。再振り分けがない限り、リクエストがサーバーキューとバックエンドキューの両方を通ることはないはずです。
8.2.3. HTTPログ形式
HTTP形式は、HTTPプロキシに最も適した、最も完全な形式です。フロントエンドで"option httplog"を指定すると有効になります。TCP形式と同じ情報に、HTTP固有の機能を追加します。TCP形式と同様、通常はストリーム終了時に出力しますが、“option logasap"を指定した場合は例外です。これを指定する意味があるのは、一般にはダウンロードサイトだけです。“monitor"ルールにマッチするストリームは、決して記録しません。フロントエンドに"option dontlognull"を指定すると、クライアントがデータを送らなかったストリームを記録しないようにもできます。“option dontlog-normal"を指定すると、成功した接続は記録しません。
HTTPログ形式は、内部では次の正確な文字列に基づくカスタムログ形式として定義しています。必要なら、これを基に形式を拡張できます。また、代わりにHAPROXY_HTTP_LOG_FMT変数も使えます。使い方は、セクション8.2.6 「カスタムログ形式」を参照してください。
CLFログ形式も、内部では次の正確な文字列に基づくカスタムログ形式として定義しています。
ほとんどのフィールドはTCPログと共通ですが、異なるものもあります。一部は、設定オプションによって少し変わる場合があります。以下では、そのフィールド名の後にアスタリスク(’*’)を付けています。
例:
フィールド 形式 上記の例からの抜粋
各フィールドの詳細:
-
“client_ip"は、HAProxyへのTCP接続を開始したクライアントのIPアドレスです。UNIXソケットで接続を受け入れた場合は、IPアドレスを"unix"という語に置き換えます。“accept-proxy"を設定したソケットでPROXYプロトコルを正しく使った場合、または"accept-netscaler-cip"を設定したソケットでNetScaler Client IP挿入プロトコルを正しく使った場合、ログには転送された接続の情報が反映されます。
-
“client_port"は、接続を開始したクライアントのTCPポートです。UNIXソケットで受け入れた場合は、そのソケットのIDに置き換えます。このIDは統計インターフェースでも報告します。
-
“request_date"は、HTTPリクエストの最初のバイトをHAProxyが受信した正確な日時です(ログフィールド%tr)。
-
“frontend_name"は、接続を受信して処理したフロントエンド(またはリスナー)の名前です。
-
“backend_name"は、サーバーへの接続を管理するために選ばれたバックエンド(またはリスナー)の名前です。切り替えルールを適用していない場合、フロントエンドと同じ名前になります。
-
“server_name"は、最後に接続を送ったサーバーの名前です。接続エラーによる再振り分けがあれば、最初のサーバーと異なる場合があります。このサーバーは、リクエストを処理したバックエンドに属します。サーバーに到達する前にリクエストを中止した場合は、サーバー名の代わりに”
<NOSRV>“を示します。統計サブシステムがリクエストを処理した場合は、"<STATS>“を示します。 -
“TR"は、最初のバイトを受信してから、クライアントの完全なHTTPリクエストを待った合計時間をミリ秒で表します(ボディーは含みません)。完全なリクエストを受信する前に接続を中止した場合や、不正なリクエストを受信した場合は、"-1"になることがあります。リクエストは通常、一つのパケットに収まるため、この値は常に非常に小さいはずです。大きい値は、一般にはクライアントとHAProxyの間のネットワーク問題、またはリクエストの手入力を示します。詳細はセクション8.4 「イベントのタイミング」を参照してください。
-
“Tw"は、各種キューで待った合計時間をミリ秒で表します。キューに到達する前に接続を中止した場合は、"-1"になることがあります。詳細はセクション8.4 「イベントのタイミング」を参照してください。
-
“Tc"は、最後のサーバーへの接続確立を待った合計時間を、再試行も含めてミリ秒で表します。接続を確立する前にリクエストを中止した場合は、"-1"になることがあります。詳細はセクション8.4 「イベントのタイミング」を参照してください。
-
“Tr"は、サーバーから完全なHTTPレスポンスを待った合計時間をミリ秒で表します(データは含みません)。完全なレスポンスを受信する前にリクエストを中止した場合は、"-1"になることがあります。通常はサーバーのリクエスト処理時間に一致しますが、クライアントからサーバーへ送るデータ量の影響を受ける場合があります。“GET"リクエストでこの値が大きければ、一般にはサーバーの過負荷を示します。詳細はセクション8.4 「イベントのタイミング」を参照してください。
-
“Ta"は、HAProxy内でリクエストが有効だった時間で、最初のリクエストバイトの受信から、最後のレスポンスバイトの送信までの合計経過時間をミリ秒で表します。ハンドシェイク(Thを参照)とアイドル時間(Tiを参照)以外の、すべての処理を含みます。ただし、“option logasap"を指定した場合は例外で、ログを出力した時点で計測を止めます。その場合、最終値はこれより大きくなることを示す’+‘を、値の前に付けます。詳細はセクション8.4 「イベントのタイミング」を参照してください。
-
“status_code"は、クライアントへ返したHTTPステータスコードです。通常はサーバーが設定しますが、サーバーに到達できない場合や、HAProxyがレスポンスをブロックした場合は、HAProxyが設定することもあります。
-
“bytes_read"は、ログ出力時点でクライアントへ転送した総バイト数です。HTTPヘッダーも含みます。“option logasap"を指定した場合は、最終値がこれより大きくなる可能性を示す’+‘を、値の前に付けます。64ビットカウンターなので、ログ解析ツールはオーバーフローせずに扱えなければなりません。
-
“captured_request_cookie"は、クライアントのリクエストにそのCookieが含まれていたことを示す、任意の"name=value"エントリーです。Cookie名と最大長は、フロントエンド設定の"capture cookie"文で定義します。未設定の場合は、単一のダッシュ(’-’)です。取得できるCookieは一つだけで、一般にはクライアントとサーバーのセッションIDの交換を追跡し、アプリケーションの不具合によるクライアント間のセッション混同を検出するために使います。詳細は後述の「HTTPヘッダーとCookieの取得」を参照してください。
-
“captured_response_cookie"は、サーバーがレスポンスでCookieを返したことを示す、任意の"name=value"エントリーです。Cookie名と最大長は、フロントエンド設定の"capture cookie"文で定義します。未設定の場合は、単一のダッシュ(’-’)です。取得できるCookieは一つだけで、一般にはクライアントとサーバーのセッションIDの交換を追跡し、アプリケーションの不具合によるクライアント間のセッション混同を検出するために使います。詳細は後述の「HTTPヘッダーとCookieの取得」を参照してください。
-
“termination_state"は、ストリーム終了時の状態です。TCPログと同様に、ストリームの状態、どちら側が終了を引き起こしたか、その理由(タイムアウト、エラーなど)を示し、最後の二文字にはCookieの永続性に関する操作の情報を含みます。正常なフラグは”–“で始まり、バッファーにデータを残さず、どちらかの側がストリームを閉じたことを示します。詳細は後述の「切断時のストリーム状態」を参照してください。
-
“actconn"は、ストリームを記録した時点の、プロセス全体の同時接続数です。プロセス単位のシステム上限に達したことを検出するのに便利です。たとえば、複数の接続エラーが起きたときにactconnが512または1024に近ければ、システムがプロセスのファイルディスクリプター数を1024に制限し、すべて使い切っている可能性が高いと考えられます。システムの調整方法は、セクション3 「グローバルセクション」を参照してください。
-
“feconn"は、ストリームを記録した時点の、フロントエンドの同時接続数です。高負荷を維持するための必要リソース量を見積もり、フロントエンドの"maxconn"に達したことを検出するのに便利です。この値が急増する原因は、ほとんどの場合バックエンドサーバーの混雑ですが、サービス拒否攻撃の場合もあります。
-
“beconn"は、ストリームを記録した時点で、バックエンドが扱う同時接続の総数です。サーバー上で有効な同時接続の総数と、キューで待機中の接続数を含みます。アプリケーションの高負荷に対応するため、追加で必要なサーバー数を見積もるのに便利です。この値が急増する原因は、ほとんどの場合バックエンドサーバーの混雑ですが、サービス拒否攻撃の場合もあります。
-
“srv_conn"は、ストリームを記録した時点で、そのサーバー上にまだ残る有効な同時接続の総数です。サーバーに設定した"maxconn"を超えることはありません。この値が頻繁に"maxconn"に近づくか等しくなる場合、トラフィック調整が多く発生しています。つまり、サーバーのmaxconnが低すぎるか、最適な応答時間で負荷を処理するだけのサーバー数がありません。一台だけ"srv_conn"が高い場合、通常は、そのサーバーに問題があり、リクエストの処理が他のサーバーより長くかかっています。
-
“retries"は、このストリームがサーバーへの接続を試みたときの再試行回数です。接続試行と同時にサーバーを停止している場合を除き、通常はゼロでなければなりません。再試行が多い場合、一般にはHAProxyとサーバーの間のネットワーク問題、または新しい接続をキューに入れられないサーバーのシステムバックログの設定不備を示します。このフィールドの前に’+‘が付く場合があり、最初のサーバーで最大再試行回数に達した後、ストリームを再振り分けしたことを示します。その場合、ログのサーバー名は最初のサーバーではなく、再振り分け先です。ただし、ハッシュなどによって両者が同じになる場合もあります。したがって、一般的な目安として、再試行回数の前に’+‘がある場合、その回数をログに記載されたサーバーのものとみなすべきではありません。
-
“srv_queue"は、サーバーのキューで、このリクエストより前に処理したリクエストの総数です。サーバーのキューを通らなければゼロです。キューで過ごした時間をキュー内のリクエスト数で割ると、サーバーのおおよその応答時間を見積もれます。ストリームを再振り分けして二つのサーバーキューを通った場合、その位置を合算します。再振り分けがない限り、リクエストがサーバーキューとバックエンドキューの両方を通ることはないはずです。
-
“backend_queue"は、バックエンドのグローバルキューで、このリクエストより前に処理したリクエストの総数です。グローバルキューを通らなければゼロです。平均キュー長を見積もることができ、サーバーの"maxconn"で割れば、不足するサーバー数に容易に換算できます。再振り分けがあると、ストリームがバックエンドのキューを二度通る場合があり、その位置を合算します。再振り分けがない限り、リクエストがサーバーキューとバックエンドキューの両方を通ることはないはずです。
-
“captured_request_headers"は、フロントエンドの"capture request header"文によって、リクエストから取得したヘッダーの一覧です。複数のヘッダーを取得でき、縦棒(’|’)で区切ります。取得を有効にしていない場合、波括弧も現れないため、後続フィールドの位置がずれます。このフィールドは空白を含む場合があるので、使わない場合より高度なログパーサーが必要である点に注意してください。詳細は後述の「HTTPヘッダーとCookieの取得」を参照してください。
-
“captured_response_headers"は、フロントエンドの"capture response header"文によって、レスポンスから取得したヘッダーの一覧です。複数のヘッダーを取得でき、縦棒(’|’)で区切ります。取得を有効にしていない場合、波括弧も現れないため、後続フィールドの位置がずれます。このフィールドは空白を含む場合があるので、使わない場合より高度なログパーサーが必要である点に注意してください。詳細は後述の「HTTPヘッダーとCookieの取得」を参照してください。
-
“http_request"は、メソッド、リクエスト、HTTPバージョン文字列を含む、完全なHTTPリクエスト行です。印字できない文字は符号化します(後述の「印字できない文字」を参照)。常に最後のフィールドで、必ず引用符で囲み、引用符を含められる唯一のフィールドです。新しいフィールドを追加する場合は、この前に追加します。リクエストが大きく、標準のsyslogバッファー(1024文字)に収まらない場合、このフィールドは切り詰められることがあります。そのため、必ず最後に置かなければなりません。
8.2.4. HTTPSログ形式
HTTPS形式は、SSL上のHTTP接続に最も適しています。HTTP形式(セクション8.2.3 を参照)を拡張し、SSL関連情報を追加します。フロントエンドで"option httpslog"を指定すると有効になります。TCP形式やHTTP形式と同様、“option logasap"を指定しない限り、通常はストリーム終了時にログを出力します。“monitor"ルールにマッチするストリームは、決して記録しません。フロントエンドに"option dontlognull"を指定すると、クライアントがデータを送らなかったストリームを記録しないようにもできます。“option dontlog-normal"を指定すると、成功した接続は記録しません。
HTTPSログ形式は、内部では次の正確な文字列に基づくカスタムログ形式として定義しています。必要なら、これを基に形式を拡張できます。また、代わりにHAPROXY_HTTPS_LOG_FMT変数も使えます。使い方は、セクション8.2.6 「カスタムログ形式」を参照してください。
基本的にはHTTP形式(セクション8.2.3 を参照)の末尾に新しいフィールドを追加したものです。ここでは、新しいフィールド(17行目と18行目)を詳しく説明します。HTTPのフィールドは、HTTPの節を参照してください。
例:
フィールド 形式 上記の例からの抜粋
各フィールドの詳細:
-
“fc_err"は、フロントエンド側の接続状態です。“fc_err"サンプル取得関数に対応します。詳細は、“fc_err"と"fc_err_str"サンプル取得関数を参照してください。
-
“ssl_fc_err"は、フロントエンドから見た接続で最初に発生したSSLエラースタックの、最後のエラーです。たとえばSSLハンドシェイクのエラー検出に使えます。問題がなければ0です。詳細は、“ssl_fc_err"サンプル取得関数の説明を参照してください。
-
“ssl_c_err"は、クライアント証明書の検証処理の状態です。無視するエラーであれば、検証エラーコードがゼロでなくても、ハンドシェイクが成功する場合があります。“ssl_c_err"サンプル取得関数と"crt-ignore-err"オプションを参照してください。
-
“ssl_c_ca_err"は、クライアント証明書チェーンの検証処理の状態です。無視するエラーであれば、検証エラーコードがゼロでなくても、ハンドシェイクが成功する場合があります。“ssl_c_ca_err"サンプル取得関数と"ca-ignore-err"オプションを参照してください。
-
“ssl_fc_is_resumed"は、受信したTLSセッションを、状態を保持するキャッシュまたは状態を持たないチケットで再開した場合に真です。TLSセッションは複数のリクエストで共有できることを忘れないでください。
-
“ssl_fc_sni"は、使う証明書を選ぶため、クライアントが提示したSNI(Server Name Indication)です。通常は、接続の最初のリクエストのホスト名と一致します。このフィールドがない場合、クライアントがSNIを送らなかった可能性があり、haproxyはデフォルト証明書を使うか、strict-sniの場合は接続を拒否します。
-
“ssl_version"は、フロントエンドのSSLバージョンです。
-
“ssl_ciphers"は、接続で使ったSSL暗号です。
8.2.5. エラーログ形式
SSLハンドシェイクや不正なPROXYプロトコルヘッダーが原因で着信接続に失敗すると、“error-log-format"行で専用のエラーログ形式を定義していない限り、HAProxyは短い固定形式の行で記録します。デフォルトのレベルはLOG_INFOですが、バックエンドで"log-separate-errors"を設定している場合はLOG_ERRです。“dontlognull"を設定していれば、データを交換しなかった接続(プローブなど)は記録しません。
デフォルトの形式は次のとおりです。
これらのフィールドは、接続失敗のデバッグに役立つ最小限の情報だけを提供します。
“error-log-format"ディレクティブを使うと、上記の従来の形式は使わず、すべてのエラーログ行が定義した形式に従います。
以下は、十分に網羅的なerror-log-formatの例です。送信元アドレスとポート、接続のaccept()日時、フロントエンド名、プロセスとそのフロントエンドの有効な接続数、フロント接続に関するhaproxy内部のエラー識別子、16進数のOpenSSLエラー番号(“openssl errstr"へコピーして完全に解読できます)、クライアント証明書の抽出状態(0はエラーなし)、CAを使ったクライアント証明書の検証状態(0はエラーなし)、接続が新規か再開かを示す真偽値、クライアントが任意で提示したサーバー名表示(SNI)、SSLバージョン名、接続で使ったSSL暗号があればそれも報告します。バックエンドの接続エラーは、ここでは決して報告しません。バックエンド接続が失敗する場合、それ以前にストリームは正常に進んでいるため、通常のトラフィックログに記録するからです(option httplogまたはoption httpslogを参照)。
8.2.6. カスタムログ形式
もともと、カスタムログ形式はログの生成だけに使っていました。しかし、複雑な複数の式を組み合わせて文字列を作る際に便利なため、以前は文字列だけを引数に取っていた多くのディレクティブでも採用され、現在はカスタムログ形式の定義も受け付けます。この文書では、こうした引数を通常”<fmt>“と示します。ここで説明する"log-format"ディレクティブの引数と、まったく同じ方法で定義します。
ログについては、デフォルトの形式で不十分なら、新しい形式を非常に細かく定義できます。ただし、一から作るのは必ずしも簡単ではないため、まず既存形式(“option tcplog”、“option httplog”、“option httpslog”)を見て、要望に最も近いものを選び、対応する"log-format"文字列をコピーして調整することを強く推奨します。
設定上、カスタムログ形式の定義は単一の引数です。したがって、バックスラッシュ(’\’)でエスケープするか、定義全体を引用符で囲まない限り、空白やタブを含められません。全体を引用符で囲む方法を推奨します。引用符のない形式文字列は、バックスラッシュが一つ欠けるだけで、形式が黙って切り詰められることがあり、誤りが多いことが分かっているため、現在は推奨しません。引用符が使えるようになる3年前の1.5-dev9以降、ログ形式が広く採用されたため、こうした設定は今もよく見かけますが、引用符で囲んだ文字列に変換し、バックスラッシュを取り除くことを推奨します。
ログ形式の定義は、テキストと空白で区切った任意の数のログ形式項目で構成します。項目は’%‘で始めます。’%‘そのものを出力するには、前にもう一つ’%‘を付け、’%%‘にしなければなりません。
ログ形式の項目には、別名またはサンプル式を使えます。
項目を角括弧(’[’ .. ‘]’)で囲むと、サンプル式のルールとして使います(セクション7.3 を参照)。クライアントSSL証明書のDNなど、あまり一般的でない情報を追加したり、スティックテーブルにエントリーを保存する際に使うキーを記録したりするのに便利です。ヘッダー操作や変数など、ログ以外のアクションでもよく使います。
それ以外で、項目が英数字の名前なら、別名です(使用可能な別名は下表を参照)。
項目は波括弧(’{}’)で引数を取れます。複数の引数は、波括弧内でカンマ区切りにします。フラグの前に’+‘または’-‘を付けると、追加または削除できます(使用可能なフラグは後述)。
特殊な別名”%o"は、そのフラグを、同じ形式文字列の他のすべての項目へ伝播できます。特に、引用符で囲む形式(“Q”)や、エスケープする形式(“E”)に便利です。
特殊な別名”%OG"は、ログの生成元(いつ、どこで生成したか)を、人が読める形式で取得できます。“option logasap"で特に便利です。ログ形式の式をいつ、どこで評価するかにより、一部のログ変数やサンプル取得関数が不完全な値を返したり、異なる動作をしたりするためです。次の値があります。
- “sess_error”:セッションのエラー処理中にログを生成しました。
- “sess_killed”:セッションの中止中にログを生成しました(生成途中のセッションを強制終了)。
- “txn_accept”:フロントエンドの接続を受け入れた直後にログを生成しました。
- “txn_request”:クライアントのリクエストを受信した後にログを生成しました。
- “txn_connect”:バックエンドの接続を確立した後にログを生成しました。
- “txn_response”:サーバーのレスポンス処理中にログを生成しました。
- “txn_close”:クローズ前の最後のトランザクション段階でログを生成しました。
- “unspec”:不明または未指定です。"%OG"が関係するのはログ出力時だけです。
項目には、任意で’()‘を使って名前を付けられます。名前は’%‘の直後、引数の前に指定しなければなりません。“json"や"cbor"などの符号化フラグを設定すると、自動的にキー名として使います。符号化フラグがないデフォルトの場合、項目名は無視します。また、名前の後に’:type’を付けると、出力を特定の型に強制できます。形式は%(itemname:itemtype)aliasnameまたは%(itemname:itemtype)[expr]で、itemtypeは’str’、‘sint’、‘bool’のいずれかです。型の指定が意味を持つのは、符号化方式を使う場合だけです。空の名前を指定して、無名の項目の出力型を強制することもできます。%(:itemtype)という形式で、たとえば、符号化を全体に設定していない場合に使います。詳細は以下のフラグ定義を参照してください。
カスタムログ形式は当初、ログ専用だったため、表示できない文字や安全でない文字(ASCIIコード32~126の範囲外と、その他の一部)は、使う場所に応じて特別に扱います。端末の出力を読みにくくする危険なコードを送らないよう、ログで具体的に何を行うかは、セクション8.6 で説明します。ヘッダーフィールド、ヘルスチェック、レスポンスのペイロードを作る場合は規則が緩く、HTTPヘッダーフィールドで禁止する文字だけを、’%‘を先頭に付けた16進符号に置き換えます。通常は問題ありませんが、文字をそのまま再現したい場合は、出力に影響することがあります。たとえば、エラーページや完全なレスポンスのペイロードを作る際に、改行が”%0A"と表示される場合です。
注意:設定ディレクティブ"log-format”、“log-format-sd”、“unique-id-format"では、空白を区切りとみなし、まとめます。
注意:RFC5424のsyslogメッセージ形式では、PARAM-VALUE内の’"’、’\’、’]‘は、前に’\‘を付けてエスケープするべきです(詳細はhttps://tools.ietf.org/html/rfc5424#section-6.3.3 を参照)。その場合は、“E"フラグの使用を検討してください。
次の項目フラグをサポートします(項目の引数で有効・無効にできます)。
- Q:文字列を引用符で囲みます。
- X:16進表現にします(IP、ポート、%Ts、%rt、%pid)。
- E:文字列内の’"’、’\’、’]‘を、前に’\‘を付けてエスケープします(RFC5424の構造化データログ形式を想定しています)。
- bin:バイナリデータを維持しようとします。バイナリデータを出力するサンプル式で、元のデータを保つのに便利です。ただし、NULLバイトを含む表示できない文字を生成し得る点に注意してください。ほとんどのsyslog受信先は、そうした文字を想定していません。したがって、主にset-var-fmt、リング、バイナリに対応するログ受信先での使用を想定しています。このオプションは、%oで全体に設定する場合だけ有効で、個々の項目に設定しても無視します。
- json:値を自動的にJSON形式に符号化します(全体に設定した場合、名前のあるログ形式項目だけが対象です)。不完全な数値(logasap使用時の’%B’など)は、符号化しない場合には通常’+‘を付けますが、そのまま符号化します。また、’+E’オプションは無視します。セクション8.6 で説明するように、32..126の範囲外の文字は、JSONのエスケープシーケンスを使ってバイトごとにエスケープします。そのため、入力にかかわらず出力は表示可能なASCIIだけになります。これは有効なUTF-8シーケンスにも適用され、デコード後には非ASCIIテキストが個々のバイトとして現れます。たとえば、0xC3 0xA9で符号化したU+00E9は”\u00C3\u00A9"としてログに記録します。このようなテキストを保持するには、以下の"utf8"を参照してください。
- utf8:“json"と組み合わせると、有効な複数バイトのUTF-8シーケンスをエスケープせずに出力できます。C1制御文字(U+0080からU+009F)は引き続きエスケープし、そのコードポイントで表します。不正なシーケンスはバイトごとにエスケープし、出力が常に有効なUTF-8になるようにします。有効なUTF-8をそのまま出力するため、クライアントが特殊な文字を使い、端末やログビューアーでのログ行の表示を変える可能性があります。たとえば、文字方向の変更、ゼロ幅文字、行や段落の区切り文字などです。そのため、信頼できるソースからの内容、またはログを端末に表示しない場合にだけ使用することを推奨します。“json"なしでは効果がありません。
- cbor:値を自動的にCBOR形式に符号化します(全体に設定した場合、名前のあるログ形式項目だけが対象です)。デフォルトでは、stdoutに表示でき、通常のsyslog受信先でも使えるよう、CBORデータを16進形式で表します。jsonと同様、不完全な数値はそのまま符号化し、’+E’を無視します。’+bin’と組み合わせると、生のバイナリCBORペイロードを直接生成します。表示できない文字を生成する点に注意してください。したがって、主にset-var-fmt、リング、バイナリに対応するログ受信先での使用を想定しています。
例:
現在定義されている別名は、下表を参照してください。
R = 制約:H = mode httpのみ; S = SSLのみ; L = ログのみ
8.3. 高度なログオプション
よく求められる高度なログ機能でも、各種オプションを見るだけでは見つけにくいものがあります。よりよいログを実現するいくつかのオプションを、ここで案内します。使用方法の詳細は、キーワードリファレンスを参照してください。
8.3.1. 外部テストのログを無効にする
監視ツールがHAProxyのヘルスチェックを行うのは一般的です。LVSや商用製品などのレイヤー3ロードバランサーの場合もあれば、Nagiosなどの本格的な監視システムの場合もあります。テストが非常に頻繁だと、そのチェックのログを無効にする方法がよく求められます。三つの方法があります。
-
さまざまな送信元からの単なるTCPプローブなら、フロントエンドで"option dontlognull"を設定し、データを交換しない接続を記録しない方法がよく使われます。ポートスキャンも記録しなくなるため、それが望ましいかは場合によります。
-
送信元ネットワーク、パス、User-Agentなど、さまざまな条件で"http-request set-log-level silent"アクションを使えます。
-
既知のURIでテストする場合は、“monitor-uri"で監視専用のURIとして宣言します。このリクエストを送ったホストには、ヘルスチェックの結果だけを返し、リクエストを記録しません。
8.3.2. ストリームの終了を待たずに記録する
接続終了時に記録する問題点は、リモート端末のセッションや大きなファイルのダウンロードなど、非常に長いストリームの途中で何が起きているか分からないことです。フロントエンドに"option logasap"を指定すると回避できます。HAProxyは、データ転送を始める直前、可能な限り早く記録します。TCPではサーバーへの接続状態を記録し、HTTPではサーバーのヘッダーを処理した直後に記録します。この場合、報告するバイト数は、クライアントへ送ったヘッダーのバイト数です。通常のログと混同しないよう、合計時間とバイト数の前に’+‘を付け、実際の値は確実にこれより大きいことを示します。
8.3.3. エラー時にログレベルを上げる
ログファイルからエラーを監視しやすくするなど、通常のトラフィックとエラーログを分けると便利な場合があります。“log-separate-errors"を使うと、エラー、タイムアウト、再試行、再振り分け、HTTPステータス5xxを経験した接続のsyslogレベルを、“info"から"err"に上げます。syslogデーモンが別ファイルに保存しやすくなります。ただし、ログの順序を変えないため、通常のトラフィックファイルにもエラーを残すことが非常に重要です。また、“notice"より高いレベルをすべて"admin"ファイルに保存する設定がすでにある場合、“err"は"notice"より高いので注意してください。
8.3.4. 成功した接続のログを無効にする
最初は奇妙に思えるかもしれませんが、大規模なサイトでは毎秒何千ものログを扱い、長期間そのまま保持したり、その中からエラーを見つけたりするのが困難な場合があります。フロントエンドで"dontlog-normal"を設定すると、正常な接続をすべて記録しません。ここで正常とは、エラー、タイムアウト、再試行、再振り分けがない接続です。HTTPではステータスコードも確認し、5xxレスポンスは正常とみなさず、記録します。ただし、有用な情報の大半がログから失われるため、この方法は強く非推奨とします。他に選択肢がない場合だけ使ってください。
8.3.5. ログプロファイル
“log-format”、“log-format-sd”、“error-log-format”、“log-tag"などにより、グローバルまたはプロキシ単位でログ形式を設定できますが、ログの送信先にできるだけ近い単位、つまり"log"ディレクティブごとに設定したい場合もあります。
そこで使うのが、設定内のどこにでも定義できる"log-profile"セクションです。このセクションは、特定のlogディレクティブで出力するログの構成方法を記述する、さまざまなキーワードを受け付けます。
“log"ディレクティブから、特定のlog-profileを名前で選べます。同じプロファイルを、複数の"log"ディレクティブで使えます。
log-profile <name> <name>で識別する新しいログプロファイルを作成します。
log-tag <string> “log-tag"でグローバルまたはプロキシ単位に設定したsyslogのログタグを上書きします。
on <step> [drop] [format <fmt>] [sd <sd_fmt>] <step>のログ段階で通常使う、ログ行生成用のlog-format文字列を上書きします。<fmt>は、<step>に応じて"log-format"または"error-log-format"を、<sd_fmt>は"log-format-sd"を上書きします。両方を組み合わせられます。
特殊キーワード"drop"は、指定した<step>でログを出力しないことを指定します。“format"や"sd"を先に定義していても、それらより優先します。
<step>には次の値を指定できます。
- “accept”:フロントエンドの接続を受け入れた直後に生成するログのlog-formatを上書きします。
- “request”:クライアントのリクエストを受信した後に生成するログのlog-formatを上書きします。
- “connect”:バックエンドの接続を確立した後に生成するログのlog-formatを上書きします。
- “response”:サーバーのレスポンス処理中に生成するログのlog-formatを上書きします。
- “close”:トランザクション(txn)の最後の段階で生成するログのlog-formatを上書きします。
- “error”:トランザクションエラーによって生成するログのerror-log-formatを上書きします。
- “any”:より具体的な段階の上書きを宣言していない限り、すべてのログ段階でlog-formatとerror-log-formatの両方を上書きします。
追加の<step>値については、“do-log"アクションを参照してください。
この設定が意味を持つのは、HTTP/TCPプロキシなど、“log-format"を使う意味がある文脈の"log"ディレクティブだけです。それ以外では、単に無視します。
例:
8.4. イベントのタイミング
タイマーは、ネットワーク問題の診断に大きく役立ちます。すべての値をミリ秒(ms)で報告します。ストリームの終了フラグと組み合わせて使うべきです。フロントエンドで"option tcplog"を設定したTCPモードでは、3つの測定点を"Tw/Tc/Tt"形式で報告し、HTTPモードでは5つを"TR/Tw/Tc/Tr/Ta"形式で報告します。さらに、“Th”、“Ti”、“Tq"の三つの測定値もあります。
HTTPモードのイベントのタイミング:
TCPモードのイベントのタイミング:
-
Th:TCP接続を受け入れ、低レベルプロトコルのハンドシェイクを実行する合計時間です。現在の対象はproxy-protocolとSSLです。接続の生存期間全体で、一度だけ発生し得ます。大きな値は、クライアントが接続だけを先に確立して何も送っていない、適切な時間内のハンドシェイク完了を妨げるネットワーク問題(MTU問題など)がある、またはSSLハンドシェイクの計算コストが非常に高かったことを示す場合があります。最初のリクエストの前だけに報告するため、全リクエストで平均して、償却した値を求めても問題ありません。二番目以降のリクエストでは、常にゼロです。
このタイマーは、ログ形式の別名では%Th、サンプル取得関数ではfc.timer.handshakeです。
-
Ti:HTTPリクエストの前のアイドル時間です(HTTPモードのみ)。ハンドシェイクの終了から、HTTPリクエストの最初のバイトまでを計測します。keep-aliveで二番目のリクエストを扱う場合、前のレスポンスの送信終了後に計測を始めます。HTTP/2などの多重化プロトコルでは、前のリクエストの直後に始めます。一部のブラウザーは、後のリクエストの遅延を減らすため、先にサーバーへの接続を確立し、必要になるまで待機させます。この待ち時間をアイドル時間として報告します。-1は、接続上で何も受信しなかったことを示します。
このタイマーは、ログ形式の別名では%Ti、サンプル取得関数ではreq.timer.idleです。
-
TR:クライアントのリクエストを受信する合計時間です(HTTPモードのみ)。最初のバイトを受信してから、HTTPヘッダーの終端を示す空行をプロキシが受信するまでです。"-1"は、ヘッダーの終端を一度も確認しなかったことを示します。クライアントが早期に閉じたり、タイムアウトしたりすると起こります。ほとんどのリクエストは一つのパケットに収まるため、通常は非常に短い時間です。大きな値は、テストでリクエストを手入力したことを示す場合があります。
このタイマーは、ログ形式の別名では%TR、サンプル取得関数ではreq.timer.hdrです。
-
Tq:接続の受け入れ、または前のレスポンスの最後のバイトを送信してから、クライアントのリクエストを受信するまでの合計時間です(HTTPモードのみ)。Th + Ti + TRに厳密に一致しますが、いずれかが-1なら、これも-1です。HTTP keep-aliveやブラウザーの事前接続機能が登場する前には、非常に便利なタイマーでした。現在は、アイドル時間が報告の大きな雑音になるため、代わりにTRを使うことを推奨します。
このタイマーは、ログ形式の別名では%Tq、サンプル取得関数ではreq.timer.tqです。
-
Tw:接続枠を待ち、キューで過ごした合計時間です。バックエンドキューとサーバーキューの両方を含み、キューサイズと、サーバーが先行リクエストを完了する時間によります。"-1"は、キューに到達する前にリクエストを強制終了したことを示し、通常は不正または拒否したリクエストで起こります。
このタイマーは、ログ形式の別名では%Tw、サンプル取得関数ではreq.timer.queueです。
-
Tc:サーバーへのTCP接続を確立する合計時間です。プロキシが接続要求を送ってからサーバーが応答確認するまで、つまりTCP SYNから、それに対応して返ってくるSYN/ACKまでの時間です。"-1"は、接続が一度も確立しなかったことを示します。
このタイマーは、ログ形式の別名では%Tc、サンプル取得関数ではbc.timer.connectです。
-
Tr:サーバーの応答時間です(HTTPモードのみ)。サーバーへのTCP接続の確立から、サーバーが完全なレスポンスヘッダーを送るまでの時間です。データ転送のネットワーク負荷を除いた、リクエスト処理時間そのものを示します。ただし、POSTリクエストなどでクライアントがサーバーへデータを送る間も、すでに計測は進んでいるため、見かけの応答時間がゆがむ場合があります。そのため、信頼できないネットワークの背後にいるクライアントからのPOSTでは、このフィールドを過信しないのが賢明です。"-1"は、最後のレスポンスヘッダー(空行)を一度も確認しなかったことを示します。多くの場合、サーバーがリクエストを処理する前にサーバータイムアウトになったか、不正なレスポンスを返したためです。
このタイマーは、ログ形式の別名では%Tr、サンプル取得関数ではres.timer.hdrです。
-
Td:レスポンスのペイロードを、最後のバイトをクライアントへ送るまで転送した合計時間です。HTTPでは、最後のレスポンスヘッダーの後(Trの後)から始まります。
送ったデータがクライアントに届いた保証はなく、カーネルやネットワーク内で止まっている場合があります。
このタイマーは、ログ形式の別名では%Td、サンプル取得関数ではres.timer.dataです。
-
Ta:HTTPリクエストの合計有効時間です。プロキシがリクエストヘッダーの最初のバイトを受信してから、レスポンスボディーの最後のバイトを送るまでです。“logasap"を指定した場合は例外で、(TR+Tw+Tc+Tr)だけになり、前に’+‘が付きます。このフィールドから、他の有効なタイマーを引くことで、データ転送時間"Td"を求められます。
値が"-1"のタイマーは、この式から除かなければなりません。"Ta"が負になることはありません。
このタイマーは、ログ形式の別名では%Ta、サンプル取得関数ではtxn.timer.totalです。
- Tt:ストリームの合計持続時間です。プロキシが受け入れてから、両端が閉じるまでを計測します。“logasap"を指定した場合は例外で、(Th+Ti+TR+Tw+Tc+Tr)だけになり、前に’+‘が付きます。このフィールドから、他の有効なタイマーを引くことで、データ転送時間"Td"を求められます。
値が"-1"のタイマーは、この式から除かなければなりません。TCPモードでは、"Ti"、"Tq"、"Tr"も除く必要があります。"Tt"が負になることはなく、HTTPでは単純に(Th+Ti+Ta)と等しくなります。
このタイマーは、ログ形式の別名では%Tt、サンプル取得関数ではfc.timer.totalです。
-
Tu:クライアントから見た推定合計時間です。プロキシの受け入れから両端が閉じるまでの時間から、アイドル時間を除きます。リクエスト間のkeep-alive待ち時間に影響されず、利用者が感じるエンドツーエンド時間を概算するのに便利です。両方向のネットワーク遅延が同じと仮定するため、あくまで利用者から見た時間の推定です。“logasap"を指定した場合は例外で、(Th+TR+Tw+Tc+Tr)だけになり、前に’+‘が付きます。
このタイマーは、ログ形式の別名では%Tu、サンプル取得関数ではtxn.timer.userです。
これらのタイマーは、問題の原因を示す貴重な手掛かりになります。TCPプロトコルは再送間隔を3、6、12…秒と規定しているため、3sの倍数に近い値は、ほぼ常にネットワーク問題(配線、ネゴシエーション、混雑)によるパケット損失に関係すると判断できます。また、“Ta"や"Tt"が設定のタイムアウト値に近ければ、タイムアウトによりストリームを中止したことを示す場合が多くあります。
よくあるケース:
-
“Th"や"Ti"が3000に近ければ、クライアントとプロキシの間でおそらくパケットを失っています。ローカルネットワークでは非常にまれですが、遠隔ネットワークのクライアントが大きなリクエストを送る場合には起こり得ます。ネットワークに原因がなくても、通常より大きな値が現れる場合があります。攻撃中やリソース不足が解消した直後に、HAProxyが数ミリ秒で何千もの接続を受け入れることがあります。その処理は、他の接続の処理をどうしても少し遅らせるため、数千の新規接続を一度に受け入れた後、数十ミリ秒程度のリクエスト時間を計測する場合があります。“Ti"は追加リクエストを待つ時間を測るため、keep-aliveモードでは長いアイドル時間が表示されることがあります。
-
“Tc"が3000に近ければ、サーバー接続の段階で、サーバーとプロキシの間のおそらくパケットを失っています。この値は常に非常に小さいはずで、ローカルネットワークなら1 ms、遠隔ネットワークでも数十ms未満などです。
-
“Tr"がほぼ常に3000未満で、ときどき平均値に3000を加えたような値が現れる場合、プロキシとサーバーの間でおそらくパケットを失っています。
-
バイト数が少ないのに"Ta"が大きい場合、一般には、HAProxyがトンネルモードで動作し、クライアントとサーバーがkeep-aliveに合意したまま、どちらも接続を閉じないためです。解決するには、フロントエンドまたはバックエンドで、keep-aliveやcloseを制御するHTTPオプションを指定する必要があります。サーバーの"maxconn"で接続を調整する場合、既存の接続が解放されるまで新しい接続を送れないため、‘Ta’や’Tt’をできるだけ小さくすることが重要です。
その他の注目すべきHTTPログの例(‘xx’は無視してよい任意の値):
8.5. 切断時のストリーム状態
TCPログとHTTPログは、有効な接続数の直前の"termination_state"フィールドで、ストリーム終了の指標を示します。TCPでは2文字、HTTPでは4文字に拡張し、各文字に固有の意味があります。
- 最初の文字は、ストリームの終了を引き起こした最初のイベントを示すコードです。
- 二番目の文字は、閉じた時点のTCPまたはHTTPストリームの状態です。
- 三番目の文字は、クライアントが永続性Cookieを送ったかどうかを示します(HTTPモードのみ)。
- 最後の文字は、サーバーが返した永続性Cookieに、どのような操作を行ったかを示します(HTTPモードのみ)。
最初の二つのフラグを組み合わせると、ストリームやセッションの終了時に何が起きていたか、なぜ終了したかについて、多くの情報を得られます。サーバーの飽和、ネットワーク問題、ローカルシステムのリソース不足、攻撃などの検出に役立ちます。
よくある終了フラグの組み合わせを以下に示します。見つけて理解しやすいよう、アルファベット順で、大文字の直後に対応する小文字を置いています。
フラグ 理由
-- 正常終了。
CC サーバーへの接続を確立する前に、クライアントが中止しました。
HAProxyが停止したばかりのサーバー(または未チェックのサーバー)に
接続しようとし、サーバーの応答または"timeout connect"の満了を
待つ間に、クライアントが中止した場合などに起こります。
CD データ転送中に、クライアントが予期せず中止しました。
ブラウザーのクラッシュ、クライアントとHAProxyの間の機器による
能動的な切断、両者の間の経路問題、またはサーバーとクライアントの
keep-aliveストリームをクライアントが先に終了したことが原因になり得ます。
cD "timeout client"の間、クライアントがデータを送信も確認応答もしませんでした。
多くの場合、クライアント側のネットワーク障害、またはクライアントが
正常な手順を踏まずにネットワークを離れたことが原因です。
CH サーバーの応答開始を待つ間に、クライアントが中止しました。
サーバーの応答が遅すぎるか、クライアントが「停止」ボタンを
押すのが早すぎた可能性があります。
cH POSTリクエストでクライアントのデータを待つ間に、"timeout client"が満了しました。
最大サイズのパケットを運べないPPPoEネットワークに対し、TCP MSSが
大きすぎる場合に起こることがあります。クライアントタイムアウトが
サーバータイムアウトより短く、サーバーの応答が遅すぎる場合も起こります。
CQ 十分な空き枠があるサーバーを待ち、ストリームがキューに入っている間に、
クライアントが中止しました。すべてのサーバーが飽和していたか、
割り当てたサーバーの応答が遅すぎた可能性があります。
CR 完全なHTTPリクエストを送る前に、クライアントが中止しました。
最も可能性が高いのは、telnetクライアントで手入力したリクエストを
早く中止しすぎた場合です。HTTPステータスは、おそらく400です。HAProxyとクライアントの
接続をIDSが切断した場合にも起こります。"option http-ignore-probes"で、
データ転送のない接続を無視できます。
cR クライアントが完全なHTTPリクエストを送る前に、"timeout http-request"が満了しました。
最大サイズのパケットを運べないPPPoEネットワークに対し、クライアントの
TCP MSSが大きすぎる、リクエストの手入力が遅すぎる、末尾の空行を
入れ忘れた場合などに起こります。HTTPステータスは、おそらく408です。
注意:最近の一部のブラウザーは、利用者が再訪する場合に備え、最近訪問した
サイトへ先回りして接続する「事前接続」機能を実装しています。そのため、
多数の接続が作られ、先にタイムアウトすれば408 Request Timeout、
ブラウザーが先に閉じれば400 Bad Requestになります。ログを埋め、
エラーカウンターを増やし、一部のブラウザーの一部の版では、エラーコードを
表示することさえ報告されています。フロントエンドに"option http-ignore-probes"を
追加すると、データ転送がゼロの接続を完全に無視し、この望ましくない影響を
回避できます。ただし、接続の問題を抱える利用者のエラーも確実に隠します。
CT ストリームをtarpitしている間に、クライアントが中止しました。
誤ったtarpitルールがないことを確かめるため、有効なリクエストで起きていないか
確認することが重要です。多発する場合は、少数の攻撃者のためにリソースを
消費しないよう、"timeout tarpit"を、報告される平均"Tw"に近づけて
下げることが有効な場合があります。
LC HAProxyがリクエストを捕捉し、ローカルで処理しました。
リクエストをサーバーへ送っていません。server行の"redir"パラメーターによる
リダイレクトの場合だけに起こります。
LR HAProxyがリクエストを捕捉し、ローカルで処理しました。
リクエストをサーバーへ送っていません。一般には、リダイレクトを返した、
HTTP return文を処理した、またはアプレット(統計、キャッシュ、Prometheus
エクスポーター、Luaアプレットなど)が処理したことを示します。
LH HAProxyがレスポンスを捕捉し、ローカルで処理しました。
一般には、リダイレクトを返したか、HTTP return文を処理したことを示します。
SC サーバーまたはHAProxyとの間の機器が、TCP接続を明示的に拒否しました
(プロキシがTCP RSTまたはICMPメッセージを受信)。状況によっては、
ネットワークスタックがサーバーに到達できないことを伝えた場合もあります
(経路がない、ローカルネットワークでARP応答がないなど)。
HTTPモードでは、ステータスはおそらく502または503です。
sC サーバーへの接続が完了する前に、"timeout connect"が満了しました。
HTTPモードでは、ステータスはおそらく503または504です。
SD データ転送中に、サーバーとの接続がエラーで切れました。
通常は、データ交換中に、HAProxyがサーバーからRSTを、または途中の機器から
ICMPメッセージを受信したことを示します。サーバーのクラッシュや、
途中の機器のネットワーク問題が原因になり得ます。
sD データ転送段階で、"timeout server"の間、サーバーがデータを送信も
確認応答もしませんでした。多くの場合、サーバーの手前のL4機器
(ファイアウォール、ロードバランサーなど)のタイムアウトが短すぎるか、
クライアントとサーバーのkeep-aliveセッションがHAProxy側で先に期限切れに
なったことが原因です。
SH サーバーがHTTPレスポンスヘッダーをすべて送る前に中断したか、
リクエストの処理中にクラッシュしました。この時点でサーバーが中断する
ことは非常にまれなので、ログを調べ、クラッシュの有無と原因を確認する
のが賢明です。ログに記録したリクエストから、問題のある少数の
リクエスト群が分かり、アプリケーションの不具合を示せる場合があります。
IDSがHAProxyとサーバーの間の接続を切ったことが原因の場合もあります。
sH サーバーがレスポンスヘッダーを返す前に、"timeout server"が
満了しました。最も一般的な異常で、トランザクションが長すぎることを
示します。おそらく、サーバーやデータベースの飽和が原因です。
当面の回避策は"timeout server"の設定を大きくすることですが、
応答時間が長いためにユーザーの使い勝手が悪くなることを忘れては
なりません。長期的な解決策は、アプリケーションの修正だけです。
sQ ストリームがキューで待ちすぎて、期限切れになりました。頻発する
場合は、"timeout queue"と"timeout connect"の設定を調べて対処して
ください。短時間に大量に発生することが多い場合、I/Oやデータベースの
混雑による、該当サーバー全体の問題、または外部からの攻撃による
飽和を示している可能性があります。
PC サーバーへの接続を試みる際に、プロセスのソケット数の上限に達した
ため、プロキシが接続の確立を拒否しました。再発しないよう、設定で
グローバルの"maxconn"パラメーターを大きくできます。
非常にまれな状態で、グローバルの"ulimit-n"パラメーターを手動で
固定した場合に起こることがあります。
PD サーバーがヘッダーを送信した後、リクエストまたはレスポンス内の、
不正な形式のchunkedエンコードされたメッセージをプロキシが遮断しました。
ほとんどの場合、サーバーからクライアントへの不正なメッセージを示します。
HAProxyは2GB - 1(2147483647バイト)までのチャンクサイズをサポートします。
それより大きなサイズは、すべてエラーとみなします。
PH レスポンスが不正、不完全、危険(キャッシュ制御)、またはセキュリティ
フィルターにマッチしたため、プロキシがサーバーのレスポンスを遮断しました。
いずれの場合も、クライアントへHTTP 502エラーを送ります。考えられる
原因の一つは、許可されない文字を含むHTTPヘッダー名の構文エラーです。
また、非常にまれですが、サーバーが応答する前に、構文が不正なため、
クライアントからのchunked-encodingリクエストを遮断する場合もあります。
この場合、クライアントへHTTP 400エラーを送り、ログにも記録します。
最後に、レスポンスのHTTPヘッダーの書き換え失敗が原因の場合もあります。
この場合はHTTP 500エラーを送ります(詳細は"tune.maxrewrite"と
"http-response strict-mode"を参照してください)。
PR プロキシがクライアントのHTTPリクエストを遮断しました。HTTP構文が
不正な場合はクライアントへHTTP 400エラーを返し、denyフィルターに
マッチした場合はHTTP 403エラーを返します。リクエストのHTTPヘッダーの
書き換え失敗が原因の場合もあり、その場合はHTTP 500エラーを送ります
(詳細は"tune.maxrewrite"と"http-request strict-mode"を参照してください)。
PT プロキシがクライアントのリクエストを遮断し、接続をtarpitで引き延ばして
から、500サーバーエラーを返しました。サーバーへは何も送っていません。
"Tw"タイマーフィールドに記録した時間だけ、接続を開いたままにしました。
RC ローカルリソース(メモリー、ソケット、送信元ポート)が枯渇し、
サーバーへの接続を確立できませんでした。不足したものは、エラーログで
正確に分かります。非常にまれで、適切なシステム調整でしか解決できません。
最後の二つのフラグの組み合わせから、クライアント、サーバー、HAProxyが永続性をどう扱ったかについて、多くの情報が得られます。ユーザーから再認証が必要になるという苦情があるとき、切断の問題を解決するうえで非常に重要です。よく見られるフラグは次のとおりです。
8.6. 印字できない文字
ログを読む際に、ログ解析ツールや端末に問題を起こさないよう、印字できない文字をそのままログファイルへ送ることはありません。ASCIIコードを二桁の16進表現にし、先頭に’#‘を付けます。エスケープせずに記録できるのは、32以上126以下の文字だけです。当然、エスケープ文字’#‘自体も、曖昧にならないよう”#23"へエンコードします。文字’"‘も同様に”#22"へ変換し、ヘッダーを記録するときは’{’、’|’、’}‘も変換します。
これはcborの符号化には適用しません。cborは、安全な16進数の数字、または正しく区切ったバイナリブロックをすでに使用します。これらのブロックは端末へ送るのではなく、CBORパーサーが処理します。
jsonの符号化では、代わりにJSONのエスケープシーケンスを使用します。+utf8オプションを指定すると、有効な複数バイトのUTF-8シーケンスもそのまま出力します(セクション8.2.6 の"utf8"フラグを参照)。
空白文字(’ ‘)はヘッダー内でエンコードしないため、空白の数でフィールドの位置を判断するツールでは問題が起こる場合があります。空白を含む典型的なヘッダーは"User-Agent"です。
最後に、syslog-ngなど、一部のsyslogデーモンは、引用符(’"’)をバックスラッシュ(’\’)でエスケープすることが確認されています。ログの他の場所に引用符が現れることはないため、逆変換は安全に行えます。
8.7. HTTP Cookieの取得
Cookieを取得すると、ユーザーセッション全体を追跡しやすくなります。フロントエンドで"capture cookie"文を使うと実現できます。詳細はセクション4.2 を参照してください。取得できるCookieは一つだけで、リクエスト(“Cookie:“ヘッダー)とレスポンス(“Set-Cookie:“ヘッダー)で、同じCookieを同時に調べます。それぞれの値は、HTTPログの"captured_request_cookie"と"captured_response_cookie"の位置に記録します(HTTPログ形式についてはセクション8.2.3 を参照)。いずれかのCookieがなければ、値の代わりにダッシュ(’-’)を記録します。たとえば、ユーザーが新しいセッションへ移ると、サーバーが新しいCookieを割り当てるため、容易に検出できます。サーバーが意図せずクライアントに誤ったCookieを設定し、セッションが混線した場合も検出できます。
例:
“http-request"と"http-response"ルールで、Cookieを"txn"スコープの変数へ代入すれば、より高度な取得が可能です。“req.cook"と"res.cook"サンプル取得関数(セクション7.3.6 )で、リクエストまたはレスポンスからCookieの値を取り出し、“set-var"または"set-var-fmt"アクション(セクション4.3 )で変数へ代入できます。その後、カスタムlog-formatで、これらの変数を希望する位置へ配置できます(セクション8.2.6 )。
8.8. HTTPヘッダーの取得(従来の方法)
ヘッダーの取得は、上位のプロキシが設定した一意のリクエスト識別子、仮想ホスト名、User-Agent、POSTのContent-Length、リファラーなどの追跡に役立ちます。レスポンスでは、長さ、サーバーがキャッシュに求めた動作、リダイレクト先のオブジェクトの位置などの情報を調べられます。
ヘッダーの取得には二つの方法があります。現在の方法では、取得するヘッダー、または"req.hdr_names”、“req.hdrs”、“res.hdr_names”、“res.hdrs"が返す複合サンプルから変数を設定します(可能な方法すべてについてはセクション7.3.6 を参照)。“http-request"と"http-response"ルールセットの"set-var"と"set-var-fmt"アクション(セクション4.3 )で、これらを"txn"スコープの変数へ代入し、カスタムログ形式から参照できます(セクション8.2.6 )。HTTPヘッダーの取得には、この方法を推奨します。
http-requestルールと変数より前からある、従来の方法もあります。ログ形式を調整する必要がなく、古い"capture"ルールセットを使い、ログの記録だけでなく、HTTPトランザクションの間ずっとリクエストの情報を伝える代用手段としても、長年使われてきました。この節では、その方法を説明します。
従来のヘッダー取得には、フロントエンドの"capture request header"文と"capture response header"文を使います。詳細は、セクション4.2 の定義を参照してください。
リクエストヘッダーとレスポンスヘッダーを同時に含められます。存在しないヘッダーは空文字列として記録し、同じヘッダーが複数回現れる場合は、最後のものだけを記録します。リクエストヘッダーは、宣言した順序で波括弧’{‘と’}‘の中にまとめ、空白を入れずに縦線’|‘で区切ります。レスポンスヘッダーも同じ表現ですが、リクエストヘッダーのブロックの後に空白を置いて表示します。これらのブロックは、ログ内のHTTPリクエストの直前に表示します。
特別な場合として、TCPフロントエンドでHTTPヘッダーの取得を指定できます。その後、リクエストをHTTPバックエンドへ切り替える場合に、そのバックエンドが解析するヘッダーをログに記録できるようにするためです。
例:
8.9. ログの例
以下は、説明を添えた実際のログの例です。一部は手作業で作成しています。読みやすくするため、syslog部分は除いています。ログの読み解き方を説明することだけが目的です。
>>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \
px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \
"HEAD / HTTP/1.0"
=> 'telnet'で手入力した、長いリクエスト(6.5秒)です。サーバーは
147 msで応答し、セッションは正常に終了しました('----')。
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \
px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \
0/9 "HEAD / HTTP/1.0"
=> 上と同じですが、リクエストはグローバルキューで、他の9件の
リクエストの後ろに並び、1230 ms待ちました。
=> 長いデータ転送のリクエストです。"logasap"オプションを指定していたため、
データ転送の直前にログを出力しました。サーバーは14 msで応答し、
243バイトのヘッダーをクライアントへ送っています。接続の受け入れから
データの最初のバイトまでの合計時間は30 msです。
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \
px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \
"GET /cgi-bin/bug.cgi? HTTP/1.0"
=> プロキシがサーバーのレスポンスを遮断しました。"http-response deny"
ルールによる場合、レスポンスの形式が不正でHTTPに準拠しない場合、または
キャッシュされるおそれのある機密情報を遮断した場合があります。
レスポンスは"502 bad gateway"へ置き換えます。フラグ("PH--")から、
502を返すと判断したのは、サーバーではなくHAProxyだと分かります。
>>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \
px-http/`<NOSRV>` -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""
=> クライアントはリクエストを完了せず、プロキシがリクエストヘッダーを
待つ間("-R--")に、8.5秒後に自ら中断しました("C---")。
どのサーバーへも、何も送っていません。
>>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \
px-http/`<NOSRV>` -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""
=> クライアントはリクエストを完了せず、プロキシがリクエストヘッダーを
待つ間("-R--")に、50秒後にタイムアウトで中断しました("c---")。
どのサーバーへも何も送っていませんが、プロキシはクライアントへ
408応答コードを送れました。
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \
px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0
=> "option tcplog"で出力したログです。クライアントは5秒後に
タイムアウトしました("c----")。
>>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \
px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \
0/0 "HEAD / HTTP/1.0"
=> リクエストの完了に3秒かかり(おそらくネットワークの問題)、
サーバーへの接続は2秒ずつ4回試みた後で失敗しました('SC--')。
設定は'retries 3'で、再振り分けはありません(あれば"/+3"になります)。
クライアントへステータスコード503を返しました。このサーバーには115接続、
このプロキシには202接続、プロセス全体には205接続ありました。
既に確立した接続が多すぎるため、サーバーが接続を拒否した可能性があります。
18 - 9. 対応するフィルター
ここでは、公式にサポートするフィルターと、それぞれが受け付けるパラメーターを示します。コンパイルオプションによっては、利用できないフィルターもあります。利用可能なフィルターの一覧はhaproxy -vvに表示されます。
関連項目:“filter”
9.1. トレース
filter trace [name <name>] [random-forwarding] [max-fwd <max>] [hexdump]
引数:
このフィルターは、新しいフィルターを開発する際のひな形として使えます。すべてのコールバックを定義し、それぞれについて有用な情報を含むメッセージを標準エラーストリーム(stderr)へ出力します。ほかのフィルターの動作や、HAProxy自体の動作のデバッグに役立つ場合があります。
<random-parsing>や<random-forwarding>パラメーターを使うと、処理に遅延を加え、クライアントとサーバーの間で交換されるデータを解析するフィルターの動作をテストできます。
9.2. HTTP圧縮
filter comp-req
“compression"設定に従って、HTTPリクエストの圧縮を明示的に試みるフィルターを有効にします。“compression direction request"を暗黙に設定します。
filter comp-res
“compression"設定に従って、HTTPレスポンスの圧縮を明示的に試みるフィルターを有効にします。“compression direction response"を暗黙に設定します。
filter compression(非推奨)
後方互換性のための別名で、“comp-req"と"comp-res"の両フィルターを有効にするのと機能的に同等です。適切な動作を設定するには、“compression"キーワードを使わなければなりません。
HTTP圧縮は、HAProxy 1.7でフィルターへ移されました。HTTP圧縮を有効化・設定するには、引き続き"compression"キーワードを使わなければなりません。ほかのフィルターを使わない場合は、それだけで十分です。cacheやfcgi-appを有効にして使う場合も、それだけで十分です。この場合、圧縮は常にレスポンスがキャッシュへ保存された後に行われます。ただし、同じリスナー/フロントエンド/バックエンドで、cacheやfcgi-app以外のフィルターを一つでも使う場合は、filter行を明示してHTTP圧縮を有効にしなければなりません。これは、フィルターの評価順を決めるために重要です。
関連項目:“compression”、キャッシュフィルターについてはセクション9.4 、fcgi-appフィルターについてはセクション9.5 。
9.3. Stream Processing Offload Engine(SPOE)
filter spoe [engine <name>] config <file>
引数:
Stream Processing Offload Engine(SPOE)は、外部コンポーネントと通信するフィルターです。階層型アプリケーションで、ストリームに対する特定の処理を外部へ任せられます。外部コンポーネントと、それらとの間で交換する情報の大部分は、専用ファイルで設定します。また、HAProxy設定内に定義した専用のバックエンドも必要です。
SPOEは、独自のバイナリプロトコルであるStream Processing Offload Protocol(SPOP)を使って外部コンポーネントと通信します。
ストリームでSPOEを使うと、外部コンポーネントとの通信を担当する専用ストリームが作られます。元のストリームは、この"SPOE"ストリームの親ストリームになります。そのため、“SPOE"ストリームから元のストリームの変数を取得できます。詳細は、変数についてのセクション2.8 を参照してください。
SPOE設定とSPOP仕様の詳しい情報は、“doc/SPOE.txt"を参照してください。
9.4. キャッシュ
filter cache <name>
引数:
キャッシュは、キャッシュ可能なレスポンスを保存するためにフィルターを使います。キャッシュをいつ、どのように使うかは、HTTPルールの"cache-store"と"cache-use"で定義しなければなりません。デフォルトでは、対応するフィルターが暗黙に定義されます。fcgi-appやcompression以外のフィルターを使わない場合は、それだけで十分です。この場合、圧縮フィルターは常にキャッシュフィルターの後に評価されます。ただし、同じリスナー/フロントエンド/バックエンドで、compressionやfcgi-app以外のフィルターを一つでも使う場合は、filter行を明示してキャッシュを使わなければなりません。これは、フィルターの評価順を決めるために重要です。
関連項目:圧縮フィルターについてはセクション9.2 、fcgi-appフィルターについてはセクション9.5 、キャッシュについてはセクション6 。
9.5. Fcgi-app
filter fcgi-app <name>
引数:
FastCGIアプリケーションは、リクエスト経路ですべてのカスタムパラメーターを評価し、レスポンス経路でヘッダーを処理するためにフィルターを使います。<name>は、既存のfcgi-appセクションを参照しなければなりません。使うアプリケーションの定義には、“use-fcgi-app"ディレクティブを使うことを推奨します。デフォルトでは、対応するフィルターが暗黙に定義されます。cacheやcompression以外のフィルターを使わない場合は、それだけで十分です。ただし、同じバックエンドでcompressionやcache以外のフィルターを一つでも使う場合は、fcgi-app用のfilter行を明示しなければなりません。これは、フィルターの評価順を決めるために重要です。
関連項目:“use-fcgi-app”、圧縮フィルターについてはセクション9.2 、キャッシュフィルターについてはセクション9.4 、FastCGIアプリケーションについてはセクション10 。
9.6. OpenTracing
OpenTracingフィルターは、HAProxyで分散トレースを直接利用できるようにします。Datadog、Jaeger、Lightstep、Zipkinなど、対応するトレーサーへOpenTracing準拠のリクエストを送ることで動作します。トレーサーは推奨順ではなく、アルファベット順に記載している点に注意してください。
この機能は、HAProxyをUSE_OT=1でビルドした場合にのみ有効です。
OpenTracingフィルターは、HAProxyの設定で明示的に指定して有効にします。指定しなければ、OpenTracingフィルターはHAProxyの動作に一切関与しません。
filter opentracing [id <id>] config <file>
引数:
フィルターの動作、設定、使い方に関する詳しいドキュメントは、addons/otディレクトリにあります。
注意:OpenTracing自体が開発元による保守・サポートを終了しているため、新しい設計ではOpenTracingフィルターを使わないことを推奨します。OpenTracingは3.3で非推奨となり、3.5で削除されます。OpenTelemetryに基づく代替フィルターは3.4から利用でき、完全なビルド手順は現在、次の場所にあります。
9.7. 帯域制限
引数:
ストリーム単位でデータの転送速度を制限するには、帯域制限フィルターを使うことを推奨します。ひいては、リソースが消費するネットワーク帯域を制限できます。複数の帯域制限フィルターを使えます。たとえば、クライアントが帯域全体を使い切ってほかのクライアントに不利益を与えないよう、送信元アドレスごとの制限を設け、同じクライアントの複数接続を公平に扱うため、さらにストリームごとの制限を設けられます。
これらのフィルターの定義順序は重要です。一つのストリームで複数の帯域制限フィルターを有効にすると、定義順に適用されます。ほかのフィルターの定義順序も影響することを理解しておく必要があります。たとえば、HTTP圧縮フィルターが帯域制限フィルターの前か後かによって、制限が圧縮後のペイロードに適用されるかどうかが変わります。キャッシュフィルターについても同様です。
帯域制限フィルターには二種類あります。一つはデフォルトの制限をストリームごとに適用します。もう一つはスティックテーブルを使い、同じテーブルエントリーを共有するすべてのストリームに、制限を均等に分配します。
さらに、同じフィルターでも、使うキーワードに応じて、クライアントから受信してサーバーへ転送する入力データか、サーバーから受信してクライアントへ送る出力データのどちらを制限するかが変わります。入力データには"bwlim-in”、出力データには"bwlim-out"キーワードを使わなければなりません。いずれも、転送するデータにストリーム単位で帯域制限を適用します。
帯域制限は、接続単位ではなくストリーム単位で適用します。多重化プロトコル(H2、H3、FastCGI)では、同じ接続内のストリームに異なる制限を設定できます。
ストリームごとの帯域制限フィルターでは、デフォルトの期間と制限を定義しなければなりません。名前のとおり、ストリームの帯域制限レートを設定するためのデフォルト値です。ただし、この種類のフィルターに限り、TCP/HTTPの"set-bandwidth-limit"アクションでフィルターを有効にする際に、サンプル式でこれらの値を再定義できます。
共有の帯域制限フィルターでは、入力・出力のどちらのデータに適用するかに応じて、使うスティックテーブルに対応するバイトレート情報を保存しなければなりません。入力データを制限するには"bytes_in_rate(<period>)“カウンターを保存し、出力データを制限するには"bytes_out_rate(<period>)“カウンターを使わなければなりません。
最後に、帯域制限フィルターが、特定のストリームで一度に転送できる最小バイト数を設定できます。小さすぎる単位での転送を避け、CPU使用率を下げるために使うことを推奨します。値は慎重に決めなければなりません。小さすぎるとCPU使用率が高くなり、大きすぎるとレイテンシーが増える可能性があります。設定した帯域制限とも密接に関係します。制限値に近すぎると、一度に多くのバイトを消費するため、上限を超えないよう途中で一時停止が入る場合があります。適切な値はフィルターの設定に大きく依存します。まずTCP MSSの約2倍、通常は2896バイト程度から始め、実験して調整するのがよいでしょう。
例:
関連項目:“tcp-request content set-bandwidth-limit”、“tcp-response content set-bandwidth-limit”、“http-request set-bandwidth-limit”、“http-response set-bandwidth-limit”。
19 - 10. FastCGIアプリケーション
HAProxyは、Responder型のFastCGIアプリケーションへHTTPリクエストを送れます。この機能はHAProxy 2.1で追加されました。使うには、サーバーでFastCGIプロトコルを使うよう設定し(server行の"proto fcgi"キーワード)、そのサーバーを管理するバックエンドでFastCGIアプリケーションを設定して使用しなければなりません(proxyセクションの"use-fcgi-app"キーワード)。複数のFastCGIアプリケーションを定義できますが、一つのバックエンドが同時に使えるのは一つだけです。
HAProxyは、Responder型アプリケーションに関するFastCGI仕様の全機能を実装しています。特に、単一の接続上で複数のリクエストを多重化できます。
10.1. 設定
10.1.1. Fcgi-appセクション
fcgi-app <name>
<name>という名前のFastCGIアプリケーションを宣言します。有効な設定とするには、少なくともドキュメントルートを定義しなければなりません。
acl <aclname> <criterion> [flags] [operator] <value> ...
アクセスリストを宣言、または既存の宣言を補完します。
詳細は、セクション4.2 の"acl"キーワードと、ACLの使い方についてのセクション7 を参照してください。FastCGIアプリケーション用に定義したACLは、そのアプリケーション専用です。ほかのアプリケーションやプロキシからは使えません。同様に、ほかのセクションで定義したACLも、FastCGIアプリケーションからは使えません。ただし、定義済みACLは利用できます。
docroot <path>
リモートホスト上のドキュメントルートを定義します。<path>は、FastCGIパラメーターSCRIPT_FILENAMEとPATH_TRANSLATEDのデフォルト値の構築に使います。必須の設定です。
index <script-name>
スラッシュ("/")で終わるURIの後に追加するスクリプト名を定義し、FastCGIパラメーターSCRIPT_NAMEのデフォルト値を設定します。任意の設定です。
例:
log-stderr global
FastCGIアプリケーションが出力するSTDERRメッセージのログ記録を有効にします。
詳細は、セクション4.2 の"log"キーワードを参照してください。任意の設定です。デフォルトでは、STDERRメッセージは無視されます。
pass-header <name> [ { if | unless } <condition> ]
FastCGIアプリケーションへ渡すリクエストヘッダーの名前を指定します。後ろに任意でACLに基づく条件を付けられ、その場合は、条件が真のときだけ評価されます。
ほとんどのリクエストヘッダーは、すでに"HTTP_“の接頭辞付きでFastCGIアプリケーションから利用できます。そのため、このディレクティブが必要なのは、意図的に除外されているヘッダーを渡す場合だけです。現在は、“Authorization”、“Proxy-Authorization”、およびホップ単位のヘッダーが除外されています。
“Content-type"と"Content-length"ヘッダーは、すでにパラメーターへ変換されているため、FastCGIアプリケーションへ渡されることはありません。
path-info <regex>
URLデコード済みのパスからscript-nameとpath-infoを抽出する正規表現を定義します。<regex>は二つのキャプチャーを持つことができ、最初のものはスクリプト名、二番目はpath-infoを取得します。最初のキャプチャーは必須で、二番目は任意です。そのため、path-infoを無視して、パスからscript-nameだけを抽出できます。これは任意の設定です。未定義の場合はパスの照合を行わず、FastCGIパラメーターのPATH_INFOとPATH_TRANSLATEDには値を設定しません。
セキュリティ上の理由から、この正規表現を定義した場合、URLデコード後のパスに改行文字とヌル文字を含めることは禁止されます。これらがあると、HAProxyでの正規表現の実行方法の制限により、照合が必ず失敗するためです。そのため、URLデコード済みのパスにどちらかの文字が見つかった場合は、クライアントへエラーを返します。ここでは驚き最小の原則を適用しています。
例:
option get-values
接続管理に関する変数の取得を有効または無効にします。
HAProxyは、接続確立時にFCGI_GET_VALUESレコードを送信し、次の変数の値を取得できます。
* FCGI_MAX_REQS このアプリケーションが受け付ける同時リクエスト数の上限。
* FCGI_MPXS_CONNS このアプリケーションが接続の多重化を行わない場合は"0"、
行う場合は"1"。
この機能をサポートしないFastCGIアプリケーションもあります。また、応答を送った直後に接続を閉じるものもあります。そのため、このオプションはデフォルトで無効です。
FastCGIアプリケーションが受け付ける同時リクエスト数の上限は、接続に属する変数であることに注意してください。制限されるのは、接続ごとのストリーム数だけです。アプリケーション全体の負荷を制限する必要がある場合は、サーバーパラメーターの"maxconn"と"pool-max-conn"を設定しなければなりません。また、アプリケーションが接続の多重化をサポートしない場合、同時リクエスト数の上限は自動的に1に設定されます。
option keep-conn
応答を送信した後も接続を開いたままにするかどうかを、FastCGIアプリケーションへ指示します。
無効にすると、FastCGIアプリケーションはこのリクエストに応答した後、接続を閉じます。デフォルトでは有効です。
option max-reqs <reqs>
このアプリケーションが受け付ける同時リクエスト数の上限を定義します。
接続確立時に変数FCGI_MAX_REQSを取得すると、このオプションが上書きされる場合があります。また、アプリケーションが接続の多重化をサポートしない場合、このオプションは無視されます。デフォルトは1です。
option mpxs-conns
接続の多重化のサポートを有効または無効にします。
接続確立時に変数FCGI_MPXS_CONNSを取得すると、このオプションが上書きされる場合があります。デフォルトでは無効です。
set-param <name> <fmt> [ { if | unless } <condition> ]
このアプリケーションへ渡すFastCGIパラメーターを設定します。<fmt>で定義する値は、カスタムログ形式の規則に従わなければなりません(セクション8.2.6
「カスタムログ形式」を参照)。後ろに任意でACLに基づく条件を付けられ、その場合は、条件が真のときだけ評価されます。
このディレクティブで、デフォルトのFastCGIパラメーターの値を上書きできます。評価結果が空文字列になる場合、そのルールは無視されます。これらのディレクティブは、宣言順に評価されます。
例:
10.1.2. Proxyセクション
use-fcgi-app <name> バックエンドで使うFastCGIアプリケーションを定義します。
引数:
このキーワードは、バックエンド機能を持ち、FastCGIサーバーが少なくとも一つあるHTTPプロキシでのみ利用できます。FastCGIサーバーとHTTPサーバーを混在させることはできますが、十分な理由がない限り推奨しません(詳細は制限についてのセクション10.3 を参照)。一つのバックエンドに対して同時に定義できるアプリケーションは一つだけです。
バックエンドからFastCGIアプリケーションを参照すると、リクエストをFastCGIサーバーへ送らない場合でも、設定によっては一部の処理が行われる点に注意してください。パラメーターの設定や、アプリケーションへヘッダーを渡すためのルールが評価されます。
10.1.3. 例
10.2. デフォルトのパラメーター
Responder型のFastCGIアプリケーションは、CGI/1.1プログラムと同じ役割を持ちます。CGI/1.1仕様(RFC3875)では、いくつかの変数をスクリプトへ渡さなければなりません。そのため、HAProxyはそれらに加え、FastCGIアプリケーションでよく使われる変数も設定します。これらの変数はすべて上書きできますが、注意が必要です。
10.3. 制限
現在の実装には、いくつかの制限があります。最初は、一部のリクエストヘッダーをFastCGIアプリケーションへ見せない方法に関するものです。この処理は、接続確立前、バックエンド側のヘッダー解析時に行われます。この段階では、HAProxyはバックエンドがFastCGIアプリケーションを使うことは分かりますが、リクエストがFastCGIサーバーへ送られるかは分かりません。ヘッダーを隠すために、HTXメッセージから単純に削除します。そのため、最終的にHTTPサーバーへ送られた場合、そのサーバーはこれらのヘッダーを受け取りません。これが、同じバックエンドにFastCGIサーバーとHTTPサーバーを混在させることを推奨しない理由です。
同様に、“set-param"と"pass-header"のルールも、リクエストヘッダーの解析時に評価します。そのため、最終的にHTTPサーバーへ転送する場合も、常に評価されます。
“set-param"ルールを適用すると、HTXメッセージへ擬似ヘッダーが追加されます。そのため、HTTPヘッダーの書き換えと同様に、バッファーが満杯の場合は失敗することがあります。“set-param"ルールは、“http-request"ルールと領域を取り合います。
最後に、すべてのFastCGIパラメーターとHTTPヘッダーは、単一のFCGI_PARAMレコードで送ります。このレコードのエンコードは一度で行わなければならず、できなければ処理エラーを返します。つまり、エンコード後のFCGI_PARAMレコードは、バッファーのサイズを超えてはなりません。ただし、ここでは確保しておくべき予約領域はありません。
20 - 11. スティックテーブルとピア
HAProxyのスティックテーブルは、特定の型のキーにさまざまな情報やメトリクスを関連付け、最後の更新から一定期間保持する仕組みです。キーの値を行番号とし、各列が異なる項目を表す、複数列のテーブルの一行と考えることができます。
スティックテーブルは当初、クライアントとサーバーの間でセッションを持続させるため、その対応付けの情報を保存する目的で設計されました。クライアントが接続またはリクエストを送信すると、識別子(送信元アドレス、Cookie、URLパラメーター)でそのクライアントを識別し、選択したサーバーをその識別子に関連付けて、設定可能な期間スティックテーブルに保存します。これにより、同じクライアントからの後続アクセスを、アプリケーションセッションを作成した同じサーバーへ自動的に振り分けられます。
現在のスティックテーブルには、サーバー番号だけでなく、特定のクライアントの活動に関するメトリクス(リクエスト数/レート、接続数/レート、バイト数/レートなど)、任意のイベントカウンター(“General Purpose Counters”、略して"gpc")、特定の特徴を持つクライアントにラベルを付けるタグ(“General Purpose Tag”、略して"gpt")も保存できます。
スティックテーブルは、クライアントとサーバーの対応付けに使う"stick"ディレクティブ、メトリクスを集めるためにどのテーブルでどのキーを追跡するかを指定する"track-sc"ルール、さらに、指定したキーを即座に検索して特定のメトリクスやデータを取得する各種サンプル取得関数やコンバーターから参照できます。原則として、テーブルの更新(gpt/gpc/メトリクス)および対応付け情報の検索は、アクセスしたエントリーを更新して有効期限を延長します。一方、サンプル取得関数やコンバーターによる単なる検索は、データを取り出すだけで、エントリーの有効期限を延長しません。
この仕組みを拡張可能にし、HAProxyのリロードやフェイルオーバーにも対応させるため、セクション11.2 の"Peers"機構を通じて、“peers"と呼ぶ他のノードとスティックテーブルの更新を共有できます。ピアとの通信を細かく調整するため、一部のテーブルはピアからの情報を受信するだけにしたり、ピアからの更新を別のテーブルへ転送したりすることもできます。
最後に、スティックテーブルはプロキシセクション(フロントエンド、バックエンド)で"stick-table"キーワードを使って宣言できます。この場合、各セクションに一つだけ定義でき、名前はセクション名になります。また、peersセクションで"table"キーワードにテーブル名を続けて宣言することもでき、この場合は同じ"peers"セクションに複数のスティックテーブルを定義できます。複数のスティックテーブルが必要な場合、通常は、共有する予定であればpeersセクションで宣言するか、“stick-table"定義だけを含むバックエンドセクションを追加で作成する方法を推奨します。
11.1. stick-tableの宣言
プロキシセクション(“frontend”、“backend”、“listen”)と"peers"セクションにおけるスティックテーブルの宣言はよく似ています。違いは、peersセクションでは名前が必須で、“peers"オプションを取らない点です。
“frontend”、“backend”、“listen"セクションの場合:
stick-table type <type> size <size> [expire <expire>] [nopurge] [recv-only] [write-to
<wtable>] [srvkey <srvkey>] [store <data_type>]* [brates-factor <factor>] [peers
<peersect>]
“peers"セクションの場合:
table <name> type <type> size <size> [expire <expire>] [nopurge] [recv-only]
[write-to <wtable>] [srvkey <srvkey>] [store <data_type>]* [brates-factor <factor>]
引数(必須のものを先に記載し、以降はアルファベット順):
-
type
<type>この必須引数はキーの型を<type>に設定します。通常は単一の語ですが、独自の引数を持つ場合もあります。-
ip この型は避け、“ipv4"や"ipv6"など、より明確な型を使うことを推奨します。バージョン3.2より前は、IPv4を設定する唯一の方法でした。3.2では"ip"は"ipv4"の別名であり、“ipv4"を使うことを推奨します。将来のバージョンでは、“ip"は代わりに"ipv6"に対応するようになります。これは、3.2より前から3.2以降への移行を容易にすることだけを目的としています。
-
ipv4 この型で宣言したテーブルは、IPv4アドレスだけを保存します。この形式は非常にコンパクト(エントリーあたり約50バイト)で、ほぼオーバーヘッドなしで非常に高速にエントリーを検索・保存できます。主にクライアントの送信元IPアドレスの保存に使います。
-
ipv6 “type ipv6"で宣言したテーブルは、IPv6アドレスだけを保存します。この形式は非常にコンパクト(エントリーあたり約60バイト)で、ほぼオーバーヘッドなしで非常に高速にエントリーを検索・保存できます。主にクライアントの送信元IPアドレスの保存に使います。
-
integer “type integer"で宣言したテーブルは32ビット整数を保存します。たとえば、リクエストに含まれるクライアント識別子を表すことができます。
-
string [len
<len>] “type string"で宣言したテーブルは、最大<len>文字の部分文字列を保存します。パターン抽出機構が提供する文字列が<len>より長ければ、保存前に切り詰めます。マッチングでは、テーブル内の文字列と抽出したパターンの最大<len>文字を比較します。指定しない場合、文字列は自動的に32文字に制限されます。長さを増やすと、メモリ使用量に無視できない影響が出る場合があります。 -
binary [len
<len>] “type binary"で宣言したテーブルは、<len>バイトのバイナリブロックを保存します。パターン抽出機構が提供するブロックが<len>より大きければ、保存前に切り詰めます。サンプル式が提供するブロックが<len>より短ければ、0で埋めます。指定しない場合、ブロックは自動的に32バイトに制限されます。長さを増やすと、メモリ使用量に無視できない影響が出る場合があります。
-
-
size
<size>この必須引数は、テーブルに格納できるエントリー数の上限を<size>に設定します。この値はメモリ使用量に直接影響します。上記のキーサイズ、必要に応じて保存するメトリクス、文字列があればそのサイズに加えて、エントリーあたり約50バイトを見込んでください。サイズには、それぞれ2^10、2^20、2^30倍を表す接尾辞"k”、“m”、“g"を使えます。 -
expire
<delay>テーブル内のエントリーについて、最後の作成、’track-sc’による更新、または’stick match’や’stick on’ルールによるマッチからの最大保持期間を定義します。有効期限までの時間<delay>は、各種タイムアウトと同じ標準の時間形式で指定し、デフォルトの単位はミリ秒です。最大期間は24日を少し超える程度です。詳しくはセクション2.5 を参照してください。指定しない場合、セッションは自動的に期限切れになりませんが、テーブルが満杯になると、新しいエントリーの作成時に最も古いエントリーを削除します。有効期限を指定しない場合は、必ず"nopurge"パラメーターを使わないでください。注意:’table_*‘コンバーターは検索を行いますが、’track-sc’を必要としないため、アクセスによる有効期限の更新は行いません。 -
brates-factor
<factor>入出力バイトレートに適用する係数を指定します。個々のバイトの代わりに、バイトのブロックを数えます。内部ではレートを32ビットカウンターで表すため、期間あたり約40億に制限されます。このパラメーターを使うと、定義した期間でこの4Gの上限を超えるレートを扱えます。係数は0より大きく、1024以下でなければなりません。 -
nopurge テーブルが満杯になったとき、古いエントリーの削除を拒否することを示します。指定しない場合、HAProxyがエントリーを保存しようとした時点でテーブルが満杯なら、最も古いエントリーをいくつか削除し、新しいエントリーのための空きを作ります。通常はこれが望ましい動作です。特定の状況では、古いエントリーを削除する代わりに、新しいエントリーを拒否したい場合があります。たとえば、保存するデータ量がハードウェアの限界を大きく超え、接続済みのクライアントを拒否するより、新しいクライアントにアクセスを提供しないほうがよい場合です。このパラメーターを使う場合は、“expire"パラメーターを必ず適切に設定してください(上記参照)。
-
recv-only このテーブルを更新には使わず、関心のあるリモートピアからデータを取得する目的だけで使うことを示します。このキーワードを使うと、“conn_cur"などのローカル専用の値も取得できます。これらはローカルピアがテーブルに加えるローカル更新と競合するため、デフォルトでは学習しません。このオプションは、テーブルを更新する追跡ルールや方式に関与しないテーブル、つまり、情報の取得にだけ使うリモートテーブルにのみ意味があります。
-
peers
<peersect>作成、変更、更新したエントリーは、同期のためにセクション<peersect>のピアへ送信します。また、このセクションのピアから学習したキーも、テーブルに挿入または更新します。さらに起動時には、このセクションで"local peer"として指定した、古いプロセスのインスタンスからエントリーの学習を試みることがあります。 -
srvkey
<srvkey>スティックテーブル内で各サーバーをどのように識別するかを指定します。有効な値は"name"と"addr"です。“name"の場合は、サーバーの<name>引数(テンプレートで生成される場合もあります)を使います。“addr"の場合は、ポートを含む現在のネットワークアドレスでサーバーを識別します。“addr"は、ピア間で共有するスティックテーブルのサーバーアドレスをサービスディスカバリーで生成し、ある対応付けトークンに対してピア間で一貫して同じホストを使いたい場合に、特に便利です。 -
store
<data_type>スティックテーブルに追加情報を保存するために使います。ACLで利用して、スティックテーブルにマッチするクライアントの活動に関する各種条件を制御できます。ここで項目を指定するごとに、追加データを収めるため、各エントリーのサイズが増えます。一つのエントリーに複数のデータ型を保存できます。“store"キーワードの後にカンマ区切りで複数のデータ型を指定するか、“store"キーワードと一つ以上のデータ型を繰り返し指定できます。自動的に検出して有効にする"server_id"型を除き、保存するデータ型はすべて明示的に宣言しなければなりません。ACLが保存していないデータ型を参照した場合、そのACLは単にマッチしません。一部のデータ型には引数が必要で、型の直後に丸括弧で囲んで渡さなければなりません。対応するデータ型と引数は以下を参照してください。 -
write-to
<wtable>ピアからの更新を元のテーブルに加えて書き込む、別のスティックテーブルの名前を指定します。<wtable>は、定義中のテーブルと同じ型で、キーの長さも同じでなければならず、元のテーブル自身を転送先にはできません。元のテーブルがピア経由でエントリーの更新を受け取るたびに、HAProxyは対応する<wtable>のエントリーを更新しようとします。エントリーがなければ作成し、すでにあれば値とタイマーを更新します。リモートテーブルで処理済みの値が、ローカルの転送先テーブルの算術演算に干渉しないように、server_id、server_key、gptなど、算術演算に関与しない型だけを<wtable>に書き込みます(つまり、共有する累積カウンターが無限に増えることを防ぎます)。このオプションの一般的な用途は、ピアクラスター構成でサーバーへの固定のためのstickルールを使えるようにすることです。マッチするキーをリモートテーブルから学習できるためです。
“store"ディレクティブでエントリーに関連付けられるデータ型を以下に示します。多数のデータ型を保存すると、必要なメモリが大きくなる場合があることを忘れないでください。実際、以下の指標をすべて各エントリーに保存すると、エントリーあたり数百バイト、100万エントリーのテーブルでは数百MBが必要になる可能性があります。このため、各型について、引数の後の角括弧内におおよその保存サイズを示します。
引数:
-
bytes_in_cnt [8バイト] クライアントからサーバーへのバイト数です。このエントリーにマッチしたクライアントから受信した累積バイト数を数える、正の64ビット整数です。ヘッダーも含みます。写真や動画サーバーでアップロード機能の悪用を制限するために使えます。データがhaproxyへ入る時点で測定するため、カウントは圧縮の影響を受けません。
-
bytes_in_rate(
<period>) [12バイト] クライアントからサーバーへのバイトレートカウンターです。平均を測定する期間の長さをミリ秒で表す、整数パラメーター<period>を取ります。その期間の平均受信バイトレートを、期間あたりのバイト数で報告します。大量のデータを高速にアップロードするユーザーの検出に使えます。警告:大規模なアップロードでは、終了時にアップロード量を一度にカウントする場合があり、平均転送速度が滑らかにならず、急上昇することがあります。“option contstats"である程度平滑化できますが、完全ではありません。より公平に扱うにはbyte_in_cntの使用を推奨します。 -
bytes_out_cnt [8バイト] サーバーからクライアントへのバイト数です。このエントリーにマッチしたクライアントへ送信した累積バイト数を数える、正の64ビット整数です。ヘッダーも含みます。サイト全体を吸い上げるボットの悪用を制限するために使えます。データがhaproxyへ入る時点で測定するため、カウントは圧縮の影響を受けません。
-
bytes_out_rate(
<period>) [12バイト] サーバーからクライアントへのバイトレートカウンターです。平均を測定する期間の長さをミリ秒で表す、整数パラメーター<period>を取ります。その期間の平均送信バイトレートを、期間あたりのバイト数で報告します。大量のデータを高速にダウンロードするユーザーの検出に使えます。警告:大規模な転送では、終了時に転送量を一度にカウントする場合があり、平均転送速度が滑らかにならず、急上昇することがあります。“option contstats"である程度平滑化できますが、まだ完全ではありません。より公平に扱うにはbyte_out_cntの使用を推奨します。 -
conn_cnt [4バイト] 接続数です。このエントリーにマッチしたクライアントから受信した接続の総数を数える、正の32ビット整数です。接続が受け入れられたことを意味するのではなく、受信したことだけを示します。
-
conn_cur [4バイト] 現在の接続数です。このエントリーの同時接続数を保存する、正の32ビット整数です。着信接続がエントリーにマッチすると増え、接続が終了すると減ります。これにより、エントリーの正確な同時接続数をいつでも把握できます。ローカルの数を無視すると意味のない値になるため、この型はデフォルトでは他のピアから学習しません。ただし、recv-onlyと組み合わせると、ピアが観測した同時接続数を学習できます。
-
conn_rate(
<period>) [12バイト] 接続の頻度カウンターです。平均を測定する期間の長さをミリ秒で表す、整数パラメーター<period>を取ります。その期間の平均着信接続レートを、期間あたりの接続数で報告します。結果は整数で、ACLでマッチできます。接続を受け入れたか拒否したかは、測定に影響しません。 -
glitch_cnt [4バイト] フロント側の異常動作数です。フロント接続で報告された異常動作の累積数を数える、正の32ビット整数です。異常動作とは、プロトコルの観点から見て珍しい、または予期しないクライアントの動作であり、大きな欠陥を持つクライアント、場合によっては攻撃者を示す可能性があります。このため、このカウンターは、そのような状況でどう対応するかを決める助けになります。
-
glitch_rate(
<period>) [12バイト] 異常動作の頻度カウンターです。平均を測定する期間の長さをミリ秒で表す、整数パラメーター<period>を取ります。その期間のフロント側の平均異常動作レートを報告します。HAProxyがそのように判定したものについて、プロトコルの観点から珍しい、または予期しない動作をする、不具合のあるクライアントや攻撃者候補の検出に使えます。 -
gpc(
<nb>) [4 *<nb>バイト]<nb>個の汎用カウンター要素の配列です。正の32ビット整数の配列で、何でも数えることができます。多くの場合、エントリーの増分カウンターとして使い、たとえば上限に達したことを記録して何らかのアクションを起動します。ピアの更新メッセージをバッファー内に収められるよう、配列はgpc0からgpc99までの最大100要素に制限されます。いずれかを更新するたびにすべてのデータ/カウンターを送るため、カウンターが多いと、ピアプロトコルのデータサイズとトラフィック負荷が増えることを考慮してください。このdata_typeを使うと、同じテーブルで従来のdata_types ‘gpc0’と’gpc1’は使えません。‘gpc’配列のdata_typeでは、‘gpc0’と’gpc1’に関するすべてのサンプル取得関数とアクションが、この配列の先頭二要素に適用されます。 -
gpc_rate(
<nb>,<period>) [12 *<nb>バイト] ある期間における汎用カウンターの増分レートの配列です。要素は正の32ビット整数で、任意の用途に使えます。<gpc>と同じくイベントを数えますが、累積数を保持する代わりに、カウンターが増加するレートを保持します。主に、特定のイベント(特定のURLへのリクエストなど)の発生頻度を測定します。ピアの更新メッセージをバッファー内に収められるよう、配列は最大100要素に制限されます。gpc_rate(100,<period>)でgpc0_rateからgpc99_rateまでを保存できます。配列は1要素未満にできません。gpc0_rateだけを保存するにはgpc_rate(1,<period>)を使います。いずれかを更新するたびにすべてのデータ/カウンターを送るため、カウンターが多いと、ピアプロトコルのデータサイズとトラフィック負荷が増えることを考慮してください。このdata_typeを使うと、同じテーブルで従来のdata_types ‘gpc0_rate’と’gpc1_rate’は使えません。‘gpc_rate’配列のdata_typeでは、‘gpc0’と’gpc1’に関するすべての取得関数とアクションが、この配列の先頭二要素に適用されます。 -
gpc0 [4バイト] 最初の汎用カウンターです。正の32ビット整数で、任意の用途に使えます。主にエントリーへ特別なタグを付け、たとえば、今後のマッチングでも把握しておく必要がある特定の動作を検出したことを記録します。
-
gpc0_rate(
<period>) [12バイト] ある期間における最初の汎用カウンターの増分レートです。正の32ビット整数で、任意の用途に使えます。<gpc0>と同じくイベントを数えますが、累積数を保持する代わりに、カウンターが増加するレートを保持します。主に、特定のイベント(特定のURLへのリクエストなど)の発生頻度を測定します。 -
gpc1 [4バイト] 二番目の汎用カウンターです。正の32ビット整数で、任意の用途に使えます。主にエントリーへ特別なタグを付け、たとえば、今後のマッチングでも把握しておく必要がある特定の動作を検出したことを記録します。
-
gpc1_rate(
<period>) [12バイト] ある期間における二番目の汎用カウンターの増分レートです。正の32ビット整数で、任意の用途に使えます。<gpc1>と同じくイベントを数えますが、累積数を保持する代わりに、カウンターが増加するレートを保持します。主に、特定のイベント(特定のURLへのリクエストなど)の発生頻度を測定します。 -
gpt(
<nb>) [4 *<nb>バイト]<nb>個の汎用タグ要素の配列です。正の32ビット整数の配列で、任意の用途に使えます。主にエントリーへ特別なタグを付け、たとえば、今後のマッチングでも把握しておく必要がある特定の動作を検出したことを記録します。ピアの更新メッセージをバッファー内に収められるよう、配列は最大100要素に制限されます。gpt(100)でgpt0からgpt99までを保存できます。配列は1要素未満にできません。gpt0タグだけを保存するにはgpt(1)を使います。いずれかを更新するたびにすべてのデータ/カウンターを送るため、カウンターが多いと、ピアプロトコルのデータサイズとトラフィック負荷が増えることを考慮してください。このdata_typeを使うと、同じテーブルで従来のdata_type ‘gpt0’は使えません。‘gpt’配列のdata_typeでは、‘gpt0’に関するすべての取得関数とアクションが、この配列の先頭要素に適用されます。 -
gpt0 [4バイト] 最初の汎用タグです。正の32ビット整数で、任意の用途に使えます。主にエントリーへ特別なタグを付け、たとえば、今後のマッチングでも把握しておく必要がある特定の動作を検出したことを記録します。
-
http_req_cnt [4バイト] HTTPリクエスト数です。このエントリーにマッチしたクライアントから受信したHTTPリクエストの総数を数える、正の32ビット整数です。リクエストが有効かどうかは関係ありません。クライアント側でkeep-aliveを使う場合は、セッションとは異なる点に注意してください。
-
http_req_rate(
<period>) [12バイト] リクエストの頻度カウンターです。平均を測定する期間の長さをミリ秒で表す、整数パラメーター<period>を取ります。その期間の平均HTTPリクエストレートを、期間あたりのリクエスト数で報告します。結果は整数で、ACLでマッチできます。リクエストが有効かどうかは関係ありません。クライアント側でkeep-aliveを使う場合は、セッションとは異なる点に注意してください。 -
http_err_cnt [4バイト] HTTPリクエストのエラー数です。このエントリーにマッチしたクライアントに起因するHTTPリクエストのエラー総数を数える、正の32ビット整数です。不正または切り詰められたリクエスト、拒否またはtarpitしたリクエスト、認証失敗をエラーとして数えます。サーバーが4xxを返した場合も、クライアントが引き起こしたエラー(脆弱性スキャンなど)なので、そのリクエストをエラーとして数えます。
-
http_err_rate(
<period>) [12バイト] HTTPリクエストの頻度カウンターです。平均を測定する期間の長さをミリ秒で表す、整数パラメーター<period>を取ります。その期間の平均HTTPリクエストエラーレートを、期間あたりのリクエスト数で報告します(何をエラーと数えるかは上記のhttp_err_cntを参照)。結果は整数で、ACLでマッチできます。 -
http_fail_cnt [4バイト] HTTPレスポンスの失敗数です。このエントリーにマッチしたサーバーに起因するHTTPレスポンスの失敗総数を数える、正の32ビット整数です。不正または切り詰められたレスポンス、および501と505を除くすべての5xxレスポンスをエラーとして数えます。パスやURIと組み合わせ、サービスの障害を検出する用途を想定しています。
-
http_fail_rate(
<period>) [12バイト] HTTPレスポンスの失敗頻度カウンターです。平均を測定する期間の長さをミリ秒で表す、整数パラメーター<period>を取ります。その期間の平均HTTPレスポンス失敗レートを、期間あたりのリクエスト数で報告します(何を失敗と数えるかは上記のhttp_fail_cntを参照)。結果は整数で、ACLでマッチできます。 -
server_id [4バイト] リクエストを割り当てたサーバーの数値IDを保持する整数です。“stick match”、“stick store”、“stick on"ルールで使います。参照すると自動的に有効になります。学習した情報に基づく対応付けには制約があり、たとえば再起動時に情報を転送するようピアを適切に設定しない限り(設定を推奨)、学習した関連付けがすべて再起動で失われることを理解しておく必要があります。一般には、他の対応付けの仕組みを補うには有用ですが、常に唯一の仕組みとして適しているわけではありません。
-
sess_cnt [4バイト] セッション数です。このエントリーにマッチしたクライアントから受信したセッションの総数を数える、正の32ビット整数です。セッションとは、レイヤー4のルール(“tcp-request connection”)で受け入れられた接続です。
-
sess_rate(
<period>) [12バイト] セッションの頻度カウンターです。平均を測定する期間の長さをミリ秒で表す、整数パラメーター<period>を取ります。その期間の平均着信セッションレートを、期間あたりのセッション数で報告します。結果は整数で、ACLでマッチできます。
例:
関連項目:“stick match”、“stick on”、“stick store-request”、“track-sc”、時間形式についてはセクション2.5 、ピアについてはセクション11.2 、帯域制限についてはセクション9.7 、ACLについてはセクション7 。
11.2. ピアの宣言
スティックテーブル内の任意のデータ型のエントリーを、TCP接続を通じて、複数のHAProxyインスタンス間でマルチマスター方式で伝播できます。各インスタンスは、ローカルでの更新と挿入をリモートピアへ送ります。送られた値は、集約せずにリモートの値を上書きします。
例外は"conn_cur"データ型です。これはローカルの値を反映するものなので、デフォルトではピアから学習しません。以前のバージョンではデフォルトで同期していましたが、active-active構成では負の値になり、リロードやactive-passiveの切り替えでは値が増え続けることが知られていました。ローカルに存在する以上の接続数をローカルの値が反映してしまうためです。ただし、ピアからこの値を学習することが有用な構成もあります。たとえば、テーブルを書き込み操作や更新には使わず、データの学習や監視にだけ使う受動的なリモートテーブルの場合です。これを実現するには、テーブルの宣言に"recv-only"キーワードを追加します。いずれの場合も、監視システムが観測できるよう、“conn_cur"情報は常に送信します。
中断した交換は自動的に検出され、最後に確認した地点から再開します。また、ソフト再起動時には、新しいプロセスが他のピアへの接続を試みる前に、古いプロセスがこのTCP接続で新しいプロセスへ接続し、すべてのエントリーを送ります。これにより、リロード時のレプリケーションは非常に高速になり、大きなテーブルでも通常は一秒未満で完了します。
リモートでのサーバー識別にはサーバーIDを使うため、設定を同様にするか、少なくとも、すべての参加者で各サーバーに同じIDを強制することが重要です。
peers <peersect>
<peersect>という名前の新しいピア一覧を作成します。一つ以上のスティックテーブルから参照される独立したセクションです。
bind [<address>]:port [param*]
この"peers"セクションのローカルピアのバインドパラメーターを定義します。同じ"peers"セクション内で、この行と"peer"行を併用することはできません。
disabled
peersセクションを無効にします。このセクションに関するリッスンと同期の両方を無効にします。すべての"peers"参照をコメントアウトせずに、スティックテーブルの同期を無効にするために用意されています。
default-bind [param*]
アドレスを除く、ローカルピアのバインドパラメーターを定義します。
default-server [param*]
“peers"セクションのサーバーのデフォルトオプションを変更します。
引数:
関連項目:“server”、およびサーバーオプションについてのセクション5 。
enabled
“disabled"キーワードで無効にしたpeersセクションを、再び有効にします。
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]
“peers"セクションは、プロキシと同じ"log"キーワードをサポートし、“peers"リスナーについての情報をログに記録します。詳しくは、プロキシの"log"オプションを参照してください。
peer <peername> [<address>]:port [param*]
peersセクション内にピアを定義します。<peername>をローカルピア名(デフォルトはホスト名、またはコマンドラインの”-L"オプションやglobal設定の"localpeer"で強制した名前)にすると、HAProxyは指定アドレスでリモートピアからの着信接続を待ち受けます。それ以外の場合、アドレスはリモートピアに参加するための接続先を定義し、<peername>はサーバー側でリモートピアを識別・検証するため、プロトコルレベルで使われます。
ソフト再起動時、古いインスタンスはローカルピアのアドレスを使って新しいインスタンスに接続し、完全なレプリケーション(学習させる処理)を開始します。
すべてのピアでまったく同じpeers宣言を使い、ローカルピア名の変更にはコマンドライン引数”-L"またはglobal設定の"localpeer"だけを使うことを強く推奨します。これにより、すべてのピアで一貫した設定ファイルを維持しやすくなります。
アドレスパラメーターで環境変数を参照したい場合は、環境変数についてのセクション2.3 を参照してください。
注意:“peer"キーワードは、透過的に"server"キーワードへ置き換えられます(以下の"server"キーワードの説明を参照)。
server <peername> [<address>:<port>] [param*]
前述のとおり、“peer"キーワードを"server"キーワードへ置き換えると、5.2にあるトランスポート設定関連のすべての"server"パラメーターを使えます。対象のピアがローカルである場合、アドレスパラメーターを記述してはいけません。アドレスは"bind"行に記述しなければなりません(この"peers"セクションの"bind"キーワードを参照)。
多くの"server"パラメーターは"peers"セクションには関係しません。ピアは本質的に動的なホスト名解決やヘルスチェックをサポートしないため、“init_addr”、“resolvers”、“check”、“agent-check”、“track"などのパラメーターには対応していません。同様に、負荷分散や対応付けもないため、“weight"や"cookie"などのパラメーターは効果を持ちません。
例:
shards <shards>
一部の構成では、“peers"セクションで宣言した各ピアへスティックテーブルの全内容を送る代わりに、一部のピアへ内容を分散させたい場合があります。この場合、“shards"はスティックテーブル内容の分散に参加するピア数を指定します。サーバーパラメーター"shard"も参照してください。
table <tablename> type {ip | integer | string [len <length>] | binary [len <length>]}
size `<size>` [expire `<expire>`] [write-to `<wtable>`] [nopurge] [store `<data_type>`]*
[recv-only]
現在のセクションにスティックテーブルを設定します。この行は、他のセクションの"stick-table"キーワードとまったく同じように解析しますが、ここでは"peers"引数が不要で、テーブルを指定する必須の先頭パラメーターが追加されます。他のセクションとは異なり、“peers"セクションには複数の"table"行を記述できます(上記セクション11.1 にある"table"と"stick-table"キーワードの完全な定義も参照)。
また、異なる"peers"セクションで同じスティックテーブル名が衝突しないよう、“peers"セクションには独自のスティックテーブル名前空間がある点にも注意してください。内部では、スティックテーブル名の前に"peers"セクション名と’/‘を付けて処理します。設定ファイルの別の場所から、“peers"セクションで宣言したテーブルを参照する場合は、次のように、接頭辞を付けた名前を使わなければなりません。
CLIからスティックテーブルを参照する場合にも、接頭辞を付けた名前を使わなければなりません。
“peers"プロトコルでは、同じセクションに属する"peers"だけが相互に通信できるため、このような区別は不要です。複数の"peers"セクションで、同じ名前のスティックテーブルを宣言できます。ネットワーク上では、この短いスティックテーブル名を送信します。ただし、バックエンドとして宣言したテーブルと"peers"セクションで宣言したテーブルの名前の衝突を避けるため、接頭辞として’/‘だけを付けます。次の例は変わった構成ですが、サポートされています。
ここでは、“mypeers"セクションで宣言した"t1"テーブルのグローバル名は"mypeers/t1"です。バックエンドとして宣言した"t1"テーブルのグローバル名は"t1"です。一方、ピアプロトコルのレベルでは、前者の名前は”/t1”、後者はやはり"t1"です。
21 - 12. その他のセクション
以下のセクションは使用頻度が低く、通常は少数のパラメーターだけをサポートします。セクション同士に暗黙の関係はありません。いずれも単一のキーワードで開始します。“global"セクションより前に置くことはできません。SSL関連など、一部のサポートはビルドオプションによる場合があります。
12.1. トレース
デバッグのために、HAProxyのサブシステムでトレースを有効にできます。特定のサブシステムのデバッグメッセージを出力する、問題の診断に非常に有効なツールです。トレースはCLIで動的に設定できます。また、専用の"traces"セクションで、一部の設定を設定ファイルにあらかじめ定義できます。詳しくは管理ガイドを参照してください。あくまで複雑なデバッグ作業で使う開発者向けツールです。出力が多く、負荷もあるため、慎重に使ってください。開発者向けツールであるため、このセクションの後方互換性は保証しません。
traces
新しいtracesセクションを開始します。“traces"セクションは一つでも複数でも構いません。すべてのディレクティブを宣言順に評価し、後の指定が前の指定を上書きします。
trace <source> <args...>
“trace"サブシステムを設定します。それぞれを管理マニュアルで説明しており、構文もまったく同じです。“trace"コマンドが生成する出力は、このセクションの解析時に出力します。通常はエラーや警告ですが、一部の不完全なコマンドは、指定可能な選択肢を一覧表示する場合があります。このコマンドは通常の利用を想定しておらず、一般には、複雑なデバッグ作業中に開発者が使用を勧めます。トレースレベルや詳細度によっては、有効化により全体の性能が大幅に低下することを覚えておいてください。文の構文は管理マニュアルを参照してください。
例:
12.2. ユーザー一覧
認証と認可を受けたユーザーだけを許可することで、frontend/backend/listenセクションやhttp統計へのアクセスを制御できます。そのためには、少なくとも一つのuserlistを作成し、ユーザーを定義する必要があります。
userlist <listname>
<listname>という名前の新しいuserlistを作成します。独立した顧客の認証・認可データを保存するため、複数の独立したuserlistを使えます。
group <groupname> [users <user>,<user>,(...)]
現在のuserlistにグループ<groupname>を追加します。“users"キーワードに続けて、名前をカンマで区切った一覧を指定すると、このグループにユーザーを所属させることもできます。
user <username> [password|insecure-password <password>]
現在のuserlistにユーザー<username>を追加します。安全な(暗号化された)パスワードと、安全でない(暗号化されていない)パスワードの両方を使えます。暗号化パスワードはcrypt(3)関数で評価するため、システムの機能に応じて対応アルゴリズムが異なります。たとえば、現在のGlibcベースのLinuxは、MD5、SHA-256、SHA-512に加えて、従来のDESによるパスワード暗号化方式もサポートします。
注意:暗号化パスワードを使うと、リクエスト数とアルゴリズムによってはCPU使用率が大幅に増えることがあります。ハッシュを使う方式では、各リクエストのパスワードを、設定ファイルの値と比較する前に、選択したアルゴリズムで処理しなければなりません。現在のほとんどのアルゴリズムは、総当たり攻撃に耐えるため、意図的に計算コストを高くしています。平文パスワードにソルトを付けて一度ハッシュするだけでなく、何千回も繰り返します。これはすぐにHAProxy全体のCPU消費の大きな要因となり、アプリケーションのクラッシュを招くことさえあります。
ハッシュ関数の高いCPU使用率への対処方法として、ハッシュ関数のラウンド数(SHA系アルゴリズム)を減らすか、対応するアルゴリズムなら関数の"cost"を下げる方法があります。
補足として、musl(Alpine Linuxなど)の実装は、ハッシュ計算でglibcの実装より遅いことが知られているため、この点も考慮するとよいでしょう。
すべてのパスワードは通常の引数として扱うため、セクション2.2 の引用とエスケープの規則が適用されます。したがって、パスワードを単一引用符で囲むことを推奨します。
例:
両方の一覧は、機能的に同じである点に注意してください。
12.3. メール送信先
サーバーの状態が変わると、メールでアラートを送信できます。設定すると、mailersセクションで指定した各送信先へアラートを送ります。メールはLuaを通じて送信します(examples/lua/mailers.luaを参照)。
mailers <mailersect>
<mailersect>という名前の新しいメール送信先一覧を作成します。一つ以上のプロキシから参照する、独立したセクションです。
mailer <mailername> <ip>:<port>
mailersセクション内にメール送信先を定義します。
例:
timeout mail <time>
メール/接続を作成し、メールサーバーへ送信するために使える時間を定義します。未指定の場合、デフォルトは10秒です。最初のTCPハンドシェイクで少なくとも二つのSYN-ACKパケットを送れるよう、この値を4秒より大きくすることを推奨します。
例:
12.4. HTTPエラー
HTTPエラーのグループをグローバルに複数宣言し、後で任意のプロキシセクションに取り込めます。同じグループを複数箇所から参照でき、全体でも一部だけでも取り込めます。
http-errors <name>
<name>という名前の新しいhttp-errorsグループを作成します。一つ以上のプロキシが名前で参照できる、独立したセクションです。
errorfile <code> <file>
ファイルの内容をHTTPエラーコードに関連付けます。
引数:
詳細はセクション4 の"errorfile"キーワードを参照してください。
例:
12.5. リング
ログサーバーやトレースの出力先として使う、リングバッファーをグローバルに宣言できます。
ring <ringname>
<ringname>という名前の新しいリングバッファーを作成します。
backing-file <path>
リングの保存先を、通常のメモリ割り当てから、RAMにマッピングしたファイルに置き換えます。低速なクライアントをCLIに接続せずに、事後解析用のトレースやログを収集するのに便利です。新しい内容が古い内容を自動的に置き換えるため、常に最新の内容を利用できます。リングに書き込んだ内容は、プロセスの停止後にファイルから見えるようになります(通常は書き込み後すぐに見えますが、同期書き込みではないため保証はありません)。
このオプションを使うと、保存領域の先頭に置く"struct ring"のサイズ分だけ、利用可能な総領域が減ります。この構造体は内容の復元に必要です。ファイルは、起動ユーザーの所有権、モード0600、“size"ディレクティブで設定したサイズで作成します。ディレクティブの解析時(したがって設定チェック時にも)、既存の空でないファイルは、まず接尾辞”.bak"を付けた名前に変更し、以前の”.bak"ファイルは削除します。これにより、プロセスを即座にリロードや再起動しても、貴重なデバッグ情報を消さずに済み、管理者が新しい”.bak"ファイルを見つけて、必要なら保管する時間を確保できます。したがって、クラッシュ直後は<path>のファイルに最新情報があり、サービスを再起動した後は”<path>.bak"にあります。必要な総保存容量はリングサイズの倍になります。ファイルのローテーション失敗は黙って無視するため、バックアップファイルが不要なら、書き込み権限のないディレクトリーにファイルを置くだけで防げます。
警告:この機能は安定性とセキュリティに影響します。第一に、低速なデバイス(物理ハードディスクなど)をリングの保存先にすると、アクセス時に体感できる遅延が生じ、多数のスレッドが競合するとパニックさえ起こる可能性があります。第二に、外部プロセスが領域を変更すると、haproxyがクラッシュしたり、自身のメモリの一部をトレースで上書きしたりする可能性があります。第三に、リングが埋まる前にファイルシステムが満杯になると、リングへの書き込みでプロセスがクラッシュする場合があります。
このリング内の情報は構造化されており、テキストエディターで直接読めるものではありません(大部分がかろうじて読めそうに見えても同じです)。このファイルの出力は、開発者だけを対象としています。
description <text>
リングの説明を指定する任意の文字列です。CLIに表示します。デフォルトでは、このフィールドに<name>を再利用します。
format <format>
リングバッファーにイベントを保存する形式です。
引数:
maxlen <length>
形式を整えたヘッダーを含め、リングに保存するイベントメッセージの最大長です。<length>より長いメッセージは、その長さに切り詰めます。
server <name> <address> [param*]
リングバッファーからメッセージを転送するsyslog TCPサーバーを設定します。5.2にあるすべての"server"パラメーターをサポートしますが、一部は"ring"セクションには関係しません。重要なのは、一つのリングに複数のサーバーを追加する理由はほとんどないことです。すべてのサーバーがリング内容のまったく同じコピーを受け取るため、リングは最も遅いサーバーの速度で進みます。一つでも応答しないサーバーがあると、古いメッセージを削除できず、新しいメッセージをリングへ挿入できなくなることがあります。複数のサーバーへ送る正しい方法は、同じリングに複数のサーバーを接続することではなく、ログサーバーごとに別のリングを使うことです。送信プロトコルの設定には、専用のサーバーディレクティブ"log-proto"を使います。
size <size>
リングバッファーのサイズをバイトで指定します。任意で、デフォルトはBUFSIZEです。
timeout connect <timeout>
サーバーへの接続試行が成功するまで待つ時間の上限を設定します。
引数:
timeout server <timeout>
送信待ちのデータが出力バッファーにとどまる時間の上限を設定します。
引数:
例:
12.6. ログ転送
ログ転送セクションを一つ以上宣言できます。HAProxyは、受信したすべてのログメッセージを、ログサーバーの一覧へ転送します。
log-forward <name>
<name>で識別する新しいログ転送プロキシを作成します。
backlog <conns>
接続を受け入れる際の、希望するリッスンバックログのおおよそのサイズを、システムへ示します。
bind <addr> [param*]
転送対象のメッセージを受信する、ストリームログリスナーを設定します。5.1の"bind"パラメーターをSSL関連も含めてサポートしますが、“alpn"などはTCP上のsyslogには関係しない場合があります。リスナーは、rfc-6587で定義する"Octet Counting"と"Non-Transparent-Framing"の両モードをサポートします。
dgram-bind <addr> [param*]
転送対象のメッセージを受信する、データグラムログリスナーを設定します。アドレスはIPv4またはIPv6形式で、その後にポートが必須です。5.1の"bind"パラメーターのうち、“interface”、“namespace”、“transparent"などをサポートします。それ以外はUDP/syslogには関係しないため、黙って無視します。
log global
転送先のログサーバーを設定します。詳細はプロキシのドキュメントを参照してください。形式を指定しない場合、HAProxyは受信ログの形式を維持しようとします。設定したfacilityは、受信メッセージにfacilityがなく、送信形式で必須である場合を除き、無視します。入力形式にタイムスタンプがなく、出力形式にそのフィールドがある場合、HAProxyはローカルの日付を使います。
例:
maxconn <conns>
ログ転送プロキシの同時接続数の上限を設定します。デフォルトは10です。
timeout client <timeout>
クライアント側の最大無通信時間を設定します。
option assume-rfc6587-ntf
受信するTCPログストリームを、常に非透過フレーミングとして扱うようHAProxyに指示します。フレーミング処理を単純化し、メッセージを一貫して扱えるようにします。特に、先頭文字が正しく形成されていない場合に便利です。
option dont-parse-log
syslogメッセージを解析・再構成せずに中継します。従来の形式に従わないメッセージの転送に便利です。元のメッセージ内容を保持するため、転送先ログターゲットのformat raw設定と併用するべきです。
option host { replace | fill | keep | append }
送信するrfc3164またはrfc5424メッセージのsyslog hostnameフィールドについて、log-forwardセクションで使うホスト処理方針を設定します。
replace 入力メッセージのhostnameフィールドに値がある場合は、
送信者の送信元IPアドレスで置き換えます。
hostnameフィールドに値がない場合(rfc5424入力が'-'の場合や、
rfc3164またはrfc5424に準拠しないメッセージの場合)も、
送信者の送信元IPアドレスをhostnameフィールドに使います。
fill 入力メッセージのhostnameフィールドに値がある場合は、維持します。
値がない場合(rfc5424入力が'-'の場合や、rfc3164またはrfc5424に
準拠しないメッセージの場合)は、送信者の送信元IPアドレスを
hostnameフィールドに使います。
(デフォルトです)
keep 入力メッセージのhostnameフィールドに値がある場合は、維持します。
値がない場合は、'localhost'(rfc3164)または'-'(rfc5424)に設定します。
append 入力メッセージのhostnameフィールドに値がある場合は、
カンマと、それに続けて送信者のIPアドレスを追加します。
値がない場合は、送信者の送信元IPアドレスを使います。
上記のすべてのオプションで、送信者の送信元IPアドレスを取得できない場合(UNIX/ABNSソケットなど)は、結果的に"keep"の方針になります。
このオプションが関係するのは、転送先のログ形式がrfc3164またはrfc5424の場合だけです。それ以外では、設定しても見える効果はありません。
12.7. 証明書ストレージ
HAProxyは、設定で使う証明書を読み込み、保持するため、内部ストレージ機構を使います。“crt-store"セクションで、証明書の定義と、そこへ読み込むファイルを設定できます。証明書の定義は、設定内の他の場所で使うより前に記述しなければなりません。
crt-store [<name>]
“crt-store"は、任意で名前を引数に取ります。名前を指定した場合、そのストアの各証明書は、”@<name>/<crt>“または”@<name>/<alias>“で参照しなければなりません。
証明書ストレージ内のファイルは、CLIで動的に更新することもできます。管理ガイドのセクション9.3 にある"set ssl cert"を参照してください。
“crt-store"セクションは、次のキーワードをサポートします。
- crt-base
- key-base
- load
crt-base <dir>
“crt"ディレクティブに相対パスを使う場合、SSL証明書を取得するデフォルトのディレクトリーを指定します。絶対パスを指定すると、そちらを優先し、“crt-base"を無視します。crt-store内で使う場合は、globalセクションのcrt-baseを無視します。
key-base <dir>
“key"ディレクティブに相対パスを使う場合、SSL秘密鍵を取得するデフォルトのディレクトリーを指定します。絶対パスを指定すると、そちらを優先し、“key-base"を無視します。crt-store内で使う場合は、globalセクションのkey-baseを無視します。
load [crt <filename>] [param*]
証明書ストレージにSSLファイルを読み込みます。パラメーター一覧は「12.7.1. 読み込みオプション」を参照してください。
例:
12.7.1. 読み込みオプション
証明書ストレージにSSLファイルを読み込みます。loadキーワードは、以下に示す複数のパラメーターを取れます。これらのキーワードはcrt-listでも使えます。
crt <filename>
必須の引数で、PEMを読み込みます。PEMには公開証明書が必須で、中間証明書や秘密鍵を含めることもできます。このファイルに秘密鍵がない場合は、“key"キーワードで指定できます。
acme <string>
指定した証明書のACMEプロトコルを設定します。実験的機能で、globalセクションに"expose-experimental-directives"が必要です。
crt-storeで"acme"キーワードを使うと、ディスク上に既存の証明書がなくても起動できます。ACME証明書を生成するまで、代わりに一時的な鍵ペアを使います。この動作はcrt-store専用で、crt-list行やssl-f-use行では、先にcrt-storeを宣言しない限り、同じことはできません。
セクション12.8 (“ACME”)と、このセクションの"domains"も参照してください。
alias <string>
任意の引数です。証明書に別名を付け、設定内でその名前で参照できるようにします。設定内の他の場所から別名を呼び出す場合は、接頭辞’@/‘を付けなければなりません。
domains <string>
ACME証明書で使うドメインの一覧を設定します。最初のドメインをCNに使います。一覧ではドメインをカンマで区切ります。
セクション12.8 (“ACME”)と、このセクションの"acme"も参照してください。
例:
ips <string>
ACME証明書にIP SANとして含めるIPアドレスの一覧を設定します。一覧ではIPアドレスをカンマで区切ります。
IPアドレスを含む証明書の生成には、“shortlived"プロファイルが必要な場合があります。
セクション12.8 (“ACME”)と、このセクションの"acme”、“domains"も参照してください。
例:
key <filename>
任意の引数です。PEM形式の秘密鍵を読み込みます。“crt"ですでに秘密鍵を定義している場合は、上書きします。
ocsp <filename>
任意の引数で、DER形式のOCSPレスポンスを読み込みます。CLIで更新できます。
issuer <filename>
任意の引数です。PEM形式のOCSP発行者証明書を読み込みます。OCSPレスポンスがどの証明書に適用されるかを識別するには、発行者の証明書が必要です。“crt"ファイルにない場合は、この引数で別のファイルから読み込めます。
sctl <filename>
任意の引数です。Certificate Transparency(RFC6962)のTLS拡張を有効にします。ファイルには、RFCで規定する有効なSigned Certificate Timestamp Listが必須です。基本構文を確認するためにファイルを解析しますが、署名は検証しません。
ocsp-update [ off | on ]
‘on’でOCSPレスポンスの自動更新を有効にし、それ以外で無効にします。デフォルトは’off’です。bind行でOCSP自動更新を有効にするには、crt-storeのこのオプション、またはglobalオプション"tune.ocsp-update.mode"を使えます。同じ証明書を複数のcrt-listで使い、‘ocsp-update’の値が異なる場合は、エラーになります。同様に、bind行でglobalオプションを継承する証明書に、crt-listで互換性のない’ocsp-update’を明示的に設定した場合も、同じエラーになります。
例:
crt-listで有効にする設定例です。
haproxy.cfg:
haproxy.list:
crt-storeで有効にする設定例です。
haproxy.cfg:
このオプションが’on’の場合、フロントエンドの証明書にOCSP URIが見つかるたびに、OCSPレスポンスの取得を試みます。このモードの唯一の制限は、OCSP certidを構築するために、証明書の発行者が分かっている必要があることです。各OCSPレスポンスを少なくとも一時間に一度更新し、有効期限がその一時間より早い場合は、さらに頻繁に更新します。ただし、有効期間が非常に短いレスポンスや、‘Next Update’がまったくないレスポンスを更新しすぎないよう、最短更新間隔は5分です。この固定の下限により、自動更新が’on’の場合、初期化時に読み込んだOCSPレスポンスは、期限がnow+5mより前でも、少なくとも5分経過するまで更新しません。初期化時に読み込むレスポンスは有効でなければならず(有効期限が未来であること)、初期化後のそれほど短い時間に期限切れになる可能性は低いため、通常は大きな問題にはならないはずです。一方、OCSP URIがあり、OCSPレスポンスがない証明書では、このオプションを’on’にすると、初期化直後に自動取得します。デフォルトの最短・最長間隔(それぞれ5分と1時間)は、globalオプション"ocsp-update.maxdelay"と"ocsp-update.mindelay"で設定できます。
自動更新タスク、またはCLIの"update ssl ocsp-response"によってOCSPレスポンスを更新するたびに、専用のログ行を出力します。専用形式のヘッダー”<OCSP-UPDATE>“に続けて、対応するフロントエンド証明書のパス、数値の更新ステータス、テキストの更新ステータス、そのレスポンスの更新失敗回数、更新成功回数というOCSP固有の情報を出力します。エラーコードとメッセージの全一覧は、CLIの"show ssl ocsp-updates"を参照してください。この行は、更新の成功・失敗にかかわらず出力します。OCSPリクエスト/レスポンスは、dontlog-normalを設定したhttp_clientインスタンスで送受信し、OCSPレスポンダーに到達できない場合などのエラー時には、通常のHTTPログ形式を使います。そのようなエラーが起きると、通常のOCSPログ(テキストステータスはおそらく"HTTP error”)とともに、HTTP関連情報を含む別のログ行を出力します。つまり、OCSPレスポンダーに到達できない場合など、純粋なHTTPエラーでは、通常のHTTPログ形式の行も追加で出力します。以下に、まずOCSP更新に成功したログ行、次に異なる二行を含むHTTPエラーの例を示します(読みやすさのため、行を分割し、URLを短くしています)。
トラブルシューティング:Let’s Encrypt証明書でよくあるエラーとして、DNSがIPv6アドレスを返すのに、システムに有効な送信用IPv6ルートがない場合があります。その場合は、適切なルートを作成するか、globalセクションに"httpclient.resolvers.prefer ipv4"を設定できます。“OCSP response check failure"の場合は、指定した発行者証明書が有効か確認してください。「汎用的な」エラーメッセージの後の括弧内に、さらに詳しいメッセージが表示されることもあります。“OCSP response check failure"や"Error during insertion"で起こり得ます。
jwt [ off | on ]
‘on’にすると、この証明書を"jwt_verify_cert”、“jwt_decrypt_cert”、“jwt_decrypt"コンバーターによるJWT検証または復号に使えます。デフォルトは’off’です。
証明書で’on’にすると、CLIの"del ssl cert"は動作しません。証明書を削除するには、SSLハンドシェイクにもJWT検証にも使われていない必要があります。
このオプションは、CLIの"add ssl jwt"と"del ssl jwt"で実行時に変更できます。“show ssl jwt"も参照してください。
generate-dummy [ off | on ]
‘on’にすると、解析時に秘密鍵とその自己署名証明書を生成できます。たとえば、テスト中に使える証明書がない場合に便利です。“keytype”、“bits”、“curves"で秘密鍵を調整できます。未指定時のデフォルトは’off’です(“keytype”、“bits”、“curves"も参照)。
keytype [ RSA | ECDSA ]
解析時に自己署名証明書を生成するための秘密鍵の型を選べます。その証明書で"generate-dummy"を’on’にした場合に使います。未指定時のデフォルトは’RSA’です(“generate-dummy"も参照)。
bits <number>
自己署名証明書で"generate-dummy"が’on’、“keytype"が’RSA’の場合、RSA自己署名証明書を生成するビット数を設定します。未指定時のデフォルトは2048です(“generate-dummy"も参照)。
curves <string>
自己署名証明書で"generate-dummy"が’on’、“keytype"が’ECDSA’の場合、曲線を設定します。デフォルトは’P-384’です。
12.8. ACME
acme <name>
ACMEプロトコルは"acme"セクションで設定できます。セクションは”<name>“を引数に取り、証明書をこのセクションに関連付けるために使います。
ACMEセクションでは、HAProxyをACMEv2クライアントとして設定できます。実験的機能であるため、使うにはglobalセクションに"expose-experimental-directives"が必須です。
HAProxyのwikiにガイドがあります。 https://github.com/haproxy/wiki/wiki/ACME:--native-haproxy
- 現在、この機能が対応するチャレンジはhttp-01、dns-01、dns-persist-01に限られます
http-01はHAProxyがすべて処理しますが、dns-01とdns-persist-01には、DNSプロバイダーのAPIと通信するため、dataplaneAPIまたは別のサードパーティーツールが必要です。dns-persist-01ではTXTエントリーを一度設定すればよいため、ツールを使わず手動で設定することもできます。
- ディスク上に既存の証明書がなくても起動できます。そのためには、
証明書をcrt-storeで設定しなければなりません。crt-storeで"acme"キーワードを使うと、ACME証明書を生成するまで一時的な鍵ペアを使います。
- 現在のHAProxyのアーキテクチャーはノンブロッキングモデルであり、ディスクへのアクセスは
設定の読み込み後には行わない前提です。イベントループをブロックし、同じスレッドのトラフィックを止める可能性があるためです。つまり、HAProxyが生成した証明書と鍵は、外部から統計ソケットの"dump ssl cert"を使って書き出す必要があります。dataplaneAPI、またはadmin/cli/ディレクトリーにあるhaproxy-dump-certsスクリプトで、証明書の書き出しを自動化できます。
ACMEスケジューラーはHAProxyの起動時に開始し、証明書を順に確認します。notAfterがcurtime + (notAfter - notBefore) / 12を過ぎた場合、またはnotBeforeが未定義なら7日を基準に、ACME更新タスクを開始します。その後、スケジューラーは休止し、12時間後に起動します。“acme renew"で更新タスクを手動で開始することもできます。管理ガイドの"acme status"も参照してください。
ACMEセクションでは、次のキーワードを使えます。
account-key <filename>
アカウント鍵のパスを設定します。鍵はHAProxyの起動前に生成する必要があります。accountキーワードがなければ、acmeセクションは、セクション名を使った”<name>.account.key"を読み込もうとします。ファイルがなければ、acmeセクションのパラメーターを使ってHAProxyが生成します。
opensslでRSA秘密鍵を手動生成することもできます。
ECDSA鍵の場合:
acme-vars <string>
外部のDNS設定ツール(dataplaneAPIなど)へ、“dpapi"出力先を通じて任意の変数を渡します。意味はツール固有なので、DNS設定ツールのドキュメントを参照してください。
このキーワードが意味を持つのは、チャレンジの型が"dns-01"または"dns-persist-01"の場合だけです。
関連項目:“challenge”、“provider-name”
bits <number>
RSA証明書を生成するビット数を設定します。デフォルトは2048です。マシンの性能に対して大きすぎる値を設定すると、警告が出る場合があります(“warn-blocked-traffic-after"で設定できますが、トラフィックを長時間ブロックするとwatchdogが作動する可能性があります)。
challenge <string>
チャレンジの型を引数に取り、http-01、dns-01、dns-persist-01のいずれかでなければなりません。未指定時のデフォルトはhttp-01です。
dns-persist-01はdraft-ietf-acme-dns-persistを実装します。dns-01とは異なり、”_validation-persist.<domain>“に静的なTXTレコードを使います。一度設定すれば、更新のたびに変わることはありません。レコードにはアカウントURIが必須で、任意のポリシーも含められます。このチャレンジでは、更新のたびにDNSプロバイダーAPIへの書き込み権限を必要としません。
challenge-ready <value>[,<value>]*
dns-01チャレンジの検証準備ができたことをACMEサーバーへ通知する前に、満たさなければならない条件を設定します。次の値を指定できます。
複数の値をカンマで組み合わせられます。複数の条件を指定した場合、まずCLIの確認(“cli”)を待ち、次に最初の遅延(“delay”)を適用し、最後にDNS事前確認(“dns”)を行います。
このオプションは、dns-01とdns-persist-01のチャレンジだけに対応します。
“challenge"が"dns-01"で、このオプションを設定しない場合、デフォルトは"cli"です。
“challenge"が"dns-persist-01"で、このオプションを設定しない場合、デフォルトは"dns,delay"です。
“challenge"が"dns-persist-01"の場合、challenge-ready条件を評価する前に、まず、すぐに先へ進めるかを判断するDNS確認を必ず行います。”_validation-persist.<domain>“のTXTレコードは一度設定すれば更新の間も変わらないため、HAProxyは更新時に、そのレコードがすでに存在するかを確認します。すべてのドメインで成功すると、challenge-readyの手順(cli、delay、dns)を経ずに、直ちにチャレンジを送信します。確認に失敗すると、通常のchallenge-readyの流れに戻ります。
例:
contact <string>
CA内でアカウント鍵に関連付ける連絡先メールアドレスです。
curves <string>
鍵の型がECDSAの場合に、曲線を設定します。デフォルトはP-384です。
directory <string>
このacmeセクションが使うCAのディレクトリーURLを設定します。デフォルトURLがないため、必須です。
例:
dns-delay <time>
“challenge-ready"の"delay"条件と"dns"条件で使う遅延を設定します。値は、HAProxyの時間形式(“5m”、“300s"など)で指定します。デフォルトは30秒です。
役割は、使う"challenge-ready"条件によって異なります。
名前解決は権威ネームサーバーではなく、設定した"default” resolversセクションを通じて行います。したがって、リゾルバー側のDNSキャッシュの影響が残る場合があります。
dns-timeout <time>
“challenge-ready"に"dns"を含める場合、チャレンジを中止する前にTXTレコードの解決に成功するまでの制限時間を設定します。値は、HAProxyの時間形式(“10m”、“600s"など)で指定します。デフォルトは600秒です。
タイマーは、最初の"dns-delay"の後、初回のDNS解決を開始した時点から動きます。次の解決試行がタイムアウト後になる場合、エラーとしてチャレンジを中止します。これにより、DNSの伝播に失敗しても、再試行が無限に続くことを防ぎます。
関連項目:“dns-delay”
keytype <string>
生成する鍵の型を設定します。“RSA"または"ECDSA"を指定できます。ECDSAの"curves"と、RSAの"bits"数も設定できます。デフォルトではEC384鍵を生成します。
map <map>
トークン(キー)とサムプリント(値)を保存するマップを設定します。複数のアカウントを使う場合、チャレンジへ応答するのに便利です。acmeタスクは、チャレンジの検証前にエントリーを追加し、タスクの終了時に削除します。
profile <string>
newOrderリクエストに"profile"フィールドを含め、CAへ特定の証明書プロファイルを要求します。draft-ietf-acme-profilesを実装します。
プロファイル名は、CA固有の短い識別子(“classic”、“shortlived"など)です。設定すると、名前をそのままnewOrderのJSONペイロードで送信します。CAは、そのプロファイルに未対応なら、要求を無視することも、エラーを返すこともできます。未設定ならprofileフィールドを含めず、CAはデフォルトの発行ポリシーを使います。
Let’s Encryptのプロファイルについては、https://letsencrypt.org/docs/profiles/ を参照してください。
例:
provider-name <string>
外部のDNS設定ツール(dataplaneAPIなど)へ"dpapi"出力先を通じて渡す、DNSプロバイダー名を設定します。受け付ける値はツール固有なので、DNS設定ツールのドキュメントを参照してください。
このキーワードが意味を持つのは、チャレンジの型が"dns-01"または"dns-persist-01"の場合だけです。
関連項目:“challenge”、“acme-vars”
reuse-key { on | off }
“on"にすると、HAProxyは新しい秘密鍵を生成せず、以前の鍵を保持します。秘密鍵のローテーションを推奨します。このオプションを有効にする場合は、定期的に手動で鍵を再生成することを推奨します。
2048を超えるRSA鍵は生成に時間がかかり、生成中のスレッドを遅くする可能性があるため、その場合に便利です。
ACMEサーバーのキャッシュを使う場合、同じ鍵の利用が役立つことがあります。現在の鍵に対応する有効な証明書を取得しやすくなります。
デフォルト設定は"off"です。
例:
eab-key-id <filename>
EAB鍵IDファイルのパスを設定します。認証情報はCAが提供し、HAProxyを起動する前に、指定したパスに置かなければなりません。アカウント作成時にだけ使います。
ファイルには、プレーンなASCII文字列が必須です。
EAB認証情報が必要なのは、ACMEアカウントの初回作成時だけです。その後は、設定から削除するか、ファイルを空にできます。空のファイルは黙って無視します。末尾の改行以外の空白文字は無視しません。
関連項目:“eab-mac-key”、“eab-mac-alg”
eab-mac-key <filename>
EAB MAC鍵ファイルのパスを設定します。認証情報はCAが提供し、HAProxyを起動する前に、指定したパスに置かなければなりません。アカウント作成時にだけ使います。
ファイルには、base64urlで符号化したMAC鍵が必須です。
EAB認証情報が必要なのは、ACMEアカウントの初回作成時だけです。その後は、設定から削除するか、ファイルを空にできます。空のファイルは黙って無視します。末尾の改行以外の空白文字は無視しません。
関連項目:“eab-key-id”、“eab-mac-alg”
eab-mac-alg { HS256 | HS384 | HS512 }
EAB署名に使うMACアルゴリズムを設定します。デフォルトはHS256です。EAB MAC鍵は、指定したMACアルゴリズムをサポートできる十分な長さが必要です。すべてのCAがHS256以外のアルゴリズムに対応するわけではありません。
関連項目:“eab-key-id”、“eab-mac-key”
12.9. ヘルスチェック
設定全体のサーバーから利用できるヘルスチェックを、グローバルに複数宣言できます。ローカルのプロキシ設定を上書きします。
healthcheck <name>
<name>という名前の新しいヘルスチェックを作成します。名前は一意でなければなりません。特定のhealth-checkセクションを参照するため、server行でこの名前を使います。
type <type>
ヘルスチェックの型を定義します。必須のパラメーターです。次の型をサポートします。
* tcp-check
* httpchk
* ssl-hello-chk
* smtpchk
* pgsql-check
* redis-check
* mysql-check
* ldap-check
* spop-check
各型は、対応するプロキシオプションにパラメーターがあれば、同じものを使います。たとえば"httpchk"では、メソッドやURIなどを指定できます。
例:
関連項目:“option tcp-check”、“option httpchk”、“option ssl-hello-chk”、“option smtpchk”、“option mysql-check”、“option pgsql-check”、“option redis-check”、“option ldap-check”、“option spop-check”
http-check comment <string>
“httpchk"ヘルスチェックに、個別のhttp-checkルールを追加します。対応するプロキシディレクティブと同じ構文を使います。詳細は、対応するプロキシのドキュメントを参照してください。
tcp-check comment <string>
“tcp-check"ヘルスチェックに、個別のtcp-checkルールを追加します。対応するプロキシディレクティブと同じ構文を使います。詳細は、対応するプロキシのドキュメントを参照してください。
22 - 1. 前提条件
このドキュメントでは、HAProxyの起動、停止、管理、トラブルシューティングの方法について説明します。また、既知の制限や回避すべき落とし穴についても述べています。設定方法については記載していません(詳細は configuration.txt
を参照してください)。
このドキュメントでは、読者がUNIX系オペレーティングシステムの十分な管理能力を持ち、日常的にシェルを使い、straceやtcpdumpなどのトラブルシューティングツールに精通していることを前提としています。
23 - 2. HAProxyのアーキテクチャ
HAProxyは、マルチスレッドで動作するイベント駆動型のノンブロッキングデーモンです。複数の処理の切り替えをシステムのスケジューリングに任せず、イベントの多重化によってすべての処理をスケジュールします。通常は単一プロセスとして動作するため、システム上で “ps aux” を実行すると “haproxy” プロセスは一つだけ表示されます。ただし、ソフトリロード中に、新しいプロセスと並行して古いプロセスが残りの処理を終えている場合は例外です。このため、straceユーティリティで動作を簡単に追跡できます。利用可能なプロセッサー数に応じて性能を拡張するため、haproxyはデフォルトで、実行を許可されたプロセッサーごとにワーカースレッドを一つ起動します。明示的に別の設定をしない限り、受信トラフィックはこれらすべてのスレッドに分散され、各スレッドは同じイベントループを実行します。ほぼ線形のスケーラビリティを実現するため、スレッド間の依存関係を必要最小限に抑えるよう細心の注意を払っています。その影響の一つとして、各接続は単一のスレッドで処理されます。したがって、利用可能な処理能力をすべて使うには、少なくともスレッド数と同じだけの接続が必要です。この条件は、ほぼ常に満たされます。
HAProxyは起動時にchroot jail内に自身を隔離し、その中ではファイルシステムに一切アクセスできないよう設計されています。これは、依存するライブラリ、たとえばlibcやlibsslなどにも当てはまります。直接的な影響として、実行中のプロセスは設定ファイルをリロードして変更を適用できません。代わりに、更新済みの設定ファイルを使って新しいプロセスを起動します。わかりにくい影響としては、libcが実行時に参照しようとするタイムゾーンファイルやリゾルバーファイルが見つからなくなる場合があります。ただし、通常これらは起動後には不要なため、この問題は一般には発生しないはずです。この設計の利点は、HAProxyプロセスが完全にステートレスであり、強制終了後のクリーンアップが不要なことです。プロセスを終了できる方法であれば、どの方法でも適切に処理できます。
HAProxyはログファイルを書き込みません。標準のsyslogプロトコルを使ってリモートサーバーにログを送信します。このサーバーは、同じシステム上に配置されていることもよくあります。
HAProxyは、システム時刻を基に予期しないずれを補正した内部クロックを使用し、タイムアウトを管理します。poll() でイベントを待つ時間を制限し、実際に経過した時間を測定することで補正します。実際には、一秒を超えて待つことはありません。そのため、完全にアイドル状態のプロセスをstraceで追跡すると、二回のgettimeofday() 呼び出しの間にpoll() またはその変種が定期的に呼ばれることがわかります。これは正常でまったく無害な動作です。コストも非常に小さく、システム全体では負荷を検出できないほどであり、異常ではありません。例:
HAProxyはTCPプロキシであり、ルーターではありません。カーネルが検証した確立済みの接続を扱い、パケットそのものや、他の状態のソケット、たとえばSYN_RECVやTIME_WAIT状態のソケットを扱うことはありません。ただし、そのようなソケットの存在がポートへのバインドを妨げる場合はあります。受信接続の受け付けと送信接続の開始はシステムに依存します。その直接的な結果として、転送される接続の両側で観測されるパケットには対応関係がなく、サイズ、個数、さらにはアドレスファミリーまで異なる場合があります。接続はLISTEN状態のソケットからしか受け付けられないため、HAProxyがリッスンしているソケットはすべて、“netstat” ユーティリティでリッスンソケットを表示すれば必ず確認できます。例:
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1629/sshd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2847/haproxy tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 2847/haproxy
24 - 3. HAProxyの起動
HAProxyは、コマンドラインでいくつかの引数を渡して"haproxy"プログラムを呼び出すことで起動します。実際の構文は次のとおりです。
ここで、[<options>]*は任意の個数のオプションです。オプションは常に’-‘で始まり、一つ以上の文字が続き、さらに一つまたは複数の引数が続くことがあります。オプションを指定しない場合、HAProxyは対応するオプションを示すヘルプページを表示します。利用可能なオプションは、OSによって多少異なる場合があります。多くのオプションには、“global"セクションに同等の設定があります。この場合、コマンドラインは常に設定ファイルより優先されるため、設定ファイルに手を加えずに、コマンドラインから特定の設定をすばやく適用できます。現在のオプション一覧は次のとおりです。
-- <cfgfile>*
“–“の後に続くすべての引数は、宣言した順序で読み込んで処理する設定ファイル/ディレクトリのパスです。主に、数値順に並んだ多数のファイルをシェルに読み込ませる場合に役立ちます。"-f"も参照してください。”–“と”-f"の違いは、"-f"は各ファイル名の前に一つずつ必要なのに対し、”–“はすべてのファイル名の前に一つだけ必要な点です。両方を併用することもでき、その場合もコマンドラインの順序が適用されます。複数のファイルを指定する場合、各ファイルはセクションの境界から始めなければなりません。つまり、各ファイルの最初のキーワードは、“global”、“defaults”、“peers”、“listen”、“frontend”、“backend"などのいずれかでなければなりません。たとえば、サーバーの一覧だけを含むファイルにはできません。
-f <cfgfile|cfgdir>
読み込む設定ファイルの一覧に<cfgfile>を追加します。<cfgdir>がディレクトリの場合、その中にあるすべてのファイル(ファイルだけ)を、辞書順(LC_COLLATE=Cを使用)で読み込み対象の設定ファイル一覧に追加します。追加するのは拡張子が”.cfg"のファイルだけで、隠しファイル(先頭が”.“のファイル)は追加しません。設定ファイルは宣言した順序で読み込み、処理します。このオプションを複数回指定して、複数のファイルを読み込めます。”–“も参照してください。”–“と”-f"の違いは、"-f"は各ファイル名の前に一つずつ必要なのに対し、”–“はすべてのファイル名の前に一つだけ必要な点です。両方を併用することもでき、その場合もコマンドラインの順序が適用されます。複数のファイルを指定する場合、各ファイルはセクションの境界から始めなければなりません。つまり、各ファイルの最初のキーワードは、“global”、“defaults”、“peers”、“listen”、“frontend”、“backend"などのいずれかでなければなりません。たとえば、サーバーの一覧だけを含むファイルにはできません。
-C <dir>
設定ファイルを読み込む前に、ディレクトリ<dir>へ移動します。相対パスを使う場合に便利です。”–“の後にワイルドカードを使う場合は、実際にはhaproxyの起動前にシェルが展開する点に注意してください。
-D
デーモンとして起動します。プロセスはfork後に現在の端末から切り離され、端末にはエラーが報告されなくなります。設定の"global"セクションにある"daemon"キーワードと同等です。不正な設定によってシステムの起動が妨げられないよう、すべてのinitスクリプトで常にこれを強制することを推奨します。
-L <name>
ローカルピア名を<name>に変更します。デフォルトはローカルホスト名です。これはpeersレプリケーションでのみ使用します。設定ファイルで変数$HAPROXY_LOCALPEERを使うと、ピア名を参照できます。
-N <limit>
プロキシごとのデフォルトのmaxconnを、組み込みのデフォルト値(通常は2000)から<limit>へ変更します。デバッグにのみ有用です。
-V
詳細モードを有効にします(静粛モードを無効にします)。"-q"または"quiet"の効果を取り消します。
-W
マスターワーカーモードです。設定の"global"セクションにある"master-worker"キーワードと同等です。このモードは"workers"を監視する"master"を起動します。マスターへSIGUSR2シグナルを送ることで、HAProxyを直接リロードできます。マスターワーカーモードは、フォアグラウンドモードとデーモンモードのどちらとも併用できます。マルチプロセスおよびsystemdでは、このモードの使用を推奨します。
-Ws
systemdサービスのnotify型をサポートするマスターワーカーモードです。
-4
DNSリゾルバーがIPv4アドレス(“A"レコード)だけを問い合わせ、受け入れるよう強制します。エンドツーエンドのデュアルスタック接続がない一部の環境で問題が起きる場合に使えます。globalの"dns-accept-family"ディレクティブを上書きし、“ipv4"を強制します。
-c
設定ファイルのチェックだけを行い、バインドを試みる前に終了します。すべて正常なら終了ステータスはゼロ、エラーがあればゼロ以外です。警告があればその存在を報告します。デフォルトでは、成功メッセージは出力しません。"-V"と組み合わせると、成功時に"Configuration file is valid"というメッセージを出力します。
スクリプトは、コマンドの成功判定に終了ステータスを使わなければなりません。
-cc
設定の条件付きブロックで使う条件を評価します。条件が真なら終了ステータスはゼロ、偽なら1、エラーが発生すれば2です。
-d
デバッグモードを有効にします。デーモンモードを無効にし、プロセスをフォアグラウンドに留め、入出力イベントを表示します。initスクリプトでは決して使ってはいけません。
-dA[file]
設定の読み込みが完了した直後に、起動時に検出したすべての依存関係をtar形式で指定ファイルにダンプします。“set-dumpable libs"と同等ですが、ライブラリをメモリに保持する代わりにファイルへダンプします。コアダンプの後、開発者がそのコアを解析できるように、必要なライブラリをすべて提供するために利用できます。すべてのOSで利用できるとは限りません。通常の設定ファイルとともに使うことを強く推奨します。また、手動実行時には必要に応じて”-c"を併用すると、haproxyは起動せず、ダンプ直後に終了します。例:
-dC[key]
設定ファイルをダンプします。各行をトークンに分割した後に行うため、コメントは除去され、インデントは強制的に整えられます。ゼロ以外のキーを指定すると、機密フィールドの手前で行を切り詰め、識別子とアドレスは、CLIの匿名化モードと同じアルゴリズムでこのキーを使ってハッシュ化して出力します。そのため、同じキーで匿名化したダンプの状況を調べるために必要とする開発者へ、安全に出力を共有できます。CLIの"set anon"コマンドも参照してください。
-dD
診断モードを有効にします。このモードでは、疑わしい設定文について追加の警告を出力します。“zero-warning"モードでは、一部の出力が起動を妨げます。
この診断は、人が潜在的な問題に気付くためのものです。その設定が完全に意図したものである場合もあります。診断内容は、安定ブランチ内でも、まったく同じ設定を実行するマシン間でも変わる可能性があります。そのため、有効な設定文も定期的に疑わしいと報告します。より詳しい診断を行うために、"-c"と組み合わせてだけ使用するべきです。その結果を、サービスの起動を妨げるために使ってはなりません(“zero-warning"または”-dW"と組み合わせると、そのようになります)。
-dF
データのfast-forwardを無効にします。これは、ストリームを起こさずに一方から他方へ直接データを渡すことで転送を最適化する仕組みです。このディレクティブで、この最適化を無効にできます。カーネルのTCP splicingもすべて無効になる点に注意してください。このコマンドは通常の利用を意図したものではなく、一般には複雑なデバッグ作業の中で開発者が提案する場合にだけ使用します。
-dG
ホスト名をアドレスに解決する際のgetaddrinfo()の使用を無効にします。getaddrinfo()が期待どおりに動作していない疑いがある場合に使えます。さまざまなシステムに誤ったgetaddrinfo()の実装が存在し、調査しにくい異常を引き起こすため、このオプションが用意されました。
-dI
安全でないforkを有効にします。globalセクションの"insecure-fork-wanted"と同等です。アドレスを解決するためにaddr2lineをforkする必要があるASANで、すべての回帰テストを実行するときに役立つ場合があります。
-dK<class[,class]*>
各クラスに登録されたキーワードの一覧をダンプします。クラスの一覧は”-dKhelp"で確認できます。"-dKall"ですべてのクラスをダンプするか、ヘルプに表示されたクラスの一部をカンマ区切りの一覧で指定できます。出力形式は、ダンプするキーワードのクラスによって異なります(たとえば、“cfg"は既知の設定キーワードを設定ファイルに似た形式で表示し、“smp"はサンプル取得関数の前に各ルールセットとの互換性マトリックスを付けて表示します)。人がそのまま利用することはあまりありませんが、特定の場所に新しいキーワードが追加されたことを検出し、文書、構文強調ファイル、設定パーサー、APIなどを自動更新する外部ツールには大いに役立ちます。出力形式は時間とともに多少変わる可能性があるため、主に過去のアーカイブとの差分検出に利用することを強く推奨します。各種キーワード登録サブシステムが作られるよりずっと前から存在するキーワードも多く、それらはここに現れないため、すべてのキーワードが一覧に含まれるわけではありません。ただし、新しいキーワードは現在の仕組みでのみ追加されるので、この出力を使って言語への追加を高い精度で検出できると考えてよいでしょう。動的に作られるキーワードもダンプできるように、設定を完全に解析した後でのみダンプします。ダンプして終了するには、既存の設定に対して静粛な設定チェックを実行するとよいでしょう。
設定ファイルがない場合でも、"-f /dev/null"を使えばデフォルトのキーワードをすべてダンプできます。ただし、リスナーが存在しないため終了ステータスはゼロにならず、無視する必要があります。
-dL
設定処理の終了時に読み込まれている動的共有ライブラリの一覧をダンプします。通常は、実行可能ファイル自身に加えて、たとえばLuaコードから読み込まれるものなど、間接的な依存関係も含みます。すべての依存関係のtarballを直接作成できるよう、容易に整形できる形式で一覧を出力します。プログラムの起動を停止しないため、読み込んだオブジェクトの一覧だけ(エラー時は何も表示しません)を出力する”-c"と”-q"の組み合わせでのみ使用することを推奨します。また、コアファイルの解析を支援するためにこのようなパッケージを提供する場合、多くのライブラリは実際にはシンボリックリンクであり、アーカイブ作成時にリンク先を取り込む必要があることを忘れないでください。
詳細モード(-V)で起動すると、静粛モード(-q)を使用していない限り、共有ライブラリのアドレス範囲も列挙します。
-dM[<byte>[,]][help|options,...]
メモリポイズニングを強制し、またはその他のメモリデバッグオプションを変更します。メモリポイズニングとは、malloc()またはpool_alloc()で割り当てるすべてのメモリ領域を、呼び出し元へ渡す前に<byte>で埋めることです。<byte>を指定しない場合、デフォルトは0x50(‘P’)です。動作は少し遅くなりますが、コードの初期化漏れによって不規則なクラッシュを引き起こす問題を、確実に再現するのに役立ちます。-dM0には、すべてのmalloc()をcalloc()に変える効果がある点に注意してください。このオプションを使って不具合が現れたり消えたりする場合は、いずれにしてもhaproxyにバグがあるため、報告してください。ほかにも、単独で、またはバイト値の後にカンマで区切って指定できるオプションがあります。特別なオプション"help"は、現在対応しているオプションと現在の値を一覧表示します。各デバッグオプションは、強制的に有効または無効にできます。通常はOSに応じた最適なオプションがビルド時に選ばれるため、開発者から提案されない限り調整する必要はありません。対応するデバッグオプションは次のとおりです(設定/解除)。
- fail / no-fail:
- no-merge / merge:
- cold-first / hot-first:
- integrity / no-integrity:
- backup / no-backup:
- no-global / global:
- no-cache / cache:
- caller / no-caller:
- tag / no-tag:
- poison / no-poison:
-dR
リッスンポートのSO_REUSEPORTソケットオプションを無効にします。“global"セクションの"noreuseport"キーワードと同等です。マルチスレッドの構成で、haproxyのスレッド間の負荷分散に問題が見られる場合(topで監視できます)に適用できます。
-dS
splice()システムコールの使用を無効にします。“global"セクションの"nosplice"キーワードと同等です。splice()の動作不良や性能問題が疑われる場合、またはstraceで転送データを確認する場合に使えます(splice()を使用すると、転送データは表示されません)。
-dT
ktlsの使用を無効にします。“global"セクションの"noktls"キーワードと同等です。主にktlsに関連するバグが疑われる場合に役立ちます。
-dV
サーバー側のSSL検証を無効にします。“global"セクションに"ssl-server-verify none"を設定するのと同等です。本番環境の問題を本番環境以外で再現する場合に便利です。サーバーとのSSL通信の安全性を低下させるため、initスクリプトでは決して使わないでください。
-dW
設定すると、設定ファイルの処理中に警告が一つでも出た場合、haproxyは起動を拒否します。微妙な誤りを検出し、設定を整理して、バージョン間での移植性を保つのに役立ちます。設定を人が管理する場合はサービススクリプトでこのオプションを設定することを推奨しますが、自動生成した設定は警告が多くなりがちなので、使用しないことを推奨します。"-c"と組み合わせると、チェック対象の設定に警告があれば失敗させられます。globalオプション"zero-warning"と同等です。
-dZ
“zero-copy"モードでのデータ転送を無効にします。“global"セクションの"tune.disable-zero-copy-forwarding"キーワードと同等です。データの欠落や整合性に問題がある場合に役立ちます。また、カーネルのTCP splicingもすべて無効にするため、straceで転送データを確認する場合にも役立ちます。
-db
バックグラウンドモードとマルチプロセスモードを無効にします。プロセスはフォアグラウンドに留まります。Ctrl-Cだけで停止できるため、主に開発中や小規模なテストで使います。initスクリプトでは決して使わないでください。
-dc
CPUアフィニティのデバッグを有効にします。起動前に、選択したCPUと除外したCPUの一覧、およびそれらのトポロジーを報告します。
-de
“epoll"ポーラーの使用を無効にします。“global"セクションの"noepoll"キーワードと同等です。主にこのポーラーに関連するバグが疑われる場合に役立ちます。epollに対応するシステムでは、通常、代わりに"poll"ポーラーを使います。
-dk
“kqueue"ポーラーの使用を無効にします。“global"セクションの"nokqueue"キーワードと同等です。主にこのポーラーに関連するバグが疑われる場合に役立ちます。kqueueに対応するシステムでは、通常、代わりに"poll"ポーラーを使います。
-dp
“poll"ポーラーの使用を無効にします。“global"セクションの"nopoll"キーワードと同等です。主にこのポーラーに関連するバグが疑われる場合に役立ちます。pollに対応するシステムでは、通常、代わりに"select"ポーラーを使います。selectは無効にできず、ファイル記述子数は1024に制限されます。
-dr
サーバーアドレスの解決失敗を無視します。本番環境の外で設定を検証すると、同じリゾルバーにアクセスできずにサーバーアドレスの解決が失敗し、設定をテストしにくくなることがよくあります。このオプションは、すべてのサーバーのアドレス解決方式の一覧の末尾に"none"を加えるだけです。これにより、libcでアドレスを解決できなくても、起動シーケンスを中断しません。
-dt [<trace_desc>,...]
stderrへのトレースを有効にします。引数がなければ、すべてのトレースソースをerrorレベルで有効にします。特に、クライアントやサーバーのプロトコル違反を検出する場合に役立ちます。任意の引数で、さまざまなトレース設定を’,‘区切りの一覧として指定できます。各要素は、一つまたはすべてのトレースソースを有効にします。また、各要素では、トレース名との内部区切りに’:‘を使い、レベルと詳細度を任意に指定できます。無効な詳細度名またはレベル名を入力すると、利用可能なキーワードの一覧を表示します。たとえば、各フィールドに’help’を渡して、先に一覧を確認すると便利です。
-dv
“evports"ポーラーの使用を無効にします。“global"セクションの"noevports"キーワードと同等です。主にこのポーラーに関連するバグが疑われる場合に役立ちます。イベントポートに対応するシステム(Solaris 10以降に由来するSunOS)では、通常、代わりに"poll"ポーラーを使います。
-m <limit>
プロセスのデータ保持に使う、割り当て可能なメモリを<limit>メガバイトに制限します。通常の動作に必要なメモリ量によっては、接続が拒否されたり、動作が遅くなったりする場合があります。主に、リソース消費が制限された状況でhaproxyプロセスを動かすために使います。メモリはhaproxyプロセス間で共有されず、fork()システムコールで作成した子プロセスは親のリソース制限を継承する点が重要です。そのため、マスターワーカーモードでは、このメモリ上限はマスターとforkされたワーカープロセスに個別に適用されます。
-n <limit>
プロセスごとの接続数の上限を<limit>に制限します。globalセクションの"maxconn"キーワードと同等で、このキーワードより優先されます。リソース制限が低すぎるシステムでサービス停止を避けるため、低い上限をすばやく強制する場合に使えます。
-p <file>
起動時に、すべてのプロセスのPIDを<file>へ書き込みます。“global"セクションの"pidfile"キーワードと同等です。ファイルは、"-C"によるchdir()の後、chroot jailに入る前に開きます。各PIDは一行ずつ記録されます。
-q
“quiet"モードを設定し、メッセージの出力を無効にします。"-c"と組み合わせ、設定ファイルが有効かどうかだけを確認するために使えます。
-S <bind>[,bind_options...]
マスターワーカーモードで、マスターCLIをバインドします。これにより、実行中または終了へ向かっているすべてのプロセスにアクセスできます。安全のため、マスターCLIはローカルのUNIXソケットにバインドすることを推奨します。バインドオプションは設定ファイルの"bind"キーワードと同じですが、語の区切りにはスペースの代わりにカンマを使います。
このソケットは、シームレスリロード時に古いプロセスからリッスンソケットを取得する用途には使えない点に注意してください。
-sf <pid>*
起動完了後、古いプロセスに"finish"シグナル(SIGUSR1)を送り、実行中の処理を終えてから終了するよう要求します。<pid>はシグナルを送るPIDの一覧です(一つの引数に一つ)。一覧は、”-“で始まるオプションで終わります。PIDの一覧が空でも問題ないため、“pidof"や"pgrep"などのコマンドの結果から、その場で組み立てられます。
-st <pid>*
起動完了後、古いプロセスに"terminate"シグナル(SIGTERM)を送り、実行中の処理を完了させず、直ちに終了させます。<pid>はシグナルを送るPIDの一覧です(一つの引数に一つ)。一覧は、”-“で始まるオプションで終わります。PIDの一覧が空でも問題ないため、“pidof"や"pgrep"などのコマンドの結果から、その場で組み立てられます。
-v
バージョンとビルド日を表示します。
-vv
バージョン、ビルドオプション、ライブラリのバージョン、利用可能なポーラーを表示します。バグ報告では、この出力が必ず求められます。
-x <unix_socket>
指定したソケットに接続し、古いプロセスからリッスンソケットを取得して、新しくバインドを試みる代わりにそれらを使います。Linuxで設定をリロードするときに、新しい接続を取りこぼさないようにするのに役立ちます。
マスターワーカーモードを使わない場合、設定内で"expose-fd listeners"を指定して、統計ソケットでこの機能を有効にしなければなりません。
マスターワーカーモードでは、“expose-fd listeners"は不要です。リロード時には、マスターが"sockpair@“構文でこのオプションを自動的に使います。これにより、設定で宣言した統計ソケットを使わずに、マスターがワーカーへ直接接続できます。これを無効にするには、-x /dev/nullを渡します。
initファイルから安全にHAProxyを起動するには、デーモンモードを強制し、既存のPIDをPIDファイルに保存し、そのファイルを使って、古いプロセスに処理を完了してから終了するよう通知します。
設定を用途別のいくつかのファイル(tcpとhttpなど)に分割している場合は、"-f"オプションの使用を推奨します。
顧客ごとのファイルなど、ファイル数があらかじめ分からない場合は、固定桁数の連番で始まる名前を付け、必要に応じてデフォルト設定を読み込んだ後、”–“で読み込むことを推奨します。
何らかの理由で起動に失敗することがあります。その場合、呼び出しているHAProxyが期待するバージョンであり、期待する機能(SSL、PCRE、圧縮、Luaなど)をサポートしているかを確認することが重要です。“haproxy -vv"で確認できます。一部のビルドオプション、対象システム、使用するライブラリのバージョンなど、重要な情報が表示されます。バグ報告を投稿するときにも、この情報が必ず求められます。
HAProxy version 1.6-dev7-a088d3-4 2015/10/08 Copyright 2000-2015 Willy Tarreau willy@haproxy.org
Build options:
Default settings:
Encrypted password support via crypt(3): yes Built with zlib version: 1.2.6 Compression algorithms supported: identity(“identity”), deflate(“deflate”), \ raw-deflate(“deflate”), gzip(“gzip”) Built with OpenSSL version: OpenSSL 1.0.1o 12 Jun 2015 Running on OpenSSL version: OpenSSL 1.0.1o 12 Jun 2015 OpenSSL library supports TLS extensions: yes OpenSSL library supports SNI: yes OpenSSL library supports prefer-server-ciphers: yes Built with PCRE version: 8.12 2011-01-15 PCRE library supports JIT: no (USE_PCRE_JIT not set) Built with Lua version: Lua 5.3.1 Built with transparent proxy support using: IP_TRANSPARENT IP_FREEBIND
Available polling systems:
Total: 3 (3 usable), will use epoll.
開発者ではない多くのユーザーも、ここで次の関連情報を確認できます。
- バージョン
上の1.6-dev7-a088d3-4は、現在のコードがコミットID “a088d3"であり、正式版"1.6-dev7"から4番目のコミットであることを意味します。バージョン1.6-dev7は"1.6-dev7-8c1ad7"のように表示されます。ここで実際に重要なのは"1.6-dev7"です。これは、将来バージョン1.6となるものの7番目の開発版です。開発版は、何をしているかを正確に理解している場合を除き、本番環境での使用には適しません。安定版は"1.5.14-16f863"のように3つの数値からなるバージョンで表示され、バージョン1.5に対する14番目の修正リリースを意味します。こちらは本番で使用できるバージョンです。
- リリース日
2015/10/08。世界共通の年/月/日の形式で表します。ここでは2015年10月8日を意味します。安定版リリースは数か月ごと(当初は1〜2か月、製品が非常に安定した後は6か月になる場合もあります)に発行されるため、ここに古い日付が表示される場合は、その後修正されたバグやセキュリティ問題の影響を受けている可能性があり、公式サイトを確認する価値があります。
- ビルドオプション
自分でパッケージをビルドする人に関係する情報で、期待どおりに動かない理由を説明できる場合があります。たとえば、上の開発版はLinux 2.6.28以降向けにビルドされ、汎用CPUを対象としており(CPU固有の最適化なし)、コードの最適化もまったく行っていない(-O0)ため、性能は低くなります。
- ライブラリのバージョン
zlibのバージョンは、ライブラリ自体から得たものを表示します。一般にzlibは非常に安定した製品と考えられており、アップグレードが必要になることはほとんどありません。OpenSSLは、ビルド時に使ったバージョンと、現在システム上で使っているバージョンの二つを表示します。末尾の文字は異なる場合がありますが、数値は決して異なりません。OpenSSLのバグの大半はセキュリティ問題で、真剣に対処する必要があるため、ビルド日も表示します。このライブラリは必ず最新の状態に保たなければなりません。ここで4か月前のバージョンが表示されるのは非常に疑わしく、実際に更新を見逃しています。PCREは非常に高速な正規表現を提供するため、強く推奨します。JITなど一部の拡張はすべてのバージョンにあるわけではなく、まだ新しいため、それらを含めずにビルドすることを好む人もいます。そのため、ビルド時の状態も表示します。Luaスクリプト言語については、HAProxyはバージョン5.3を想定しています。HAProxy 1.6の少し前にリリースされたばかりなので、まだ非常に新しいバージョンです。このブランチ向けの修正が出ていないか、LuaのWebサイトを確認することが重要です。
- 利用可能なポーリング方式は、次の場合にプロセスの拡張性に影響します
同時接続数が約千を超える場合です。これらの方式は、ビルド時にTARGET変数へ正しいシステムを指定した場合にのみ利用できます。Linuxでは"epoll"方式、BSDではkqueue方式を強く推奨します。これらがなければpoll()、場合によってはselect()を使うことになり、多数の接続を処理するとCPU使用率が高くなります。
25 - 4. HAProxyの停止と再起動
HAProxyはグレースフル停止と強制停止をサポートしています。強制停止は単純で、haproxyプロセスにSIGTERMシグナルを送ると即座に終了し、確立済みの接続はすべて閉じられます。グレースフル停止は、haproxyプロセスにSIGUSR1シグナルを送ると開始されます。リッスンポートのバインドだけを解除し、既存の接続が閉じられるまで処理を続けます。最後の接続が閉じられると、プロセスが終了します。
サービス管理スクリプトの"stop"や"restart"アクションでは、強制停止が使われます。新しいプロセスで新しい設定を途切れなく読み込もうとする"reload"アクションでは、グレースフル停止が使われます。
これらのシグナルは、リロードや再起動の際に新しいhaproxyプロセス自身から送ることもできます。これにより、絶対に必要な場合に限り、可能な限り遅い時点で送信されます。この動作を行うのが、それぞれ"-st"(強制停止)と"-sf"(グレースフル停止)オプションです。
マスターワーカーモードでは、設定のリロードのために新しいhaproxyプロセスを起動する必要はありません。マスタープロセスはSIGUSR2シグナルを受け取ると、-sfパラメーターにワーカーのPIDを続けて指定し、自身を再実行します。その後、設定ファイルを解析し、新しいワーカーをforkします。
これらのシグナルの使われ方をよりよく理解するには、再起動の仕組み全体を理解することが重要です。
まず、既存のhaproxyプロセスが動作しています。管理者は"/etc/init.d/haproxy reload"など、システム固有のコマンドを使って、新しい設定ファイルの適用を指示します。すると、次の処理が行われます。最初に、サービススクリプト(/etc/init.d/haproxyなど)が"haproxy -c"で設定ファイルを正しく解析できることを確認します。その後、この設定ファイルを使い、"-st"または"-sf"を指定してhaproxyの起動を試みます。
次に、HAProxyはすべてのリッスンポートへのバインドを試みます。致命的なエラー(システムにアドレスが存在しない、権限がないなど)が発生すると、エラーで終了します。ポートがすでに使用されているためにソケットのバインドに失敗した場合は、まず"-st"または"-sf"のPIDリストで指定されたすべてのPIDにSIGTTOUシグナルを送ります。これが"pause"シグナルです。既存のすべてのhaproxyプロセスに対し、一時的にポートでのリッスンを停止して、新しいプロセスが再度バインドを試せるよう指示します。この間も、古いプロセスは既存の接続を処理し続けます。それでもバインドに失敗する場合(別のデーモンとポートを共有している場合など)は、新しいプロセスが古いプロセスにSIGTTINシグナルを送り、何も起きなかったかのように動作を再開するよう指示します。古いプロセスはポートでのリッスンを再開し、接続を受け付け続けます。この仕組みはシステムに依存し、OSによってはマルチプロセスモードでサポートされない場合があります。
新しいプロセスがすべてのポートに正常にバインドできた場合は、すべてのプロセスにSIGTERM("-st"の場合の強制停止)またはSIGUSR1("-sf"の場合のグレースフル停止)を送ります。これにより、新しいプロセスが処理を引き継ぎ、古いプロセスは即座に、または処理を終えた時点で終了しなければならないことを通知します。
この一連の処理には、それぞれ数ミリ秒の短い期間が2つあり、高負荷時にはその間に少数の接続失敗が発生する可能性がある点に注意が必要です。一般的に観測される失敗率は、新規接続が毎秒10000件ある場合、リロード操作中に約1件です。つまり、新規接続を毎秒30000件処理している高負荷のサイトでは、リロードのたびに約3件の接続失敗が発生する可能性があります。これが起きるのは、次の2つの状況です。
-
古いプロセスが存在するために新しいプロセスがバインドできない場合は、まずSIGTTOU+SIGTTINの手順を実行する必要があります。フロントエンドが数十個ある場合、通常は約1ミリ秒かかり、この間、一部のポートは古いプロセスのバインドが解除され、新しいプロセスにもまだバインドされていない状態になります。SO_REUSEPORTソケットオプションをサポートするシステムでは、古いプロセスにバインド解除を求めずに新しいプロセスがバインドできるため、HAProxyはこの問題を回避できます。ほとんどのBSDシステムは、非常に古くからこれをサポートしています。Linuxではバージョン2.0でサポートされていましたが、2.2頃に削除されました。当時もいくつかのパッチは流通していました。カーネル3.9で再導入されたため、上記よりも高い接続失敗率が見られる場合は、カーネルが3.9以降であるか、該当するパッチがバックポートされているか(その可能性は低いですが)を確認してください。
-
古いプロセスがリッスンポートを閉じる際、ソケットのバックログに残っていた保留中の接続を、カーネルが必ずしも再分配するとは限りません。高負荷時には、ソケットが閉じられる直前にSYNパケットが届き、クライアントにRSTパケットが送られることがあります。1件の切断も許されない重要な環境では、リロード中にファイアウォールルールでSYNパケットをブロックしてクライアントに再送させ、この問題に対処することがあります。ほかのリッスンキューを調べてこのRSTを回避できるシステムもあるため、この動作は完全にシステムに依存します。もう1つは、閉じられる直前にSYN_RECV状態にあったローカルソケットに、クライアントからACKが届く場合です。このACKによってRSTパケットが送られますが、haproxyプロセスはまだこの接続を認識していません。このケースの回避はより困難ですが、プロセスを再起動する約1秒前に上記のファイアウォールのフィルタールールを適用すると、うまく対処できます。
大多数のユーザーでは、競合状態を引き起こすほど負荷が高くないため、このような切断は発生しません。また、トラフィックの多いユーザーでも、少なくともSO_REUSEPORTがシステムで正しくサポートされていれば、失敗率は通常のばらつきの範囲に十分収まります。
26 - 5. ファイル記述子の制限
受信したすべての接続を正常に処理できるように、HAProxyは読み込み時に、プロセスの存続期間中に必要となるファイル記述子の総数を計算します。通常のUnixプロセスには、デフォルトで一般に1024個のファイル記述子が許可され、特権プロセスはこの上限を自分で引き上げられます。これが、HAProxyをrootで起動して上限を調整させる理由の1つです。デフォルトの上限である1024個のファイル記述子では、約500の同時接続を処理できます。計算には、プロセスごとの接続総数を制限するグローバルのmaxconnパラメーター、リスナー数、ヘルスチェックが有効なサーバー数、エージェントチェック、ピア、ロガー、場合によってはその他の技術的要件が使われます。簡単な概算として、maxconnの値を2倍して数十を加えると、必要なファイル記述子数のおおよその値が得られます。
当初のHAProxyはこの値を計算できず、globalセクションの"ulimit-n"設定で値を渡す必要がありました。現在でも多くの設定にこの項目が残っているのは、このためです。残念ながら、この値はしばしば誤って計算されていました。その結果、maxconnに近づくと、必要なリソースを待つ間に受信接続を抑制する代わりに、接続が失敗していました。このため、非常に古いバージョンから残っている"ulimit-n"設定は削除することが重要です。
中程度の負荷であっても、受け付けるにはファイル記述子数を増やすことが必須ですが、OS固有の調整も伴います。まず、select()によるポーリングは1024個のファイル記述子に制限されます。実際にはLinuxのselect()はかつてそれ以上を扱えましたが、一部のOSに付属する過度に厳しいSELinuxポリシーが、1024個を超えるファイル記述子でのselect()の使用を禁止しています。そのため、実行時の問題を避けるため、HAProxyはこの場合に起動を拒否するようになりました。サポート対象のすべてのOSではpoll()が利用でき、この制限を受けません。自動的に選択されるため、動作させるための特別な設定は不要です。しかし、poll()はファイル記述子数が増えると非常に遅くなります。HAProxyは内部のファイル記述子キャッシュやバッチ処理などで性能への影響を抑えるよう最善を尽くしますが、目安として、1000を超える同時接続でpoll()を使うと多くのCPUを消費します。
カーネル2.6以降を使うLinuxシステムでは、epoll()システムコールが使われます。これは、カーネル内のコールバックに基づく、はるかに拡張性の高い仕組みで、監視対象として登録されたファイル記述子の数によらず、一定の起床時間を保証します。HAProxyがLinux向けのいずれかの設定でビルドされていれば、検出時に自動的に使われます。利用可否とサポート状況は"haproxy -vv"で確認できます。
対応するBSDシステムでは、代替としてkqueue()が利用できます。poll()よりはるかに高速で、変更をバッチ処理するためepoll()よりもわずかに高速です。少なくともFreeBSDとOpenBSDがサポートしています。Linuxのepoll()と同様に、サポート状況と利用可否は"haproxy -vv"の出力に表示されます。
優れたポーラーを使うだけでは十分ではなく、プロセスが必要な上限まで利用できることが必須です。HAProxyは起動するとすぐに新しいプロセスのファイル記述子上限を設定し、成功したか確認します。失敗した場合は、管理者が問題を確認できるよう、forkする前に報告します。rootとして起動している限り、この設定が失敗する理由は通常ありません。ただし、非特権ユーザーとして起動した場合は失敗することがあります。rootとしてhaproxyを起動しないやむを得ない理由(エンドユーザーやアプリケーション別アカウントで起動する場合など)がある場合は、システム管理者がそのユーザーに対するファイル記述子上限を引き上げられます。設定が有効かどうかは、そのユーザーのコマンドラインで"ulimit -n"を実行して確認できます。新しい上限が表示されるはずです。
警告:非特権ユーザーのアカウントで上限を変更しても、その値はログイン時にのみ反映され、システム起動時の一部のスクリプトやcrontabではまったく考慮されないことがよくあります。これは完全にOSに依存します。この方法で実行する場合は、haproxyを起動する前に"ulimit -n"を確認することを忘れないでください。一般的な推奨は、本番用途ではhaproxyを非特権ユーザーとして起動しないことです。非特権ユーザーで起動するとhaproxyが一部のセキュリティ保護を有効にできなくなることも、重要な理由です。
haproxyプロセスが要求した数のファイル記述子をシステム上で使えると確認した後も、システム固有の別の上限に2つ遭遇する可能性があります。1つはシステム全体のファイル記述子上限で、すべてのプロセスを合わせてシステム上で開けるファイル記述子の総数です。この上限に達すると、通常、accept()やsocket()はENFILEを返します。もう1つは、プロセスごとのファイル記述子数のハード上限で、setrlimit()でそれより大きな値を設定することを防ぎます。どちらもOSに大きく依存します。Linuxでは、システム全体の上限は起動時にメモリ量に基づいて設定され、“fs.file-max"のsysctlで変更できます。プロセスごとのハード上限はデフォルトで1048576ですが、“fs.nr_open"のsysctlで変更できます。
ファイル記述子の上限が低すぎる場合は、実行中のプロセスでその制限を確認できます。プロセスの上限に達すると、straceユーティリティはaccept()とsocket()が”-1 EMFILE"を返したと報告します。この場合は、“ulimit-n"の値を引き上げる(または削除する)だけで解決します。これらのシステムコールが”-1 ENFILE"を返す場合は、カーネルの上限に達しており、システム全体のパラメーターに対処する必要があります。これらの問題は、CPU使用率の上昇(accept()が失敗した場合)や、通常ユーザーにも見える接続失敗につながるため、必ず解決しなければなりません。グローバルのmaxconn値を下げて処理を直列化し、必要に応じてHTTP keep-aliveを無効にして接続をより早く解放・再利用させる方法もあります。
27 - 6. メモリ管理
HAProxyは、単純で高速なプール方式のメモリ管理を使用します。扱うオブジェクトの種類が少ないため、サイズごとにmalloc()を呼び出すより、適切なサイズのオブジェクトを持つプールから取得するほうがはるかに効率的です。プールはスタック、つまりLIFOとして構成されます。このため、新たに割り当てるオブジェクトには、解放されたばかりでCPUキャッシュにまだ残っているものを使用します。メモリの断片化を抑えるため、サイズが近いプールは統合されます。
デフォルトでは性能を重視し、解放された各オブジェクトを元のプールに戻します。すぐに再利用すると想定しているため、割り当て済みのオブジェクトのメモリは解放しません。
CLIの「show pools」コマンドで、プールのメモリ使用状況を確認できます。
プール名は目安であり、そのプールを最初に使用したオブジェクト型の名前です。括弧内のサイズは、そのプールのオブジェクトサイズです。オブジェクトサイズは常に16バイトの倍数に切り上げられます。現在割り当てられているオブジェクト数と総バイト数が表示されるため、どのプールが最も多くのメモリを使用しているかを簡単に把握できます。現在使用中のオブジェクト数は「used」フィールドに表示されます。“allocated"と"used"の差は、解放済みですぐに再利用できるオブジェクトの数です。行末のアドレスはプールのアドレスで、続く数値はプールのインデックスです。インデックスが割り当てられていなければ-1と表示されます。
コマンドラインオプション「-m」に続けてメガバイト数を指定すると、プロセスごとに割り当てるメモリ量を制限できます。プロセスがアドレス指定できる空間全体が対象となるため、一部のライブラリやスタックが使うメモリも含まれますが、リソースに制約のあるシステムでは確実な上限として利用できます。「ulimit -v」があるシステムではそれと同じように、それ以外では「ulimit -d」と同じように機能します。
メモリ上限に達した場合やシステムのメモリが不足した場合に割り当てが失敗すると、haproxyはまずすべてのプールから未使用のオブジェクトをすべて解放し、その後メモリの割り当てを再試行します。この未使用メモリの解放処理は、haproxyプロセスにSIGQUITシグナルを送ることでも実行できます。
リロード時にグレースフルシャットダウン状態に移ったプロセスは、接続を解放するたびに自動的にメモリの解放処理も行います。これにより、解放可能なメモリをすべて解放し、新しいプロセスが利用できるようにします。
28 - 7. CPU使用率
バージョンについて:この章には旧版のマルチプロセス運用に関する説明が残っています。HAProxy 2.5以降、nbprocとbind processはサポートされていません。この版では、グローバル設定
のnbthread、thread-groups、cpu-mapでスレッドを設定してください。
HAProxyは通常、ほとんどの時間をシステム内で費やし、ユーザー空間で費やす時間はそれより短くなります。適切に調整された3.5 GHzのCPUは、1コアのCPU使用率100%で、エンドツーエンドの接続確立と終了を毎秒約80000回処理できます。1コアが飽和している場合の典型的な内訳は、次のとおりです。
- 長時間のTCP接続や大きなHTTPオブジェクトでは、システム95%、ユーザー5%
- 短時間のTCP接続やcloseモードの小さなHTTPオブジェクトでは、システム85%、ユーザー15%
- keep-aliveモードの小さなHTTPオブジェクトでは、システム70%、ユーザー30%
ルール処理や正規表現の量が増えると、ユーザー空間の割合が増えます。一方、システム内のファイアウォールルール、接続追跡、複雑なルーティングテーブルは、システムの割合を増やします。
ほとんどのシステムでは、ネットワーク転送中に観測されるCPU時間は4つに分けられます。
-
割り込み:I/Oを受信してから、対象プロセスが判明するまでに行われるすべての処理です。通常、Rxパケットは割り込みに計上されます。Linuxなど、割り込み処理を専用スレッドに遅延できるシステムでは、softirqとして表示される場合があり、スレッド名はksoftirqd/0(CPU 0の場合)です。この負荷を処理するCPUは通常、ハードウェアの設定で決まりますが、softirqでは処理先を別のCPUに変更できることがよくあります。この割り込み部分は、どのプロセスにも関連付けられないため、余分な負荷と見なされがちですが、実際にはプロセスの仕事を準備するための処理です。
-
システム:ユーザー空間から呼び出されたカーネルコードで行われるすべての処理です。たとえば、システムコールはシステムに計上されます。同期的に送出されるTxパケットは、すべてシステム時間に計上されます。キューが満杯になって一部のパケットを遅延させる必要がある場合は、後で割り込みコンテキストで処理されることがあります(TCPウィンドウを広げるACKを受信したときなど)。
-
ユーザー:ユーザー空間でアプリケーションコードだけを実行する部分です。HAProxyはシステムコールを多用しますが、それ自体はこの部分だけで動作します。ルール処理、正規表現、圧縮、暗号化はいずれもCPU消費のユーザー部分を増やします。
-
アイドル:CPUに処理すべきことがない状態です。たとえば、HAProxyが着信接続を待っている場合や、データが送出されるのを待っている場合です。後者では、システムはそのデータを送るためにクライアントからのACKを待っています。
実際のHAProxyの動作については、割り込み/softirqはカーネルドライバーでのRx処理、ユーザー空間はHAProxyでのレイヤー7処理、システム時間はTx経路のネットワーク処理によるものと考えると、厳密にはまったく正しくありませんが、一般にはおおむね実態を捉えられます。
HAProxyはイベントループを中心に動作するため、poll()(または代替機構)で新しいイベントを待ち、受け取ったイベントをできるだけ速くすべて処理してから、再びpoll()に戻って次のイベントを待ちます。poll()で待機した時間と、イベントの処理に費やした時間を測定します。合計時間に対するポーリング時間の比率を"idle"時間と呼び、何かが起こるのを待っていた時間の割合を表します。この比率は、統計ページでは"idle"行、CLIでは"Idle_pct"に表示されます。100%に近ければ、負荷が極めて低いことを意味します。0%に近ければ、常に何らかの処理があることを意味します。過負荷のシステムでは、ほかのプロセスがhaproxyプロセスからCPUを奪う場合があるため、あまり正確にはなりません。それでも、HAProxy自身がどの程度仕事をしていると認識しているかを把握する有用な目安になります。負荷が低いのにアイドル比率も低い場合は、非常に処理コストの高いルールなどにより、HAProxyに多くの仕事がある可能性を示します。逆に、動作が遅いのにHAProxyのアイドル比率が100%に近い場合は、すでに処理するデータの到着を待っている状態であり、HAProxy側ではそれ以上高速化できないことを意味します。次の例では、haproxyは完全にアイドル状態です。
アイドル比率が非常に低くなり始めたら、すべてのタスクにできるだけ多くのCPUリソースを残すため、システムを調整し、プロセスと割り込みを適切に配置することが重要です。ファイアウォールがある場合は、それが性能制限の大きな原因になっていないかを確認するため、無効化や調整を試す価値があります。ステートフルファイアウォールはRxとTxの両方の経路で動作するため、アンロードすると通常、割り込み/softirqとシステム使用率の両方が減少します。Linuxでは、nf_conntrackとip_conntrackモジュールをアンロードすると、改善の余地があるか確認できます。改善する場合、モジュールはデフォルト設定で動作しているため、性能を向上させる調整方法を調べる必要があります。一般には、ハッシュテーブルのサイズを大幅に増やします。FreeBSDでは、“pfctl -d"で"pf"ファイアウォールとそのステートフルエンジンを同時に無効にできます。
割り込み/softirqに多くの時間を費やしている場合は、それらとHAProxyが同じCPUで動作しないようにすることが重要です。ほとんどのシステムは、ネットワークトラフィックを受信するCPUにタスクを固定する傾向があります。特定のワークロードでは、そのほうが性能が向上するためです。しかし、ネットワークが大きな制約になるワークロードでは逆効果で、haproxyプロセスがカーネル側の処理とCPUを奪い合うことになります。haproxyを1つのCPUコアに、割り込みを別のコアに固定し、両方が同じL3キャッシュを共有するようにすると、ネットワーク性能は大きく向上する傾向があります。実際には、haproxyとネットワークスタックの仕事量はかなり近く、それぞれがほぼCPU全体を使い切れるためです。Linuxでは、haproxyにはtaskset、またはhaproxy設定のcpu-mapを使い、割り込みは/proc/irq配下で割り当てます。多くのネットワークインターフェースは複数のキューと割り込みをサポートしています。一般には、同じL3キャッシュを共有する少数のCPUコアに分散すると効果があります。この種のワークロードではirq_balanceは常に最悪の配置を行うため、必ず停止してください。
大量のSSLトラフィックや圧縮によりCPUが制約になるワークロードでは、特定のタスク専用の複数プロセスを使う価値がある場合があります。ただし、普遍的な規則はないため、実験が必要です。
CPU処理能力を増やすため、globalセクションの"nbproc"ディレクティブでHAProxyを複数のプロセスとして動作させることができます。ただし、いくつか制限があります。
- ヘルスチェックはプロセスごとに実行されるため、対象サーバーは実行中のプロセス数と同じ数のチェックを受けます。
- maxconnの値とキューはプロセスごとに適用されるため、サーバーに過負荷をかけないよう、正しい値を設定しなければなりません。
- 競合を避けるため、送信接続でのポート範囲の使用は避けることを推奨します。
- スティックテーブルはプロセスごとに存在し、プロセス間で共有されません。
- 各peersセクションは、一度に1つのプロセスでしか実行できません。
- CLI操作は、一度に1つのプロセスにのみ作用します。
これらを考慮すると、最も簡単な構成は、多くの場合、負荷の高い処理を担当する第1層を複数プロセスで動作させ、単一プロセスで動作する第2層にトラフィックを渡すものです。この仕組みは、CPU負荷の高い2つの機能であるSSLと圧縮に適しています。インスタンスは、UNIXソケット(TCPソケットより低コストで、ポートを消費しません)と、次の段階へクライアント情報を渡すのに便利なproxyプロトコルを使って簡単に連結できます。この場合は通常、単一プロセスのタスクをすべてプロセス番号1に、追加のタスクをそれ以降のプロセスに割り当てるとよいでしょう。異なるマシン向けに同様の設定を生成しやすくなります。
Linuxバージョン3.9以降では、マルチプロセスモードでHAProxyを動かす際、各プロセスが同じIP:port上で個別のリッスンソケットを使うと、はるかに効率的です。カーネルがすべてのプロセスを起こす代わりに、全プロセスに負荷を均等に分散するようになるためです。詳細は、設定マニュアルの"bind"キーワード行の"process"オプションを確認してください。
29 - 8. ログ
HAProxyはファイルシステムにアクセスしないため、ログの記録には常にsyslogサーバーを使用します。通常はUDPでログサーバーに送信します。デフォルトのポートは514です。ローカルのsyslogデーモンが動作する127.0.0.1を指定することが多いものの、ネットワーク経由で中央サーバーにログを集約する使い方もあります。特にアクティブ/アクティブ構成でログを到着順に統合したい場合、中央サーバーに集約する利点があります。UNIXソケットでローカルのsyslogデーモンに送信することもできますが、まったく推奨しません。haproxyの実行中にsyslogサーバーが再起動するとソケットが置き換えられ、以後のログが失われるためです。HAProxyはchroot jail内に隔離されているので、新しいソケットに再接続できません。また、UNIXソケットのログバッファは非常に小さく、ごく軽い負荷でもメッセージが失われる事例が運用現場で確認されています。ただし、テスト用途なら使える場合があります。
HAProxyのログをファシリティ"local0"でローカルデーモンに送るには、「global」セクションに次のディレクティブを追加することを推奨します。
続いて、各"defaults"セクション、または各フロントエンドとバックエンドのセクションに、次のディレクティブを追加します。
これにより、globalセクションで定義したログサーバーにすべてのログが集約されます。
デフォルトではUDPトラフィックを受け付けないsyslogデーモンもあります。有効にする設定方法は、使用するデーモンによって異なります。
-
sysklogdでは、デーモンのコマンドラインに引数「-r」を渡し、UDPソケットでリモートのログを受け付ける必要があります。アドレスを127.0.0.1に制限する方法はないため、リモートシステムからのログも受信することに注意してください。
-
rsyslogdでは、設定ファイルに次の行を追加する必要があります。
- syslog-ngでは、次のように新しいソースを作成できます。その後、いずれかの「log」ディレクティブに有効なソースとして追加する必要があります。
詳細は、使用するsyslogデーモンのマニュアルを参照してください。システムのログファイルにログが出ない場合は、次の確認を検討してください。
-
haproxyを再起動します。各フロントエンドとバックエンドが、起動を示すログを一行出力します。それを受信できれば、ログの送信は機能しています。
-
「strace -tt -s100 -etrace=sendmsg -p <haproxy’s pid>」を実行し、ログが出るはずの操作を行います。sendmsg()でログメッセージを送信する様子が確認できるはずです。表示されない場合は、straceの下でhaproxyを再起動します。それでもログが出なければ、設定に問題があることが確実です。
-
tcpdumpでポート514を監視します。ローカルに送信している場合は、たとえば「tcpdump -As0 -ni lo port 514」でループバックインターフェースを監視します。パケットを確認できれば送信されている証拠なので、syslogdデーモンの問題を調べる必要があります。
トラフィックログは接続を受け付けるフロントエンドから送信しますが、バックエンドも、ヘルスチェックに伴うサーバーの状態変化を報告するためにログを送信できる必要があります。ログ設定の全項目については、HAProxyの設定マニュアルを参照してください。
他のデーモンが使っていないファシリティを選ぶと便利です。HAProxyの設定例では、トラフィックログに「local0」、管理ログに「local1」をよく勧めています。他のデーモンがこれらを使う例を運用現場では見かけないためです。ファシリティは一つでも十分です。ログを分けると分析しやすくなります。ただし、ログには機密情報が含まれることもあるため、権限のない人に誤って渡される可能性のある他のログと混ぜてはいけません。
サーバーの処理能力への影響を抑えながら運用現場で問題を調べるには、HAProxyに付属する「halog」ユーティリティを推奨します。grepに似たツールで、HAProxyのログファイルを高速に処理でき、一般に毎秒1~2GBのログを処理します。特定のログの抽出(HTTPステータスコードのクラス、接続終了状態、応答時間の範囲、エラーなどによる検索)、行数の集計、出力行数の制限が可能です。さらに、応答時間やエラー数でサーバーを並べ替える、時間や件数でURLを並べ替える、アクセス数でクライアントアドレスを並べ替えるといった高度な統計処理もできます。サイトを巡回し続けるボットなどの異常をすばやく見つけ、ブロックするのに便利です。
30 - 9. 統計情報とモニタリング
HAProxyに状態を問い合わせられます。最も一般的な方法はHTTP統計ページです。このページは、監視ツール向けにCSV出力形式も提供します。Unixソケットでも、同じ形式を利用できます。
統計情報は、HAProxy の複数のコンポーネントに対応するドメインと呼ばれるカテゴリに分類されます。利用可能なドメインは 2 つあります:proxy と resolvers。指定がなければ proxy ドメインが選択されます。なお、HTTP ページには proxy の統計情報のみが表示されます。
9.1. CSV 形式
統計情報は Unix ソケットまたは HTTP ページから参照できます。両方の方法とも、次のフィールドを持つ CSV 形式を提供します。最初の行はシャープ (’#’) で始まり、コンマ区切りの各フィールドごとに 1 つの単語が含まれ、それが列の見出しを表します。2 行目以降は、コンマを区切り文字として使用する通常の CSV 形式であり、テキストの曖昧さがある場合(クォートやコンマを含む場合)にのみダブルクォート(’"’)をオプションのテキスト区切り文字として使用します。テキスト内のダブルクォート文字(’"’)は二重に(’""’)エスケープされ、これはほとんどのツールが認識する形式です。列の先頭に追加の列を挿入しないでください。そうしないと、列位置をハードコードして処理しているツールが破損する可能性があります。
proxy 統計情報の場合、各フィールド名の後に、そのフィールドに値を持つ可能性があるタイプが括弧内に指定されます。タイプは L(リスナー)、F(フロントエンド)、B(バックエンド)、S(サーバ)です。静的フィールドは固定されたセットであり、常に同じ順序で利用可能です。文字 ‘-’ を含む列は静的フィールドの終了を示し、その後のフィールドの存在や順序は保証されません。
以下は proxy 統計情報ドメインにおける静的フィールドの一覧です:
他のすべての統計情報ドメインについては、フィールドの存在や順序は保証されません。この場合、常にヘッダー行を使用して CSV データを解析してください。
9.2. 型付き出力形式
“show info"と"show stat"は、各出力値に型と、プロセス間でどのように集計するべきか、値がどう変化するかを知るための十分な情報を添えるモードをサポートします。
すべての場合において、出力は 1 行あたり 1 つの値で構成され、すべての情報がコロン(’:’)で区切られたフィールドに分割されます。
1 番目の列はダンプ対象のオブジェクトまたはメトリクスを示します。その形式は、この出力を生成するコマンドに固有であり、本節では説明しません。通常、識別子とフィールド名の連続で構成されます。
2 番目の列には 4 文字が含まれ、それぞれが報告されている値の起源、性質、スコープ、および永続状態を示します。1 番目の文字(起源)は、値がどこから抽出されたかを示します。可能な文字は:
2 番目の文字(性質)は、フィールドが伝える情報の性質を示し、集計ツールが複数の値をどのように集計するかを判断するためのものです。可能な文字は:
三番目の文字(スコープ)は、値が反映する範囲を示します。プロセス単位の要素もあれば、設定単位やシステム単位の要素もあります。集計時に一つの値だけを保持するべきか、複数の値を集計する必要があるかを判断するうえで、この区別が重要です。現在は、次の文字をサポートします。
4 番目の文字(永続状態)は、値(メトリクス)がリロード間で揮発的か、永続的かを示します。期待される文字は:
これらの情報を利用する側は、一般に、この4文字があれば、複数のプロセスにまたがる集計情報を正しく報告する方法を判断できます。
この列の後、3 番目の列はフィールドの型を示します。可能な型は “s32”(符号付き 32 ビット整数)、“s64”(符号付き 64 ビット整数)、“u32”(符号なし 32 ビット整数)、“u64”(符号なし 64 ビット整数)、“str”(文字列)です。値を正しく読み取るためには、型を事前に知ることが重要です。たとえば、数字のみを含む文字列であっても、整数ではなく文字列であることに注意してください(例:チェックによって抽出されたエラーコード)。
その後、4 番目の列は、その型に従ってエンコードされた値そのものです。文字列はコロンの直後にスペースを挿入せずにそのままダンプされます。文字列にコロンが含まれる場合、通常通り表示されます。これは、出力をコロンで単純に分割しないようにする必要があることを意味します。そうでないと、チェックの出力やサーバアドレスが途中で切り捨てられる可能性があります。
9.3. Unix ソケット コマンド
統計ソケットは、デフォルトでは有効になっていません。有効にするには、haproxy設定のグローバルセクションに一行追加する必要があります。手動でコマンドを入力するときに便利な、長めのタイムアウトを設定するため、二行目も追加することを推奨します。
同じ行を繰り返すと、統計ソケットを複数追加でき、UNIXソケットの代わりにTCPポートで待ち受けるようにもできます。危険なので、デフォルトでは決してこのようにしませんが、場合によっては便利です。
ソケットにアクセスするには、“socat” などの外部ユーティリティが必要です。Socat はあらゆるものをあらゆるものに接続する万能ツールです。私たちは、端末をソケットに接続する、またはスクリプト用に stdin/stdout パイプをソケットに接続するために使用します。主に使用する 2 つの構文は以下の通りです:
1 番目の構文はスクリプトで使用します。スクリプトの出力を HAProxy に送信し、HAProxy の出力を別のスクリプトに渡すことが可能です。これは、カウンターや攻撃トレースを取得する場合などに有用です。
2 番目は手動でコマンドを発行する場合にのみ有用です。readline ライブラリが端末を処理するため、行編集や履歴がサポートされ、繰り返しコマンドを発行する場合(例:カウンタの監視)に非常に便利です。
ソケットは以下の 3 種類の操作モードをサポートしています:
- 非インタラクティブ、サイレント
- インタラクティブ、サイレント
- インタラクティブでプロンプト付き
非インタラクティブモードは、socat がソケットに接続する際のデフォルトです。このモードでは 1 行のみ送信できます。1 行全体が処理され、レスポンスが返信された後、接続が閉じられます。これはスクリプトやモニタリングツールが使用するモードです。このモードでは複数のコマンドを送信することも可能ですが、セミコロン (’;’) で区切る必要があります。たとえば:
コマンド内でセミコロンやバックスラッシュ(例:値の中)を使用する場合、それらの前にバックスラッシュ (’\’) を付ける必要があります。
インタラクティブモードでは、前の行のコマンドが終了した後に新しいコマンドを送信できます。このモードは 2 つのバリエーションがあります。1 つはサイレントで、非インタラクティブモードと同様ですが、接続が閉じる代わりに新しいコマンドを待機します。もう 1 つは行頭にプロンプト (’>’) が表示されるモードです。高度なツールにはインタラクティブモードが推奨され、人間が使うにはプロンプトモードが推奨されます。
モードは “prompt” コマンドで変更できます。デフォルトでは、インタラクティブ+プロンプトモードを切り替えます。インタラクティブモードで “prompt” を入力すると、プロンプトモードに切り替わります。コマンドはオプションで以下の特定モードを指定できます:
- “n”:非インタラクティブモード(1 コマンドのみ、終了)
- “i”:インタラクティブモード(複数のコマンド、プロンプトなし)
- “p”:プロンプトモード(複数のコマンド、プロンプト付き)
デフォルトモードが非インタラクティブであるため、モードを切り替えるには最初に “prompt” を実行する必要があります。それ以外の場合、前のコマンドが接続を閉じてしまいます。非インタラクティブモードに切り替えると、同じ行のすべてのコマンドが終了した後に接続が閉じられます。
このため、手動でデバッグを行う際には “prompt” コマンドから始めるのが一般的です:
show info …
対話的なツールでは、“prompt i"で開始して、プロンプトなしの対話モードへ切り替える方法が適している場合があります。
任意で、プロセスの稼働時間をプロンプトに表示できます。“prompt timed"コマンドは、プロンプトを有効にし、時間表示の有無を切り替えます。稼働時間の形式は"d:hh:mm:ss"で、“d"は日数、“hh”、“mm”、“ss"は、それぞれ二桁の時間、分、秒です。
[23:03:34:39]> show version 2.8-dev9-e5e622-18
[23:03:34:41]> quit
タイム付きプロンプトがマスタ CLI で設定されている場合、プロンプトには現在選択されているプロセスのアップタイムが表示されるため、マスタ、現在のワーカ、または以前のワーカのいずれでも動作します。
複数のコマンドを一度に入力できるため、haproxyは空行を各コマンドの出力終了を示す区切りに使い、どのコマンドも出力に空行を含められないようにします。そのため、一行に複数のコマンドを連ねても、スクリプトは容易に出力を解析できます。
一部のコマンドは、任意のペイロードを受け取れます。追加するには、最初の行を”<<\n"パターンで終える必要があります。それ以降の行をペイロードとして扱い、必要なだけ行を含められます。ペイロード付きコマンドを確定するには、空行で終える必要があります。
ペイロードの終了パターンはカスタマイズ可能です。空行以外のものでペイロードを終了させるには、’<<’ と ‘\n’ の間にカスタムパターンを設定できます。’<<’ に加えて最大 64 文字まで使用でき、それ以上はペイロードと見なされません。ランダムなペイロードパターンを使用するには十分な長さです。たとえば、空行やコメントを含む PEM ファイルを使用する場合:
制限があります:パターン “<<” は行の最後の単語に接着してはいけません。コマンド行の長さは、ペイロードを開始するパターンを含むがペイロード自体は除く、tune.bufsize を超えてはいけません。ペイロードサイズはデフォルトで 128KB までです。この値は “tune.cli.max-payload-size” グローバルパラメータを設定することで変更できますが、注意が必要です。ペイロードの終了を示すパターンはこの制限に含まれます。
インタラクティブモードでペイロードを入力する際、プロンプトは “> " から “+ " に変わります。
複数のhaproxyプロセスを同じソケットで起動すると、どのプロセスがリクエストを受け取るかは決まっておらず、受け取ったプロセスが自分自身の統計を出力することを理解しておく必要があります。
統計ソケットが現在サポートするコマンドを以下に示します。未知のコマンドを送ると、haproxyは、サポートする全コマンドを確認できる使用法メッセージを表示します。一部のコマンドは複雑な構文に対応しており、その場合、通常は、コマンドのどの部分が不正かを説明します。
一部のコマンドはより高い権限レベルが必要です。十分な権限がない場合、「Permission denied」というエラーが表示されます。詳細については、設定マニュアルの “bind” キーワード行の “level” オプションを確認してください。
abort ssl ca-file <cafile>
一時的なCAファイルの更新トランザクションを中止し、破棄します。
「set ssl ca-file」と「commit ssl ca-file」も参照してください。
abort ssl cert <filename>
一時的なSSL証明書の更新トランザクションを中止し、破棄します。
「set ssl cert」と「commit ssl cert」も参照してください。
abort ssl crl-file <crlfile>
一時的な CRL ファイル更新トランザクションを中止し、破棄します。
「set ssl crl-file」と「commit ssl crl-file」も参照してください。
acme renew <certificate>
指定した証明書名で、ACME証明書の生成タスクを開始します。証明書はacmeセクションに関連付けられていなければなりません。設定マニュアルのセクション12.8 「ACME」を参照してください。“acme status"も参照してください。
acme status
ACME で設定されたすべての証明書の状態を表示します。
このコマンドは、タブで区切って出力します:
- HAProxy で設定された証明書の名前
- 設定で使用された acme セクション
- ACME タスクの状態。いずれか「Running」、「Scheduled」、「Stopped」
- 証明書の UTC での有効期限日時(ISO8601 形式)
- 有効期限までの相対時間(期限切れなら0d)
- 証明書の UTC でのスケジュール日時(ISO8601 形式)
- 相対的なスケジュール時間(Running の場合は 0d)
例:
add acl [@<ver>] <acl> <pattern>
ACL <acl> にエントリを追加します。<acl> は “show acl” によって返された #<id> または <name> です。エントリが既に存在するかの検証は行われません。エントリは、特定のバージョンが指定されていない限り、現在の ACL バージョンに追加されます。特定のバージョンを指定するには “@<ver>” を使用します。このバージョン番号は、事前に “prepare acl” で割り当てられている必要があります。また、“show acl” の出力で報告される “curr_ver” と “next_ver” の間のバージョンになります。特定のバージョン番号で追加されたエントリは、「commit acl」操作が実行されるまで一致しません。ただし、「show acl @<ver>」コマンドで照会したり、「clear acl @<ver>」コマンドでクリアすることは可能です。参照する <acl> がマップと同時に使用されている名前である場合、このコマンドは使用できません。この場合、「add map」コマンドを使用する必要があります。
add backend <name> from <defproxy> [mode <mode>] [guid <guid>]
名前 <name> の新しいバックエンドプロキシをインスタンス化します。
作成できるのはTCPまたはHTTPプロキシだけです。設定はすべて、デフォルトプロキシのインスタンス<defproxy>から継承します。デフォルトでは、<defproxy>が明示的に定義していない限り、同名の引数でバックエンドのモードを必ず指定しなければなりません。必要なら、任意のGUID引数も使えます。
サーバは「add server」コマンドで追加できます。バックエンドは非公開状態で初期化されます。トラフィックに使用可能と判断されたら、「publish backend」を使用して新しく作成されたインスタンスを公開します。
名前付きのデフォルトプロキシは、設定解析時に適用される継承ルールを満たしている限り使用可能です。ただし例外もあり、たとえばモードが TCP でも HTTP でもない場合などです。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
add map [@<ver>] <map> <key> <value>
マップ <map> にエントリを追加し、キー <key> に値 <value> を関連付けます。エントリが既に存在するかの検証は行われません。主に「clear」または「prepare」操作後にマップを埋めるために使用します。エントリは、特定のバージョンが指定されていない限り、現在の ACL バージョンに追加されます。特定のバージョンを指定するには “@<ver>” を使用します。このバージョン番号は、事前に “prepare acl” で割り当てられている必要があります。また、“show acl” の出力で報告される “curr_ver” と “next_ver” の間のバージョンになります。特定のバージョン番号で追加されたエントリは、「commit map」操作が実行されるまで一致しません。ただし、「show map @<ver>」コマンドで照会したり、「clear acl @<ver>」コマンドでクリアすることは可能です。指定されたマップが ACL としても使用されている場合、ACL は <key> 部分のみを一致させ、<value> 部分を無視します。ペイロード構文を使用すると、複数のキー/値ペアを別々の行に記述することで追加できます。各行の最初の単語がキーとなり、残りの行は値として扱われ、スペースを含むことも可能です。
例:
add server <backend>/<server> [args]*
バックエンド <backend> に接続された新しいサーバをインスタンス化します。
<server>の名前は、バックエンド内で未使用でなければなりません。バックエンドには、動的ロードバランシングアルゴリズムを使わなければならないという、特別な制限があります。設定ファイルのserver文の一部のキーワードで、サーバーの動作を設定できます(一覧は"add server help"を参照)。同じバックエンドに’default-server’文があったとしても、その設定は一切再利用しない点にも注意してください。
現在、動的サーバーは、init-addrの"none"方式で静的に初期化します。そのため、アドレスにFQDNを指定しても、サーバーの作成自体が受け付けられたとしても、名前解決は行いません。
リロード操作に対応するため、CLIで作成したサーバーは、該当するhaproxy設定ファイルにも手動で追加しておくことを想定しています。設定にない動的サーバーは、リロード後に復元しません。
動的サーバは、構成内の別のサーバのチェックステータスを追跡する「track」キーワードを使用できます。ただし、別の動的サーバを追跡することはできません。これは、動的サーバの削除が発生しても追跡チェーンが一貫性を保つようにするためです。
ヘルスチェックをサポートするには、“check"キーワードを使います。ヘルスチェックはデフォルトでは無効で、サーバー自体とは別に、“enable health"コマンドで有効にしなければなりません。エージェントチェックには、“agent-check"キーワードと"enable agent"コマンドを使います。この場合、報告される状態に応じて、明示的な"enable server"コマンドがなくても、エージェントがサーバーを有効にすることがあります。そのため、エージェントチェックを持つ動的サーバーの削除には、特に注意が必要です。削除に必要なメンテナンスモードへサーバーを移せるよう、先に"disable agent"でエージェントを無効にするべきです。
大量の動的サーバーを使用する場合、ファイルディスクリプタの制限に達する可能性があります。その場合は、「u-limit」グローバルキーワードのドキュメントを参照してください。
add server help
現在の HAProxy バージョンでサポートされる動的サーバー用のキーワードをリストアップします。キーワードの構文は設定ファイルのサーバーラインと類似しており、詳細については個別ドキュメントを参照してください。
add ssl ca-file <cafile> <payload>
CA ファイルに新しい証明書を追加します。CLI でのバッファサイズ制限に達した場合に、複数の証明書を追加するのに有用です。すべての証明書を一度に「set」する代わりに、個別に証明書を追加できます。「set ssl ca-file」は CA ファイルをリセットします。
例:
add ssl crt-list <crtlist> <certificate>
crt-listに証明書を追加します。ディレクトリも現在はcrt-listと同じ方法で読み込むため、ディレクトリにも使えます。このコマンドは、パラメーターに証明書名を指定できます。SSLオプションやフィルターを使う場合は、代わりにcrt-listの一行をペイロードとして送らなければなりません。ペイロードでサポートするのはcrt-listの一行だけです。このコマンドは、crt-listを使うすべてのbind行に証明書を読み込みます。HAProxyへ新しい証明書を送るには、“new ssl cert"と"set ssl cert"コマンドを使わなければなりません。
例:
add ssl ech <bind> <payload>
<bind> 行に ECH キーを追加します。ペイロードは ECH 形式の PEM でなければなりません。
(https://datatracker.ietf.org/doc/html/draft-farrell-tls-pemesni
)
bind行の形式は<frontend>/@<filename>:<linenum>(例:frontend1/@haproxy.conf:19)です。“name"キーワードでbind行に名前を付けた場合は、<frontend>/<name>形式も使えます。
OpenSSL のバージョンが ECH をサポートしている必要があり、HAProxy は USE_ECH=1 でコンパイルされている必要があります。このコマンドは、実験モードで実行されている CLI 接続でのみサポートされます(「experimental-mode on」を参照)。
“show ssl ech"と、設定マニュアルのセクション5.1 にある"ech"も参照してください。
例:
add ssl jwt <filename>
JWT 検証に使用できる証明書リストに、すでに読み込まれた証明書を追加します(“jwt_verify_cert” コンバーターを参照)。このコマンドは進行中のトランザクションでは動作しません。また、「del ssl jwt」と「show ssl jwt」コマンドも参照してください。詳細については「jwt」証明書オプションを参照してください。
clear counters
各プロキシ(フロントエンドおよびバックエンド)および各サーバーの統計カウンターの最大値をクリアします。累積カウンターには影響しません。「show activity」で報告される内部アクティビティカウンターもリセットされます。このコマンドは、事故後のクリーンなカウンターを取得するために使用でき、再起動やトラフィックカウンターのクリアを必要としません。このコマンドは制限付きであり、レベル「operator」または「admin」に設定されたソケットでのみ実行できます。
clear counters all
各プロキシ(フロントエンドおよびバックエンド)および各サーバーのすべての統計カウンターをクリアします。再起動と同等の効果があります。このコマンドは制限付きであり、レベル「admin」に設定されたソケットでのみ実行できます。
clear acl [@<ver>] <acl>
ACL <acl> からすべてのエントリを削除します。<acl> は「show acl」によって返される #<id> または <name> です。参照 <acl> が名前であり、マップと共有されている場合、そのマップもクリアされます。デフォルトでは、現在のバージョンの ACL(照合対象となっているもの)のみがクリアされます。ただし、’@’ に続いてバージョンを指定することで、別のバージョンを指定することも可能です。
clear map [@<ver>] <map>
マップ <map> からすべてのエントリを削除します。<map> は「show map」によって返される #<id> または <name> です。参照 <map> が名前であり、ACL と共有されている場合、その ACL もクリアされます。デフォルトでは、現在のバージョンのマップ(照合対象となっているもの)のみがクリアされます。ただし、’@’ に続いてバージョンを指定することで、別のバージョンを指定することも可能です。
clear table <table> [ data.<type> <operator> <value> ] | [ key <key> ] |
stick-table <table> からエントリを削除します。
通常は、サービスへのアクセスが不当に拒否されたと訴えるユーザーのブロック解除に使いますが、交換予定のサーバーに対応する永続性のエントリーを消す用途にも使えます(詳細は後述の"show table"を参照)。現在、セッションがエントリーを追跡しているために、削除を拒否する場合がある点に注意してください。通常は、数秒後、セッションが終了してから再試行すれば十分です。
オプション引数が指定されない場合、すべてのエントリが削除されます。
“data.“形式では、保存データに適用したフィルターにマッチするエントリーを削除します(セクション4.2の"stick-table"を参照)。<type>には保存データの型を指定しなければならず、その型のデータをテーブルに保存していなければ、エラーになります。<operator>に従い、データを64ビット整数<value>と比較します。演算子はACLと同じです。
- eq:データがこの値と等しいエントリをマッチ
- ne:データがこの値と等しくないエントリをマッチ
- le:データがこの値以下のエントリーにマッチします。
- ge:データがこの値以上のエントリーにマッチします。
- lt:データがこの値未満のエントリーにマッチします。
- gt:データがこの値より大きいエントリーにマッチします。
key形式では、エントリー<key>を削除します。キーはテーブルと同じ型でなければならず、現在はIPv4、IPv6、整数、文字列に限られます。
ptr形式では、エントリー<ptr>を削除します。<ptr>は0xffff形式で書き、以前の"show table"コマンドが返したアドレスに対応していなければなりません。空のキーやCLIで扱えない文字のためにキーでマッチできない場合、ポインターでエントリーをマッチさせる方法が有効な場合があります。
data.<type>が配列型なら、”[]“で特定のインデックスへアクセスできます。たとえば、data.gpt[1]です。
例:
commit acl @<ver> <acl>
バージョン <ver> の ACL <acl> に対して行ったすべての変更をコミットし、過去のすべてのバージョンを削除します。<acl> は “show acl” から返された #<id> または <name> です。バージョン番号は “show acl” で報告された “curr_ver”+1 から “next_ver” の範囲内である必要があります。コミット対象の内容は、必要に応じて “show acl @<ver> <acl>” で確認できます。指定されたバージョン番号は通常、“prepare acl” コマンドで作成されています。置換はアトミックです。これは、現在のバージョンを指定されたバージョンにアトミックに更新することを意味し、これにより他のバージョンのすべてのエントリが即座に非表示になり、新しいバージョンのすべてのエントリが表示されます。また、“prepare acl” を実行した後にエントリを追加せずにコミットすることで、ACL のすべての表示エントリをアトミックに削除することも可能です。参照 <acl> がマップとしても使用されている名前である場合、このコマンドは使用できません。この場合、代わりに “commit map” コマンドを使用する必要があります。
commit map @<ver> <map>
バージョン <ver> のマップ <map> に対して行ったすべての変更をコミットし、過去のすべてのバージョンを削除します。<map> は “show map” から返された #<id> または <name> です。バージョン番号は “show map” で報告された “curr_ver”+1 から “next_ver” の範囲内である必要があります。コミット対象の内容は、必要に応じて “show map @<ver> <map>” で確認できます。指定されたバージョン番号は通常、“prepare map” コマンドで作成されています。置換はアトミックです。これは、現在のバージョンを指定されたバージョンにアトミックに更新することを意味し、これにより他のバージョンのすべてのエントリが即座に非表示になり、新しいバージョンのすべてのエントリが表示されます。また、“prepare map” を実行した後にエントリを追加せずにコミットすることで、マップのすべての表示エントリをアトミックに削除することも可能です。
commit ssl ca-file <cafile>
一時的な SSL CA ファイル更新トランザクションをコミットします。
既存の CA ファイル(“show ssl ca-file” で “Used” 状態)の場合、新しい CA ファイルのツリー エントリが CA ファイルツリーに挿入され、CA ファイルエントリを使用していたすべてのインスタンスが再構築され、必要な SSL コンテキストも再構築されます。再構築されたインスタンスが以前に使用していたすべてのコンテキストは削除されます。成功した場合、以前の CA ファイルエントリはツリーから削除されます。失敗した場合、何も削除されず、すべての元の SSL コンテキストが保持され使用されます。一時トランザクションがコミットされると、そのトランザクションは破棄されます。
新しいCAファイルの場合(“new ssl ca-file"の後、“show ssl ca-file"で"Unused"の状態)は、CAファイルツリーへ挿入しますが、HAProxy内のどこでも使いません。使い始め、そのSSLコンテキストを生成するには、“add ssl crt-list"でcrt-listへ追加する必要があります。
“new ssl ca-file”、“set ssl ca-file”、“add ssl ca-file”、“abort ssl ca-file”、“add ssl crt-list” も参照してください。
commit ssl cert <filename>
一時的な SSL 証明書更新トランザクションをコミットします。
既存の証明書(“show ssl cert” で “Used” 状態)の場合、必要なすべての SSL コンテキストと SNI を生成し、挿入し、以前のものを削除します。構成で <filename> が使用されていた場所すべてで、以前の SSL 証明書をメモリ上に置き換える。失敗した場合、何も削除または挿入しません。一時トランザクションがコミットされると、そのトランザクションは破棄されます。
新しい証明書の場合(“new ssl cert"の後、“show ssl cert"で"Unused"の状態)は、証明書ストレージへコミットしますが、haproxy内のどこでも使いません。使い始め、そのSNIを生成するには、“add ssl crt-list"でcrt-listまたはディレクトリへ追加する必要があります。
“new ssl cert”、“set ssl cert”、“abort ssl cert”、“add ssl crt-list” も参照してください。
commit ssl crl-file <crlfile>
一時的な SSL CRL ファイル更新トランザクションをコミットします。
既存の CRL ファイル(“show ssl crl-file” で “Used” 状態)の場合、新しい CRL ファイルエントリが CA ファイルツリー(CA ファイルと CRL ファイルを両方保持)に挿入され、CRL ファイルエントリを使用していたすべてのインスタンスが再構築され、必要な SSL コンテキストも再構築されます。再構築されたインスタンスが以前に使用していたすべてのコンテキストは削除されます。成功した場合、以前の CRL ファイルエントリはツリーから削除されます。失敗した場合、何も削除されず、すべての元の SSL コンテキストが保持され使用されます。一時トランザクションがコミットされると、そのトランザクションは破棄されます。
新しいCRLファイルの場合(“new ssl crl-file"の後、“show ssl crl-file"で"Unused"の状態)は、CRLファイルツリーへ挿入しますが、HAProxy内のどこでも使いません。使い始め、そのSSLコンテキストを生成するには、“add ssl crt-list"でcrt-listへ追加する必要があります。
“new ssl crl-file”、“set ssl crl-file”、“abort ssl crl-file”、“add ssl crt-list” も参照してください。
debug counters [reset|show|on|off|all|bug|chk|cnt|glt|?]*
コード内に配置された内部カウンターの一覧を表示します。これらのカウンターは、ビルドオプションによって異なる場合があります。一部は DEBUG_STRICT に依存し、他の一部は DEBUG_COUNTERS に依存します。このコマンドは複数の引数の組み合わせを取るため、一部はアクションを定義し、他の一部はフィルターを定義します。- bug は BUG_ON() ステートメントのカウンターを表示します - cnt は COUNT_IF() ステートメントのカウンターを表示します - chk は CHECK_IF() ステートメントのカウンターを表示します - glt は COUNT_GLITCH() ステートメントのカウンターを表示します - all は一度もトリガーされなかったカウンター(値が 0)を表示します - off アクション:COUNT_IF() カウンターの更新を無効化します - on アクション:COUNT_IF() カウンターの更新を有効化します - reset アクション:指定されたすべてのカウンターをリセットします - show アクション:指定されたすべてのカウンターを表示します
デフォルトのアクションは、カウンターを表示する"show"で、種類を問わず、値がゼロでないカウンターを一覧にします。他のアクションを指定しなければ"show"は暗黙的に適用します。明示的な"show"は、スクリプトからコマンドを生成しやすくするためだけに存在します。
出力は整数のカウンターから始まり、その後にカウンターのタイプ(大文字)、コード上の位置(ファイル:行)、関数名が続き、必要に応じて “: " と説明が続きます。出力形式はメジャーバージョン間で変更される可能性があること、また新しいタイプやエントリが安定版にバックポートされる場合があることに注意してください。これはデバッグ能力の向上のためです。それらに対する監視は、非常に緩やかで許容的な方法で行うべきであり、できれば行わないでください。
通常、エンドユーザーはこのコマンドを使用しませんが、問題の原因を特定しようとしている開発者が、CNT または GLT エントリを探すためにユーザーに使用を依頼することがあります。一方、非ゼロの “CHK” エントリは想定されておらず、コード内の誤った仮定を示している可能性があるため、開発者に報告すべきです。
debug dev <command> [args]*
開発者専用のコマンドを呼び出します。CLI 接続でエキスパートモードが有効になっている場合にのみサポートされます(「expert-mode on」を参照)。これらのコマンドは極めて危険であり、誤操作に対する余裕がなく、誤用するとプロセスのクラッシュを引き起こす可能性があります。これらはエキスパート専用であり、指示された場合を除き、絶対に使用してはなりません。一部のコマンドは haproxy を DEBUG_DEV を定義してビルドした場合にのみ利用可能であり、セキュリティ上の影響を伴う可能性があるためです。これらのすべてのコマンドには管理者権限が必要であり、ソースコードに精通していない人が使用することを避けるために意図的にドキュメント化されていません。
del acl <acl> [<key>|#<ref>]
キー <key> に対応する acl <acl> からすべての acl エントリを削除します。<acl> は “show acl” によって返された #<id> または <name> です。<ref> が使用された場合、このコマンドはリストされた参照のみを削除します。参照は acl の内容をリストすることで確認できます。参照 <acl> が名前であり、map と共有されている場合、エントリは map でも削除されます。
del backend <name>
名前 <name> のバックエンドプロキシを削除します。
この操作は TCP または HTTP プロキシに対してのみ可能です。成功するためには、まずバックエンドインスタンスが公開解除されている必要があります。また、そのすべてのサーバーはまず削除されている必要があります(“del server” CLI を使用)。最後に、バックエンドインスタンスにまだ接続されているストリームが存在してはなりません。
バックエンドの削除を妨げる、その他の制限もあります。まず、use_backendルールやサンプル式など、設定の要素が明示的に参照するバックエンドは削除できません。一部のプロキシオプションも実行中の削除と両立せず、現在は、非推奨のdispatchまたはoption transparentを使う場合が該当します。また、スティックテーブルを宣言しているバックエンドも削除できません。最後に、QUICサーバーが存在していたバックエンドは、現時点では削除できません。
このコマンドの前に"wait be-removable"を使うと、上記の条件を確認するのに便利です。また、対象のバックエンドに結び付いたストリームが最後に閉じられるまで待つ方法にもなります。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
del map <map> [<key>|#<ref>]
キー <key> に対応する map <map> からすべての map エントリを削除します。<map> は “show map” によって返された #<id> または <name> です。<ref> が使用された場合、このコマンドはリストされた参照のみを削除します。参照は map の内容をリストすることで確認できます。参照 <map> が名前であり、acl と共有されている場合、エントリは map でも削除されます。
del ssl ca-file <cafile>
HAProxy から CA ファイルツリーのエントリを削除します。CA ファイルは使用されておらず、すべての crt-list から削除されている必要があります。“show ssl ca-file” は CA ファイルの状態を表示します。設定ファイル内の “ca-file” または “ca-verify-file” ディレクティブで直接参照されている証明書に対しては削除はできません。
del ssl cert <certfile>
HAProxyから証明書ストアを削除します。証明書は、JWT検証も含めて未使用で、すべてのcrt-listやディレクトリから取り除かれていなければなりません。“show ssl cert"で証明書の状態を表示できます。設定の"crt"ディレクティブが直接参照する証明書は、削除できません。
del ssl crl-file <crlfile>
HAProxy から CRL ファイルツリーのエントリを削除します。CRL ファイルは使用されておらず、すべての crt-list から削除されている必要があります。“show ssl crl-file” は CRL ファイルの状態を表示します。設定ファイル内の “crl-file” ディレクティブで直接参照されている証明書に対しては削除はできません。
del ssl crt-list <filename> <certfile[:line]>
crt-list 内のエントリを削除します。これにより、このエントリに使用されているすべての SNI がフロントエンドで削除されます。同じ証明書が crt-list 内で複数回使用されている場合、削除する行を指定する必要があります。行番号を表示するには “show ssl crt-list -n <crtlist>” を使用します。
del ssl ech <bind>
バインド行のECHキーを削除します。
bind行の形式は<frontend>/@<filename>:<linenum>(例:frontend1/@haproxy.conf:19)です。“name"キーワードでbind行に名前を付けた場合は、<frontend>/<name>形式も使えます。
OpenSSL のバージョンが ECH をサポートしている必要があり、HAProxy は USE_ECH=1 でコンパイルされている必要があります。このコマンドは、実験モードで実行されている CLI 接続でのみサポートされます(「experimental-mode on」を参照)。
“show ssl ech”、“add ssl ech"と、設定マニュアルのセクション5.1 にある"ech"も参照してください。
例:
del ssl jwt <filename>
JWT検証に使える証明書の一覧から、既に読み込んだ証明書を取り除きます(“jwt_verify_cert"コンバーターを参照)。進行中のトランザクションには、このコマンドは使えません。“add ssl jwt"と"show ssl jwt"コマンドも参照してください。詳細は"jwt"証明書オプションを参照してください。
del server <backend>/<server>
バックエンド <backend> に接続された削除可能なサーバーを削除します。削除可能なサーバーとは、以下のすべての条件を満たすサーバーを指します:
- 他の構成要素によって参照されていないこと
- すでにメンテナンスモードにあること(「disable server」を参照)
- アクティブまたはアイドル状態の接続が存在しないこと
これらの条件のいずれかを満たさない場合、コマンドは失敗します。
有効な接続とは、進行中のリクエストが少なくとも一つある接続です。“shutdown sessions server"で、終了を早められます。有効な接続とアイドル接続がすべて閉じられ、コマンドが確実に成功するよう、“del server"の前に"wait srv-removable"を使うことを強く推奨します。
disable agent <backend>/<server>
補助エージェントチェックを一時停止状態としてマークします。
serverディレクティブのagent-checkパラメーターにより、エージェントチェックを補助チェックとして使っている場合、新しいチェックは、エージェントが有効な場合だけ開始します。したがって、disable agentは、enable agentで再び有効にするまで、すべての新しいエージェントチェックの開始を防ぎます。
エージェントが無効化された場合、エージェントが有効状態であった間に開始された補助エージェントチェックの処理は以下の通りです:重みを変更する可能性のある結果(特に「drain」またはエージェントが返す重み)は無視されます。エージェントチェックの処理その他の部分は変更されません。
この機能の目的は、エージェントチェックによる重みの変更効果を一時停止し、set weight コマンドでサーバーの重みを設定した後にエージェントによる上書きを防ぐことです。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
disable dynamic-cookie backend <backend>
バックエンド <backend> における動的クッキーの生成を無効化します。
disable frontend <frontend>
フロントエンドを一時停止状態にします。ソフト再起動で使うモードに相当し、ポートを解放しますが、必要なら再び有効にできます。Linux以外の一部のOSは再び有効にできないため、慎重に使うべきです。プロキシの停止など考えられない環境で、誤って設定したプロキシを修正しなければならない場合を想定しています。ポートを解放して別のプロセスにバインドし、運用を復旧できます。統計ページでは、フロントエンドを"STOP"状態で表示します。
フロントエンドは名前またはシャープ記号(’#’)を付加した数値IDのいずれかで指定できます。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
disable health <backend>/<server>
プライマリヘルスチェックを一時停止状態としてマークします。これによりヘルスチェックの送信が無効化され、最後のヘルスチェック結果は無視されます。サーバーはチェック未実施状態となり、補助エージェントチェックが強制的にダウンにしない限りUPと見なされます。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
disable server <backend>/<server>
サーバーをメンテナンス用にDOWN状態としてマークします。このモードでは、サーバーがメンテナンスから離れるまで、さらにチェックは実行されません。他のサーバーによって追跡されている場合、その追跡サーバーはメンテナンス中はDOWN状態になります。
統計ページでは、メンテナンス用にDOWN状態のサーバーは「MAINT」ステータスで表示され、追跡サーバーは「MAINT(via)」ステータスで表示されます。
バックエンドおよびサーバーは、名前またはシャープ記号(’#’)を付加した数値IDのいずれかで指定できます。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
dump ssl cert <certfile>
HAProxyのメモリーに読み込んだ証明書を出力します。PEM形式で、秘密鍵、リーフ証明書、最後にチェーンの順に出力します。ファイル名の前にアスタリスクを付けると、トランザクションも出力できます。ファイルシステム上では更新せず、CLIで更新した証明書を、ファイルシステムへ保存するのに便利です。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
例:
dump stats-file
起動時にHAProxyカウンター値を事前読み込みできるようにするためのstats-fileを生成します。詳細については「統計ファイル」セクションを参照してください。
echo <text>
CLIでテキストを出力します。複数のコマンドの結果を出力するとき、コマンドの間にコメントを書くのに便利です。
例:
enable agent <backend>/<server>
一時停止状態にされた補助エージェントチェックを再開します。
補助エージェントの一時停止および再開の効果については、「disable agent」を参照してください。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
enable dynamic-cookie backend <backend>
バックエンド<backend>の動的Cookieの生成を有効にします。秘密キーも指定しなければなりません。
enable frontend <frontend>
一時停止状態にされたフロントエンドを再開します。一部のリスニングポートが再バインドできなくなる可能性があります(例:‘disable frontend’操作後に別のプロセスがそれらを占有した場合)。その場合、エラーが表示されます。一部のオペレーティングシステムでは、無効化されたフロントエンドの再開ができない場合があります。
フロントエンドは名前またはシャープ記号(’#’)を付加した数値IDのいずれかで指定できます。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
enable health <backend>/<server>
一時停止したプライマリヘルスチェックを再開し、チェックの送信を再び有効にします。詳細は"disable health"を参照してください。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
enable server <backend>/<server>
サーバーが以前にメンテナンスのために DOWN とマークされていた場合、このコマンドはサーバーを UP にマークし、ヘルスチェックが再び有効になります。
バックエンドおよびサーバーは、名前またはシャープ記号(’#’)を付加した数値IDのいずれかで指定できます。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
experimental-mode [on|off]
オプションを指定しない場合、現在の接続で実験モードが有効化されているか否かを示します。“on” を指定すると、現在の CLI 接続でのみ実験モードを有効化します。“off” を指定すると無効化します。
実験モードは開発中の追加機能にアクセスするために使用されます。これらの機能は現在安定しておらず、注意を要します。バージョン間で破壊的な変更が加えられる可能性があります。
マスターCLIから使う場合、このコマンドに接頭辞を付けるべきではありません。各ワーカーのCLIに接続するときに、そのワーカーのモードを設定するためです。
例:
expert-mode [on|off]
このコマンドは experimental-mode に似ていますが、エキスパートモードを切り替えるために使用されます。
エキスパートモードは、プロセスにとって極めて危険になり得るエキスパートコマンドの表示を有効にします。これらのコマンドは、開発者が複雑な不具合に関する重要な情報を集めるのに役立つ場合があります。誤用すれば、プロセスがクラッシュする可能性が高いため、使用するよう求められない限り、このオプションを使わないでください。このコマンドは、意図的にヘルプメッセージへ載せていません。adminレベルでだけ使えます。他のレベルへ変更すると、エキスパートモードは自動的にリセットされます。
マスターCLIから使う場合、このコマンドに接頭辞を付けるべきではありません。各ワーカーのCLIに接続するときに、そのワーカーのモードを設定するためです。
例:
get map <map> <value>
マップ <map> または ACL <acl> 内で <value> の値を検索します。<map> または <acl> は “show map” または “show acl” によって返される #<id> または <name> です。このコマンドは、このマップに関連付けられたすべての一致するパターンを返します。マップや ACL のデバッグに有用です。出力形式は、一致するタイプごとに1行ずつ構成されます。各行はスペース区切りの単語列で構成されます。
最初の2つの単語は:
次の単語は、パターンがエントリと一致した場合にのみ返されます。
`<index type>`: "tree" または "list"。内部の検索アルゴリズム。
`<case>`: "case-insensitive" または "case-sensitive"。大文字小文字の解釈。
`<entry matched>`: match="`<entry>`"。一致したパターンを返す。正規表現と組み合わせて有用。
最後の2つの単語は、返された値とその型を示すために使用されます。“acl” の場合、パターンは存在しません。
return=nothing: "map" が存在しないため、返却なし。
return="`<value>`": 文字列形式で返された値。
return=cannot-display: 値を文字列に変換できない。
type="`<type>`": 返されたサンプルの型。
get var <name>
プロセス全体の変数 ’name’ の存在、型、内容を表示します。プロセス全体の変数のみが読み取り可能であるため、名前は ‘proc.’ で始まる必要があります。それ以外の場合は、変数は見つかりません。このコマンドは “operator” または “admin” レベルが必要です。
get weight <backend>/<server>
バックエンド <backend> のサーバー <server> の現在の重みと初期重みを報告するか、いずれかが存在しない場合はエラーを報告します。初期重みは設定ファイルに記載されている重みです。現在の重みが変更されていない限り、両者は通常等しくなります。バックエンドおよびサーバーは、名前またはシャープ記号 (’#’) を付加した数値 ID のいずれかで指定できます。
help [<command>]
既知のキーワードと基本的な使い方、または、指定したものにマッチするコマンドの一覧を表示します。未知のコマンドに対しても、同じヘルプ画面を表示します。
httpclient [--htx] <method> <URI>
HTTPクライアントリクエストを開始し、CLIへレスポンスを出力します。エキスパートモードで動作するCLI接続だけでサポートします(“expert-mode on"を参照)。デバッグ専用です。httpclientは、“default"のresolversセクションを使い、URL内のサーバー名を解決できます。このセクションには、デフォルトで/etc/resolv.confのDNSサーバーを設定します。ただし、/etc/hostsのホストを解決できるローカルDNSデーモンを使わなければ、そこに記載したホストは解決できません。
–htx オプションは、htx_dump() 関数を使用して HAProxy 内部の htx 表現を使用することを可能にします。主にデバッグ用途で使用されます。
new ssl ca-file <cafile>
空のCAファイルツリーエントリーを新しく作成します。後でCA証明書の集合を設定し、crt-listへ追加するためのものです。このコマンドは、“set ssl ca-file”、“add ssl ca-file”、“add ssl crt-list"と組み合わせて使うべきです。
new ssl cert <filename>
空のSSL証明書ストアを新しく作成します。後で証明書を設定し、ディレクトリまたはcrt-listへ追加するためのものです。このコマンドは、“set ssl cert"と"add ssl crt-list"と組み合わせて使うべきです。
new ssl crl-file <crlfile>
空のCRLファイルツリーエントリーを新しく作成します。後でCRLの集合を設定し、crt-listへ追加するためのものです。このコマンドは、“set ssl crl-file"と"add ssl crt-list"と組み合わせて使うべきです。
prepare acl <acl>
アトミックな置換のため、ACL <acl>に新しいバージョン番号を割り当てます。<acl>は、“show acl"が返す#<id>または<name>です。新しい番号は、応答の"New version created:“の後に表示します。この番号で新しいエントリーの追加を準備し、コミット時に、現在のエントリーをアトミックに置き換えられます。“show acl"では"next_ver"と報告します。より新しいバージョンをコミットすると、使っていないバージョンは自動的に削除するため、新しいバージョンの割り当てによる影響はありません。バージョン番号は、上限で一周する符号なし32ビット値なので、外部プログラムで比較するときには注意が必要です。参照<acl>がマップにも使う名前なら、このコマンドは使えず、代わりに"prepare map"を使わなければなりません。
prepare map <map>
アトミックな置換のため、マップ<map>に新しいバージョン番号を割り当てます。<map>は、“show map"が返す#<id>または<name>です。新しい番号は、応答の"New version created:“の後に表示します。この番号で新しいエントリーの追加を準備し、コミット時に、現在のエントリーをアトミックに置き換えられます。“show map"では"next_ver"と報告します。より新しいバージョンをコミットすると、使っていないバージョンは自動的に削除するため、新しいバージョンの割り当てによる影響はありません。バージョン番号は、上限で一周する符号なし32ビット値なので、外部プログラムで比較するときには注意が必要です。
prompt [help | n | i | p | timed]*
対話モードの動作と、対話モードで行頭に表示するプロンプトを変更します。- “help”:コマンドの使用法を表示します。- “n”:非対話モードへ切り替えます。- “i”:対話モードへ切り替えます。- “p”:プロンプト付きの対話モードへ切り替えます。- “timed”:プロンプトの時間表示の有無を切り替えます。
オプションがなければ、プロンプトモード、非対話モードの順に循環します。非対話モードでは、現在の行の最後のコマンドが完了すると、接続を閉じます。対話モードでは、コマンドの完了後も閉じず、新しいコマンドを入力できます。プロンプトモードも対話モードとして動き、行頭のプロンプトで、新しいコマンドを待っていることを利用者へ示します。プロンプトは、右山括弧の後に空白を置いた”> “です。
プロンプトモードは人の操作、対話モードは高度なスクリプト、デフォルトの非対話モードは基本的なスクリプトに適しています。マスターソケットでは、非対話モードを使えない点に注意してください。
publish backend <backend>
バックエンドのインスタンスへのコンテンツ切り替えを有効にします。“unpublish backend"コマンドの逆の操作です。このコマンドは制限されており、“operator"または"admin"レベルを設定したソケットからだけ実行できます。
quit
対話モードで、接続を閉じます。
set anon [on|off] [<key>]
現在のCLIセッションの「匿名化モード」を有効または無効にします。コマンド出力のうち、機密とみなす一部のフィールドをハッシュで置き換えます。開発者が不具合を探す際に要素間の関係を把握できる程度の一貫性は残しつつ、ビット数を十分に少ない24にして、候補が非常に多いため元に戻せないようにします。有効にするときにキーを指定しなければ、グローバルキーを使います。これは、設定ファイルの"anonkey"またはCLIコマンド"set anon global-key"で設定したものです。そのキーもなければ、ランダムに生成します。あるいは、現在のセッションで使う32ビットキーを指定できます。たとえば、前のダンプで使ったキーを再利用して、出力を比較しやすくできます。開発者がこのキーを必要とすることは決してなく、ハッシュの背後にある値の推測を肯定・否定できるおそれがあるため、決して共有しないことを推奨します。
set dynamic-cookie-key backend <backend> <value>
動的な永続性Cookieの生成に使う秘密キーを変更します。これにより、既存のセッションは維持できなくなります。
set anon global-key <key>
グローバルな匿名化キーを<key>に設定します。0から4294967295までの32ビット整数でなければなりません(0はグローバルキーを無効にします)。管理者権限が必要です。
set map <map> [<key>|#<ref>] <value>
マップ<map>の各キー<key>に対応する値を変更します。<map>は、“show map"が返す#<id>または<name>です。<key>の代わりに<ref>を使うと、<ref>が指すエントリーだけを変更します。新しい値は<value>です。
set maxconn frontend <frontend> <value>
指定したフロントエンドのmaxconn設定を動的に変更します。ゼロを含む任意の正の値を指定できますが、グローバルのmaxconnより大きな値にしても、あまり意味はありません。上限を増やし、待機中の接続があれば、直ちに受け入れます。現在の接続数より小さな値へ下げると、そのしきい値に達するまで、新しい接続の受け入れを遅らせます。フロントエンドは、名前、または先頭にシャープ(’#’)を付けた数値IDで指定できます。
set maxconn server <backend/server> <value>
指定したサーバーのmaxconn設定を動的に変更します。ゼロを含む任意の正の値を指定できますが、グローバルのmaxconnより大きな値にしても、あまり意味はありません。
set maxconn global <maxconn>
最初のグローバルmaxconn設定で定めた範囲内で、グローバルmaxconnを動的に変更します。増やしたときに待機中の接続があれば、直ちに受け入れます。現在の接続数より小さな値へ下げると、そのしきい値に達するまで、新しい接続の受け入れを遅らせます。ゼロにすると、初期設定へ戻します。
set profiling memory { on | off }
指定したサブシステムのCPUまたはメモリーのプロファイリングを、有効または無効にします。設定ファイルの"global"セクションの"profiling"設定を、設定または解除するのと同等です。“show profiling"も参照してください。タスクのプロファイリングを手動で"on"にすると、スケジューラーの統計を自動的にリセットするため、一定期間の活動を確認できます。メモリーのプロファイリングは、一部のOSに限られ(linux-glibcターゲットで動作が確認されています)、コンパイル時にUSE_MEMORY_PROFILINGを設定する必要があります。
タスクのプロファイリングでは、タスクごとのロックとメモリーの所要時間の収集を、実行時に有効・無効にできます。ただし、変更を反映するのは、プロファイラーが次にoff/autoからonへ切り替わるときだけです(自動でも手動でも同じです)。したがって、“no-lock"でタスクごとのロックのプロファイリングを無効にし、CPUサイクルを節約する場合は、変更を反映するため、タスクのプロファイリングを一度offにしてからonに戻すことを推奨します。
set rate-limit connections global <value>
グローバル設定’maxconnrate’で定める、プロセス全体の接続レート上限を変更します。ゼロは制限を無効にします。すべてのフロントエンドに適用し、変更は即座に有効になります。値は毎秒の接続数で渡します。
set rate-limit http-compression global <value>
グローバル設定’maxcomprate’で定める、圧縮入力レートの上限を変更します。ゼロは制限を無効にします。値は毎秒のキロバイト数で渡します。“show info"の"CompressBpsRateLim"行では、バイト単位の値を確認できます。
set rate-limit sessions global <value>
グローバル設定’maxsessrate’で定める、プロセス全体のセッションレート上限を変更します。ゼロは制限を無効にします。すべてのフロントエンドに適用し、変更は即座に有効になります。値は毎秒のセッション数で渡します。
set rate-limit ssl-sessions global <value>
グローバル設定’maxsslrate’で定める、プロセス全体のSSLセッションレート上限を変更します。ゼロは制限を無効にします。すべてのフロントエンドに適用し、変更は即座に有効になります。値は、SSLスタックへ毎秒送るセッション数で渡します。ハンドシェイクの悪用からスタックを守るため、ハンドシェイクの前に適用します。
set server <backend>/<server> addr <ip4 or ip6 address> [port <port>]
サーバーの現在のIPアドレスを、指定したものに置き換えます。任意で、‘port’パラメーターでポートも変更できます。ヘルスチェック用のポートを設定している場合だけ、ポート変更時に、ポートマッピング(+Xまたは-Y表記)への切り替えや、その逆もサポートする点に注意してください。
set server <backend>/<server> agent [ up | down ]
サーバーのエージェントを、新しい状態へ強制的に変更します。たとえば、遅いエージェントチェックにかかわらず、サーバーの状態を直ちに切り替えるのに便利です。追跡しているサーバーがあれば、変更を伝播する点に注意してください。
set server <backend>/<server> agent-addr <addr> [port <port>]
サーバーのエージェントチェックのアドレスを変更します。実行中に別のアドレスへ移せます。IPアドレスとホスト名のいずれも指定でき、名前解決します。任意で、エージェントのポートも変更できます。
set server <backend>/<server> agent-port <port>
エージェントチェックに使うポートを変更します。
set server <backend>/<server> agent-send <value>
エージェントチェックの宛先へ送るエージェント文字列を変更します。サーバーのアドレス変更とともに文字列を更新し、両者の対応を保てます。
set server <backend>/<server> health [ up | stopping | down ]
サーバーのヘルス状態を、新しい状態へ強制的に変更します。たとえば、遅いヘルスチェックにかかわらず、サーバーの状態を直ちに切り替えるのに便利です。追跡しているサーバーがあれば、変更を伝播する点に注意してください。
set server <backend>/<server> check-addr <ip4 | ip6> [port <port>]
サーバーのヘルスチェックに使うIPアドレスを変更します。任意で、ヘルスチェックのポートも変更できます。
set server <backend>/<server> check-port <port>
ヘルスチェックに使うポートを<port>へ変更します。
set server <backend>/<server> state [ ready | drain | maint ]
サーバーの管理状態を、新しい状態へ強制的に変更します。サーバーへの負荷分散や、あらゆるトラフィックを無効にするのに便利です。“ready"にすると通常のモードになり、“enable server"コマンドと同等です。“maint"にすると、そのサーバーへのすべてのトラフィックとヘルスチェックを無効にし、“disable server"コマンドと同等です。“drain"は、サーバーを負荷分散から外すだけで、チェックの実行と、永続性による新規接続の受け入れは引き続き許可します。追跡しているサーバーがあれば、変更を伝播します。
set server <backend>/<server> weight <weight>[%]
サーバーの重みを、引数で指定した値に変更します。後述の"set weight"コマンドと、まったく同等です。
set server <backend>/<server> fqdn <FQDN>
サーバーのFQDNを、引数で指定した値に変更します。このサーバーについて、内部の実行時DNSリゾルバーを設定し、有効にしておく必要があります。
set server <backend>/<server> ssl [ on | off ] (非推奨)
このオプションは、サーバーへの送信接続のSSL暗号化を設定します。無効にすると、すべてのトラフィックが平文になります。ヘルスチェックの経路は変えません。
このコマンドは非推奨です。代わりに、“add server"コマンドで、SSLを使う、または使わない新しいサーバーを動的に作成してください。
set severity-output [ none | number | string ]
現在のセッションの間、接続先の統計ソケットの重大度の出力形式を変更します。
set ssl ca-file <cafile> <payload>
このコマンドはトランザクションシステムの一部で、“commit ssl ca-file"や"abort ssl ca-file"コマンドが必要になる場合があります。進行中のトランザクションがなければ、ペイロード内の証明書を保存するCAファイルツリーのエントリーを作成します。エントリーをCAファイルツリーには保存せず、一時的なトランザクションの中だけで保持します。同名のファイルに対するトランザクションが既にあれば、前のCAファイルエントリーを削除し、新しいもので置き換えます。変更を終えたら、“commit ssl ca-file"を呼び出してコミットしなければなりません。複数の証明書を別々に追加するには、“add ssl ca-file"コマンドを使えます。
例:
set ssl cert <filename> <payload>
このコマンドはトランザクションシステムの一部で、“commit ssl cert"や"abort ssl cert"コマンドが必要になる場合があります。このシステム全体は、“show ssl cert"が表示するすべての証明書、つまりフロントエンドとバックエンドのいずれの証明書にも対応します。進行中のトランザクションがなければ、証明書<filename>をメモリー内で一時トランザクションへ複製し、ペイロードのPEMファイルで更新します。同名のファイルのトランザクションがあれば、それを更新します。証明書に関連付けられたファイル(.issuer、.sctl、.ocspなど)も更新できます。変更を終えたら、“commit ssl cert"でトランザクションをコミットしなければなりません。
空行でペイロードの終了を通知するため、CLIからファイルを投入する際には注意が必要です。不要な部分を取り除いたPEMファイルの投入を推奨します。簡単な方法は、空行をすべて削除し、PEMセクションの内容だけを残すことです。sedコマンドで実現できます。
例:
set ssl crl-file <crlfile> <payload>
このコマンドはトランザクションシステムの一部で、“commit ssl crl-file"や"abort ssl crl-file"コマンドが必要になる場合があります。進行中のトランザクションがなければ、ペイロード内の失効リストを保存するCRLファイルツリーのエントリーを作成します。エントリーをCRLファイルツリーには保存せず、一時トランザクションの中だけで保持します。同名のファイルに対するトランザクションが既にあれば、前のCRLファイルエントリーを削除し、新しいもので置き換えます。変更を終えたら、“commit ssl crl-file"を呼び出してコミットしなければなりません。
例:
set ssl ech <bind> <payload>
bind行のECHキーを、このキーで置き換えます。ペイロードはECH用のPEM形式でなければなりません。 (https://datatracker.ietf.org/doc/html/draft-farrell-tls-pemesni )
bind行の形式は<frontend>/@<filename>:<linenum>(例:frontend1/@haproxy.conf:19)です。“name"キーワードでbind行に名前を付けた場合は、<frontend>/<name>形式も使えます。
OpenSSL のバージョンが ECH をサポートしている必要があり、HAProxy は USE_ECH=1 でコンパイルされている必要があります。このコマンドは、実験モードで実行されている CLI 接続でのみサポートされます(「experimental-mode on」を参照)。
“show ssl ech”、“add ssl ech"と、設定マニュアルのセクション5.1 にある"ech"も参照してください。
$ openssl ech -public_name foobar.com -out foobar3.com.ech
$ echo -e "experimental-mode on;
set ssl ech frontend1/@haproxy.conf:19 <<%EOF%\n$(cat foobar3.com.ech)\n%EOF%\n" | \
socat /tmp/haproxy.sock -
set new ECH configs for frontend1/@haproxy.conf:19
set ssl ocsp-response <response | payload>
証明書のOCSPレスポンスを更新します(“bind"行の"crt"を参照)。最初のレスポンス読み込みと同じ検査を行います。<response>には、OCSPサーバーからのDER形式のレスポンスを、base64符号化した文字列で渡さなければなりません。BoringSSLでは、このコマンドをサポートしません。
例:
set ssl tls-key <id> <tlskey>
<id>リスナーの次のTLSキーを<tlskey>に設定します。このキーは最後のキーになり、その一つ前のキーを暗号化に使います(他のキーは復号だけに使います)。存在する最も古いTLSキーを上書きします。<id>は、“show tls-keys"が返す数値の#<id>、または<file>です。<tlskey>は、base64符号化した48または80バイトのTLSチケットキーです(例:openssl rand 80 | openssl base64 -A)。
set table <table> key <key> [data.<data_type> <value>]*
テーブル内のスティックテーブルのエントリーを作成、または更新します。キーがなければ、エントリーを挿入します。<data_type>で使える全値は、セクション4.2のstick-tableを参照してください。最も想定される用途は、送信元IPアドレスのエントリーを動的に登録し、gpc0のフラグでIPアドレスを動的に遮断したり、サービス品質に影響を与えたりすることです。一度の呼び出しで、複数のdata_typesを渡せます。
既存のエントリーについては、キーによる検索の代わりに、任意でptr検索を使えます。<ptr>は0xffff形式で書き、以前の"show table"が返したアドレスに対応していなければなりません。空のキーやCLIで扱えない文字のためにキーでマッチできない場合、ポインターでエントリーをマッチさせる方法が有効な場合があります。
data.<data_type>が配列型なら、”[]“で特定のインデックスへアクセスできます。たとえば、data.gpt[1]です。
set timeout cli <delay>
現在の接続のCLIインターフェースのタイムアウトを変更します。長いデバッグセッションで、切断されずに指標を継続して確認したい場合に便利です。遅延時間は秒で渡します。
set var <name> <expression>
式<expression>または形式文字列<format>の結果で、プロセス全体の変数’name’を設定、または上書きできます。使えるのはプロセス全体の変数だけなので、名前は’proc.‘で始まらなければならず、そうでなければ変数を設定しません。<expression>と<format>に含められるのは、“internal"サンプル取得キーワードとコンバーターだけですが、便利なのは主にstr(‘something’)、int()、単純な文字列、他の変数への参照でしょう。コマンド行パーサーは引用符を認識しないため、式の中の空白の前には、必ずバックスラッシュを付けなければなりません。“operator"または"admin"レベルが必要です。このコマンドをサポートするのは、実験モードのCLI接続だけです(“experimental-mode on"を参照)。
set weight <backend>/<server> <weight>[%]
サーバーの重みを、引数で指定した値に変更します。値が’%‘で終わる場合、新しい重みは初期設定の重みに対する相対値になります。絶対値は0から256まで指定できます。相対値は正でなければならず、結果の絶対値は256を上限とします。静的ロードバランシングアルゴリズムで動くサーバー群に属するサーバーには、設定後に重みを変更できないため、より厳しい制限があります。受け付ける値は0と100%だけです(または0と初期の重み)。変更は即座に有効になりますが、一部の負荷分散アルゴリズムでは、変更を反映するまでに一定数のリクエストが必要です。典型的な用途は、更新中に重みをゼロにしてサーバーを無効にし、更新後に100%へ戻して再び有効にすることです。このコマンドは制限されており、“admin"レベルを設定したソケットからだけ実行できます。バックエンドとサーバーは、いずれも名前、または先頭にシャープ(’#’)を付けた数値IDで指定できます。
show acl [[@<ver>] <acl>]
ACLコンバーターの情報を出力します。引数がなければ、使用可能な全ACLの一覧を返します。<acl>を指定すれば、その内容を出力します。<acl>は#<id>または<name>です。デフォルトでは、現在のACLバージョンを表示します。これは、現在マッチングに使い、ACL一覧で’curr_ver’と報告するバージョンです。ACL識別子の前に’@<ver>‘を付けると、他のバージョンも出力できます。バージョンはフィルターとして働き、存在しないバージョンは、単に結果を返しません。出力形式は、サンプル値も含めてマップと同じです。返すデータは、使用可能なACLの一覧ではなく、いずれかのACLを構成する全パターンの一覧です。多くのパターンは、マップと共有できます。’entry_cnt’は、有効なものだけでなく、追加中のものも含む、ACLの全エントリー数を表します。
show anon
匿名化モードの現在の状態(有効または無効)と、現在のセッションのキーを表示します。
show backend
実行中のプロセスで使用できるバックエンドの一覧を出力します。
show cli level
現在のCLIセッションのCLIレベルを表示します。結果は’admin’、‘operator’、‘user’のいずれかです。‘operator’と’user’コマンドも参照してください。
例:
operator
現在のCLIセッションのCLIレベルをoperatorへ下げます。上げることはできません。エキスパートモードと実験モードも解除します。“show cli level"も参照してください。
unpublish backend <backend>
バックエンドを、今後のトラフィックの選択対象外にします。実際には、そのバックエンドを参照するuse_backend / default_backendルールを無視し、次のコンテンツ切り替えルールを評価します。無効化したバックエンドとは異なり、サーバーのヘルスチェックは有効なままです。このコマンドは制限されており、“operator"または"admin"レベルを設定したソケットからだけ実行できます。
user
現在のCLIセッションのCLIレベルをuserへ下げます。上げることはできません。エキスパートモードと実験モードも解除します。“show cli level"も参照してください。
show activity [-1 | 0 | thread_num]
内部イベントのカウンターを報告します。開発者や、より一般にはhaproxyを十分に知る人が、報告された異常な動作の原因を絞り込むのに役立ちます。典型例は、正常に動くプロセスがまったくスリープせず、CPUを100%使う場合です。出力は指標ごとに一行で、スレッドごとのカウンターを同じ行に並べます。カウンターは32ビットで、プロセスの生存期間中に一周しますが、通常はこのコマンドを二度呼び出すため、問題ありません。フィールドの正確な意味を、カウンターを更新するコードで確認するよう、意図的に文書化していません。“clear counters"コマンドでも値をリセットします。マルチスレッド構成では、最初の列に全スレッドの合計(指標の性質によっては平均)を示し、全スレッドの値を、スレッドの順に角括弧内へ並べます。任意で、出力するスレッド番号を引数に指定できます。特別な値"0"は集計値(最初の列)を報告し、デフォルトの”-1"は全列を表示します。一列だけを要求した場合は、シングルスレッドモードと同様に、括弧を付けない点に注意してください。
show cli sockets
CLIソケットの一覧を表示します。出力は、空白で区切った3フィールドです。最初のフィールドは、UNIXソケット、IPv4のアドレス:ポート、IPv6のアドレス:ポートのいずれかのソケットアドレスです。他の種類のソケットは出力しません。二番目は、ソケットのレベル(‘admin’、‘user’、‘operator’)です。最後は、ソケットをバインドしているプロセスをカンマ区切りで並べ、数値または’all’を使います。
例:
show cache
設定したキャッシュと、各キャッシュツリーに保存したオブジェクトを一覧にします。
$ echo ‘show cache’ | socat stdio /tmp/sock1 0x7f6ac6c5b03a: foobar (shctx:0x7f6ac6c5b000, available blocks:3918) 1 2 3 4
- キャッシュ構造体へのポインター
- キャッシュ名
- mmap領域(shctx)へのポインター
- shctx内の再利用できるブロック数
0x7f6ac6c5b4cc hash:286881868 vary:0x0011223344556677 size:39114 (39 blocks), refcount:9, expire:237 1 2 3 4 5 6 7
- キャッシュエントリーへのポインター
- ハッシュの先頭32ビット
- varyがある場合の、エントリーの二次ハッシュ
- オブジェクトのサイズ(バイト)
- オブジェクトに使うブロック数
- エントリーを使用中のトランザクション数
- 有効期限までの時間。期限切れなら、負の場合があります。
show dev
HAProxyの開発者が問題の原因を詳しく理解するために必要とする情報を、まとめて提供するコマンドです。通常、利用者に役立つ情報ではありませんが、開発者がいくつかの仮説を除外するのに役立ちます。形式は、おおむね、インデントした行を含むセクションの列で、一行に一項目を示します。OSの種類とバージョン、CPUの種類、起動時のFD上限などです。値が無制限など、情報として意味を持たないフィールドは、繰り返しや出力の煩雑さを避けるため省略します。将来は、項目を増やしたり変えたりする場合があります。スクリプトで解析するための出力ではなく、強く信頼すべきものでもありません。主な目的は、読める人の時間を節約することです。
技術的には、起動時にこれらの情報をまとめて保存した内部構造体から、そのまま取り出しています。クラッシュ後のコアファイルにも残るようにするためです。そのため開発者は、コアダンプの内容と比較したり、複数のリロード間で比較したりするために、正常に動くプロセスの早い段階の出力を求めることがあります(上限などが変わる場合があります)。匿名化を有効にしていれば、ノード名など、機密性があり得る値も匿名化します。
出力例:
show env [<name>]
プロセスが認識する環境変数を、一つまたはすべて出力します。引数がなければすべてを、引数があれば、指定した変数が存在する場合に限り、それだけを出力します。なければ"Variable not found"を出力します。変数の形式は、保存時や"env"ユーティリティの出力と同じ”<name>=<value>“です。環境変数を多用する設定ファイルのデバッグで、期待する値が入っていることを確認するのに便利です。このコマンドは制限されており、“operator"または"admin"レベルを設定したソケットからだけ実行できます。
show errors [<iid>|<proxy>] [request|response]
フロントエンドとバックエンドが収集した、最後に認識したHTTP/1.xのリクエストとレスポンスのエラーを出力します。<iid>を指定すると、IDが<iid>のフロントエンドまたはバックエンドに関係するエラーだけに絞ります。プロキシIDに”-1"を指定すると、全インスタンスを出力します。代わりにプロキシ名を指定すれば、そのIDをフィルターに使います。プロキシ名またはIDの後に"request"または"response"を付けると、リクエストまたはレスポンスのエラーだけを出力します。このコマンドは制限されており、“operator"または"admin"レベルを設定したソケットからだけ実行できます。
収集できるのは、プロトコル違反による最後のリクエストとレスポンスのエラーで、よくある原因は、ヘッダー名の不正な文字です。どの文字がプロトコルに違反したかを、正確に報告します。エラーを検出した正確な日時、フロントエンド名とバックエンド名、分かればサーバー名、内部トランザクションID、セッションを開始した送信元アドレスといった重要な情報も報告します。
すべての文字を返し、印字できない文字は符号化します。よく使うもの(\t = 9、\n = 10、\r = 13、\e = 27)は、バックスラッシュの後に一文字を付けます。混同しないよう、バックスラッシュ自体は’\\‘にします。他の印字できない文字は’\xNN’とし、NNは、その文字のASCIIコードを二桁の16進数で表したものです。
各行の前に、バッファーの先頭を0とする、その行の最初の文字の位置を付けます。出力一行に含める入力行は最大一行で、長い行は連続する複数の出力行に分割し、幅が79文字を超えないようにします。分割した行は’\n’で終わらず、次の行のオフセットの後に、前の行からの続きであることを示す’+‘が付くため、容易に見分けられます。
例:
show events [<sink>] [-w] [-n] [-0] [-s]
オプションがなければ、既知の全イベント出力先とその種類を一覧にします。指定があれば、指定した出力先がバッファー型の場合、その中の利用可能なイベントをすべて出力します。出力先名の後に”-w"を指定すると、バッファーの末尾に達した後、新しいイベントを待って表示します。任意の入力を送る(その入力は破棄します)か、セッションを閉じると停止できます。"-n"は、バッファーの末尾へ直接移動します。"-w"と組み合わせ、新しいイベントだけを報告すると便利なことがよくあります。便宜上、"-wn"または”-nw"で、両方を同時に有効にできます。デフォルトでは、すべてのイベントを改行文字(’\n’、10、または0x0A)で区切ります。"-0"引数を渡すと、NUL文字(’\0’または0)へ変更できます。"-s"オプションは出力を無害化し、キャプチャまたはデコードしたデータのバイナリ内容が端末の表示を変えないようにします。空白文字(スペースとタブ)はスペースに置き換え、各レコードが一行に収まるようにします。それ以外の制御文字(0x00から0x1F、および0x7F)と非ASCII文字(0x80以上)は’?‘に置き換えます。出力の長さは保持します。これにより、リングの出力でANSIエスケープシーケンスや文字方向の制御コードが操作担当者の端末に挿入されることを防ぎます。端末に出力する場合や、入力を特殊なものとして解釈してはならないプログラムへ渡す場合に便利です。たとえば、出力をそのままレポートにコピーする監視スクリプトが該当します。
show fd [-!plcfbsd]* [[<tgid>]/[<fd>] | <fd>]
開いている全ファイルディスクリプター、または指定した番号<fd>だけを一覧にして出力します。"<tgid>/<fd>“形式も受け付け、左右いずれの側も、空ならワイルドカードとして扱います(”/<fd>“はスレッドグループをまたぐfd <fd>、"<tgid>/“は<tgid>の全fd)。現在は<tgid>を解析しても無視し、スレッドグループごとのfdテーブルの将来の対応を待っています。任意でフラグを指定し、特定の種類のFDだけに絞ったり、特定の種類を除いたりできます。’-‘または’!‘があると、同じ引数の後続文字の選択を反転します。反転状態は、空白で区切った各引数の前にリセットします。選べるFDの種類は、‘p’がパイプ、’l’がリスナー、‘c’が接続(全種類)、‘f’がフロントエンド接続、‘b’がバックエンド接続(全種類)、’s’がサーバーへの接続、’d’が"dispatch"アドレスまたはバックエンドの透過アドレスへの接続です。したがって、‘b’は’sd’、‘c’は’fb’または’fsd’の短縮形です。‘c!f’は’b’と同等です(「フロントエンド以外の全接続」は、バックエンド接続だからです)。CPUの異常な使用率など、複雑な問題のデバッグで内部状態を観察する開発者だけを対象とします。一行に一つのfdを報告し、まずポーラー内の状態を、有効なフラグは大文字、無効なものは小文字で示します。“P"はポーリング対象、“R"は準備完了、“A"はアクティブを表します。イベント状態は、“H"が切断、“E"がエラー、“O"が出力、“P"が優先、“I"が入力です。他にも、“N"は新規(fdキャッシュへ追加した直後)、“U"は更新済み(fdキャッシュ内で更新を受信)、“L"は"linger_risk”、“C"は複製済みを示します。その後に、キャッシュ内のエントリー位置、内部の所有者へのポインター、I/Oコールバックへのポインターと、分かればその名前を示します。所有者が接続なら、接続フラグと宛先(フロントエンド、プロキシ、サーバー)を、リスナーなら、その状態とフロントエンドを報告します。内部をよく理解せずに使っても意味がありません。出力形式は変わり得るため、長期間使うツールで解析してはなりません。内部構造の状態を、一覧化する関数が不審と判断した場合、出力行の末尾に感嘆符(’!’)を付けます。障害を診断する際の手掛かりになる場合があります。
show info [typed|json] [desc] [float]
現在のプロセスのhaproxyの状態情報を出力します。任意の引数"typed"を渡すと、フィールド番号、名前、型も出力します。外部の監視製品が、未知のフィールドの情報でも、容易に取得し、必要なら集計し、報告できるようにするためです。各フィールドを独立した行に出力します。任意の引数"json"を渡すと、“typed"と同じ情報を、JSONオブジェクトの一覧としてJSON形式で提供します。デフォルトの形式は、コロン(’:’)で区切った二列だけで、左がフィールド名、右が値です。型付き出力では、一つのオブジェクトの情報を連続して出力するため、利用する側がすべてを一度に保存する必要がない点が非常に重要です。任意の引数"float"を渡すと、精度を高めるため、通常は整数で出力する一部のフィールドが浮動小数点数に変わる場合があります。対象は将来変わり得るため、意図的に規定していません。このオプションを使う側は、浮動小数点数を処理できる必要があります。出力形式はsprintf("%f”)です。
型付き出力では、各行はコロン(’:’)で区切った4列です。最初の列は、ドットで区切った3要素の列です。最初の要素は、ゼロから始まる、一覧内のフィールドの数値位置です。この位置は将来も変更してはなりませんが、ビルドオプションや将来のフィールド削除により、欠番が生じることは想定してください。二番目の要素は、デフォルトの"show info"出力に現れるフィールド名です。三番目は、1から始まる相対プロセス番号です。
最初のコロンより後は、上の節で説明した「型付き出力形式」に従います。つまり、二番目の列(最初の’:‘の後)は、変数の生成元、性質、スコープを示します。三番目はフィールドの型で、“s32”、“s64”、“u32”、“u64”、“str"のいずれかです。四番目は値そのものです。利用する側は、列3から解析方法を、列2から処理方法を判断できます。
したがって、型付きモードでの行全体の形式は次のとおりです。
コマンドに"desc"を付けると、コロンをもう一つ追加し、その後に、指標の説明を引用符付き文字列で付けます。執筆時点では、“typed"とデフォルトの出力形式だけでサポートします。
例:
型付き形式は、最初の列の末尾にプロセスIDがあるため、複数のプロセスの出力を目で見て容易に集約できます。例:
JSON出力の形式は、“show schema json"で出力できるスキーマに記述されています。
出力量を減らすため、JSON出力には余分な空白がありません。人が読む場合は、整形ツールに通すと便利です。例:
$ echo “show info json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
出力量を減らすため、JSON出力には余分な空白がありません。人が読む場合は、整形ツールに通すと便利です。例:
$ echo “show info json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
show libs
対応するシステムでは、読み込んだ共有動的ライブラリとオブジェクトファイルを一覧にして出力します。取得できる場合、各共有オブジェクトについて、仮想アドレスの範囲、サイズ、パスを示します。たとえば、ダンプに現れた関数をどのライブラリが提供するかの見当を付けるのに使えます。多くのシステムでは、再起動のたびにアドレスが変わるため(アドレス空間のランダム化)、コアファイルの解析に使う予定なら、起動時に一覧を取得しておく必要があります。このコマンドは、“operator"または"admin"レベルを設定したソケットからだけ実行できます。出力形式はOS、アーキテクチャー、さらにはhaproxyのバージョンによっても変わり得るため、スクリプトで依存するべきではありません。
show map [[@<ver>] <map>]
マップコンバーターの情報を出力します。引数がなければ、使用可能な全マップの一覧を返します。<map>を指定すれば、その内容を出力します。<map>は#<id>または<name>です。デフォルトでは、現在のマップバージョンを表示します。これは、現在マッチングに使い、マップ一覧で’curr_ver’と報告するバージョンです。マップ識別子の前に’@<ver>‘を付けると、他のバージョンも出力できます。バージョンはフィルターとして働き、存在しないバージョンは、単に結果を返しません。’entry_cnt’は、有効なものだけでなく、追加中のものも含む、マップの全エントリー数を表します。
出力の最初の列は、一意のエントリー識別子で、“del map"や"set map"操作の参照として使えます。二番目はパターン、三番目は、あればサンプルです。返すデータは、使用可能なマップの一覧そのものではなく、いずれかのマップを構成する全パターンの一覧です。多くのパターンは、ACLと共有できます。
show peers [dict|-] [<peers section>]
“peers"セクションで設定したピアの情報を出力します。引数がなければ、すべての"peers"セクションに属するピアを一覧にします。<peers section>を指定すると、その"peers"セクションのピアの情報だけを出力します。セクション名の前に"dict"を指定すると、送受信(Tx/Rx)の辞書キャッシュ全体も出力します(非常に大きな出力です)。“dict"という名前のpeersセクションを出力するには、”-“を渡す必要がある場合があります。
以下は、hostA、hostB、hostCのピアが"sharedlb"というpeersセクションに属する、二つの出力例です。接続しているのはhostAとhostBだけで、データを送ったのはhostAからhostBへの方向だけです。
$ echo “show peers” | socat - /tmp/hostA 0x55deb0224320: [15/Apr/2019:11:28:01] id=sharedlb
state=0 flags=0x3 \ resync_timeout=<PAST> task_calls=45122
0x55deb022b540: id=hostC(remote) addr=127.0.0.12:10002 status=CONN \
reconnect=4s confirm=0 flags=0x0 0x55deb022a440: id=hostA(local) addr=127.0.0.10:10000 status=NONE
\ reconnect=<NEVER> confirm=0 flags=0x0 0x55deb0227d70: id=hostB(remote)
addr=127.0.0.11:10001 status=ESTA reconnect=2s confirm=0 flags=0x20000200 appctx:0x55deb028fba0
st0=7 st1=0 task_calls=14456 \ state=EST xprt=RAW src=127.0.0.1:37257
addr=127.0.0.10:10000 remote_table:0x55deb0224a10 id=stkt local_id=1 remote_id=1
last_local_table:0x55deb0224a10 id=stkt local_id=1 remote_id=1 shared tables:
$ echo “show peers” | socat - /tmp/hostB 0x55871b5ab320: [15/Apr/2019:11:28:03] id=sharedlb
state=0 flags=0x3 \ resync_timeout=<PAST> task_calls=3 0x55871b5b2540:
id=hostC(remote) addr=127.0.0.12:10002 status=CONN \ reconnect=3s
confirm=0 flags=0x0 0x55871b5b1440: id=hostB(local) addr=127.0.0.11:10001 status=NONE
\ reconnect=<NEVER> confirm=0 flags=0x0 0x55871b5aed70: id=hostA(remote)
addr=127.0.0.10:10000 status=ESTA \ reconnect=2s confirm=0
flags=0x20000200 appctx:0x7fa46800ee00 st0=7 st1=0 task_calls=62356 \
state=EST remote_table:0x55871b5ab960 id=stkt local_id=1 remote_id=1 last_local_table:0x55871b5ab960
id=stkt local_id=1 remote_id=1 shared tables:
show pools [byname|bysize|byusage] [detailed] [match <pfx>] [<nb>]
内部メモリープールの状態を出力します。たとえば、メモリーリークを疑う場合に、使用状況を追うのに便利です。フォアグラウンド実行中のSIGQUITとまったく同じ処理ですが、プールをフラッシュしません。デフォルトでは並べ替えません。“byname"を指定するとプール名で、“bysize"なら要素サイズの降順で、“byusage"なら総使用量の降順で並べます。“byusage"では、使用中のエントリーだけを表示します。使用量順の場合など、先頭<nb>件に制限することもできます。“detailed"を指定すると、統合した全プールの一覧など、より詳しい内部情報も出力できます。最後に、“match"の後に接頭辞を指定すると、その接頭辞で名前が始まるプールだけを表示します。報告する合計値は、フィルター条件にマッチするプールだけが対象です。例:
show profiling [{all | status | tasks | memory}] [byaddr|bytime|byctx|aggr|<max_lines>]*
現在のプロファイリング設定を一行に一つずつ、変更に必要なコマンドとともに出力します。タスクのプロファイリングが有効なら、スケジューラーが収集した関数ごとの統計と、呼び出し回数、CPU時間の合計と平均、遅延の合計と平均を含む要約も出力します。メモリーのプロファイリングが有効なら、割り当て・解放の回数とサイズなどを報告します。対応するキーワードを指定し、プロファイリングの状態、タスク、メモリーのいずれかだけに絞れます。デフォルトでは、すべてのプロファイリング情報を出力します。数値の上限を指定すると、各分類の出力行数も制限できます。たとえば、続けて呼び出した結果を比較したり、最適化する箇所を調べたりしやすいよう、使用量の代わりに、アドレス、合計実行時間、呼び出し文脈で並べるよう要求できます。また、詳細を見る代わりに、呼び出された関数ごとにタスクの活動を集約できます。プロファイリングは、コード内でCPUサイクルやメモリーを浪費する箇所の手掛かりを与えるため、主に開発者向けである点に注意してください。監視に役立つ情報はありません。
show resolvers [<resolvers section id>]
指定したresolversセクションの統計を出力します。セクションを指定しなければ、すべてのresolversセクションが対象です。
ネームサーバーごとに、次のカウンターを報告します。
show quic [<format>] [<filter>]
有効なすべてのQUICフロントエンド接続の情報を出力します。このコマンドは制限されており、“operator"または"admin"レベルを設定したソケットからだけ実行できます。
任意の引数で、出力の詳しさを制御できます。値には複数の解釈方法があります。まず、定義済みの値を使えます。“oneline"はデフォルトの形式、“stream"は有効な全ストリームの一覧、“full"は全情報の表示です。代わりに、フィールドをカンマ区切りで指定し、出力を絞ることもできます。現在サポートする値は、“tp”、“sock”、“pktns”、“cc”、“mux"です。最後に、形式へ"help"を指定すると、代わりに詳しいヘルプを表示します。
最後の引数は、接続一覧を絞ったり広げたりします。デフォルトでは、有効なフロントエンド接続だけを表示します。追加引数"clo"なら、代わりにクローズ中のフロントエンド接続を、“be"ならバックエンド接続、“all"なら全種類を一覧にします。接続の16進アドレスを指定し、一つの接続だけに絞ることもできます。
show servers conn [<backend>]
指定したバックエンドに属するサーバーの、現在の接続とアイドル接続の状態を出力します。指定がなければ全バックエンドが対象です。バックエンド名または識別子を使えます。
出力は、フィールドの見出しを示すヘッダー行と、それに続くサーバーごとの一行から成ります。各行には、バックエンド名とID、サーバー名とID、アドレス、ポート、各種の値を示します。フィールド数はスレッド数によって変わります。正確な出力形式は、バージョンやスレッド数によって、多少異なる場合があります。値を取り出すときは、ヘッダー行を見て列を対応させ、末尾の列はスレッドごとなので、スレッド数にも注意する必要があります。
<idle_cur> + <used_cur>の合計が推定値<need_est>を超えると、HAProxyは<purge_delay>ごとに<idle_cur>の一部を終了させます。この推定値は、接続の活動状況によって変わります。
アイドル接続はスレッドごとに管理するため、読み取った後に変わる値もあり、一行の中でも整合性を保証しないことを理解しておくのが重要です。この出力は主にデバッグ用で、定期的な監視やグラフ化には適しません。
show servers state [<backend>]
実行中の設定にあるサーバーの状態を出力します。バックエンド名または識別子を指定し、そのバックエンドだけに絞れます。
出力は次の形式です。
- 最初の行は形式のバージョンです(この仕様では1)。
- 二行目は列の見出しで、先頭にシャープ(’#’)を付けます。
- 三行目以降はデータです。
- シャープ(’#’)で始まる行は、すべてコメントとみなします。
複数の出力バージョンが共存し得るため、以下に、ファイル形式のバージョンごとのフィールドと順序を示します。
show sess [<options>*]
既知の有効なストリーム(以前の呼称は「セッション」)をすべて出力します。出力が非常に大きくなり得るため、遅い接続では避けてください。このコマンドは制限されており、“operator"または"admin"レベルを設定したソケットからだけ実行できます。接続をすぐに再利用するマシンでは、実際より少ないエントリーしか報告しない場合があります。コマンドを入力する前に作成した最後のストリームまでの、存在するストリームを出力するためで、その間に消えたものは現れません。使えるオプションは、以下を参照してください。
show sess [<id> | all | help] [<options>*]
マッチするストリームの内部情報を詳しく表示します。出力形式は二つあります。特定のストリーム識別子を指定しない場合のデフォルトである短い形式と、指定したストリームを一覧にする拡張形式です。“show sess"のデフォルトである短い形式は、一行に一つのストリームと少数の情報だけを出力し、先頭にストリーム識別子を16進数で示します(ストリームへのポインターに対応します)。
“show sess <id>“または"show sess all"で使う拡張形式は、ストリームごとに複数行(それぞれ約20行)で、大量のデバッグ情報を出力します。この場合も、先頭は識別子です。ストリーム同士の区切りは行頭の識別子で、同じストリームの追加行は、一つ以上の空白で始まります(インデントして出力します)。多数のストリームを出力すると、出力が膨大になり、多くの時間とCPUを使うため、常に必要最小限だけを出力するほうがよいでしょう。大半の利用者には役立たない情報ですが、HAProxyの開発者が複雑な不具合を調べるのに使う場合があります。安定版のブランチも含め、必要に応じて自由に変えられるよう、正確な出力形式は意図的に文書化していません。特定のフィールドの正確な意味を知るには、src/stream.cのstrm_dump_to_buffer()関数を確認しながら、出力を読み解くことを想定しています。
“help"引数を指定すると、ストリームの出力の代わりに、コマンドの詳しい使い方を表示します。
オプションで出力を調整したり、フィルターを適用したりできます。サポートするオプションは次のとおりです。- backend <b>:このバックエンドに結び付いたストリームだけを表示します。- frontend <f>:このフロントエンドに結び付いたストリームだけを表示します。- older <age>:<age>秒より古いストリームだけを表示します。- server <b/s>:このバックエンドとサーバーに結び付いたストリームだけを表示します。- show-uri:リクエスト解析中に取得したトランザクションURIを出力します。取得していた場合だけ表示します。- susp:開発者の基準で不審とみなすストリームだけを表示します。基準は、時間の経過やバージョンによって変わり得ます。
show stat [domain <resolvers|proxy>] [{<iid>|<proxy>} <type> <sid>] \
統計を出力します。domainは、どの統計を出すかを選び、現在はresolversとproxyを使えます。デフォルトはCSV形式です。他の引数の後に"typed"を渡すと、上の節で説明した拡張された型付き出力形式を、“json"を渡すとJSONを使えます。<id>、<type>、<sid>を渡すと、選んだ項目だけを出力できます。- <iid>はプロキシIDで、-1ならすべてを出力します。代わりにプロキシ名<proxy>も指定でき、その場合は、そのプロキシのIDを選択条件に使います。- <type>は、出力するオブジェクトの種類です。1はフロントエンド、2はバックエンド、4はサーバー、-1はすべてです。値をORで組み合わせられます。例:
- `<sid>`はサーバーIDで、-1なら選択したプロキシのすべてを出力します。
例:
この例では、二つのコマンドを一度に実行しています。こうすると、マルチプロセスモードで、統計がどのプロセスのものかを容易に判断できます。型付き出力では、各行にプロセス番号を報告するため、不要です。情報出力の後の空行は、最初のブロックの終了を示します。同様の空行が二番目のブロック(統計)の末尾にもあるため、読む側は出力が途中で切れていないことを確認できます。
“typed"を指定した出力は、数値位置と各フィールドの型を示すため、監視ツールにより適しています。値ごとに独立した行を使い、プロセス番号、要素番号、性質、生成元、スコープを含めます。URIの後に”;typed"を渡すと、HTTP統計でも同じ形式を使えます。型付き出力では、一つのオブジェクトの情報を連続して出力するため、利用する側がすべてを一度に保存する必要がない点が非常に重要です。
“up"修飾子は、稼働中と報告されるサーバー、またはチェックしていないサーバーだけを一覧にします。停止中、未解決、メンテナンス中のものは表示しません。HTTP統計の”;up"に相当します。同様に、“no-maint"は、HTTPの”;no-maint"と同じように働き、無効なサーバーを一覧から除きます。違いは、有効だが停止中のサーバーを除外しないことです。
型付き出力では、各行はコロン(’:’)で区切った4列です。最初の列は、ドットで区切った5要素の列です。最初の要素は、オブジェクトの種類を表す文字です。現在知られている種類は、‘F’がフロントエンド、‘B’がバックエンド、‘L’がリスナー、‘S’がサーバーです。二番目は、そのオブジェクトが属するプロキシの一意の識別子を表す正の整数です。CSV出力の"iid"列と同等で、フロントエンドまたはバックエンドセクションの任意の"id"ディレクティブに指定する値に一致します。三番目は、プロキシ内のオブジェクトの一意の識別子を含む正の整数で、CSV出力の"sid"列に対応します。フロントエンドやバックエンドを出力する場合は、ID 0を報告します。リスナーやサーバーなら、プロキシ内のそれぞれのIDです。四番目は、ゼロから始まる、一覧内のフィールドの数値位置です。この位置は将来も変更してはなりませんが、ビルドオプションや将来のフィールド削除により、欠番が生じることは想定してください。五番目は、CSV出力に現れるフィールド名です。六番目は正の整数で、1から始まる相対プロセス番号です。
最初のコロンより後は、上の節で説明した「型付き出力形式」に従います。つまり、二番目の列(最初の’:‘の後)は、変数の生成元、性質、スコープ、永続状態を示します。三番目はフィールドの型で、“s32”、“s64”、“u32”、“u64”、“flt”、“str"のいずれかです。四番目は値そのものです。利用する側は、列3から解析方法を、列2から処理方法を判断できます。
コマンドに"desc"を付けると、コロンをもう一つ追加し、その後に、指標の説明を引用符付き文字列で付けます。執筆時点では、“typed"出力形式だけでサポートします。
したがって、型付きモードでの行全体の形式は次のとおりです。
型付き出力形式の例を示します。
型付き形式は、最初の列の末尾にプロセスIDがあるため、複数のプロセスの出力を目で見て容易に集約できます。以下の例では、各行がプロセスごとに現れます。
JSON出力の形式は、“show schema json"で出力できるスキーマに記述されています。
出力量を減らすため、JSON出力には余分な空白がありません。人が読む場合は、整形ツールに通すと便利です。例:
$ echo “show stat json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
出力量を減らすため、JSON出力には余分な空白がありません。人が読む場合は、整形ツールに通すと便利です。例:
$ echo “show stat json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
show ssl ca-file [[*][\]<cafile>[:<index>]]
プロセスに読み込まれたCAファイルと、それぞれに含まれる証明書の数を表示します。証明書は、ステータスが"Used"になるまでフロントエンドやバックエンドで使用されません。一覧に”@system-ca"エントリーが表示されることがあります。これはhttpclientがデフォルトで読み込むもので、OpenSSLが返すシステムの信頼されたCAの一覧を含みます。ファイル名の先頭にアスタリスクが付いている場合は、まだコミットされていないトランザクションです。<index>を付けずに<cafile>を指定すると、CAファイルのステータス(“Used”/“Unused”)に続いて、そのCAファイルに含まれるすべての証明書の詳細を表示します。各証明書について表示される詳細は、“show ssl cert"コマンドと同じです。<cafile>に続けて<index>を指定すると、そのインデックスの証明書の詳細だけを表示します。インデックスは1から始まります。インデックスが無効な場合(大きすぎる場合など)は何も表示しません。このコマンドは、CAファイルが正しく更新されたかを確認するのに役立ちます。ファイル名の先頭に’‘を付けると、進行中のトランザクションの詳細も表示できます。ファイル名の最初の文字が’‘の場合は、’\*‘でエスケープできます。
例:
show ssl cert [[*][\]<filename>]
プロセスに読み込まれた証明書の一覧を表示します。証明書は、ステータスが"Used"になるまでフロントエンドやバックエンドで使用されません。ファイル名の先頭にアスタリスクが付いている場合は、まだコミットされていないトランザクションです。ファイル名を指定すると、その証明書の詳細を表示します。このコマンドは、証明書が正しく更新されたかを確認するのに役立ちます。ファイル名の先頭に’‘を付けると、トランザクションの詳細も表示できます。ファイル名の最初の文字が’‘の場合は、’\*‘でエスケープできます。ファイル名の末尾に”.ocsp"拡張子を付けると、証明書のOCSPレスポンスの詳細も表示できます。コミット済みの証明書と進行中のトランザクションの両方に対応しています。コミット済みの証明書の場合、このコマンドは、証明書に対応するOCSPレスポンスIDを指定して"show ssl ocsp-response"を呼び出すのと同じです。
例:
show ssl crl-file [[*][\]<crlfile>[:<index>]]
プロセスに読み込まれたCRLファイルの一覧を表示します。CRLファイルは、ステータスが"Used"になるまでフロントエンドやバックエンドで使用されません。ファイル名の先頭にアスタリスクが付いている場合は、まだコミットされていないトランザクションです。<index>を付けずに<crlfile>を指定すると、CRLファイルのステータス(“Used”/“Unused”)に続いて、そのCRLファイルに含まれるすべての失効リストの詳細を表示します。各リストの詳細は、“openssl crl -text -noout -in <file>“の出力に基づきます。<crlfile>に続けて<index>を指定すると、そのインデックスのリストの詳細だけを表示します。インデックスは1から始まります。インデックスが無効な場合(大きすぎる場合など)は何も表示しません。このコマンドは、CRLファイルが正しく更新されたかを確認するのに役立ちます。ファイル名の先頭に’‘を付けると、進行中のトランザクションの詳細も表示できます。ファイル名の最初の文字が’‘の場合は、’\*‘でエスケープできます。
例:
show ssl crt-list [-n] [<filename>]
HAProxyの設定で使用されているcrt-listとディレクトリの一覧を表示します。ファイル名を指定すると、crt-listまたはディレクトリの内容を出力します。この出力はcrt-listファイルとして使用できます。’-n’オプションを指定すると行番号を表示できます。エントリーが重複している場合に、‘del ssl crt-list’オプションと組み合わせると便利です。’-n’オプション付きの出力はcrt-list形式と互換性がなく、haproxyに読み込むことはできません。
例:
show ssl ech [<name>]
HAProxyプロセスに読み込まれたECHキーの一覧を表示します。
<name>を指定すると、特定のbind行のキーを表示します。bind行の指定形式は<frontend>/@<filename>:<linenum>(例:frontend1/@haproxy.conf:19)です。“name"キーワードでbind行に名前を付けている場合は、<frontend>/<name>も使用できます。
‘age’エントリーは、そのbind行にキーが読み込まれてからの経過時間を秒単位で表します。この値は、HAProxyの起動、リロード、再起動時にリセットされます。
OpenSSL のバージョンが ECH をサポートしている必要があり、HAProxy は USE_ECH=1 でコンパイルされている必要があります。このコマンドは、実験モードで実行されている CLI 接続でのみサポートされます(「experimental-mode on」を参照)。
設定マニュアルのセクション5.1 にある"ech"も参照してください。
例:
show ssl jwt
JWTの検証に使用できる証明書の一覧を表示します。“add ssl jwt"および"del ssl jwt"コマンドも参照してください。詳細は、証明書オプション"jwt"を参照してください。
例:
show ssl ocsp-response [[text|base64] <id|path>]
HAProxyで使用されるすべてのOCSPレスポンスに対応するOCSPツリーのエントリーIDと、対応するフロントエンド証明書のパス、発行者の名前とキーハッシュ、OCSPレスポンスの対象となる証明書のシリアル番号を表示します。有効な<id>または有効なフロントエンド証明書の<path>を指定すると、対応するOCSPレスポンスの内容を表示します。<id>を指定する場合は、データの出力形式も指定できます。デフォルトは’text’で、“openssl ocsp -respin <ocsp-response> -text"の呼び出しと同様に、OCSPレスポンスの詳細情報を表示します。‘base64’形式では、OCSPレスポンスの内容をbase64で出力できます。
例:
show ssl ocsp-updates
OCSP更新機構の対象となるエントリーの情報を表示します。OCSPレスポンスごとに一行を出力し、レスポンスの更新予定時刻、最後に更新が成功した時刻、更新の成功回数と失敗回数を含めます。前回の更新のステータス(成功か失敗か)も、数値と文字列の両方で表示します。起こりうるエラーの一覧は下記を参照してください。各行は’Next Update’の時刻の昇順で並びます。また、そのOCSPレスポンスを使用する最初のフロントエンド証明書のパスも含みます。OCSPの自動更新については、“show ssl ocsp-response"コマンドと"ocsp-update"オプションを参照してください。
更新エラーのコードと文字列には、次のものがあります。
例:
show ssl providers
初期化時にOpenSSLが読み込んだプロバイダーの名前を表示します。プロバイダーの読み込みはOpenSSL設定ファイルで設定でき、このオプションで目的のプロバイダーが読み込まれたかを確認できます。このコマンドはOpenSSL v3でのみ使用できます。
例:
show ssl sni [-f <frontend>] [-A] [-t <offset>]
指定したフロントエンドに設定されているすべてのSNIを出力します。フロントエンドを指定しない場合は、すべてのフロントエンドを対象とします。フロントエンドが提供するSNIを確認し、同じフロントエンドの複数の証明書で同じSNIが重複して定義されていないかを調べることができます。
-Aオプションは、notAfterの日付を過ぎた証明書だけに一覧を絞り込み、有効期限が切れた証明書だけを表示します。
-tオプションは、秒単位、または時間単位(s、m、h、d)付きのオフセットを受け取り、現在時刻に加算します。-Aと組み合わせると、そのオフセット後にどの証明書の有効期限が切れているかを確認できます。たとえば、30d後に有効期限が切れている証明書を確認するには、“show ssl sni -A -t 30d"を実行します。
列は一つの\tで区切られるため、簡単に解析できます。
‘Frontend/Bind’列には、フロントエンド名に続いて設定内のbind行の位置(frontend/file:linenum)が表示されます。
‘SNI’列には、CN、SAN、またはcrt-listのフィルターであるSNIが表示されます。bind行のデフォルト証明書(‘default-crt’で明示的に指定した証明書、または’strict-sni’を使用していない場合に暗黙的にデフォルトとなるbind行の最初の証明書)では、SNI列に’*‘文字が表示されます。
‘Negative Filter’列は、ワイルドカードに関連付けられた否定フィルターの一覧で、同じcrt-list行にあるすべての否定フィルターを表示します。該当するフィルターがなければ、ダッシュ文字を表示します。
‘Type’列は暗号化アルゴリズムの種類を示し、“rsa”、“ecdsa”、“dsa"のいずれかです。
‘Filename’列は、設定に記載されたファイル名、またはcrt-storeで宣言されたエイリアスです。
‘NotAfter’列と’NotBefore’列は、X509リーフ証明書から直接抽出したものです。
例:
show startup-logs
現在のhaproxyプロセスの起動時に出力されたすべてのメッセージを出力します。各startup-logsバッファーは、そのhaproxyワーカーに固有です。
このキーワードはマスターCLIにもあり、直近の起動またはリロードの試行を表示します。
show table
認識されているすべてのスティックテーブルの概要を出力します。テーブル名(テーブルを保持するプロキシの名前)、型(現在はゼロで、常にIP)、格納可能な最大エントリー数で表したサイズ、現在使用中のエントリー数を返します。
例:
show table <name> [ data.<type> <operator> <value> [data.<type> ...]] |
スティックテーブル<name>の内容を出力します。このモードでは、最初の行に"show table"と同様のテーブルの概要を出力し、続いてすべてのエントリーを出力します。処理の負荷が非常に高くなることがあるため、フィルターを指定して表示するエントリーを選択できます。
“data.“形式を使用すると、保存されているデータにフィルターを適用します(セクション4.2の"stick-table"を参照)。保存データの型を<type>に指定する必要があり、その型のデータがテーブルに保存されていなければエラーになります。データは<operator>に従って64ビット整数<value>と比較します。演算子はACLと同じです。
- eq:データがこの値と等しいエントリをマッチ
- ne:データがこの値と等しくないエントリをマッチ
- le:データがこの値以下のエントリーにマッチします。
- ge:データがこの値以上のエントリーにマッチします。
- lt:データがこの値未満のエントリーにマッチします。
- gt:データがこの値より大きいエントリーにマッチします。
この形式では、ビルド時に定義した上限(デフォルトは4)まで、複数のデータフィルターエントリーを使用できます。
key形式では、エントリー<key>を表示します。キーはテーブルと同じ型でなければなりません。現在使用できる型はIPv4、IPv6、整数、文字列に限られます。
ptr形式では、エントリー<ptr>を表示します。<ptr>は0xffffの形式で記述し、以前の"show table"コマンドが返したアドレスに対応している必要があります。キーが空であるか、CLIで使用できない文字が含まれるためにキーでエントリーを照合できない場合は、ポインターによる照合が適していることがあります。
data.<type>が配列型なら、”[]“で特定のインデックスへアクセスできます。たとえば、data.gpt[1]です。
例:
データ条件をバイトレートなどの時間に依存する動的な値に適用する場合は、エントリーの評価時に値を動的に計算して、出力するかどうかを決定します。そのため、このようなフィルターは、しばらく一致していても、時間の経過に伴って平均イベントレートが下がると一致しなくなることがあります。
この機能を使ってサービスを不正利用するIPアドレスの一覧を抽出し、監視したり、ファイアウォールのブラックリストに登録したりできます。例:
スティックテーブルをシャーディング対応のpeersセクションと同期している場合は、各キーのシャード番号を表示します(それ以外の場合は'0’を表示します)。これにより、そのキーを受け取るピアを確認できます。例:
show tasks
現在実行キューにあるタスクの数を、関数ごとの出現回数および、判明している場合は平均レイテンシーとともに出力します(タスクプロファイリングを有効にした純粋なタスクの場合)。出力は実行した瞬間のスナップショットであり、その時点でキューに残っているタスクによって変動することがあります。特にシングルスレッドモードでは、I/Oがキューを再び埋める機会が少ないため、変動しやすくなります(キューがいっぱいの場合を除きます)。このコマンドはプロセスに排他的にアクセスするため、高負荷のプロセスで実行すると、小さいながらも測定可能なレイテンシーが生じることがあります。監視ボットで過度に実行してはなりません。
show threads
各スレッドの内部状態と構造の一部を出力します。開発者が問題を理解するのに役立つことがあります。読みやすくするために、スレッドごとに一つのブロックとして表示します。USE_THREAD_DUMP=1を指定してhaproxyをビルドした場合は、スレッドシグナルを使う高度な出力機構によって、各スレッドが順番に自身の状態を出力します。このオプションがない場合は、コマンドを処理するスレッドについてはすべての詳細が表示されますが、他のスレッドの詳細は少なくなります。コマンドを処理するスレッドの前には星印(’*’)が表示されます。また、前回このコマンドを実行してから処理が進んでいないスレッドの前には、右山括弧(’>’)が表示されることがあります。これは必ず報告しなければならないコードのバグを示します。二つのスレッド間でこの状態が起きた場合は、通常デッドロックを示します。単独のスレッドで起きた場合は、リストの破損など、別のバグです。いずれの場合も、プロセスは正常に動作しなくなっているため、再起動する必要があります。
新たな要件に応じて、後方互換性を維持することなく出力形式を変更できるように、形式は意図的に文書化していません。“show activity"と同様に、コードを参照しなければ値の意味を理解できません。
show tls-keys [id|*]
読み込まれたすべてのTLSチケットキーの参照を出力します。TLSチケットキーの参照IDと、キーの読み込み元ファイルを表示します。どちらも"set ssl tls-key"でTLSキーを更新する際に使用できます。パラメーターとしてIDを指定すると、そのチケットを出力します。*を指定すると、すべての参照のすべてのキーを出力します。
show schema json
“show info json"と"show stat json"の出力に使用されるスキーマを出力します。
出力量を減らすため、余分な空白は含みません。人が読む場合は、出力を整形ツールに渡すと便利です。例:
$ echo “show schema json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool
スキーマは"JSON Schema”(json-schema.org)に準拠しているため、検証ツールで"show info json"と"show stat json"の出力がスキーマに適合するかを確認できます。
show trace [<source>]
現在のトレースの状態を表示します。ソースごとに一行を表示し、トレースが停止中、待機中、実行中のいずれかを一文字のステータスで示します。トレースの出力先シンク(未設定の場合は"none”)、そのシンクで破棄されたイベントの数、ソースの簡単な説明も表示します。ソース名を指定すると、そのソースがサポートするすべてのイベントと、各アクション(report、start、pause、stop)での状態を詳しく表示します。有効な場合は”+"、それ以外は”-“で示します。これらのイベントはすべて独立しており、報告されずに開始を引き起こすイベントも、その逆のイベントもあり得ます。
show version
現在のHAProxyプロセスのバージョンを表示します。マスターCLIとワーカーCLIの両方で使用できます。例:
shutdown frontend <frontend>
指定したフロントエンドを完全に削除します。バインドしていたすべてのポートが解放されます。この操作の後で、フロントエンドを再び有効にすることはできません。プロキシの停止が到底許されないものの、誤ったプロキシ設定を修正する必要がある環境での使用を想定しています。ポートを解放して別のプロセスでバインドすることで、運用を復旧できます。終了したフロントエンドは、統計ページに一切表示されなくなります。
フロントエンドは名前またはシャープ記号(’#’)を付加した数値IDのいずれかで指定できます。
このコマンドは制限付きであり、レベル「admin」で構成されたソケットでのみ実行できます。
shutdown session <id>
指定したストリーム識別子に一致するストリームを直ちに終了します。この識別子は、“show sess"の出力行の先頭にあるフィールドです(ストリームのポインターに対応します)。タイムアウトを待たずに長時間続くストリームを終了する場合や、終わりのない転送が続いている場合に使用できます。この方法で終了したストリームには、ログに’K’フラグが記録されます。
shutdown sessions server <backend>/<server>
指定したサーバーに接続するすべてのストリームを直ちに終了します。たとえば、サーバーをメンテナンスモードにした後に、長時間続くストリームを終了する場合に使用できます。この方法で終了したストリームには、ログに’K’フラグが記録されます。
バックエンド接続はアイドル状態のまま残ります。ただし、サーバーがすでにメンテナンスモードの場合は、直ちに削除の対象としてスケジュールされます。
trace
“trace"コマンドを単独で実行すると、トレースソース、その現在の状態、簡単な説明の一覧を表示します。下位レベルへ進むためのメニューにすぎません。下記の他の"trace"コマンドを参照してください。
trace 0
すべてのトレースを直ちに停止します。デバッグセッションをすぐに終えるため、または複数のソースで複雑なトレースを有効にした結果、サービスに影響が出た場合の緊急措置として使用するものです。
trace <source> [<args...>]
ソース<source>のトレースを設定します。引数を指定しないと、指定したソースがサポートするすべてのサブコマンドを表示します。複数のサブコマンドを連ねることができます。次のサブコマンドをサポートしています。
event [ [+|-|!]<name> ] 引数を指定しないと、指定したソースがサポートするすべてのイベントを表示します。無効なイベントには”-"、有効なイベントには”+“が先頭に付きます。一つのトレースに複数のイベントのラベルが付くことがあり、有効なイベントのいずれかがトレースに付いたイベントのいずれかに一致すれば、そのイベントはトレースサブシステムに渡されます。たとえば、HEADERSタイプのHTTP/2フレームを受信すると、そのフレームが新しいストリームを作成するため、フレームイベントとストリームイベントの両方が発生することがあります。そのソースでフレームイベントかストリームイベントのいずれかが有効であれば、フレームはトレースフレームワークに渡されます。
引数を指定すると、各イベントの状態を切り替え、個別に有効または無効にできます。特別なキーワードを二つサポートしています。"none"はどのイベントにも一致せず、すべてのイベントを一度に無効にします。"any"はすべてのイベントに一致し、すべてを一度に有効にします。他のイベントはイベントソースごとに異なります。イベント名を指定すると、そのイベントを有効にできます。読みやすくするために、先頭に'+'を付けてもかまいません。イベント名の先頭に'-'または'!'を付けると、そのイベントを無効にできます。
トレースソースを完全に無効にするには、"event none"を指定する方法があります。そのソースは直ちに完全に無視されます。
follow <other_source> 別のソース<other_source>がある条件にロックオンされており、現在のソースもその条件に一致する場合に、ソース<source>からもトレースを出力できるようにします。たとえば、あるソースがセッションにロックオンしているときに、別のソースからそのソースを追跡すると、追跡する側もそのセッションに関連するすべてのイベントのトレースを出力します。これを利用すると、バックエンドのリクエストと関連するフロントエンド接続を、ある程度まとめて追跡できます。“session"ソースにはロックオン処理に利用できる"new"と"end"イベントがあり、この処理を容易にします。この場合、ソース<source>のトレースが有効である必要はなく、そのトレース状態も変わりません。ただし、追跡対象の要素と関連付けるための情報を含まないイベントは、欠落することがあります。このコマンドではメタソース"all"も使用できます。この場合、すべてのソースが<other_source>を追跡します。
例:
level [<level>] 引数を指定しないと、そのソースのすべてのトレースレベルを表示します。現在のレベルには先頭に星印(’*’)が付きます。引数を指定すると、トレースレベルを指定したレベルに変更します。詳細レベルは、イベントを報告する前に適用するフィルターの一種です。イベントの重要度に応じて、報告に含めるか除外するかを選択します。たとえば、開発者はHTTPヘッダーがコードのどの位置で無効と判断されたかを正確に知る必要があるかもしれませんが、エンドユーザーはそのヘッダーの有効性にさえ関心がないかもしれません。現在、トレースには5つの異なるレベルがあります。
常に"user"レベルだけを使用し、開発者から指示された場合に限り他のレベルへ切り替えることを強く推奨します。また、先にイベントを設定してから上位レベルに切り替えるとよいでしょう。フィルターが適用されていないために大量の行が出力される事態を防げる場合があります。このコマンドではメタソース"all"も使用できます。この場合、既存のすべてのソースに一度にそのレベルを適用します。
lock [criterion] 引数を指定しないと、そのソースがロックオン処理でサポートするすべての条件を表示します。現在の選択には先頭に星印(’*’)が付きます。ロックオンとは、最初に一致したイベントに注目し、そのイベントを引き起こした条件だけを追跡して、トレースが停止するまで他をすべて無視することです。たとえば、単一の接続や単一のストリームをトレースできます。次の条件は一部のトレースでサポートされていますが、ソースによっては利用できない条件もあるため、必ずしもすべてをサポートしているとは限りません。
さらに、各ソースは内部状態や接続IDなど、固有の条件を最大4つ提供できます。たとえばHTTP/2では、H2ストリームにロックオンして、トレースが始まった後は他のストリームを無視できます。
引数に条件を渡すと、他の条件に代えてその条件を使用し、既存の追跡を直ちに終了して、新しい条件で再開できるようにします。特別なキーワード"nothing"はすべてのソースでサポートされており、追跡を常に無効にします。
{ pause | start | stop } [ [+|-|!]event] 引数を指定しないと、そのソースのトレースを自動的に一時停止、開始、停止するために有効になっているイベントを表示します。これらのイベントはトレースソースごとに異なります。引数を指定すると、指定したアクションについてそのイベントを有効にするか(先頭に’+‘を付けてもかまいません)、無効にします(先頭に’-‘または’!‘を付けた場合)。特別なキーワード"now"はイベントではなく、アクションを直ちに実行するよう要求します。“none"と"any"も"trace event"と同じように使用できます。
サポートする3つのアクションは"pause"、"start"、"stop"です。"pause"アクションでは、実行中のトレースを停止し、新たな開始イベントによる再開を待つ状態にするイベントを列挙します。"start"アクションでは、開始イベントのいずれかが発生するまでトレースを待機モードにするイベントを列挙します。"stop"アクションでは、手動で再び有効にするまでトレースを完全に停止するイベントを列挙します。実際には、イベントを気にせず"start now"で手動開始し、"stop now"で停止するのが理にかなっています。より細かなイベントの連続を記録するには、"start"を通常のイベント(HTTPリクエストの受信など)、"stop"を特定のエラーの発生などの非常にまれなイベントに設定します。これにより、最後に記録されるイベントが目的の条件に一致するようになります。また、一時停止イベントは、一連の処理の終わりを検出し、ロックオンを解除して、次の記録機会を待つのに便利です。この場合、ロックオンを有効にして特定の条件(ストリームなど)だけを捉え、"start"にはその条件の始まりとなるもの(ストリームを作成するすべてのイベントなど)、"stop"には想定する異常、"pause"にはその条件の終わりとなるもの(ストリームの終了イベントなど)を設定するとよいでしょう。すると、トレースログには、単一のオブジェクトに対する正常な処理の全過程が繰り返し記録され、最後に、処理の開始から異常に至るまでのすべてを含む一連のイベントが記録されます。
sink [<sink>] 引数を指定しないと、そのソースで利用可能なすべてのイベントシンクを表示します。現在設定されているシンクには先頭に星印(’*’)が付きます。シンク"none"は常に使用でき、すべてのイベントを単に破棄することを意味します。ただし、イベントの処理自体は省略しません(たとえば、ロックオンは行われます)。他のシンクは設定やビルドオプションによって異なりますが、通常はデバッグモードで"stdout"と"stderr"が使用でき、メモリ内のリングバッファーも利用できるはずです。名前を指定すると、指定したソースのシンクが直ちに変わります。シンクの変更によってイベントは変わりません。無効なシンク(または"none”)を使用すると、最悪の場合、一部のイベントが失われることがありますが、処理は別の出力先で継続します。このコマンドではメタソース"all"も使用できます。この場合、既存のすべてのソースに一度にそのシンクを適用します。
verbosity [<level>] 引数を指定しないと、そのソースのすべての詳細度レベルを表示します。現在のレベルには先頭に星印(’*’)が付きます。引数を指定すると、詳細度を指定したレベルに変更します。
詳細度レベルは、トレースデコーダーがどこまで詳しい情報を提供するかを示します。固有のデコーダーを持たないソースもあるため、トレースソースによって異なります。"quiet"レベルは常に使用でき、すべてのデコードを無効にします。パフォーマンスやトレースサイズへの影響が非常に小さいため、詳細を理解する前に何が起きているかを把握したいときに便利です。ソースが詳細度レベルを宣言していない場合は"default"レベルが使用でき、トレースでデコーダーが指定されていれば呼び出します。つまり、利用できる場合にデコードします。ソースが詳細度レベルを宣言している場合は、各レベルとその内容の説明を一覧表示します。この場合、ソースが提供するトレースデコーダーは、トレース位置で得られる情報に基づき、可能な限り正確にデコードします。デフォルトでは、"quiet"の一つ上のレベルが設定されます。
update ssl ocsp-response <certfile>
指定した<certfile>のOCSPリクエストを作成し、OCSPレスポンダーに送信します。レスポンダーのURIは、証明書の"Authority Information Access"セクションに指定しておくべきです。最初のURIだけを使用します。返されるはずのOCSPレスポンスを検証し、ローカルのOCSPレスポンスツリーに挿入します。このコマンドが動作するのは、初期化時に提供されたか、以前に"set ssl cert"または"set ssl ocsp-response"コマンドで設定されたOCSPレスポンスを、すでに保持している証明書だけです。受信したOCSPレスポンスが有効で、ローカルツリーに正しく挿入された場合は、その内容を標準出力に表示します。形式は"show ssl ocsp-response"で説明したものと同じです。
wait { -h | <delay> } [<condition> [<args>...]]
条件を指定しない最も単純な形式では、指定した時間だけ待ってから処理を続けます。特定の間隔を空けてメトリクスを収集する場合に使用できます。
条件と任意の引数を指定すると、その条件が満たされるか、回復不能な失敗となるか、条件が満たされないまま<delay>の時間がすべて経過するまで待機します。次の条件をサポートしています。
-
be-removable
<proxy>:指定したプロキシのバックエンドを"del backend"コマンドで削除できるようになるまで待機します。決して受け入れられない状態(バックエンドがまだ非公開になっていない、またはサーバーが残っている場合など)もあり、その場合は、満たされていない条件を示す固有のエラーメッセージを返します。待機時間が経過する前にすべての条件が整えば、成功を返して処理を終了します。 -
srv-removable
<proxy>/<server>:指定したサーバーを"del server"コマンドで削除できるようになるまで待機します。つまり、メンテナンス状態にあり、アクティブな接続もアイドル接続も残っていない状態を待ちます。決して受け入れられない状態(メンテナンス状態ではない場合など)もあり、その場合は、満たされていない条件を示す固有のエラーメッセージを返します。並行してサーバーが削除され、すでに存在しない場合もあります。待機時間が経過する前にすべての条件が整えば、成功を返して処理を終了します。
待機時間のデフォルト単位はミリ秒ですが、通常の時間単位(us、ms、s、m、h、d)を末尾に付ければ、他の単位も使用できます。‘socat’ユーティリティと併用する場合は、socatのクローズタイムアウトを待機時間に合わせて延長することを忘れないでください。最初または二番目の引数に”-h"を渡すと、コマンドの使用方法を表示します。例:
9.4. マスターCLI
マスターCLIは、master-workerモードでマスタープロセスにバインドされるソケットです。このCLIから、実行中または終了処理中の各プロセスのUNIXソケットコマンドにアクセスでき、これらのプロセスの基本的な監視を行えます。
マスターCLIは、haproxyプログラムの引数に-Sオプションを指定する方法でのみ設定できます。このオプションには、コンマで区切ったbindオプションも指定できます。
例:
9.4.1. マスターCLIのコマンド
@<[!]pid>
マスターCLIでは、特別な接頭辞表記で複数のプロセスにアクセスします。この表記は@で始まるため、簡単に識別できます。
@接頭辞の後には、相対プロセス番号、または感嘆符とPIDを指定できます(例:@1、@!1271)。@だけを指定すると、マスターを指定できます。相対プロセス番号は現在のプロセスにしか使用できないため、終了処理中のプロセスにはPIDでのみアクセスできます。
この接頭辞をコマンドの前にラッパーとして付けると、そのコマンドだけを指定したプロセスに送信します。この場合、通常のコマンドと同様に、行末またはセミコロンでコマンド全体が終了します。
バグ:マスターとワーカー間の通信に使うsockpair@プロトコルは、macOSのsendmsg(2)実装の問題により、macOSでは信頼性に問題があることが知られています。そのため、コマンドが応答のないまま終わることがあります。
例:
接頭辞を単独のコマンドとして使用して、デフォルトの実行コンテキストを指定したプロセスに切り替えることもできます。以後のコマンドは、新たな’@‘コマンドで再び実行コンテキストを変更するまで、すべてそのプロセスで実行されます。
例:
制限事項:一部のまれなコマンドはCLIセッションの状態を変更します(“set anon”、“set timeout"など)。マスターCLIからは、コマンドがそれぞれ専用のCLIセッションで一つずつ送られるため、まったく同じようには動作しないことがあります。また、一部のまれなコマンド(“show events”、“wait”)は、CLIの入力や切断を継続的に監視し、CLIが閉じられると直ちに中断します。マスターCLIでは、コマンドごとに入力が閉じられるため、これらのコマンドは期待どおりに動作しません。このようなまれな場合には、下記の”@@“形式がより適している場合があります。
@@<[!]pid> [command...]
この接頭辞またはコマンドは、上記の”@“接頭辞とよく似ていますが、ワーカープロセスに入り、コマンド行全体をそのまま渡して、コマンドが終了するまでそこに留まる点が異なります。セミコロンも渡されるため、連結したコマンド全体をワーカープロセスで実行できます。コマンドの一覧を実行し終えるまで、ワーカーとの接続は開いたままです。コマンドの後に送信したデータは、ワーカープロセスのCLIに転送され、実行中のコマンドが消費する可能性があります。マスタープロセスのCLIには戻りません。これにより、ワーカープロセスとの完全な双方向接続を実現します。そのため、このようなコマンドを使用する場合は、マスターCLIへ次のコマンドを送る前に、必ず実行中のコマンドの完了を待つよう十分に注意しなければなりません。
単一のコマンドを実行する代わりに、コマンドを何も指定せず(つまり、一行に”@@1"だけを記述して)、ワーカープロセスで完全な対話型セッションを開くこともできます。このセッションは、接続を閉じるか、ワーカープロセス側で"quit"コマンドを実行して終了できます。この場合、マスターソケットのプロンプトモード(interactive、prompt、timed)がワーカープロセスに引き継がれます。
バグ:マスターとワーカー間の通信に使うsockpair@プロトコルは、macOSのsendmsg(2)実装の問題により、macOSでは信頼性に問題があることが知られています。そのため、コマンドが応答のないまま終わることがあります。
例:
expert-mode [on|off]
このコマンドは、マスターCLIからアクセスするすべてのワーカーで"expert-mode"を有効にします。“mcli-debug-mode"と組み合わせると、マスターでもこのコマンドを有効にします。マスターCLIのプロンプトに"e"フラグを表示します。
セクション9.3 の"expert-mode"および9.4.1の"mcli-debug-mode"も参照してください。
experimental-mode [on|off]
このコマンドは、マスターCLIからアクセスするすべてのワーカーで"experimental-mode"を有効にします。“mcli-debug-mode"と組み合わせると、マスターでもこのコマンドを有効にします。マスターCLIのプロンプトに"x"フラグを表示します。
セクション9.3 の"experimental-mode"および9.4.1の"mcli-debug-mode"も参照してください。
hard-reload
このコマンドは、マスターCLIの"reload"コマンドと同じ処理を行いますが、以前のプロセスに対してstop-stop(-sf)の代わりにhard-stop(-st)を行います。つまり、以前のプロセスは処理の完了を何も待たずに終了するため、すべての接続が閉じられます。
“reload"コマンドも参照してください。
mcli-debug-mode [on|off]
このキーワードは、マスターCLIで特別なモードを有効にします。ワーカーCLI向けのすべてのキーワードをマスターCLIで使用できるようにして、マスタープロセスをデバッグできます。有効にした後は、“help"で新たに使用可能になったキーワードを一覧表示できます。“experimental-mode"または"expert-mode"と組み合わせると、さらに多くのキーワードを有効にできます。マスターCLIのプロンプトに"d"フラグを表示します。
prompt
(“prompt"コマンドで)プロンプトを有効にすると、CLIが処理対象としているコンテキストをプロンプトに表示します。マスターは"master"文字列、他のプロセスはPIDで識別します。直前のリロードが失敗した場合は、マスターのプロンプトが"master[ReloadFailed]>“に変わり、プロセスが以前の設定で動作し続けていて、新しい設定が有効になっていないことが分かります。
マスターCLIのプロンプトには、有効なモードを示す複数のフラグを表示できます。“d"はmcli-debug-mode、“e"はexpert-mode、“x"はexperimental-modeを示します。
例:
reload
ユーザーに少なくとも"operator"または"admin"権限があれば、“reload"コマンドでHAProxyのマスタープロセスをリロードすることもできます。これは、マスタープロセスに対してkill -USR2を実行するのと同じです。
このコマンドでは同期的にリロードできます。リロードを実行した後、そのステータスを返します。ツールで結果を解析する場合は、タイムアウトに注意してください。設定の解析と新しいワーカーのforkが終わるまで、結果は返りません。“socat"コマンドのデフォルトのタイムアウトは0.5sなので、リロードに時間がかかりすぎると、メッセージを表示する前に終了します。“ncat"にはデフォルトではタイムアウトがありません。USE_SHM_OPEN=1でコンパイルした場合は、reloadコマンドでマスターのstartup-logsも出力できます。
例:
reloadコマンドはマスターCLIで実行される最後のコマンドであり、その後のコマンドはすべて無視されます。reloadコマンドがステータスを返すと、CLIへの接続を閉じます。
リロードすると、マスターCLIへのすべての接続が閉じられることに注意してください。“hard-reload"コマンドも参照してください。
show proc [debug]
マスターCLIには、プロセスを監視する’show proc’コマンドがあります。
例:
この例では、マスターが5回リロードされていますが、以前のワーカーの一つがまだ動作しており、3回のリロードを経ても残っています。このワーカーのCLIにアクセスして、何が起きているかを調べることができます。
‘debug’パラメーターは、デバッグ用の詳細を表示するのに便利です。現在はIPC通信用のFDを表示します。デバッグ出力がhaproxyのバージョン間で安定している保証はありません。
show startup-logs
マスターCLIで正しく使用するには、HAProxyをUSE_SHM_OPEN=1でコンパイルする必要があります。そうしないと、すべてのメッセージを確認できません。
統計ソケットの同名コマンドと同様に、HAProxyの起動メッセージを表示できます。ただし、出力するのは現在のワーカーの起動メッセージではなく、直近の起動またはリロード時のメッセージです。そのため、リロードが失敗した際の解析メッセージも出力できます。
これらのメッセージは"reload"コマンドでも出力します。
9.5. 統計ファイル
stats-fileと呼ばれるファイルを使用すると、プロセスの起動時に、haproxy内部のカウンターにゼロ以外の値を事前に読み込めます。主な目的は、ワーカープロセスの統計値をリロード後も維持することです。事前に読み込む意味があるのはメトリクス型の値だけなので、stats-fileに含まれるのは、haproxyが公開する統計値の一部だけです。
現在、stats-fileがサポートするのはプロキシのカウンターだけです。フロントエンド、バックエンド、サーバー、リスナーの値を事前に読み込めます。ただし、stats-fileに保存されるのは、GUIDが空でないオブジェクトのインスタンスだけです。これにより、他のパラメーターが異なっていても、型とGUIDが一致するオブジェクトに値を事前に読み込むことが保証されます。
CLIコマンド"dump stats-file"は、stats-fileを生成するためのものです。stats-fileの形式は内部で定義されており、今後自由に変更や拡張が行われる可能性があります。少なくとも隣接するhaproxy安定ブランチのリリース間では互換性を維持する設計ですが、古いバージョンで動作するプロセスにstats-fileを読み込む場合は、必要に応じて追加の設定が求められることがあります。
31 - 10. 設定管理を容易にする方法
クラスターを構成する2つのHAProxyノードが、少数のアドレスを除いてまったく同じ設定を共有することはよくあります。ノードごとに設定の複製を管理すると、その内容は必然的に食い違っていきます。設定に環境変数を組み込めば、システム全体の環境変数をいくつか変えるだけで、複数の設定でまったく同じファイルを共有できます。この機能はバージョン1.5で導入され、当初はアドレスにのみ環境変数を含めることができました。1.6では対応範囲が広がり、どこでも環境変数を使用できます。構文はUNIXシェルと同じで、変数はドル記号 (’$’)、開き波括弧 (’{’)、変数名、閉じ波括弧 (’}’) の順に記述します。アドレスを除き、環境変数は二重引用符で囲まれた引数の中でのみ解釈されます。これは、ドル記号を含む正規表現を使用する既存の設定を壊さないために必要な制限です。
環境変数を使用すると、アドレスだけが異なる複数の拠点で動作する設定を簡単に記述できます。一部の設定からパスワードを取り除くためにも利用できます。次の例では、起動時にinitスクリプトが “site1.env” ファイルを読み込みます。
32 - 11. 回避すべき既知の落とし穴
システムの再起動後にhaproxyサービスが起動せず、手動で起動すると動く、という報告をときどき受けます。多くの場合、keepalivedなどのクラスターIPアドレス管理機構を使い、マスターノードだけにサービスのIPアドレスを割り当てています。haproxyを0.0.0.0にバインドしていたときは動作していたものが、仮想IPアドレスにバインドするように変更すると動かなくなります。これは、サービスの起動時点ではローカルノードが仮想IPアドレスをまだ所有しておらず、HAProxyがそのアドレスにバインドしようとすると、ローカルのIPアドレスではないためシステムが拒否することが原因です。解決策はhaproxyサービスの起動を遅らせることではありません。それでは再起動に対応できません。ローカルに存在しないアドレスへのバインドを許可するよう、システムを正しく設定します。Linuxでは、net.ipv4.ip_nonlocal_bind sysctlを1に設定するだけです。この設定は、特定の宛先アドレスに向けてHAProxyを通過するIPトラフィックを透過的に捕捉する場合にも必要です。
送信元ポートの範囲を使用するマルチプロセス構成は、一見動作しているようでも、高負荷時にランダムな障害を起こします。複数のプロセスが同じ送信元ポートを使って同じサーバーに接続しようとする可能性があり、それはできないためです。システムがエラーを返し、別のポートを選んで再試行します。“retries” パラメーターに大きな値を設定すれば影響をある程度隠せますが、CPU使用量と処理時間も増加します。ログにも一定数の再試行が記録されます。このため、マルチプロセス構成ではポート範囲の使用を避けてください。
HAProxyはSO_REUSEPORTを使用し、複数の独立したプロセスを同じIP:portにバインドできます。このため、トラブルシューティング中に古いプロセスを停止しないまま新しいプロセスを起動してしまうことがあります。その結果、設定の変更がすべて無視されているかのような、不可解なテスト結果が得られます。新しいプロセスを新しい設定で再起動しても、古いプロセスが受信接続の一部を処理し、想定外の結果を返すためです。疑わしい場合は新しいプロセスを停止し、もう一度試してください。それでも動作するなら、古いプロセスが残っていて停止する必要がある可能性が非常に高いと考えられます。Linuxの “netstat -lntp” が調査に役立ちます。
コマンドラインからACLにエントリーを追加する場合、たとえば送信元アドレスをブラックリストに登録する場合は、これらのエントリーがファイルに同期されないことに注意してください。誰かが設定をリロードすると、更新内容は失われます。ブラックリストへの登録ではこの動作が望ましいことも多いものの、問題を修正するための変更であれば、期待どおりとは限りません。CLIインターフェースの “add acl” アクションを参照してください。
33 - 12. デバッグと性能の問題
HAProxyを"-d"オプションで起動すると、フォアグラウンドで動作し、着信接続や接続の終了などのイベントごと、および受信したリクエスト・レスポンスのヘッダー行ごとに1行を出力します。このデバッグ出力は内容を処理する前に生成されるため、ローカルでの変更は反映されません。主な用途は、ネットワークスニファーを使わずにリクエストとレスポンスを表示することです。複数の接続を並列に処理すると出力は読みにくくなりますが、examples/ディレクトリにある"debug2ansi"と"debug2html"スクリプトで色分けすると、かなり読みやすくなります。
HAProxyがHTTP/1.xのリクエストやレスポンスを不正な形式と判断して拒否した場合は、CLIに接続して"show errors"を実行するのが最適です。フロントエンドとバックエンドごとに、最後に取得された不正なHTTP/1.xリクエストとレスポンス、および入力ストリームで最初に拒否された文字を正確に特定するための情報がすべて表示されます。顧客や開発者のコードにバグがあることを証明するため、これが必要になる場合があります。この場合、“option accept-unsafe-violations-in-http-request”、またはサーバーからのレスポンスに対する同等の"option accept-unsafe-violations-in-http-response"を使うと、取得は続けたままチェックを緩和できることがよくあります。詳細は設定マニュアルを参照してください。
例:
CLIの"show info"の出力には、これまでの最大接続レート、最大SSL鍵処理レートなど、CPUやメモリ使用量に関する一時的な問題の説明に役立つさまざまな情報が含まれます。例:
新しいHAProxyバージョンで問題が不規則に発生するように見える場合(リクエストが1つおきに中断される、時折クラッシュするなど)は、メモリポイズニングを有効にしてみる価値があります。malloc()を呼ぶたびに、直後にメモリ領域を設定可能なバイトで埋める機能です。デフォルトのバイトは0x50(ASCIIの’P’)ですが、ゼロを含む任意のバイトを使えます。ゼロの場合はcalloc()と同じ効果になり、問題が消えることがあります。メモリポイズニングは、コマンドラインの"-dM"オプションで有効にします。性能にわずかな影響があるため、本番環境での使用は推奨しません。有効にすると必ず問題が起きる場合や、ゼロでポイズニングすると一切起きなくなる場合は、明らかにバグを発見したことを意味するため、必ず報告してください。明確な変化がなければ、その問題はこれとは関係ありません。
レイテンシーの問題をデバッグする際は、ローカルマシンでstraceとtcpdumpの両方を使い、リモートシステムでも別のtcpdumpを使うことが重要です。処理の各段階に遅延があり、どこで対処するべきかを判断するには、どの遅延が原因かを知る必要があるためです。実際には、ローカルのtcpdumpで入力データの到着時刻を確認し、straceでhaproxyがそのデータを受け取る時刻(recv/recvfrom)を確認します。opensslはrecv()/send()ではなくread()/write()システムコールを使う点に注意してください。straceはhaproxyのデータ送信時刻も表示し、tcpdumpはシステムがそのデータをインターフェースへ送る時刻を表示します。次に、外部のtcpdumpで、送信されたデータが実際に受信された時刻を確認します。ローカルのtcpdumpで分かるのは、パケットがキューに入った時刻だけだからです。ローカルシステムで取得する利点は、straceとtcpdumpが同じ基準時計を使うことです。straceは"-tts200"を指定して使うことを推奨します。完全なタイムスタンプと、内容を読めるだけの大きさのデータを表示できます。tcpdumpは"-nvvttSs0"を指定し、完全なパケット、実際のシーケンス番号、完全なタイムスタンプを表示することを推奨します。
実際には、マシンのCPUが飽和している場合や、データが不正で配送されない場合を除き、受信データはほぼ常に直ちにhaproxyへ渡されます。受信されても送信されない場合は、通常、出力バッファーが満杯であることが原因です。つまり、受信側が十分な速さでデータを消費していません。出力ファイル記述子への書き込み可能通知がポーリングでしばらく届かないことから確認できます。strace出力でデータが最終的に送出される箇所を見つけ、さかのぼって書き込みイベントの通知時刻を調べると分かりやすいことがよくあります。通常、tcpdumpで検出される受信側からのACKと一致します。送信後も、データがシステム内でしばらく待機することがあります。ここでも、TCPの輻輳ウィンドウの制限によってデータを送出できず、ウィンドウを広げるACKを待っている可能性があります。トラフィックがないのにデータの送出まで40 msや200 msかかる場合は、別の現象です(問題ではありません)。Nagleアルゴリズムが、後続データとの結合を期待して、空のパケットの即時送出を防いでいるためです。HAProxyは純粋なTCPモードとトンネルではNagleを自動的に無効にします。ただし、HTTPボディーの転送時には有効なままであり、パケット数を減らすことで性能向上に寄与します。HTTPに準拠していない一部のアプリケーションは、不完全なHTTPレスポンスメッセージの配送時のレイテンシーに影響を受ける場合があります。その設計に対処するには、“option http-no-delay"を有効にしてNagleを無効にする必要があります。その際、経路上のほかのプロキシも同様の影響を受ける可能性があることを念頭に置いてください。tcpdumpでは即座にデータが送出されているのに、相手側ですぐに受信できない場合は、WANリンクの輻輳、フロー制御が有効なLANの輻輳による送出の抑止、または、より一般的には、HAProxyが実際には仮想マシンで動作し、ハイパーバイザーが何らかの理由で即時送信は不要と判断したことが考えられます。仮想化環境のレイテンシー問題は、ほぼ常に仮想化層が原因です。時間を節約するには、まずVM内と外部コンポーネントのtcpdumpを比較する価値があります。差があれば、その原因はハイパーバイザーと付随するドライバーにあります。
tcpdumpのトレース(-vvを使用)にTCP SACKセグメントが見られる場合、それを送った側はパケット損失の証拠を得ています。SACKが見えなくても損失がないとは限りませんが、見えた場合は確実にネットワークで損失が発生しています。ネットワークでの損失は正常な現象ですが、通常はSACKが目視で目立たない程度の頻度です。トレースに大量に現れる場合は、何が起きているのか、どこでパケットが失われているのかを詳しく調べる価値があります。HTTPはTCPの損失にうまく対処できず、大きなレイテンシーが生じます。
“netstat -i"コマンドは、インターフェースごとの統計を表示します。Rx-Ovrカウンターが増えているインターフェースでは、すべての受信パケットを受け取るためのシステムリソースが足りず、ネットワークドライバーで処理される前にパケットが失われています。Rx-Drpは、アプリケーションの処理が遅いために、受信済みのパケットがネットワークスタック内で失われたことを示します。これは攻撃中にも起こり得ます。Tx-Drpは、出力キューが満杯で、パケットを破棄する必要があったことを示します。TCP使用時には極めてまれなはずですが、送信リンクが飽和している可能性を示します。
34 - 13. セキュリティに関する考慮事項
HAProxyは、非常に限られた権限で動作するよう設計されています。標準的な使用方法は、chroot jailに隔離したうえで、jail内で何の権限も持たない非rootユーザーに権限を落とすことです。これにより、将来脆弱性が発見されても、侵害がシステムの他の部分に影響しないようにします。
chrootを実行するには、最初にrootユーザーとして起動する必要があります。手作業でchroot環境を構築し、その中でプロセスを起動するのは意味がありません。そのような環境の構築は面倒で、適切に保守されることがなく、メインのファイルシステムよりはるかに多くの問題を抱えがちです。侵害された場合、侵入者はその専用のファイルシステムを利用できます。残念ながら、多くの管理者が「rootとして起動する」ことと「rootとして動作する」ことを混同し、haproxyの起動前にuidを変更してしまうため、実際のセキュリティ制限が弱くなっています。
HAProxyは、次の処理を行うためにrootとして起動する必要があります。
- ファイル記述子の上限を調整する。
- 特権ポート番号にバインドする。
- 特定のネットワークインターフェースにバインドする。
- 他のホストのアドレスで透過的にリッスンする。
- chroot jail内に自身を隔離する。
- 別の非特権UIDに切り替える。
次の処理を行うには、HAProxyをrootとして動作させる必要がある場合があります。
- 送信接続を特定のインターフェースにバインドする。
- 送信接続を特権送信元ポートにバインドする。
- 送信接続を他のホストのアドレスに透過的にバインドする。
ほとんどのユーザーは「rootとして動作する」必要はありません。一方、ほとんどの用途では「rootとして起動する」必要があります。
安全な設定には、次の要素を含めます。
- アクセス権限が一切ない空の場所を指すchroot文。UNIXのコマンドラインでは、次のように準備できます。
HAProxy設定のglobalセクションでは、次のように参照します。
- globalセクション内のuid/user文とgid/group文の両方。
- CLIへのアクセスを許可するユーザーまたはグループに合わせてmode、uid、gidを設定したstatsソケット。これにより、他のユーザーからのアクセスを防ぎます。
13.1. Linux capabilitiesのサポート
バージョンv2.9以降、haproxyはLinux capabilitiesをサポートしています。バイナリーがUSE_LINUX_CAP=1でコンパイルされている場合、rootユーザーから非rootユーザーに切り替える際に、‘setcap’ キーワードで指定されたcapabilityを保持できます。
バージョンv3.1以降では、‘setcap’ キーワードで指定されたcapabilityが、管理者によってバイナリーファイルのPermittedセットに設定されているかも確認します(capgetシステムコール)。設定されていれば、非rootユーザーとして動作しながら、それらをプロセスのEffectiveセットに移します(capsetシステムコール)。
これは、透過プロキシモードや特権ポートへのバインドなど、haproxyをrootとして起動し、動作させる必要があるすべての用途をなくすための対応です。
‘setcap’ キーワードは、次のネットワークcapabilityをサポートします。
- cap_net_admin: 透過プロキシ、特定のネットワークインターフェースへのソケットのバインド、set-markアクションの使用。
- cap_net_raw(cap_net_adminのサブセット): 透過プロキシ。
- cap_net_bind_service: 特権ポートへのソケットのバインド。
- cap_sys_admin: 特定のネットワーク名前空間内でのソケットの作成。
HAProxyは、これらのcapabilityが ‘setcap’ の引数に列挙されていない限り、PermittedセットからEffectiveセットへ移しません。‘setcap’ キーワードとサポートされるcapabilityの詳細は、設定ガイドの第3.1章「プロセス管理とセキュリティ」を参照してください。
管理者は、次のコマンドでhaproxyバイナリーファイルのPermittedセットに必要なcapabilityを追加できます。
例:
追加したcapabilityは、プロセスの起動後にそのPermittedセットで確認できます。同じcapabilityを ‘setcap’ キーワードの引数に指定していれば、プロセスのEffectiveセットでも確認できる場合があります。次のコマンドで確認できます。
例:
CapInh: 0000000000000000
CapPrm: 0000000000001400
CapEff: 0000000000001400
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
setcapとcapabilityのセットの詳細は、Linuxのマニュアルページcapabilities(7) を参照してください。
透過プロキシや、特定のネットワーク名前空間内でのソケットの作成などの用途では、設定ファイルのパーサーがcap_net_raw、cap_sys_admin、その他のサポート対象capabilityが必要であることを検出します。その後、初期化段階でhaproxyプロセスが、それらを自身のEffectiveセットに設定できるか確認します。SELinuxやSeccompなどのセキュリティモジュールによるシステムコール制限のためcapgetやcapsetが失敗するなど、設定できない場合は、診断用の警告を出力します(-dDを指定して起動します)。
システム設定の異なる多数のプラットフォームをサポートしているため、特権ポートへのバインドが行われるかどうかを、パーサーが設定ファイルだけから判断することはできません。そのため、非rootでの動作など権限が不足する場合は、次のようなアラートメッセージを出してプロセスが終了するだけです。設定とhaproxyバイナリーのcapabilityセットは、ユーザー自身が再確認する必要があります。
例: