土日の勉強ノート

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

nginx(エンジンエックス)を理解する

前回 は、HTTP を題材に tcpdump の使い方を理解しました。

今回は、「nginx実践ガイド impress top gearシリーズ」と「Nginx ポケットリファレンス」を参考書として、Webサーバの nginx(エンジンエックス)の理解を行います。

それでは、やっていきます。

参考文献

はじめに

「セキュリティ」の記事一覧です。良かったら参考にしてください。

セキュリティの記事一覧

今回は、Webサーバの nginxt を理解したいと思います。

ParrotOS には、デフォルトで nginx がインストールされています。

設定ファイル

nginx の設定ファイルは、/etc/nginx/nginx.conf です。

ParrotOS のデフォルトの設定ファイルを見ながら、内容を理解していきます。

/etc/nginx/nginx.conf:全体像

まず、全体を貼り付けます。一部、コメントアウトされてるところは削除しています。

events { ... } や、http { ... } は、コンテキストと呼ばれるもので、eventsコンテキストと、httpコンテキストです。

これら以外のトップ階層で定義されているもの(user www-data; など)は、mainコンテキストと呼ばれます。

# 以降はコメントです。

$ cat /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

3つのコンテキストがあります。順番に見ていきます。

/etc/nginx/nginx.conf:mainコンテキスト

mainコンテキストは以下の5行です。

  • user:nginx の worker が動作するユーザ名で、ParrotOS には www-data というユーザが用意されています
  • worker_processes:worker のプロセス数で、auto の場合はコア数と同数になります
  • pid:プロセスID を記述したファイルの配置先で、シグナルを送信するときに使用します
  • error_log:エラーログの書き込み先で、ここに出力するログレベルも書かれるようです(今回は書かれてないのでデフォルト値が適用される? error がデフォルト?)
  • include:includeディレクティブで、書かれたファイルが展開されますが、デフォルトではこのディレクトリにファイルは存在しません
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

/etc/nginx/nginx.conf:eventsコンテキスト

eventsコンテキストは1行です。

  • worker_connections:1つの worker プロセスが同時に受け付けられる接続数で、768 が設定sれています
events {
        worker_connections 768;
}

/etc/nginx/nginx.conf:httpコンテキスト

httpコンテキストは少し長いので、コメントで分けてくれている通りに分けて読んでいきます。

/etc/nginx/nginx.conf:httpコンテキストのBasic Settings

httpコンテキストの Basic Settings です。

  • sendfile:tcp_nopushディレクティブと一緒に使われるディレクティブで、ファイル送信の性能改善用であり、on に設定するとユーザ空間を介さずにカーネル空間でファイル送信することが出来るようになり、性能が改善されます(ただし、HTTPS では使えない)
  • tcp_nopush:sendfileディレクティブと一緒に使われるディレクティブです
  • types_hash_max_size:参考書に載ってなかったディレクティブで、少し調べるとコンテンツ配信の性能向上用のディレクティブのようです
  • default_type:ファイルタイプのデフォルトを設定するディレクティブで、1行上の includeディレクティブで多くのファイルタイプが設定されていて、定義が無い場合に使用されるファイルタイプを設定します、application/octet-stream は任意のバイナリファイルが設定されています(これにより、HTTP の Content-Typeヘッダが正しく設定されます)
##
# Basic Settings
##

sendfile on;
tcp_nopush on;
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;
/etc/nginx/nginx.conf:httpコンテキストのSSL Settings

httpコンテキストの SSL Settings です。

  • ssl_protocols:SSL/TLS のプロトコルバージョンを指定するディレクティブです
  • ssl_prefer_server_ciphers:SSL/TLS で使用する暗号化アルゴリズムの優先度をクライアントが提示した優先度に従う場合は off、サーバが持つ優先度に従う場合は on に設定します
##
# SSL Settings
##

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
/etc/nginx/nginx.conf:httpコンテキストのLogging Settings

httpコンテキストの Logging Settings です。

  • access_log:アクセスログの出力先ファイル名を指定します
##
# Logging Settings
##

