【備忘録】KaliLinuxにnginxでWebサーバを構築

こんにちは、なつきです。
今回はWebアプリ脆弱性診断の学習に使用するためのWebサーバを構築してみました。

ちなみにnginxは「えんじんえっくす」と発音します。
読み方知らない時は「んぎっくす」って発音してました(\*_*)

必要最低限の設定だけ行い、新たな設定が必要なった場合に、その都度追記していこうと思います。

# 目次
[1. はじめに](#1-はじめに)
[2. 実施内容](#2-実施内容)
[3. 前提条件](#3-前提条件)
[4. nginxとは](#4-nginxとは)
[5. インストール](#5-インストール)
[6. 起動と終了](#6-起動と終了)
[7. 基本設定](#7-基本設定)
[8. 静的コンテンツの公開](#8-静的コンテンツの公開)
[9. 最後に](#9-最後に)
[10. 参考資料](#10-参考資料)

# 1. はじめに
やられサイトはネット上でいくつか提供されているので自作する必要はないですが、今後もWebアプリ脆弱性を学んでいくにあたりWebサーバ構築ナレッジはあった方が良いと思うので、nginxを使用して構築していきます。

# 2. 実施内容
nginxのインストール～インデックスページ表示

# 3. 前提条件
- OS KaliLinux

# 4. nginxとは
- 概要
    以下の記事を参考にします
    [NGINXとは？ NGINXとNGINX Plusを徹底解説](https://www.nginx.co.jp/blog/what-is-nginx/)
    
    - C10k問題(クライアント1万台問題)を解決することを念頭に開発され、優れたスケーラビリティを誇る
        - C10K問題：1台のサーバが1万のクライアントから同時接続された場合、サーバの処理が追い付かなくなるスケーラビリティ面での問題
    - HTTPサーバとしての機能に加え、以下の機能も持っている
        - ロードバランサ
        - リバースプロキシ
        - コンテンツキャッシュ
        - APIゲートウェイ
        - Web Application Firewall

- Webサーバ利用シェア率
    [2021年5月のWebサーバ利用シェア、「Nginx」が「Apache」を初めて上回る](https://atmarkit.itmedia.co.jp/ait/articles/2105/17/news053.html#:~:text=%E4%B8%BB%E8%A6%81%E3%81%AAWeb%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E3%82%B7%E3%82%A7%E3%82%A2%E3%81%AE%E6%8E%A8%E7%A7%BB%EF%BC%88%20%E5%87%BA%E5%85%B8%EF%BC%9AQ-Success%20%EF%BC%89,%E8%AA%BF%E6%9F%BB%E5%AF%BE%E8%B1%A1%E3%81%AEWeb%E3%82%B5%E3%83%BC%E3%83%90%E6%8A%80%E8%A1%93%E3%81%AE%E6%95%B0%E3%81%AF%E7%8F%BE%E5%9C%A8%E3%80%8198%E3%81%AB%E9%81%94%E3%81%97%E3%81%A6%E3%81%8A%E3%82%8A%E3%80%812021%E5%B9%B45%E6%9C%884%E6%97%A5%E4%BB%98%E3%81%AE%E5%B8%82%E5%A0%B4%E3%82%B7%E3%82%A7%E3%82%A2%E3%81%AE3%EF%BD%9E7%E4%BD%8D%E3%81%AF%E3%80%81%E3%80%8CCloudflare%20Server%E3%80%8D%EF%BC%8818.4%EF%BC%85%EF%BC%89%E3%80%81%E3%80%8CLiteSpeed%E3%80%8D%EF%BC%888.6%EF%BC%85%EF%BC%89%E3%80%81IIS%EF%BC%887.0%EF%BC%85%EF%BC%89%E3%80%81%E3%80%8CNode.js%E3%80%8D%EF%BC%881.2%EF%BC%85%EF%BC%89%E3%80%81%E3%80%8CGoogle%20Servers%E3%80%8D%EF%BC%881.1%EF%BC%85%EF%BC%89%E3%81%A0%E3%81%A3%E3%81%9F%E3%80%82)
    >>Q-Successは2021年5月4日（米国時間）、Webサーバ技術の使用サイト数に基づく市場シェア調査結果を発表した。「Nginx」と「Apache」がともに33.8％を占め、わずかな差でNginxが首位、Apacheが2位となった。

# 5. インストール
ソースコードからのインストールとビルド済みパッケージからのインストール方法がある。
今回はビルド済みパッケージからインストールを行う。
[【参考】nginx: Linux packages #Debian](https://nginx.org/en/linux_packages.html#Debian)

- <font color="Gray">※それぞれのインストール方法のメリデメについては以下を参照
<a href="https://atmarkit.itmedia.co.jp/ait/articles/1407/24/news003.html">Nginxのインストールと基本設定</a></font>

## 5-1. 前提条件をインストール
```Linux:
sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring
```

## 5-2. 公式のnginx署名キーをインポート
```Linux:
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
```

## 5-3. ダウンロードしたファイルに適切なキーが含まれていることを確認します。
```Linux:
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
```

## 5-4. 安定したnginxパッケージ用にaptリポジトリを設定するには、 次のコマンドを実行します。
```Linux:
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/debian `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list
```

## 5-5. リポジトリの固定を設定して、パッケージを優先する 配布によって提供されるもの
```Linux:
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
    | sudo tee /etc/apt/preferences.d/99nginx
```

## 5-6. nginxをインストールするには、次のコマンドを実行します。
```Linux:
sudo apt update
sudo apt install nginx
```

# 6. 起動と終了
## 実行ファイルコマンド
- 起動時のオプション
    | オプション | 説明 |
    | :--- | :--- |
    | -t| 設定ファイルの構文チェック |
    | -c nginx.conf | 設定ファイルを指定する |
    | -g settings | 設定ファイルに記載されていない設定を指定する |

- 終了時のオプション
    | オプション | 説明 |
    | :--- | :--- |
    | stop   | リクエストの処理を待たずに終了 |
    | quit   | 現在のリクエスト処理が完了してから終了する |
    | reload | nginxを終了せず、設定ファイルの再読み込みを行う |
    | reopen | ログファイルを再度開く |

## 6-1. nginxの起動
```Linux:
sudo nginx
or
systemctl start nginx
```

## 6-2. 起動確認
- 起動確認
    ```Linux:
    systemctl status nginx
    ```

- プロセス確認
    ```Linux:
    # ps aux | grep nginx
    root       94175  0.0  0.0  10204   992 ?        Ss   19:49   0:00 nginx: master process nginx
    root       94190  0.0  0.1   6096  1964 pts/0    S+   19:51   0:00 grep --color=auto nginx
    ```
    - nginxのプロセスにはマスタプロセスとワーカプロセスなどがある

- ポート確認
    ```Linux:
    # lsof -i:80 | grep root
    nginx   94175     root    5u  IPv4 300655      0t0  TCP *:http (LISTEN)
    nginx   94175     root    6u  IPv6 300656      0t0  TCP *:http (LISTEN)
    ```
## 6-3. nginxの終了
```Linux:
sudo nginx -s stop
systemctl stop nginx
```

# 7. 基本設定
設定ファイル「/etc/nginx/nginx.conf」を編集する
設定ファイルはビルド時に指定するか、起動時にオプション引数で指定する

- 参考
    [【Nginx】設定ファイルとは（nginx.conf、conf.d、sites-available、uwsgi_paramsなど）](https://office54.net/iot/linux/nginx-setting-file)

## 7-1. 変数
- ディレクティブのパラメータには変数を使用することが出来る
    nginxでは頭に$をつけて表現する
    リクエストを処理するときなど、値が評価されるときに値が展開される
- 変数例
    | 変数名 | 説明 |
    | :--- | :--- |
    | $connection | コネクションのシリアル番号 |
    | $host | マッチしたサーバ名もしくはHostヘッダの値、なければリクエスト内のホスト |
    | $hostname | ホスト名 |
    | $nginx_version | nginxのバージョン |

- リクエストに応じて定義される変数
    | 変数名 | 説明 | 例 |
    | :--- | :--- | :--- |
    | $arg_属性名 | クエリストリングに含まれる値 | $arg_page |
    | $cookie_属性名 | Cookieに含まれる値 | $cookie_PHPSESSID |
    | $http_フィールド名 | リクエストヘッダの値 | $http_user_agent |
    | $sent_http_フィールド名 | 送信したレスポンスヘッダの値 | $sent_http_chahe_control |

## 7-2. 設定のインクルード
includeディレクティブを用いると、複数に分割したファイルを読み込んで使用できる
相対パス/絶対パスでの指定ができる
```
include mime.types;
include /etc/nginx/mime.types;
```

ファイルマスクを利用すると、ワイルドカードでの指定ができる
```
include sites-enabled/*.conf
```

## 7-3. HTTPサーバに関する設定
HTTPサーバに関する設定を記述するには、httpディレクティブを用いてhttpコンテキストを定義する

### 7-3-1. バーチャルサーバの定義
別々の設定を持つ複数のHTTPサーバを動作されることが出来る(=バーチャルサーバ)
バーチャルサーバは別々のHTTPサーバであるかのように動作し、独立した設定を持っている
serverディレクティブで定義する
```
http{
    server{
        ～
    }

    server{
        ～
    }
}
```
### 7-3-2. ディレクティブの設定
| ディレクティブ名 | 説明 | 設定例 |
| :--- | :--- | :--- |
| listen | バーチャルサーバが使用するアドレス、ポートを指定 | listen *:8080;<br>listen 127.0.0.1:8080; |
| server_name | ホスト名(正規表現しよう可能) | server_name example.com *.example.com; |
| root | 公開するディレクトリを設定<br>ここで指定したディレクトリのパスがURIのルートにマッピングされる | root /var/www/html; |
| types | 参照されたファイルの拡張子と、Content-Typeとして使用するMIMEタイプのマッピングをtypesディレクティブによって定義する | text/html html;<br> image/gif gif;<br> image/jpeg jpg; |
| location | マッチするURIごとに設定を指定する | |
| index | ディレクトリにアクセスされた場合に表示するページ(インデックスページ)を指定 | index ファイル名; |
| autoindex | インデックスページの自動生成の有効/無効を設定 | autoindex on | off; |
| error_page | エラー時に表示するページを指 | error_page 404 /404.html |

## 7-4. nginx本体の設定
| ディレクティブ名 | 説明 | 設定例 |
| :--- | :--- | :--- |
| error_log | エラーログの出力パスを指定<br>第2パラメータには出力レベルを指定できる<br>バーチャルサーバごとの設定が可能　 | error_log /var/log/nginx/error.log; |
| log_not_found | ファイルが存在しない場合のエラー出力を有効/無効にする | log_not_found on | off; |
| pid | PIDファイルの出力先を指定する。PIDファイルにはマスタプロセスのPIDが出力される。 | pid PIDファイルパス; | 

## 7-5. パフォーマンスに関する設定
| ディレクティブ名 | 説明 | 設定例 |
| :--- | :--- | :--- |
| keepalive_timeout | nginxに常時接続しているクライアントに対するタイムアウト時間を第1パラメータに設定する | keepalive_timeout 60s |

## 7-6. アクセス制限に関する設定
TODO


# 8. 静的コンテンツの公開
1. 以下の設定を追記
    ```Linux:/etc/nginx/nginx.conf
    ##
    # Server
    ##
    server {
      listen 80;
      server_name www.zeizyaku.com;
    
      location / {
            access_log /var/www/zeizyaku/nginx/www.zeizyaku.com_access.log;
            error_log /var/www/zeizyaku/nginx/www.zeizyaku.com_error.log;
    
            root /var/www/zeizyaku/;
    
            error_page 404 /404.html;
            error_page 500 502 503 504 /50x.html;
    
            index zeizyaku.html;
      }
    }
    ```

1. 指定したパス配下に資産を配置
    ```Linux
    # ls -la /var/www/zeizyaku/zeizyaku.html
    -rw-r--r-- 1 root root 211 Oct  9 22:03 /var/www/zeizyaku/zeizyaku.html
    
    # ls -la /var/www/zeizyaku/nginx/ | grep .log
    -rw-r--r-- 1 root root 2119 Oct  9 22:41 www.zeizyaku.com_access.log
    -rw-r--r-- 1 root root    0 Oct  9 22:10 www.zeizyaku.com_error.log
    ```

1. http接続確認
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1677523/e3be7144-7e07-dd75-d8f7-39e661b7b492.png)

1. ログ出力確認
    ```
    # tail -n 1 /var/www/zeizyaku/nginx/www.zeizyaku.com_access.log
    192.168.3.26 - - [09/Oct/2023:22:41:22 +0900] "GET /zeizyaku.html HTTP/1.1" 304 0 "-" "～
    ```

# 9. 最後に
とりあえずhttp接続でインデックスページが表示されるところまで確認ができた。
これからいわゆる「やられサイト」Webシステムを作成して載せていきたい。

# 10. 参考資料
- 参考書
    - [nginx実践入門](https://amzn.asia/d/gKRdEzj)