前にHTTPプロトコルについて説明したときは、HTTPの「要求/応答」モデルに厳密に従いましたが、相互に通信するプロトコルには、「要求側」ブラウザ(クライアント)と「応答側」サーバーの2つの役割しかありません。
本日、このモデルに新しい役割、つまりHTTPプロキシを導入します。
HTTPプロキシの導入後、2つのパーティ間の元の単純な通信はさらに複雑になりました。1つ以上の仲介者が追加されましたが、全体としては、シーケンス関係を持つチェーンであり、チェーン内の2つの隣接する役割はまだ単純です。 1対1のコミュニケーションでは、跳躍はありません。
チェーンの開始点はクライアント(つまり、ブラウザー)であり、中間の役割はプロキシサーバーと呼ばれ、チェーンの終点はオリジンサーバーと呼ばれます。つまり、データの「ソース」と「オリジン」を意味します。
代行サービス
「エージェント」という言葉は非常に神秘的で、少し「背が高い」ように聞こえます。
しかし、実際には、HTTPプロトコルにはそれについての特別な説明はありません。クライアントとサーバー間の元の通信リンクに挿入される中間リンクであり、サーバーでもありますが、「プロキシサービス」を提供します。
いわゆる「プロキシサービス」とは、サービス自体はコンテンツを生成せず、中間の位置でアップストリームとダウンストリームの要求と応答を転送することを意味します。2つのIDがあります。ダウンストリームユーザーに対面すると、サーバーとして機能し、ソースサーバーに代わってクライアント要求に応答します。上流のソースサーバーに面している場合、クライアントとしても機能し、クライアントに代わってリクエストを送信します。
例として挙げた「生鮮スーパー」を例に考えてみましょう。
以前はいつもスーパーで買い物をしていましたが、階下にスーパーが直営の24時間営業のコンビニエンスストアがオープンし、スーパーに行かなくてはならなかったコンビニで買い物ができるようになりました。
このように、スーパーマーケットはあなたと直接取引するのではなく、「ソースサーバー」になり、コンビニエンスストアはスーパーマーケットの「プロキシサーバー」になります。
で第四講義、私はそのような匿名プロキシ、透過プロキシ、フォワードプロキシとリバースプロキシなどの薬剤の多くの種類が存在している、と述べています。
本日は、実際の作業で最も一般的なリバースプロキシについてお話しますが、リバースプロキシは送信リンクでソースサーバーに近く、ソースサーバーにプロキシサービスを提供します。
エージェントの役割
なぜエージェントが必要なのですか?つまり、エージェントは何ができ、どのようなメリットがありますか?
「コンピュータサイエンスの分野におけるあらゆる問題は、中間層を導入することで解決できる」(「中間層が問題を解決できない場合、中間層を追加します ")。これは、プロキシと同様に、TCP / IPプロトコルスタックの場合です。
プロキシはHTTP通信プロセスの途中にあるため、実クライアントは上方向にシールドされ、実サーバーは下方向にシールドされます。簡単に言えば、これは「詐欺と隠蔽」です。この中間層の「リトルワールド」では、さまざまなことを実行でき、HTTPプロトコルに柔軟性を追加して、クライアントとサーバー間で「双方にとって有利」になります。
エージェントの最も基本的な機能の1つは、負荷分散です。ソースサーバーはクライアントに面しているときにブロックされるため、クライアントはプロキシサーバーのみを認識し、ソースサーバーが持つIPアドレスの数とIPアドレスは不明です。そのため、プロキシサーバーは、要求の分散の「力」を把握し、要求に応答するサーバーを決定できます。
また、ポーリング、一貫性のあるハッシュなど、エージェントで一般的に使用される負荷分散アルゴリズムについて聞いたことがあるはずです。これらのアルゴリズムの目標は、システムの全体的なリソースを改善するために、外部トラフィックを複数の送信元サーバーに合理的に分散することを試みることです。使用率とパフォーマンス。
ロードバランシング中、プロキシサービスは次のような機能も実行できます。
ヘルスチェック:「ハートビート」などのメカニズムを使用してバックエンドサーバーを監視し、障害が発生した場合にクラスターを適時に「キックアウト」して、高いサービス可用性を確保します。
セキュリティ保護:プロキシされているバックエンドサーバーを保護し、IPアドレスまたはトラフィックを制限し、ネットワーク攻撃と過負荷に抵抗します。
暗号化とオフロード:外部ネットワークにはSSL / TLS暗号化通信認証が使用されますが、安全な内部ネットワークでは暗号化されないため、暗号化と復号化のコストがかかりません。
データフィルタリング:アップストリームデータとダウンストリームデータをインターセプトし、ポリシーの変更要求または応答を任意に指定します。
コンテンツキャッシュ:サーバーの応答を一時的に保存して再利用します。これは、講義20と密接に関連しています。これについては後で説明します。
次に、今すぐコンビニエンスストアを例にします。
コンビニエンスストアとスーパーマーケットの間に特別な車の配達があるので、コンビニエンスストアを使用すると、将来物を購入するのがより便利になります。コンビニエンスストアに電話して商品を受け取ることができます。スーパーマーケットが閉店していて過密であるかどうかを心配する必要はありません。いつでも新鮮なものを買うことができます。
スーパーマーケットにもコンビニエンスストアが便利です。追加の店先がなくても、顧客のソースと販売量を増やすことができます。商品の集中的な積み下ろしは、物流コストも節約します。コンビニエンスストアは直接顧客に面しているため、悪意のある嫌がらせの電話をブロックすることもできます。
エージェント関連のヘッダーフィールド
プロキシには多くの利点がありますが、「ブラフと非表示」の特性により、実際のクライアントとサーバーを隠します。2つのパーティがこれらの「失われた」元の情報を取得したい場合はどうなりますか?
まず、プロキシサーバーは、フィールド " Via "でプロキシのID を示す必要があります。
Viaは一般的なフィールドであり、要求ヘッダーまたは応答ヘッダーのいずれかに表示できます。メッセージがプロキシノードを通過するときはいつでも、プロキシサーバーは、メッセージを処理した人が章を持っているかのように、フィールドの末尾に独自の情報を追加します。
通信リンクに多数の中間エージェントがある場合、リンクされたリストがViaに形成され、メッセージが宛先に到達するために移動したリンクの数を知ることができます。
たとえば、次の図には、proxy1とproxy2の2つのプロキシがあります。クライアントは、「Via:proxy1、proxy2」という順番で追加されたこれらの2つのプロキシを介してリクエストを送信します。サーバーが応答メッセージを返すと、その逆になります。フィールドは「Via:proxy2、proxy1」です。
Viaフィールドは、プロキシがあるかどうかを判断するクライアントとソースサーバーの問題を解決するだけであり、相手の実際の情報を知ることはできません。
ただし、サーバーのIPアドレスは、企業のイントラネットセキュリティに関連する秘密にしておく必要があるため、通常はクライアントにはわかりません。しかし逆に、通常、サーバーはクライアントの実際のIPアドレスを知って、アクセス制御、ユーザーポートレート、統計分析を容易にする必要があります。
残念ながら、HTTP標準ではこのために定義されたヘッダーフィールドはありませんが、多くの「事実上の標準」が登場しています。最も一般的に使用される2つのヘッダーフィールドは、「X-Forwarded-For」と「X-Real-IP」です。
「X-Forwarded-For」は文字通り「転送先」を意味し、形式は「Via」と同様です。また、プロキシノードが通過するたびにフィールドにメッセージを追加します。ただし、「Via」はプロキシホスト名(またはドメイン名)を追加し、「X-Forwarded-For」はリクエスタのIPアドレスを追加します。したがって、フィールドの左端のIPアドレスはクライアントのアドレスです。
「X-Real-IP」は、クライアントの実際のIPを取得するもう1つの方法です。その機能は非常に簡単です。つまり、中間プロキシ情報なしでクライアントのIPアドレスを記録します。これは、「X-Forwarded-For」の簡易バージョンに相当します。 。クライアントとオリジンサーバーの間にプロキシが1つしかない場合、これら2つのフィールドの値は同じです。
私たちの実験環境はリバースプロキシを実装しています。「http://www.chrono.com/21-1」にアクセスすると、「http://origin.io」にアクセスします。ここで「origin.io」はオリジンであり、「Via」「X-Forwarded-For」などのプロキシヘッダーフィールド情報を応答メッセージに出力します。
エージェントの転送はバックグラウンドで表示されないため、エージェントがブラウザページから実行した作業を確認するのは困難です。そのため、Wiresharkを使用してこのプロセスのパッケージを取得しました。
パケットキャプチャから、エージェントとクライアントおよびソースサーバーとの通信プロセスを明確に見ることができます。
クライアント55061は、3ウェイハンドシェイクでエージェントのポート80に接続し、GETリクエストを送信します。
エージェントはコンテンツを直接生成しないため、クライアントを表し、ポート55063でソースサーバーに接続します。これは、3ウェイハンドシェイクでもあります。
プロキシがソースサーバーに正常に接続した後、HTTP / 1.0 GETリクエストを発行します。
HTTP / 1.0はデフォルトで短い接続であるため、オリジンサーバーはすぐに応答メッセージを送信して、4つの手を振った接続を閉じます。
応答メッセージを受信した後、エージェントはそれをクライアントに送り返し、エージェントサービスを完了します。
この実験では、「X-Forwarded-For」と「X-Real-IP」に加えて、「X-Forwarded-Host」と「X-Forwarded-Proto」という2つのフィールドが表示されていることがわかります。この機能は「X-Real-IP」に似ており、クライアントから要求された元のドメイン名と元のプロトコル名であるクライアントの情報のみを記録します。
代理店契約
「X-Forwarded-For」ヘッダーフィールドを使用すると、ソースサーバーは正確なクライアント情報を取得できます。ただし、これはプロキシサーバーに最適なソリューションではありません。
プロキシ情報は、「X-Forwarded-For」プロキシの操作を介して解析する必要があるため、プロキシにとって比較的コストがかかります。元々は、メッセージを転送するだけで十分でしたが、今度は、データを解析してからデータを変更する必要があります。 、エージェントの転送パフォーマンスが低下します。
別の問題は、「X-Forwarded-For」ヘッダーが元のメッセージを変更する必要があり、場合によっては許可されないか、不可能でさえある(HTTPS通信を使用して暗号化されるなど)ことです。
そのため、有名なプロキシソフトウェアHAProxyによって定義された特別な「プロキシプロトコル」(PROXYプロトコル)もあり、広く使用されている「ファクトスタンダード」でもあります(RFCではないことに注意してください)。
「プロキシプロトコル」には、v1とv2の2つのバージョンがあります。v1はHTTPに似ており、プレーンテキストでもありますが、v2はバイナリ形式です。今日はわかりやすいv1のみを紹介しますが、HTTPメッセージの前に追加のヘッダーに相当するASCIIテキストの行が追加されます。
このテキスト行は実際には非常に単純です。5つの大文字の「PROXY」で始まり、次に「TCP4」または「TCP6」でクライアントのIPアドレスタイプを示し、その後にリクエスタアドレス、レスポンダアドレス、リクエスタポート番号が続きます。 3.応答側のポート番号。最後に、キャリッジリターンとラインフィード(\ r \ n)で終わります。
たとえば、次の例では、GET要求行の前にPROXY情報行が追加され、クライアントの実際のIPアドレスは「1.1.1.1」、ポート番号は55555です。
プロキシTCP4 1.1.1.1 2.2.2.2 55555 80 \ r \ n |
|
GET / HTTP / 1.1 \ r \ n |
|
ホスト:www.xxx.com \ r \ n |
|
\ r \ n |
コードをコピー
サーバーがこのようなメッセージを見ると、最初の行が解析される限り、クライアントアドレスを取得できます。背後のHTTPデータを無視する必要がないため、多くのことを節約できます。
ただし、プロキシプロトコルは "X-Forwarded-For"チェーンアドレス形式をサポートしていないため、クライアントアドレスを取得した後、プロキシサーバーとバックエンドは、その処理方法について合意する必要があります。
まとめ
HTTPプロキシは、クライアントとサーバー間の通信リンクの中間リンクであり、両端に「プロキシサービス」を提供します。
プロキシは中間層にあり、HTTP処理に柔軟性を追加し、ロードバランシング、セキュリティ保護、データフィルタリングなどの機能を実現できます。
プロキシサーバーは、フィールド「Via」を使用してIDをマークする必要があります。複数のプロキシがリストを形成します。
クライアントの実際のIPアドレスを知りたい場合は、「X-Forwarded-For」および「X-Real-IP」フィールドを使用できます。
特別な「プロキシプロトコル」は、元のメッセージを変更せずにクライアントの実際のIPを渡すことができます。
宿題
代理店の欠点は何だと思いますか?実際のアプリケーションでそれを回避するには?
リバースプロキシで使用される負荷分散アルゴリズムの数を知っていますか?それらの長所と短所は何ですか?