クライアント証明書を要求するサイトの構築（nginx)

* debian9にて実施

## 参考

* [Nginx 入門 - 松江工業高等専門学校](http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/)

## 1. openssl.cnfの準備

* 入力が大変なので、共通の設定はopenssl.cnfに書いておく。

```bash:
mkdir /opt/demoCA
cd /opt/demoCA
cp -a /etc/ssl/openssl.cnf .
```

```diff:/opt/demoCA/openssl.cnf
-dir            = ./demoCA              # Where everything is kept
+dir            = /opt/demoCA           # Where everything is kept
 certs          = $dir/certs            # Where the issued certs are kept
 crl_dir                = $dir/crl              # Where the issued crl are kept
 database       = $dir/index.txt        # database index file.
@@ -70,7 +70,7 @@
 # crlnumber must also be commented out to leave a V1 CRL.
 # crl_extensions       = crl_ext

-default_days   = 365                   # how long to certify for
+default_days   = 3650                  # how long to certify for
 default_crl_days= 30                   # how long before next CRL
 default_md     = default               # use public key default MD
 preserve       = no                    # keep passed DN ordering
@@ -126,17 +126,17 @@

 [ req_distinguished_name ]
 countryName                    = Country Name (2 letter code)
-countryName_default            = AU
+countryName_default            = JP
 countryName_min                        = 2
 countryName_max                        = 2

 stateOrProvinceName            = State or Province Name (full name)
-stateOrProvinceName_default    = Some-State
+stateOrProvinceName_default    = Tokyo

 localityName                   = Locality Name (eg, city)

 0.organizationName             = Organization Name (eg, company)
-0.organizationName_default     = Internet Widgits Pty Ltd
+0.organizationName_default     = mycompany.jp

 # we can do this but it is not needed normally :-)
 #1.organizationName            = Second Organization Name (eg, company)
```

## 2. 認証局(CA)の作成

* [10.2.1 認証局の作成](http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node95.html)

```bash:
openssl  genrsa  -out cakey.pem   2048
```

```bash:
# Common Name : サーバーの名前を入力すること
openssl req -config openssl.cnf -new -x509 -key cakey.pem \
     -out cacert.pem
```

## 3. サーバー証明書の作成

* [10.2.2 サーバ証明書の作成](http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node96.html)

```
openssl  genrsa  -out  private.pem  2048
```

```bash:
# Common Name : サーバーの名前を入力すること
openssl req -config openssl.cnf -new -key private.pem -out newreq.pem
```

### 署名

```bash:
mkdir private newcerts
mv cakey.pem private/
openssl ca -config openssl.cnf -policy policy_anything \
    -out cert.pem -in newreq.pem
```

```bash:nginx用に結合
cat  cert.pem  cacert.pem  >  allcert.pem
```

## 4. nginx設定

* [10.2.3 NginxのサーバSSLの設定](http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node97.html)

```nginx:/etc/nginx/sites-enabled/default
# httpの設定
server {
        listen 80 default_server;
        listen [::]:80 default_server;
        ...
}

# httpsの設定
server {
        listen 443 ssl;
        ssl_certificate /opt/demoCA/allcert.pem;
        ssl_certificate_key /opt/demoCA/private.pem;

        root /srv/www/html;
        charset   utf-8;

        index index.html index.htm index.nginx-debian.html index.php;
        server_name _;
        location / {
                try_files $uri $uri/ =404;
                autoindex on;
        }
        # phpの設定
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        }
        # ssl証明書がないと閲覧できないようにする
        ssl_verify_client on;
        ssl_client_certificate /opt/demoCA/cacert.pem;
}
```

```bash:syntaxチェック
nginx -t -c /etc/nginx/nginx.conf
```

```bash:
/etc/init.d/nginx restart
```


### 5. クライアントに配布用の証明書

* [10.2.4.1 クライアント証明書の作成](http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node99.html)

```bash:
openssl  genrsa  -out  client_private.pem  2048
```

```bash:
# Common Name : ユーザー名を指定
openssl req -config openssl.cnf -new -key client_private.pem -out newreq.pem
```

```
cat private.pem cert.pem cacert.pem \
| openssl pkcs12 -export -out client.p12 -name "client key"
```

* `client.p12`を配布し、`https://サーバーのIP/`にアクセスできることを確認。