nginxによるリクエスト処理

未定義のサーバー名を持つリクエストの処理を防止する方法
名前ベースとIPベースの仮想サーバーの混合
シンプルなPHPサイトの設定

名前ベースの仮想サーバー

nginxはまず、リクエストを処理するサーバーを決定します。3つの仮想サーバーがすべてポート*:80でリスンするシンプルな設定から始めましょう。

server {
    listen      80;
    server_name example.org www.example.org;
    ...
}

server {
    listen      80;
    server_name example.net www.example.net;
    ...
}

server {
    listen      80;
    server_name example.com www.example.com;
    ...
}

この設定では、nginxはリクエストのヘッダーフィールド「Host」のみをテストして、リクエストをどのサーバーにルーティングするかを決定します。その値がサーバー名と一致しない場合、またはリクエストにこのヘッダーフィールドが含まれていない場合、nginxはリクエストをこのポートのデフォルトサーバーにルーティングします。上記の設定では、デフォルトサーバーは最初のサーバーです。これはnginxの標準的なデフォルト動作です。listenディレクティブのdefault_serverパラメーターを使用して、明示的にデフォルトサーバーを設定することもできます。

server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}

default_serverパラメーターはバージョン0.8.21から利用可能です。それ以前のバージョンでは、代わりにdefaultパラメーターを使用する必要があります。

デフォルトサーバーは、サーバー名ではなく、リスンポートのプロパティであることに注意してください。これについては後で詳しく説明します。

未定義のサーバー名を持つリクエストの処理を防止する方法

「Host」ヘッダーフィールドのないリクエストを許可しない場合は、リクエストをただドロップするサーバーを定義できます。

server {
    listen      80;
    server_name "";
    return      444;
}

ここでは、サーバー名が空文字列に設定されており、「Host」ヘッダーフィールドのないリクエストと一致します。そして、接続を閉じるnginx独自の非標準コード444が返されます。

バージョン0.8.48以降、これはサーバー名のデフォルト設定であるため、server_name ""は省略できます。それ以前のバージョンでは、マシンのホスト名がデフォルトのサーバー名として使用されていました。

名前ベースとIPベースの仮想サーバーの混合

いくつかの仮想サーバーが異なるアドレスでリスンする、より複雑な設定を見てみましょう。

server {
    listen      192.168.1.1:80;
    server_name example.org www.example.org;
    ...
}

server {
    listen      192.168.1.1:80;
    server_name example.net www.example.net;
    ...
}

server {
    listen      192.168.1.2:80;
    server_name example.com www.example.com;
    ...
}

この設定では、nginxはまず、リクエストのIPアドレスとポートを、serverブロックのlistenディレクティブと照合します。次に、IPアドレスとポートに一致したserverブロックのserver_nameエントリに対して、リクエストの「Host」ヘッダーフィールドをテストします。サーバー名が検出されない場合、リクエストはデフォルトサーバーによって処理されます。たとえば、192.168.1.1:80ポートで受信されたwww.example.comのリクエストは、192.168.1.1:80ポートのデフォルトサーバー、つまり最初のサーバーによって処理されます(このポートにはwww.example.comが定義されていないため)。

既に述べたように、デフォルトサーバーはリスンポートのプロパティであり、異なるポートに対して異なるデフォルトサーバーを定義できます。

server {
    listen      192.168.1.1:80;
    server_name example.org www.example.org;
    ...
}

server {
    listen      192.168.1.1:80 default_server;
    server_name example.net www.example.net;
    ...
}

server {
    listen      192.168.1.2:80 default_server;
    server_name example.com www.example.com;
    ...
}

シンプルなPHPサイトの設定

次に、典型的なシンプルなPHPサイトのリクエストの処理方法を見てみましょう。

server {
    listen      80;
    server_name example.org www.example.org;
    root        /data/www;

    location / {
        index   index.html index.php;
    }

    location ~* \.(gif|jpg|png)$ {
        expires 30d;
    }

    location ~ \.php$ {
        fastcgi_pass  localhost:9000;
        fastcgi_param SCRIPT_FILENAME
                      $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}

nginxはまず、リストされている順序に関係なく、リテラル文字列によって与えられる最も具体的なプレフィックスロケーションを検索します。上記の設定では、唯一のプレフィックスロケーションは「/」であり、任意のリクエストと一致するため、最後の手段として使用されます。次に、nginxは設定ファイルにリストされている順序で、正規表現によって与えられるロケーションをチェックします。最初に一致する正規表現で検索は停止し、nginxはこのロケーションを使用します。正規表現がリクエストと一致しない場合、nginxは先に検出された最も具体的なプレフィックスロケーションを使用します。

すべてのタイプのロケーションは、引数なしでリクエストラインのURI部分のみをテストすることに注意してください。クエリ文字列の引数は、次のようにいくつかの方法で指定できるためです。

/index.php?user=john&page=1
/index.php?page=1&user=john

また、誰でもクエリ文字列に何でも要求できます。

/index.php?page=1&something+else&user=john

次に、上記の設定でリクエストがどのように処理されるかを見てみましょう。

執筆者:Igor Sysoev
編集者:Brian Mercer