Nginxにおけるフォワードプロキシとリバースプロキシ

✍🏼 作成日 2021年07月06日   
❗️ 注意:この記事が作成されてから既に 日が経過しています。情報の鮮度にご注意ください
🖥  説明:無知こそがすべての始まり

本文の経緯

フォルダ/ファイル名にコロンを含めることができないため、Chromeがポート番号付きURLに対してOverride機能を使用できないと誤解していました。そのため、社内のリモートテスト環境のポート付きURLをローカルのデフォルトポート80に変更し、Chromeでoverrideできるようにしようと考えました。後になって、Chromeは実際にはポート番号付きURLをoverride可能で、それを%3aにデコードすればよいことが分かりました。

自分の愚かさに気づいた後、Nginxでフォワードプロキシを設定してこのポート問題を解決するのに1時間も費やしたことが無駄だったと悔しく思い、その過程を記録することにしました。これにより、後続の方が同じ過ちを犯さずに済むように、この記事を執筆しました。

ここで扱う概念のいくつかは大学で学んだかもしれませんが、初心者向けに解説します。

用語解説

フォワードプロキシ(正向代理)

フォワードプロキシは一般的にクライアント側の概念です。例えば、VPNはフォワードプロキシの一種で、ローカルのリクエストがプロキシサーバーで設定されたルールに従って遠隔サーバーに送信されます。もちろん、サーバーが他のサーバーリソースをリクエストする際にもフォワードプロキシを設定できますが、この場合はサーバー側のフォワードプロキシとなります。

フォワードプロキシで最も広く使われているのがVPNです。

リバースプロキシ(反向代理)

その名の通り、上記のフォワードプロキシとは逆のプロキシです。これはサーバー側の概念です。つまり、クライアントからのリクエストがサーバーに到達した後、サーバー側で設定されたリバースプロキシを通じてリクエストが分散され、異なるサーバーにトラフィックが誘導されます。

nginxのリバースプロキシはサーバー側で広く利用されており、例えばロードバランシングでは、5台のサーバーがある場合、リクエストの数をカウントして5で割った余りに基づいてトラフィックを振り分ける(余り1なら1台目、2なら2台目など)といった戦略が可能です。また、パス書き換え(xxx/yyyをzzzにリライトしてサーバーに誘導するなど)にも使用されます。

私の要件

私はhttp://baidu.com:8888``にアクセスしたいのですが、http://baidu.com:80つまり`http://baidu.comという形で`http://baidu.com:8888``にアクセスしたいと考えています。そのため、動作原理はVPNと同じで、フォワードプロキシとなります。

難点

全体としては難しい点はなく、server.listenで80ポートを監視し、パスマッチングを行い、proxy_passを使って8888ポートなどの正しいパスにリクエストを送信するだけです。唯一少し面倒な点は、wsリクエストもプロキシを通す必要があるため、httpの開始部分に以下の記述が必要だということです:

1
2
3
4
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

次に、server.location ブロック内に以下を追加します:

1
2
3
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

もちろん、proxy_set_headerproxy_pass なども関係してきますが、今回の議論の範囲外です。興味があれば公式ドキュメントを参照してください:http://nginx.org/en/docs/http/websocket.html

そうそう、忘れるところでした。nginxサーバーはローカルの127.0.0.1で起動しているので、http://baidu.com`` にアクセスして http://baidu.com:8888`` を閲覧するには、ローカルのhostsファイルを修正し、127.0.0.1をbaidu.comに指向する必要があります:

1
127.0.0.1  www.baidu.com

ある学生が質問するかもしれません:なぜ直接hostsでポートを指定しないのでしょうか?例えばこのように:

1
127.0.0.1. www.baidu.com:8888

答えは明らかで、hostsファイルはポートをサポートしていないからですね〜

後書き

ずっとフロントエンドやツール関連の開発をしてきたので、サーバーサイドにはあまり触れておらず、今のところnginxに追加モジュールをインストールする方法がよく分かっていません。軽く調べたところ、nginxと一緒にコンパイルする必要があるようで、ソフトウェアのようにプラグインをインストールするわけにはいかないようです。プラグインが必要な理由は、nginxはデフォルトでhttpsリクエストをプロキシしないためで、この機能が必要な場合は追加モジュールをインストールする必要があります。

nginxは非常に用途が広いと感じたので、時間があるときにしっかり勉強したいと思います!

- EOF -
この記事の初出: Nginxにおけるフォワードプロキシとリバースプロキシ - Xheldon Blog