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/ に接続。 nginx側から308リターンを返していて、Locationヘッダーにリダイレクト先がセットされています。その後SSLのハンドシェイクが始まっています。
SSL化の確認 http://<サーバIPアドレス>8081/page1/ に接続。 無事SSL化されました。ちなみに自己証明書なので、通常はセキュリティ警告が表示されます。前もってnginxのサーバー証明書をHOST側にエクスポートし、"信頼済みルート署名書"として証明書をインポートしています。あと、Hostsファイルにexample.comを追記。
6.まとめ
SSL化を行う上では、受け入れるSSLバージョンの指定、暗号セキュリティースイートの指定を考慮したほうが良い。この辺はガイドライン等も出ているので参考にしながら機会があれば本実装したい。
7.参考リンク
https://www.cryptrec.go.jp/report/archives/cryptrec-gl-3001-1.0.pdf