1.はじめに

Nginxに関して言えば、Nginxは世の中で最も人気のあるサーバーの1つです。 それは高速で軽量であり、インターネット上で最大のサイトのいくつかをホストする責任があります。 Nginxは、ロードバランサー、リバースプロキシ、HTTPキャッシュなどの用途でよく使用されます。

このチュートリアルでは、要求された場所のフォワードプロキシとして使用する方法の学習に焦点を当てています。

2.フォワードプロキシの動機

プロキシサーバーは、要求されたリソースのクライアントとホストの間の仲介役として機能するエンティティです。 これは、トラフィックが宛先(ホストサーバー)に到達するために追加のマシンを通過することを意味します。 プロキシはクライアントに代わってリクエストを続行するため、ホストサーバーがリクエストを受け入れると、プロキシのIPのみが表示されます。 対照的に、リバースプロキシはWebの直前に配置され、クライアントからの要求を正しいWebサーバー(複数のサーバーのネットワーク内)にルーティングします。

フォワードプロキシを使用することの唯一の欠点は、アプリケーションレベルで機能することです。そのため、トラフィックをルーティングする予定のアプリごとにプロキシを設定する必要があります。

フォワードプロキシを使用するためのいくつかのユースケースは次のとおりです

  • 場所が制限されたサービスにアクセスするためのIPと場所のマスキング
  • インターネット上の特定のリソースに接続する必要がある分離された内部ネットワークの場合
  • リソースを節約するためにめったに変更されないコンテンツの特定のサーバーへのリクエストをキャッシュする場合

プロキシはトラフィックを暗号化しないのに対し、VPNは安全で暗号化されたトンネルを介してトラフィックをリダイレクトすることに注意してください。

3.Nginxを使用したフォワードプロキシの実装

転送プロキシを実装するために、NginxがインストールされたLinuxマシンを使用します。 このチュートリアルでは、NginxがインストールされたLinuxディストリビューションサーバーでVirtualBoxを使用しますが、Dockerや古いPCなど、より便利なものを使用できます。何年もの間コーナー。

まず、デフォルトの Nginx 構成ファイルを見つけ、 server 部分をコメント化して、アーカイブされたコピーとして保存します。 通常、 / etc / nginx / sites-enabled /defaultにあります。

# Default server configuration
#server {
    #listen 80 default_server;
    #listen [::]:80 default_server;

    #root /var/www/html;

    # Add index.php to the list if you are using PHP
    #index index.html index.htm index.nginx-debian.html;

    #server_name _;

    #location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        #try_files $uri $uri/ =404;
    #}
#}

次に、 forwardという新しいファイルを作成し、必要なすべての構成を追加して、Nginxを機能するフォワードプロキシに変えましょう。

server {

    listen 8888;

    location / {

        resolver 8.8.8.8;

        proxy_pass http://$http_host$uri$is_args$args;

    }

}

最初の構成では‘listen8888;’ – 基本的に、このポートに送信されるすべての要求は次の構成で処理する必要があることをサーバーに通知しています。 location 引数は、特定のサーバーサブディビジョンブロック構成を担当し、基本的にサーバーに特定のURIの要求を処理する方法を指示します。

‘resolver 8.8.8.8’ ディレクティブは、アップストリームサーバーの名前をアドレスに解決するために使用するネームサーバーを指定します。この場合、8.8.8.8はGoogleのネームサーバーに対応します。

変数$http_host には元のリクエストのホストが含まれていますが、 $uriにはドメインまたはIPの後のパスが含まれています。 最後の2つの変数$is_args$args は、最初のリクエストで追加の引数をチェックし、それらをプロキシされたリクエストに自動的に追加します。

必要なすべての構成を更新したら、nginx.serviceを再起動して有効にする必要があります。

sudo systemctl restart nginx.service

4. フォワードプロキシの使用

前述したように、フォワードプロキシはアプリケーションレベルで機能するため、当然、クライアントによっては、フォワードプロキシを構成する方法が複数あります。 このステップでは、JavaScriptで単純なクライアントを作成し、リクエストをトレースします。

