かなりゆるーいインフラエンジニアのブログ

zawayaブログ

インフラエンジニアとして活動しています。現場での経験や技術的なことを思ったように書いていきます。

nginxを動かしてみる part2 -サーバSSL対応-

1.概要

初期設定の続き。サーバーのSSL化を試した時の備忘録 httpブロックでSSLバージョンの指定を行い、serverブロックでSSLの受け入れポートと使用する証明書の指定を行う。

2.実行環境

ubuntu version 18.04 TLS
nginx version: nginx/1.14.0 (Ubuntu) built with OpenSSL 1.1.1 11 Sep 2018 OpenSSL 1.1.1 ※自己証明書発行のため

3.自己証明書の準備

自己署名用の秘密鍵の作成

#mkdir /etc/nginx/server_cert #証明書保管フォルダ作成
#cd /etc/nginx/server_cert
#openssl genrsa -aes256 -out key.pem 2048

Generating RSA private key, 2048 bit long modulus (2 primes)
..........+++++
.........+++++
e is 65537 (0x010001)
Enter pass phrase for ca.key:
Verifying - Enter pass phrase for ca.key:

サーバ用の自己署名書を作成

# openssl req -new -x509 -days 365 -key ./key.pem -out example.pem

Enter pass phrase for ./key.pem:
Can't load /root/.rnd into RNG
139655662956992:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/root/.rnd
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Shinjuku
Organization Name (eg, company) [Internet Widgits Pty Ltd]:company,inc.
Organizational Unit Name (eg, section) []:system
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []: #空白

-x509オプションをつけて自身で作成した秘密鍵を署名しています。なので自己署名と呼ばれます。通常は認証局に申請し、認証局の鍵で署名します。

秘密鍵パスワードファイルの作成

echo password > ./pass

ここまでで、証明書保管フォルダ(/etc/nginx/server_cert)には以下のファイルが存在

Tips!
nginxは秘密鍵パスフレーズが設定されている場合は以下のエラーが出力されます。

nginx[5240]: Enter PEM pass phrase:
nginx[5240]: nginx: [emerg] SSL_CTX_use_PrivateKey_file("/etc/nginx/server_cert_tmp/key.pem") failed (SSL: error:2807106B:UI routines:UI_process:process
nginx[5240]: nginx: configuration file /etc/nginx/nginx.conf test failed

対策としては以下の2つになります。
1.パスフレーズを記載したファイルを作成し読み込む
2.秘密鍵のパスワードを外す↓
https://rms.ne.jp/sslserver/basis/decrypt_key/

4.nginxの設定

serverブロックを書き換えます。今回完全SSL化としますのでhttp⇒httpsへのリダイレクトの設定も行います。

/etc/nginx/sites-available/example.com

server {
       listen 80 default;
       return 308 https://$host$request_uri;
       }

server {

        listen 443 ssl;

        server_name  example.com;
        root /var/www/html/;

        ssl_certificate /etc/nginx/server_cert/example.pem;
        ssl_certificate_key /etc/nginx/server_cert/key.pem;
        ssl_password_file /etc/nginx/server_cert/key_pass;
        ssl_protocols  TLSv1.1 TLS1.2;
        ssl_ciphers   "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;

        location / {
               index index.html;
       }

       location /page1 {
               root /var/www/html_tmp/;
               index index.html;
       }
       location /page2 {
               root /var/www/html_tmp/;
               index index.html;
       }

}

--ssl_certificate--
SSLサーバ証明書ファイルを指定します。

--ssl_certificate_key--
SSLサーバ証明書秘密鍵ファイルそ指定します。

--ssl_password_file--
秘密鍵パスフレーズを記載したファイルを指定します。

--ssl_protocols--
受け付けるSSLバージョンを指定します。

--ssl_ciphers--
使用可能なセキュリティスイートを指定します。Mozilla wikiにreccomendが記載されていましたので参考にしました。

--ssl_session_cache shared-- SSLセッションキャッシュの設定です。ハンドシェイクの情報をキャッシュし再利用することでサーバの負荷を軽減可能です。サーバリソースに不安がある場合は設定をお勧め。

--ssl_session_timeout--
SSLセッションのタイムアウトの時間です。

5.nginxを起動

nginxを再起動し、example.comへ変更を適用します。

systemctl restart nginx.service

起動確認のためホストOSから接続をしてみます。

  • リダイレクトの確認 http://<サーバIPアドレス>/page1/ に接続。 f:id:blackstar01:20200504030929p:plain nginx側から308リターンを返していて、Locationヘッダーにリダイレクト先がセットされています。その後SSLのハンドシェイクが始まっています。

  • SSL化の確認 http://<サーバIPアドレス>8081/page1/ に接続。 f:id:blackstar01:20200504030324p:plain 無事SSL化されました。ちなみに自己証明書なので、通常はセキュリティ警告が表示されます。前もってnginxのサーバー証明書をHOST側にエクスポートし、"信頼済みルート署名書"として証明書をインポートしています。あと、Hostsファイルにexample.comを追記。  

6.まとめ

SSL化を行う上では、受け入れるSSLバージョンの指定、暗号セキュリティースイートの指定を考慮したほうが良い。この辺はガイドライン等も出ているので参考にしながら機会があれば本実装したい。

7.参考リンク

自己署名証明書の作成 - Qiita

https://www.cryptrec.go.jp/report/archives/cryptrec-gl-3001-1.0.pdf

Security/Server Side TLS - MozillaWiki