NginxでDigest認証をしてみた

## Digest認証とはなんぞ
その前にそれ以外認証方式を見ていきましょう

### Basic認証
よく聞く認証方式で、手軽ですべてのWebサーバー、ブラウザで対応しているため簡易的な認証で使われます。
Basic認証はIDとPasswordをbase64エンコードして送信するので途中で盗聴された場合base64でデコードすればID、Passwordが簡単に解読されてしまいます。これを防ぐ方法としてHTTPSで暗号化通信をする必要があります。

### Form認証
こちらは名前の通りHTMLで作られたFormからIDとPasswordを平文で送信する方法です。
こちらも棟梁を防ぐ方法としてHTTPSでの暗号化通信をする必要があります

### Digest認証
今回の目玉でBasic認証の平文でIDとPasswordを送るというのを改善した認証方式でハッシュ化して送信します。
IDとPasswordをMD5でハッシュ化し送信しするため盗聴されてもパスワードの解析が困難です。
HTTPSで通信を行えばBasic認証で良いのでDigest認証は基本的にHTTPS通信ができないときのHTTP認証方式です。



## 実際にやってみる
NginxでのDigest認証はデフォルトで対応していないため外部モジュールを使用します。
外部モジュールを入れる場合はNginxはソースからインストールします。

必要なパッケージインストール
- gcc →コンパイル
- make→インストールで必要
- pcre-devel→Perl互換正規表現ライブラリ
- httpd-tools→Digest認証で使うhtdigestファイルを作成するため

```
# yum install gcc pcre pcre-devel make perl httpd-tools
```

NginxはDigest認証を使用するのでソースからインストールします


Nginx本体
```
# wget "http://nginx.org/download/nginx-1.20.0.tar.gz" -O /tmp/nginx-1.20.0.tar.gz
```

Digest認証
```
# wget "https://github.com/atomx/nginx-http-auth-digest/archive/master.zip" -O /tmp/nginx-http-auth-digest.zip
```

/usr/local/src/に展開
```
# tar zxvf /tmp/nginx-1.20.0.tar.gz -C /usr/local/src/
# unzip /tmp/nginx-http-auth-digest.zip -d /usr/local/src/
```

コンパイルとインストール

```
# cd /usr/local/src/nginx-1.20.0
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache
/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --add-module=../nginx-http-auth-digest-master/
# make && make install
```

systemdにnginx.serviceを追加
```
$ vi nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=mixed
PrivateTmp=true
Restart=always

[Install]
WantedBy=multi-user.target
```

自動起動

```
systemctl enable nginx.service     
```

スタート

```
systemctl start nginx.service
```

### ここからDigest認証の設定

パスワードファイルの作成
```
# htdigest -c /etc/nginx/.htdigest_test "test" test
Adding password for user in realm test.
New password: candidate
Re-type new password: testpassword
```

`vi /etc/nginx/nginx.conf`

```
下記を追記
location /secret {
    root   html;
    index  index.html index.htm;
    auth_digest "test";  パスワードファイルのrelm名を
    auth_digest_user_file /etc/nginx/.htdigest_test; パスワードファイルのパスを
}
```

`/etc/nginx/html/sercret/index.html`を作成して
"Digest認証成功"と記載する

digest認証しない場合は401を返している
```
# curl http://<public ip>/secret/
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.20.0</center>
</body>
</html>
# curl --digest -u test:testpassword http://35.75.22.153/secret/
Digest認証成功
```