Ubuntu 22.04でNginxをリバースプロキシとして設定する方法
はじめに
リバースプロキシは、アプリケーションサーバーをインターネットに公開するための推奨される方法です。Node.jsの本番環境でアプリケーションを実行している場合や、Flaskで組み込みのウェブサーバーを使用している場合でも、これらのアプリケーションサーバーはよくTCPポートでlocalhostにバインドされます。つまり、デフォルトでは、アプリケーションにはそのマシン上でのみアクセスできます。インターネット経由でのアクセスを強制するために別のバインドポイントを指定することもできますが、これらのアプリケーションサーバーは本番環境ではリバースプロキシの後ろで提供されるように設計されています。これにより、アプリケーションサーバーを直接のインターネットアクセスから分離するセキュリティ上の利点、ファイアウォール保護を集中化できる利点、およびサービス拒否攻撃などの一般的な脅威に対する攻撃面が最小限に抑えられる利点が得られます。
クライアントの視点からすると、リバースプロキシとのやり取りはアプリケーションサーバーと直接やり取りすることと同じです。機能的にも同じであり、クライアントは違いに気付くことはありません。クライアントがリソースを要求し、それを受け取り、追加の設定を必要としません。
このチュートリアルでは、人気のあるウェブサーバー兼逆プロキシソリューションであるNginxを使用して逆プロキシを設定する方法を説明します。Nginxをインストールし、proxy_passディレクティブを使用して逆プロキシを設定し、適切なヘッダーをクライアントのリクエストから転送します。テスト用のアプリケーションサーバーが手元にない場合、WSGIサーバーであるGunicornを使用してテストアプリケーションをオプションで設定します。
前提条件
このチュートリアルを完了するためには、以下が必要です:
- An Ubuntu 22.04 server, set up according to our initial server setup guide for Ubuntu 22.04,
- The address of the application server you want to proxy, this will be referred to as app_server_address throughout the tutorial. This can be an IP address with TCP port (such as the Gunicorn default of http://127.0.0.1:8000), or a unix domain socket (such as http://unix:/tmp/pgadmin4.sock for pgAdmin). If you do not have an application server set up to test with, you will be guided through setting up a Gunicorn application which will bind to http://127.0.0.1:8000.
- A domain name pointed at your server’s public IP. This will be configured with Nginx to proxy your application server.
ステップ1 – Nginxのインストール
デフォルトのリポジトリを通じてNginxをaptでインストールすることができます。リポジトリインデックスを更新してから、Nginxをインストールしてください。
- sudo apt update
- sudo apt install nginx
インストールを確認するには、Yキーを押してください。サービス再起動の要求がある場合は、デフォルトを受け入れるためにENTERキーを押してください。
あなたはファイアウォールを介してNginxへのアクセスを許可する必要があります。初期のサーバーの前提条件に従ってサーバーを設定した後、次のufwのルールを追加してください。
- sudo ufw allow ‘Nginx HTTP’
今、Nginxが動作していることを確認できます。
- systemctl status nginx
● nginx.service – A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2022-08-29 06:52:46 UTC; 39min ago Docs: man:nginx(8) Main PID: 9919 (nginx) Tasks: 2 (limit: 2327) Memory: 2.9M CPU: 50ms CGroup: /system.slice/nginx.service ├─9919 “nginx: master process /usr/sbin/nginx -g daemon on; master_process on;” └─9920 “nginx: worker process
次に、あなたはカスタムサーバーブロックを追加して、ドメインとアプリサーバープロキシを設定します。
ステップ2 — サーバーブロックの設定
デフォルトの設定を直接編集する代わりに、新しいサーバーブロックの追加にカスタム設定ファイルを作成することが推奨されています。nanoまたはお好みのテキストエディタを使用して、新しいNginxの設定ファイルを作成して開いてください。
- sudo nano /etc/nginx/sites-available/your_domain
新しいファイルに以下を挿入してください。your_domainとapp_server_addressを適切に置き換えてください。アプリケーションサーバーがない場合は、ステップ3のオプションのGunicornサーバーセットアップには、http://127.0.0.1:8000をデフォルトとして使用してください。
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
location / {
proxy_pass app_server_address;
include proxy_params;
}
}
保存して終了します。nanoでは、CTRL+Oを押してからCTRL+Xを押すことでこれができます。
この設定ファイルは、標準的なNginxのセットアップから始まります。Nginxはポート80でリクエストを待ち受け、your_domainとwww.your_domainへのリクエストに応答します。逆プロキシ機能は、Nginxのproxy_passディレクティブを使用して有効になります。この設定により、ローカルのWebブラウザでyour_domainにアクセスすることは、リモートマシン上のapp_server_addressを開くことと同じです。このチュートリアルでは、単一のアプリケーションサーバーをプロキシとして使用しますが、Nginxは複数のサーバーを同時にプロキシとして使用することも可能です。必要に応じて、さらにlocationブロックを追加することで、単一のサーバー名で複数のアプリケーションサーバーをプロキシして一つの統合されたWebアプリケーションにすることができます。
すべてのHTTPリクエストには、リクエストを送信したクライアントに関する情報を含むヘッダーが付属しています。これには、IPアドレス、キャッシュの設定、Cookieの追跡、認証状態などの詳細が含まれます。Nginxは、プロキシパラメーターとして含めることを推奨するヘッダー転送の設定を提供しており、詳細は”/etc/nginx/proxy_params”に記載されています。
「/etc/nginx/proxy_params」
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
逆プロキシを使用する場合、クライアントに関する関連情報や逆プロキシサーバー自体に関する情報を伝達することが目的です。プロキシされたサーバーがリクエストを処理した逆プロキシサーバーを知りたい場合もありますが、一般的には重要な情報は元のクライアントのリクエストから取得します。これらのヘッダーを伝達し、期待される場所に情報を提供するために、Nginxはproxy_set_headerディレクティブを使用します。
デフォルトでは、Nginxはリバースプロキシとして動作する際に2つのヘッダーを変更し、すべての空のヘッダーを削除してリクエストを転送します。変更される2つのヘッダーは、ホストヘッダーと接続ヘッダーです。HTTPヘッダーは多数存在し、それぞれの目的について詳細なHTTPヘッダーリストで確認できます。ただし、リバースプロキシに関連するヘッダーについては後述します。
プロキシパラメータとして転送されるヘッダーと、データを保存する変数です。
- Host: This header contains the original host requested by the client, which is the website domain and port. Nginx keeps this in the $http_host variable.
- X-Forwarded-For: This header contains the IP address of the client who sent the original request. It can also contain a list of IP addresses, with the original client IP coming first, then a list of all the IP addresses of the reverse proxy servers that passed the request through. Nginx keeps this in the $proxy_add_x_forwarded_for variable.
- X-Real-IP: This header always contains a single IP address that belongs to the remote client. This is in contrast to the similar X-Forwarded-For which can contain a list of addresses. If X-Forwarded-For is not present, it will be the same as X-Real-IP.
- X-Forwarded-Proto: This header contains the protocol used by the original client to connect, whether it be HTTP or HTTPS. Nginx keeps this in the $scheme variable.
次に、Nginxが起動時に読み込むsites-enabledディレクトリへのリンクを作成することで、この設定ファイルを有効化してください。
- sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
現在、構成ファイルの文法エラーをテストすることができます。 (Genzai, kōsei fairu no bunpō erā o tesuto suru koto ga dekimasu.)
- sudo nginx -t
問題の報告がない場合、変更を適用するためにNginxを再起動してください。
- sudo systemctl restart nginx
現在、Nginxはアプリケーションサーバーのリバースプロキシとして設定されており、アプリケーションサーバーが稼働している場合は、ローカルブラウザからアクセスすることができます。もし稼働していない場合は、意図したアプリケーションサーバーを起動してください。このチュートリアルの残りはスキップすることができます。
それ以外の場合は、次のステップでGunicornを使用してテストアプリケーションとサーバーの設定を進めてください。
ステップ3 — Gunicornを使用してリバースプロキシをテストする(オプション)
もし、このチュートリアルを始める前にアプリケーションサーバーを準備して起動していた場合、今すぐブラウザでそれを訪れることができます。
your_domain
ただし、リバースプロキシをテストするためのアプリケーションサーバーを手元に持っていない場合は、以下の手順に従ってGunicornとテストアプリケーションをインストールすることができます。 Gunicornは、しばしばNginxリバースプロキシとペアで使用されるPythonのWSGIサーバーです。
アプトリポジトリインデックスを更新して、Gunicornをインストールしてください。
- sudo apt update
- sudo apt install gunicorn
最新バージョンのGunicornをPython仮想環境と組み合わせてインストールするために、pipとPyPIを使用するオプションもありますが、ここでは速やかなテストのためにaptを使用しています。
次に、ウェブブラウザで表示されるHTTPレスポンスとして「Hello World!」を返すPythonの関数を作成します。nanoまたはお好みのテキストエディタを使用して、test.pyを作成してください。
- nano test.py
ファイルに以下のPythonコードを挿入してください。
def app(environ, start_response):
start_response("200 OK", [])
return iter([b"Hello, World!"])
これは、Gunicornが提供するHTTPレスポンスを開始するための最小限のコードです。このコードを確認した後、ファイルを保存して閉じてください。
今、Gunicornサーバーを起動してください。テスト用のPythonモジュールとそれに含まれるアプリケーション関数を指定してください。サーバーを起動すると、ターミナルは制御を奪われます。
- gunicorn –workers=2 test:app
[2022-08-29 07:09:29 +0000] [10568] [INFO] Starting gunicorn 20.1.0 [2022-08-29 07:09:29 +0000] [10568] [INFO] Listening at: http://127.0.0.1:8000 (10568) [2022-08-29 07:09:29 +0000] [10568] [INFO] Using worker: sync [2022-08-29 07:09:29 +0000] [10569] [INFO] Booting worker with pid: 10569 [2022-08-29 07:09:29 +0000] [10570] [INFO] Booting worker with pid: 10570
次のように日本語で言い換えます。:
出力からは、Gunicornがデフォルトのアドレスhttp://127.0.0.1:8000でリスニングしていることが確認されます。これは、以前にNginxの設定でプロキシに設定したアドレスです。設定していない場合は、/etc/nginx/sites-available/your_domainファイルに戻り、proxy_passディレクティブに関連付けられているapp_server_addressを編集してください。
ウェブブラウザを開き、Nginxで設定したドメインにアクセスしてください。
your_domain
あなたのNginxリバースプロキシは、Gunicornウェブアプリケーションサーバーをサービスし、”Hello World!”と表示しています。
結論
このチュートリアルでは、ローカルでしか利用できないアプリケーションサーバーへのアクセスを可能にするために、Nginxをリバースプロキシとして設定しました。さらに、リクエストヘッダーの転送も設定し、クライアントのヘッダー情報を引き継ぎました。
Nginxをリバースプロキシとして使用した完全なソリューションの例については、Ubuntu 22.04でFlaskアプリケーションをGunicornとNginxで提供する方法や、Ubuntu 22.04でInstantSearchを使用してMeilisearchフロントエンドを実行する方法を参照してください。