このチュートリアルでは、本番環境用に Nginx Web サーバーを構成する方法を見ていきます。
本番環境の Web サーバーは、パフォーマンスやセキュリティなどの点でテスト環境の Web サーバーとは異なります。
デフォルトでは、Nginx Web サーバーを正常にインストールすると、すぐに使用できる構成設定が常に存在します。ただし、デフォルトの構成は実稼働環境には十分ではありません。したがって、私たちは、大量のトラフィックと通常のトラフィックの急増時にパフォーマンスを向上させるために Nginx を構成する方法と、Nginx を悪用しようとするユーザーから Nginx を保護する方法に焦点を当てます。
マシンに Nginx をインストールしていない場合は、ここでインストール方法を確認できます。 Unix プラットフォームに Nginx をインストールする方法を示します。事前に構築された Nginx にはこのチュートリアルで使用される一部のモジュールが付属していないため、ソース ファイル経由で Nginx をインストールすることを選択します。

要件
以下をマシンにインストールし、このチュートリアルを Ubuntu などの Debian ベースのプラットフォームで実行する必要があります。
- Ubuntu またはその他の Debian ベースのプラットフォーム
- ウィゲット
- Vim (テキストエディタ)
また、このチュートリアルの一部のコマンドは、root ユーザーとして
sudo
コマンドを使用して実行する必要があります。