始める前に、最新のnode.jsとnpmがローカルマシンにインストールされていることを確認しましょう。 次に、クライアントのディレクトリとファイルを作成します。 ディレクトリProxyTestとファイルproxytest.jsをそれに応じて呼び出しましょう。

次に、NPMの package.json を初期化して、必要なすべてのライブラリをインストールできるようにする必要があります。 これを行うには、プロジェクトのディレクトリ内のターミナルで npminitコマンドを実行します。

npm init

リポジトリの初期化に成功したら、プロキシ構成でカスタムリクエストを作成するために使用するrequestライブラリをインストールする必要があります。

npm install request

最後に、IDEを開いて、以下のコードをproxytest.jsファイルに貼り付けます。

var request = require('request');

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

それでは、このコードスニペットを実行してみましょう。

node proxytest.js 

一歩下がって、各行を見てみましょう。 最初の行は、ライブラリを request オブジェクトにインポートします。これは、後で使用します。

request オブジェクト内で、宛先サーバーのURL、HTTPメソッド、およびプロキシをURLとポートキーペアとして指定します。 コールバック関数内で、リクエストが成功した場合、コンソールにレスポンスの本文を記録します。

次に、Nginxのデバッグログを見てみましょう:

2022/02/20 13:46:13 [debug] 1790#1790: *1 http script copy: "http://"
2022/02/20 13:46:13 [debug] 1790#1790: *1 http script var: "www.google.com"
2022/02/20 13:46:13 [debug] 1790#1790: *1 http script var: "/"
2022/02/20 13:46:13 [debug] 1790#1790: *1 http script var: ""
2022/02/20 13:46:13 [debug] 1790#1790: *1 http init upstream, client timer: 0
2022/02/20 13:46:13 [debug] 1790#1790: *1 epoll add event: fd:7 op:3 ev:80002005
2022/02/20 13:46:13 [debug] 1790#1790: *1 http script copy: "Host"
2022/02/20 13:46:13 [debug] 1790#1790: *1 http script var: "www.google.com"
2022/02/20 13:46:13 [debug] 1790#1790: *1 http script copy: "Connection"
2022/02/20 13:46:13 [debug] 1790#1790: *1 http script copy: "close"
2022/02/20 13:46:13 [debug] 1790#1790: *1 http script copy: ""
2022/02/20 13:46:13 [debug] 1790#1790: *1 http script copy: ""
2022/02/20 13:46:13 [debug] 1790#1790: *1 http proxy header:
"GET / HTTP/1.0
Host: www.google.com
Connection: close

"
2022/02/20 13:46:13 [debug] 1790#1790: *1 http cleanup add: 0000560CE3CF5E30
2022/02/20 13:46:13 [debug] 1790#1790: *1 http finalize request: -4, "/?" a:1, c:2
2022/02/20 13:46:13 [debug] 1790#1790: *1 http request count:2 blk:0
2022/02/20 13:46:13 [debug] 1790#1790: *1 http run request: "/?"
2022/02/20 13:46:13 [debug] 1790#1790: *1 http upstream check client, write event:1, "/"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http upstream resolve: "/?"
2022/02/20 13:46:14 [debug] 1790#1790: *1 name was resolved to 142.250.184.100
2022/02/20 13:46:14 [debug] 1790#1790: *1 name was resolved to 2a00:1450:4002:406::2004
2022/02/20 13:46:14 [debug] 1790#1790: *1 get rr peer, try: 2
2022/02/20 13:46:14 [debug] 1790#1790: *1 get rr peer, current: 0000560CE3CF5EB8 -1
2022/02/20 13:46:14 [debug] 1790#1790: *1 stream socket 12
2022/02/20 13:46:14 [debug] 1790#1790: *1 epoll add connection: fd:12 ev:80002005
2022/02/20 13:46:14 [debug] 1790#1790: *1 connect to 142.250.184.100:80, fd:12 #3