access_log /var/log/nginx/access.log;
/etc/nginx/nginx.conf:httpコンテキストのGzip Settings

httpコンテキストの Gzip Settings です。

  • gzip:クライアントにコンテンツを転送するときに圧縮して転送する場合は on に設定します(デフォルト:off)
##
# Gzip Settings
##

gzip on;
/etc/nginx/nginx.conf:httpコンテキストのVirtual Host Configs

httpコンテキストの Virtual Host Configs です。

includeディレクティブだけ記述されています。

/etc/nginx/conf.d/ にはファイルはありませんでしたが、/etc/nginx/sites-enabled/ にファイルが1つありました(/etc/nginx/sites-available/default)。

##
# Virtual Host Configs
##

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

/etc/nginx/sites-available/default には、serverコンテキストが書かれていました。

  • listen:待ち受けるポート番号の指定で、default_server は、複数の設定があった場合に、デフォルトで使われるサーバを指定します
  • root:ドキュメントルートの指定で、/var/www/html には index.html ファイルと、index.nginx-debian.html ファイルが用意されていました
  • index:ディレクトリにアクセスしたときにレスポンスに使用されるファイル名を指定します(前から順にファイルが存在するかを見ていき、最初に存在したファイルが使われます)
  • server_name:この serverコンテキストで処理するホスト名(例:www.example.com)を指定し、_ の場合は全てのホスト名の場合の処理となります(1つしか無い場合に使われる)

続いて、locationコンテキストです。/ にアクセスされた場合の設定になります。

  • try_files:コメントに説明がありますが、指定された URL(URI)をどのような順序で対応するかを指定するディレクティブで、まずは存在すればファイルを返し、存在すればディレクトリを返し、両方無ければ 404(Not Found)を返します
$ cat /etc/nginx/sites-enabled/default
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;
        }
}

リバースプロキシ

nginx は、通常の Webサーバとして利用できますが、リバースプロキシや、ロードバランサとしても、よく利用されます。

まずは、これらの用語の定義を整理して、その後、リバースプロキシの設定について書こうと思います。

リバースプロキシ

リバースプロキシとは、Webサイトの最初の窓口として HTTPリクエストを受け付ける役割をします。

Webブラウザなどのクライアントからの HTTPリクエストを受け付け、必要に応じて、他のサーバ(アプリケーションサーバ)にリクエストを転送したりします。

リバースプロキシは、プロキシサーバとアクセス方向が逆のサーバです。

プロキシサーバ

プロキシサーバという名前をよく聞くと思います。これはクライアントが外部のネットワークにアクセスするときに、クライアントの代わりにプロキシサーバがアクセスしてくれるというものです。

プロキシサーバの用途は、キャッシュを使うことで、Webサイトのアクセスを効率化したり、ウィルスチェック、フィルタリングのためだったりします。

ロードバランサ

機能としては、リバースプロキシと同じなのですが、目的が負荷を分散するために設置した場合に、ロードバランサと呼ばれるようです。

リバースプロキシの設定

ParrotOS のデフォルトの設定ファイルには出てこなかった設定をいくつかここに書こうと思います。

  • proxy_pass:locationコンテキストに書かれる場合が多く、そのパスにアクセスされた場合に、ここに書かれた IPアドレスとポート番号(例:192.168.1.10:8080)にリクエストを転送します
  • proxy_set_header:リバースプロキシを使用してクライアントのリクエストを転送した場合、転送先の Webサーバは、HTTPリクエストヘッダを見ると、リバースプロキシからのアクセスと見えてしまうため、HTTPリクエストヘッダにクライアントの情報を付加したり、HTTPリクエストヘッダを書き換えることができます(例:Hostヘッダをリバースプロキシのアドレスからクライアントの IPアドレスに書き換える)

おわりに

今回は、nginx について参考書を読みながら、理解を進めました。今回は基本的な部分だけを書いたので、また、必要に応じて、内容を追記したいと思います。

次回から、ハッキング・ラボのつくりかた 完全版 仮想環境におけるハッカー体験学習 を読みながら、セキュリティの理解を進めていきたいと思います。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。