Nginx 構成構造を理解する
このセクションでは次のことを見ていきます。
- Nginxの構造
- イベント、HTTP、メールなどのセクション
- Nginx の有効な構文
このセクションの最後では、Nginx 構成の構造、セクションの目的または役割、およびセクション内で有効なディレクティブを定義する方法を理解できます。
完全な Nginx 構成ファイルは、
event section
、
http section
、
mail section
などのいくつかのセクションにグループ化されたディレクティブで構成される論理構造を持っています。
主要な設定ファイルは
/etc/nginx/nginx.conf
にあり、他の設定ファイルは
/etc/nginx
にあります。
メインコンテキスト
このセクションまたはコンテキストには、
mail section
などの特定のセクションの外側にあるディレクティブが含まれています。
user nginx;
、
worker_processes 1;
,
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid
メインセクションまたはコンテキスト内に配置できます。
ただし、
worker_processes
などのこれらのディレクティブの一部は、
event section
に存在することもできます。
セクション
Nginx のセクションでは、Nginx モジュールの構成を定義します。
たとえば、
http section
ngx_http_core module
の構成を定義し、
event section
ngx_event_module
の構成を定義し、mail セクションは
ngx_mail_module
の構成を定義します。
Nginx のセクションの完全なリストについては 、ここで 確認できます。
指令
Nginx のディレクティブは、次のような変数名といくつかの引数で構成されます。
worker_processes
変数名であり、
auto
引数として機能します。
worker_processes auto;
ディレクティブは、上に示したようにセミコロンで終わります。
最後に、Nginx 構成ファイルは特定のルール セットに従う必要があります。 Nginx 構成の有効な構文は次のとおりです。
- 有効なディレクティブは変数名で始まり、その後に 1 つ以上の引数が続きます
-
有効なディレクティブはすべてセミコロンで終わります
;
-
セクションは中括弧
{}
で定義されます - セクションは別のセクションに埋め込むことができます
- セクション外の構成は、Nginx グローバル構成の一部です。
-
ハッシュ記号
#
で始まる行はコメントです。
パフォーマンスのための Nginx のチューニング
このセクションでは、大量のトラフィックやトラフィックの急増時にパフォーマンスが向上するように Nginx を構成します。
以下の構成方法を見ていきます。
- 労働者
- ディスク I/O アクティビティ
- ネットワーク活動
- バッファー
- 圧縮
- キャッシング
- タイムアウト
それでも、アクティブ化された仮想環境内で次のコマンドを入力して Nginx ディレクトリに移動し、その内容を一覧表示します。
cd nginx && ls
フォルダー
conf
を検索します。このフォルダー内には
nginx.conf
ファイルがあります。
このファイルを使用して Nginx を設定します
次に、次のコマンドを実行して
conf
フォルダーに移動し、
<a href="https://.com/best-vim-editors/">vim editor</a>
で
nginx.conf
ファイルを開きます。
cd conf
sudo vim nginx.conf
以下は、
nginx.conf
ファイルがデフォルトでどのように表示されるかを示すスクリーンショットです。
労働者
Nginx のパフォーマンスを向上させるには、イベント セクションで
workers
構成する必要があります。 Nginx ワーカーを構成すると、クライアントからの接続を効率的に処理できるようになります。
vim エディターを閉じていない場合は、キーボードの
i
ボタンを押して
nginx.conf
ファイルを編集します。
以下に示すように、
events section
内に以下をコピーして貼り付けます。
events {
worker_processes auto;
worker_connections 1024;
worker_rlimit_nofile 20960;
multi_accept on;
mutex_accept on;
mutex_accept_delay 500ms;
use epoll;
epoll_events 512;
}
worker_processes
: このディレクティブは、Nginx のワーカーの数を制御します。このディレクティブの値は
auto
に設定され、Nginx が利用可能なコア、ディスク、サーバー負荷、およびネットワーク サブシステムの数を決定できるようになります。ただし、ターミナルで
lscpu
コマンドを実行すると、コアの数を確認できます。
worker_connections
: このディレクティブは、ワーカーが開くことができる同時接続の数の値を設定します。デフォルト値は
512
ですが、1 つのワーカーがクライアントから多数の同時接続を受け入れることができるように、
1,024
に設定しました。
worker_rlimit_nofile:
このディレクティブは、何らかの形で
worker_connections
に関連しています。大量の同時接続を処理するために、大きな値に設定します。
multi_accept:
このディレクティブにより、ワーカーはキュー内の多くの接続を一度に受け入れることができます。この文脈におけるキューは、単に処理を待っている一連のデータ オブジェクトを意味します。
mutex_accept:
このディレクティブはデフォルトではオフになっています。ただし、Nginx で多くのワーカーを構成したため、ワーカーが新しい接続を 1 つずつ受け入れることができるように、上記のコードに示すように Nginx をオンにする必要があります。
mutex_accept_delay:
このディレクティブは、ワーカーが新しい接続を受け入れるまでに待機する時間を決定します。
accept_mutex
オンになると、
accept_mutex_delay
で指定されたタイムフレームの間、ミューテックス ロックがワーカーに割り当てられます。時間が経過すると、次のワーカーが新しい接続を受け入れる準備が整います。
use:
このディレクティブは、クライアントからの接続を処理する方法を指定します。このチュートリアルでは、
Ubuntu
プラットフォームで作業しているため、値を
epoll
に設定することにしました。
epoll
方式は、Linux プラットフォームにとって最も効果的な処理方式です。
epoll_events:
このディレクティブの値は、Nginx がカーネルに転送するイベントの数を指定します。
ディスクI/O
このセクションでは、Nginx で非同期 I/O アクティビティを構成して、効果的なデータ転送を実行し、キャッシュの効率を向上できるようにします。
ディスク I/O は、単にハードディスクと RAM 間の書き込みおよび読み取り操作を指します。カーネル内の
<a href="https://linux.die.net/man/2/sendfile">sendfile(</a>)
関数を使用して小さなファイルを送信します。
この領域のディレクティブには、
http section
、
location section
、
server section
を使用できます。
location section
、
server section
http section
内に埋め込むか配置して、構成を読み取り可能にすることができます。
次のコードをコピーして、HTTP セクション内に埋め込まれた location セクション内に貼り付けます。
location /pdf/ {
sendfile on;
aio on;
}
location /audio/ {
directio 4m
directio_alignment 512
}
sendfile:
オペレーティング システムのリソースを利用するには、このディレクティブの値を
on
に設定します。 sendfile は、アプリケーション バッファにデータを送信せずに、OS カーネル空間内のファイル記述子間でデータを転送します。このディレクティブは、小さなファイルを提供するために使用されます。
directio:
このディレクティブは、読み取りと書き込みをアプリケーションに直接送信できるようにすることで、キャッシュの効率を向上させます。
directio
、最新のすべてのオペレーティング システムのファイルシステム機能です。このディレクティブは、ビデオなどの大きなファイルを提供するために使用されます。
aio:
このディレクティブは、書き込みおよび読み取り操作で
on
に設定すると、マルチスレッドを有効にします。マルチスレッドは、ホスティング プロセス リソースを共有しながら、複数のスレッドが互いに個別に実行できるようにする実行モデルです。
directio_alignment:
このディレクティブは、データ転送にブロック サイズ値を割り当てます。それは
directio
ディレクティブに関連していました。
ネットワーク層
このセクションでは、
tcp_nodelay
や
tcp_nopush
などのディレクティブを使用して、小さなパケットが一度に送信される前に、指定された約 200 ミリ秒の時間枠を待機するのを防ぎます。
通常、パケットが「断片」で転送されると、高負荷のネットワークが飽和状態になる傾向があります。そこで、John Nagle は、この問題を解決するための バッファリング アルゴリズム を構築しました。 Nagle のバッファリング アルゴリズムの目的は、小さなパケットが高負荷のネットワークを飽和させるのを防ぐことです。
次のコードをコピーして、HTTP セクション内に貼り付けます。
http {
tcp_nopush on;
tcp_nodelay on;
}
tcp_nodelay:
このディレクティブはデフォルトで無効になっており、小さなパケットが一度に送信される前に指定された期間待機できるようになります。すべてのデータを一度に送信できるようにするには、このディレクティブを有効にします。
tcp_nopush:
tcp_nodelay
ディレクティブを有効にしているため、小さなパケットが一度に送信されます。ただし、それでも John Nagle のバッファリング アルゴリズムを利用したい場合は、
tcp_nopush
を有効にしてパケットを相互に追加し、すべてを一度に送信することもできます。
バッファー
リクエストを効果的に処理するために Nginx でリクエスト バッファを構成する方法を見てみましょう。バッファは、データを一定期間保持して処理する一時的なストレージです。
以下をサーバーセクションにコピーできます。
server {
client_body_buffer_size 8k;
client_max_body_size 2m;
client_body_in_single_buffer on;
client_body_temp_pathtemp_files 1 2;
client_header_buffer_size 1m;
large_client_header_buffers 4 8k;
}
これらのバッファーラインが何を行うのかを理解することが重要です。
client_body_buffer_size:
このディレクティブは、リクエスト本文のバッファ サイズを設定します。 64 ビット システムで Web サーバーを実行する予定がある場合は、値を 16k に設定する必要があります。 32 ビット システムで Web サーバーを実行する場合は、値を 8k に設定します。
client_max_body_size:
大きなファイルのアップロードを処理する場合は、このディレクティブを少なくとも
2m
以上に設定する必要があります。デフォルトでは、
1m
に設定されています。
client_body_in_file_only:
ハッシュタグ記号
#
を使用して
client_body_buffer_size
ディレクティブを無効にし、このディレクティブ
client_body_in_file_only
が設定されている場合、Nginx はリクエスト バッファを一時ファイルに保存します。これは実稼働環境には推奨されません。
client_body_in_single_buffer:
リクエスト本文のすべてがバッファーに格納されない場合があります。残りの部分は一時ファイルに保存または書き込まれます。ただし、完全なリクエスト バッファを単一のバッファに保存または保存する場合は、このディレクティブを有効にする必要があります。
client_header_buffer_size:
このディレクティブを使用して、リクエスト ヘッダーのバッファーを設定または割り当てることができます。この値は
1m
に設定できます。
large_client_header_buffers:
このディレクティブは、大きなリクエスト ヘッダーを読み取るための最大数とサイズを設定するために使用されます。最大数とバッファ サイズを
4
および
8k
に正確に設定できます。
圧縮
ネットワーク経由で転送されるデータ量を圧縮することも、Web サーバーのパフォーマンスを向上させるもう 1 つの方法です。このセクションでは、
gzip
、
gzip_comp_level
、
gzip_min_length
などのディレクティブを使用してデータを圧縮します。
以下に示すように、
http section
内に次のコードを貼り付けます。
http {
gzip on;
gzip_comp_level 2;
gzip_min_length 1000;
gzip_types text/xml text/css;
gzip_http_version 1.1;
gzip_vary on;
gzip_disable "MSIE [4-6] \.";
}
gzip:
圧縮を有効にする場合は、このディレクティブの値を
on
に設定します。デフォルトでは無効になっています。
gzip_comp_level:
このディレクティブを使用して圧縮レベルを設定できます。 CPU リソースを無駄にしないために、圧縮レベルをあまり高く設定する必要はありません。
1
~
9
の間で、圧縮レベルを
2
または
3
に設定できます。
gzip_min_length:
content-length response header field
を介して圧縮の最小応答長を設定します。 20 バイト以上に設定できます。
gzip_types:
このディレクティブを使用すると、圧縮する応答タイプを選択できます。デフォルトでは、応答タイプ
text/html
は常に圧縮されます。上記のコードに示すように、
text/css
などの他の応答タイプを追加できます。
gzip_http_version:
このディレクティブを使用すると、圧縮された応答に対するリクエストの最小 HTTP バージョンを選択できます。デフォルト値の
1.1
を使用できます。
gzip_vary:
gzip
ディレクティブが有効な場合、このディレクティブはヘッダー フィールド
Vary:Accept Encoding
を応答に追加します。
gzip_disabled:
Internet Explorer 6
などの一部のブラウザは、
gzip compression
をサポートしていません。このディレクティブは、
User-Agent
リクエスト ヘッダー フィールドを利用して、特定のブラウザの圧縮を無効にします。
キャッシング
キャッシュ機能を活用して、同じデータを複数回ロードする回数を減らします。 Nginx は、
open_file_cache
ディレクティブを介して静的コンテンツのメタデータをキャッシュする機能を提供します。
このディレクティブは、
server
、
location
、および
http
セクション内に配置できます。
http {
open_file_cache max=1,000 inactive=30s;
open_file_cache_valid 30s;
open_file_cache_min_uses 4;
open_file_cache_errors on;
}
open_file_cache:
このディレクティブはデフォルトでは無効になっています。 Nginx でキャッシュを実装する場合は、これを有効にします。このディレクティブは、ユーザーがよく要求するファイルとディレクトリのメタデータを保存します。
open_file_cache_valid:
このディレクティブには、
open_file_cache
ディレクティブ内のバックアップ情報が含まれます。このディレクティブを使用して、ファイルとディレクトリに関連する情報が再度再検証されるまでの有効期間を通常は秒単位で設定できます。
open_file_cache_min_uses:
Nginx は通常、一定期間非アクティブになった後、
open_file_cache_min_uses
に基づいて
open_file_cache
ディレクティブ内の情報をクリアします。このディレクティブを使用して最小アクセス数を設定し、アクティブにアクセスされているファイルとディレクトリを識別できます。
open_file_cache_errors:
このディレクティブを使用して、ファイルがアクセスされたときに Nginx が「アクセス許可が拒否されました」または「このファイルにアクセスできません」などのエラーをキャッシュできるようにすることができます。そのため、権限のないユーザーがリソースにアクセスすると、Nginx は同じエラー レポート「アクセスが拒否されました」を表示します。
タイムアウト
keepalive_timeout
や
keepalive_requests
などのディレクティブを使用してタイムアウトを構成し、長時間待機する接続によるリソースの浪費を防ぎます。
HTTP セクションで、次のコードをコピーして貼り付けます。
http {
keepalive_timeout 30s;
keepalive_requests 30;
send_timeout 30s;
}
keepalive_timeout
: 接続を約 30 秒間維持します。デフォルトは 75 秒です。
keepalive_requests
: 特定の期間存続するように多数のリクエストを構成します。リクエスト数は 20 または 30 に設定できます。
keepalive_disable
: ブラウザの特定のグループに対してキープアライブ接続を無効にする場合は、このディレクティブを使用します。
send_timeout
: クライアントへのデータ送信のタイムアウトを設定します。