ご覧のとおり、最初のリクエストはプロキシを経由します。 直後に、プロキシサーバーは、最初のリクエストからのすべてのデータを含む新しいリクエストを宛先リソースに起動します。 その後、リソースからの応答を受け取り、それをクライアントに返します。

2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy status 200 "200 OK"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "Date: Sun, 20 Feb 2022 12:46:15 GMT"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "Expires: -1"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "Cache-Control: private, max-age=0"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "Content-Type: text/html; charset=ISO-8859-1"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info.""
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "Server: gws"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "X-XSS-Protection: 0"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "X-Frame-Options: SAMEORIGIN"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "Set-Cookie: 1P_JAR=2022-02-20-12; expires=Tue, 22-Mar-2022 12:46:15 GMT; path=/; domain=.google.com; Secure"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "Set-Cookie: NID=511=IkyJTmMt6I2b3fHpGNUwdfCkv1q9cjzyeUaxC-cxMZWcbmSi4sVlRlwXJUTRA9ujqQnK2v6DNyhitL3zPRSf7RSIHDCv8aYcUD7jp3vX4sE7ZkiprAWmJo9FlnUJtV9H0IzOFyPck15Jfs0zb1VeOMOjKZk0BZ0XRQ3gNptMOl8; expires=Mon, 22-Aug-2022 12:46:15 GMT; path=/; domain=.google.com; HttpOnly"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "Accept-Ranges: none"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header: "Vary: Accept-Encoding"
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy header done
2022/02/20 13:46:14 [debug] 1790#1790: *1 xslt filter header
2022/02/20 13:46:14 [debug] 1790#1790: *1 HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Sun, 20 Feb 2022 12:46:14 GMT
Content-Type: text/html; charset=ISO-8859-1
Transfer-Encoding: chunked
Connection: close
Expires: -1
Cache-Control: private, max-age=0
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Set-Cookie: 1P_JAR=2022-02-20-12; expires=Tue, 22-Mar-2022 12:46:15 GMT; path=/; domain=.google.com; Secure
Set-Cookie: NID=511=IkyJTmMt6I2b3fHpGNUwdfCkv1q9cjzyeUaxC-cxMZWcbmSi4sVlRlwXJUTRA9ujqQnK2v6DNyhitL3zPRSf7RSIHDCv8aYcUD7jp3vX4sE7ZkiprAWmJo9FlnUJtV9H0IzOFyPck15Jfs0zb1VeOMOjKZk0BZ0XRQ3gNptMOl8; expires=Mon, 22-Aug-2022 12:46:15 GMT; path=/; domain=.google.com; HttpOnly
Accept-Ranges: none
Vary: Accept-Encoding

2022/02/20 13:46:14 [debug] 1790#1790: *1 write new buf t:1 f:0 0000560CE3CF7AD0, pos 0000560CE3CF7AD0, size: 760 file: 0, size: 0
2022/02/20 13:46:14 [debug] 1790#1790: *1 http write filter: l:0 f:0 s:760
2022/02/20 13:46:14 [debug] 1790#1790: *1 http cacheable: 0
2022/02/20 13:46:14 [debug] 1790#1790: *1 http proxy filter init s:200 h:0 c:0 l:-1
2022/02/20 13:46:14 [debug] 1790#1790: *1 http upstream process upstream

リクエストが宛先に正常に送信されると、ログに「200 OK」という応答が表示されます。これは、リクエストが受け入れられ、応答が正常に返されたことを意味します。 ログから、応答が返したすべてのHTTPヘッダーを1行ずつリストすることもできます。 宛先サーバーが返すHTTPヘッダーはすべて、プロキシリターンオブジェクトに自動的に追加されます。

5. 結論

このチュートリアルでは、Nginxサーバーを使用して簡単で軽量なフォワードプロキシを設定する方法を学びました。 フォワードプロキシとVPNの重要な違いを学びました。 最後に、JavaScriptベースのクライアントを新しく作成したフォワードプロキシに接続する方法も学びました。

完全なソースコードは、GitHubにあります。