4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

エアークローゼットAdvent Calendar 2022

Day 17

Forward Proxy vs Reverse Proxy

Last updated at Posted at 2022-12-17

バックエンド開発の経験があれば、「フォワードプロキシ」と「リバースプロキシ」という用語をどこかで聞いたことがあるかもしれません。

そのため、今日はそれらについて「概要と用途」を詳しく説明させていただきます。

フォワードプロキシ (Forward Proxy)

フォワードプロキシまたは単純なプロキシは、クライアントインターネットの間にある仲介者です。
ざっくりにはこんな感じです。

Without Proxy.png

サーバーがある場合

With Server & Proxy.png

そして、サーバーに直接接続する代わりに、クライアントはプロキシ経由でサーバーに接続し、クライアントに代わってプロキシがサーバーとやりとりするということになります。

さて、「プロキシの目的は何ですか?」と自問があるでしょうか。

簡単に言うと、それらは次となります。
① facebook.com や 18+ サイトなどの特定のサイトへのアクセスを制限する。
② クライアントがサイト全体ではなく、一部のみにアクセスできるようにする (リソースアクセスを制限する)。
③ インターネットでの活動を記録する。
...

リバースプロキシ (Reverse Proxy)

リバースプロキシは、インターネットサーバーの間にある仲介者です。
一旦こんな感じです。

Reverse Proxy.png

では、リバースプロキシの目的は何でしょうか。

これはサーバーを表します。つまり、「リバースプロキシ」はクライアントからのリクエストを受け取り、それをサーバーに送信し、サーバーからのレスポンスを受け取り、それをクライアントに送信します。下記の画像はイメージです。

Req.png

「リバースプロキシ」はサーバーの代表であるため、クライアントはサーバーと通信していることを認識せずリバースプロキシと通信していることを認識しているだけです

じゃ、リバースプロキシの目的とはどのようなものでしょうか。
まあ、それは次のようにリストすることができます。
① サーバーを公開したくない場合、「リバースプロキシ」は、クライアントからサーバーを非表示にするための最良の選択です。
② 「リバースプロキシ」はサーバーの前にあるため、ロードバランシングとして機能して、システムに複数のサーバーがある場合クライアントからサーバーにリクエストを均等に分散できます。
...

コンセプトは十分なので、デモを見てみましょう。 まず、フォワードプロキシで確認します。 ここでは、次のように「フォワードプロキシ」経由でhttp://google.comに接続するクライアントを作成します。

CLIENT UMM_PROXY wwwwwygoogle.com (1).png

JavaScriptライブラリrequestを使用してプロキシ経由でhttp://google.comにリクエストを送信するクライアントをセットアップします。

※ ライブラリのリンク先: https://www.npmjs.com/package/request

// index.js
const request =  require('request');

request({
  url: 'http://www.google.com/',
  method: 'GET',
  proxy: 'http://127.0.0.1:8888',
}, (err, response, body) => {
  if (!err && response.statusCode === 200) {
    console.log(body);
  }
});

nginx を次のように設定します。

events {}

http {
  server {
    listen 8888 default_server;

    access_log  log/access.log; #アクセスログ
    error_log log/error.log debug; #エラーログ

    location / {
      resolver 8.8.8.8;
      proxy_pass https://$host$request_uri;
    }
  }
}

上のnginx設定の意味はnginxがローカルホストのポート8888でリッスンして、リクエストがhttp://localhost:8888/に来るたびに、リクエストはhttps://$host$request_uriに転送されます。ここでは

  • $hostは、リクエストヘッダー内のホストの名前です (今回はgoole.comです)。
  • $request_uriはホスト名の後のURIです。(例:google.com/statusの場合、$request_uri/statusです)

まず、クライアントを起動する

node index.js

次にnginxのログを確認してみましょう。

Screen Shot 2022-12-11 at 18.34.14.png

プロキシがクライアントに代わってリクエストをgoogle.comに送信することがわかります。 プロキシはgoogle.comからの応答を受け取り、それをクライアントに送り返します。

Screen Shot 2022-12-11 at 18.35.59.png

フォワードプロキシについてはここまで以上です。

リバースプロキシなんですが、次のように、それぞれexpressJSによってポート11112222、および3333でリッスンする3つのサーバーを作っておきます。

サーバー1 (ポート1111でリッスンする)

const express = require('express');

const app = express();

app.get('/', (req, res) => {
  res.send('Server 1\n');
});

app.listen(1111, () => {
  console.log('Listening on port 1111');
});

サーバー2 (ポート2222でリッスンする)

const express = require('express');

const app = express();

app.get('/', (req, res) => {
  res.send('Server 2\n');
});

app.listen(2222, () => {
  console.log('Listening on port 2222');
});

サーバー3 (ポート3333でリッスンする)

const express = require('express');

const app = express();

app.get('/', (req, res) => {
  res.send('Server 3\n');
});

app.listen(3333, () => {
  console.log('Listening on port 3333');
});

そして、nginxの設定は次のとおりです。

events {}

http {
  upstream express_servers {
    server localhost:1111;
    server localhost:2222;
    server localhost:3333;
  }

  server {
    listen 8888;

    location / {
      proxy_pass http://express_servers;
    }
  }
}

nginxの設定について説明します。ここで、nginxはローカルホストのポート8888でリッスンし、http://localhost:8888/へのすべてのリクエストは、express_serversリスト (Server1Server2Server3)の3つのサーバーのいずれかに転送されます。

ここで使用されるデフォルトのリクエストローテーションアルゴリズムはラウンドロビンです。

これは、各サーバーに対応するサーバーの重みに基づいて、サーバーへのリクエストをローテーションするアルゴリズムです。 重みが高いほど、リクエストを受信する頻度が高くなり、その逆も同様です。 デフォルトでは、全サーバーの重みは同じです。

「リバースプロキシ」が意図したとおりに動作するかどうかを確認するには、下記のコマンドを使ってみてください。

while sleep1; do curl http://localhost:8888; done

上記のコマンドは定期的にcurl http://localhost:8888コマンドをリバースプロキシに対して毎秒実行します。下は我々の結果なんです。

191910278-62a2fe09-8940-49d1-9d0e-c660d375e2d0.png

リクエストはそれぞれ Server1、Server2、および Server3にルーティングされています。

リバースプロキシについては以上です。

読んでくれてありがとうございます。次のブログにお会いしましょう。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?