Nginx のセキュリティ構成
以下では、Web アプリケーションではなく Nginx を安全に構成する方法のみに焦点を当てます。したがって、SQL インジェクションなどの Web ベースの攻撃については説明しません。
このセクションでは、次の設定方法を見ていきます。
- ファイルとディレクトリへのアクセスを制限する
- 悪意のあるアクティビティを監視するためのログを構成する
- DDoS を防ぐ
- ディレクトリリストを無効にする
ファイルとディレクトリへのアクセスを制限する
次の方法で機密ファイルとディレクトリへのアクセスを制限する方法を見てみましょう。
HTTP認証を利用することで
ユーザーまたは管理者に認証を求めることで、機密ファイルや一般公開を意図していない領域へのアクセスを制限できます。パスワード ファイル作成ユーティリティをインストールしていない場合は、次のコマンドを実行してインストールします。
apt-get install -y apache-utils
次に、以下に示すように、
htpasswd
ツールを使用してパスワード ファイルとユーザーを作成します。
htpasswd
ツールは、
apache2-utils
ユーティリティによって提供されます。
sudo htpasswd -c /etc/apache2/ .htpasswd mike
次のコマンドを使用して、ユーザーとランダムなパスワードが正常に作成されたかどうかを確認できます。
cat etc/apache2/ .htpasswd
location セクション内に次のコードを貼り付けて、
auth_basic
ディレクティブを使用してユーザーに認証を求めることができます。
location /admin {
basic_auth "Admin Area";
auth_basic_user_file /etc/apache2/ .htpasswd;
}
「Allow」ディレクティブを利用することで、
basic_auth
ディレクティブに加えて、
allow
ディレクティブを使用してアクセスを制限できます。
location セクション内で次のコードを使用すると、指定した IP アドレスが機密領域にアクセスできるようになります。
location /admin {
allow 192.168.34.12;
allow 192.168.12.34;
}
悪意のあるアクティビティを監視するためのログを構成する
このセクションでは、
error
と
access
ログを構成して、有効なリクエストと無効なリクエストを具体的に監視します。これらのログを調べて、特定の時間に誰がログインしたか、またはどのユーザーが特定のファイルにアクセスしたかなどを調べることができます。
error_log:
syslog
や
stderr
などの特定のファイルへのログ記録を設定できます。ログに記録するエラー メッセージのレベルを指定することもできます。
access_log:
ユーザーのリクエストをファイル
access.log
に書き込むことができます。
HTTP セクション内では、以下を使用できます。
http {
access_log logs/access.log combined;
error_log logs/warn.log warn;
}
DDO を防止する
次の方法で Nginx を DDOS 攻撃から保護できます。
ユーザーリクエストの制限
limit_req_zone
および
limit_req
ディレクティブを使用して、ユーザーが送信するリクエストのレートを分単位で制限できます。
サーバーセクションに埋め込まれた
location
セクションに次のコードを追加します。
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
server {
location /admin.html {
limit_req zone=one;
}
}
接続数を制限する
limit_conn
および
limit_conn_zone
ディレクティブを使用して、特定の場所またはエリアへの接続を制限できます。たとえば、以下のコードは、特定の期間にクライアントから 15 の接続を受信します。
次のコードは
location
セクションに移動します。
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /products/ {
limit_conn addr 10;
}
}
遅い接続を終了する
client_body_timeout
や
client_header_timeout
などのタイムアウト ディレクティブを使用して、Nginx が
client body
と
client header
からの書き込みを待機する時間を制御できます。
server
セクション内に以下を追加します。
server {
client_body_timeout 5s;
client_header_timeout 5s;
}
ここで説明したように、クラウドベースのソリューションを活用して、DDoS 攻撃をエッジで阻止することも良い考えです。
ディレクトリリストを無効にする
以下のコードに示すように、
auto_index
ディレクティブを使用して、ディレクトリの一覧表示を防ぐことができます。ディレクトリのリストを無効にするには、値を
off
に設定する必要があります。
location / {
auto_index off;
}
結論
Nginx Webサーバーは効果的に動作し、運用環境での過度の乱用から保護されるように構成されています。インターネットに接続する Web アプリケーションに Nginx を使用している場合は、パフォーマンスとセキュリティを向上させるために、CDN とクラウドベースのセキュリティの使用も検討する必要があります。
