とーますメモ

Ruby on Rails / Goなどの学習メモ

【Lightsail】Ubuntu上でNginxにSSL証明書を設定してみた

近々リリース予定のサイトがあるのだが、Let's Encryptの無料SSL証明書ではなく
ちゃんとした有料の証明書を使用しようと思ったのでその過程を書いてみる

SSL証明書はNamecheapからPositiveSSLを1年契約で$5.88で購入
ドメインの種類としては3つあるなかで一番安いDV-SSL。
【保存版】やさしく分かる!SSL移行の全手順(WordPress対応) | 大分県のインターネット集客専門コンサルティング | 株式会社シャーロック

SSLについての説明は以下のサイトがわかりやすい。
【図解】よく分かるデジタル証明書(SSL証明書)の仕組み 〜https通信フロー,発行手順,CSR,自己署名(オレオレ)証明書,ルート証明書,中間証明書の必要性や扱いについて〜 | SEの道標
SSLって何?意味や仕組みをわかりやすく解説! | さくらのSSL
SSLサーバー証明書の発行手順 – ラボラジアン
NginxでSSLを設定する方法を基本から学ぶ - Kattsu Sandbox

[SSL申請から設定までの流れ]

1) 秘密鍵の作成
2) CSR(証明書発行要求: Certificate Signing Request) の作成
3) サーバ証明書の取得
4) 秘密鍵と証明書を設置し、Nginx設定変更する

1)と2)を同時に行うコマンドもあるが、長いので噛み砕いて説明する意味を込めてコマンドを分けることにする。

1) 秘密鍵の作成

秘密鍵の作成と、以降で説明するCSRの作成には、opensslコマンドを使用する。

バージョンの確認

$ openssl version
OpenSSL 1.1.1g  21 Apr 2020

秘密鍵の作成は、サーバ上で行うため、まずは鍵と証明書を配置するためのディレクトリを作成する。以降の作業は全てこのディレクトリ内で行う。
また権限を厳しく設定する。

$ mkdir /etc/nginx/ssl
$ chown root:root -R /etc/nginx/ssl/
$ chmod 700 /etc/nginx/ssl

以下のコマンド入力後、パスフレーズを聞かれるので任意のパスフレーズを入力する。
openssl genrsaは秘密鍵を生成するコマンドで、以下のコマンドでは暗号化方式に「des3」を使用し、2048ビットのRSA秘密鍵を作成する。
また秘密鍵を「private.key」というファイル名で保存する。

$ openssl genrsa -des3 -out private.key 2048

暗号化方式には「-aes128 | -aes192 | -aes256 | -des | -des3」のどれかが選べるが、正直どれが良いのかとかは分からない...
色んなサイトを見て多かった設定が「-des3」なのでとりあえずこの方式を選ぶ。

またサーバ再起動時に毎回パスフレーズを聞かれるのを避けるため、オリジナルはバックアップし、パスフレーズは秘密鍵から削除しておく。

$ cp private.key private.key.with_pass_phrase
$ openssl rsa -in private.key -out private.key

バックアップしたオリジナル秘密鍵は別の媒体にもバックアップしておけば、サーバトラブル時などで秘密鍵が失われてしまってもうまく対応できる。

2) CSR(証明書発行要求: Certificate Signing Request) の作成

上記の1)で作成した秘密鍵を指定し、以下のコマンドでCSRを作成する。

$ openssl req -new -key private.key -out server.csr
  • new: CSR新規作成
  • key: 秘密鍵を指定
  • out: CSRの出力先ファイル名を指定

コマンドを入力されると以下の項目を聞かれる。以下の項目以外は必須ではないので、Enterを押してスキップする。

Country Name・・・2文字の国コード (ex: JP)
State or Province Name・・・都道府県 (ex: Fukuoka)
Locality Name・・・市区町村 (ex: Hakata-city)
Organization Name・・・組織 (ex: 任意の組織名)
Organizational Unit Name・・・部署名(ex: Admin、Webmaster、System Team)
Common Name・・・SSL接続に使用するドメイン名 (ex: blog.example.jp)

Common Name は、SSL接続する際に使われるドメイン名(FQDN)を入力する
例えばhttps://blog.example.jp/page/というURLの場合、blog.example.jpを入力する
またワイルドカード証明書はサブドメイン名を「*」にする(例:*.example.jp)。
ワイルドカード証明書 CSR生成時の注意 | BestSSL


更新の際のことを考えて、上記の設定を記入した設定ファイルを読み込むことでも作成できる
OpenSSLによるSSL証明書の発行の準備 - Qiita

以下がCSRの内容を表示するコマンド

$ openssl req -in certreq.csr -text

3) サーバ証明書の取得

2)で作成したCSRをNamecheapに送信し、サーバ証明書を取得する。

Namecheapの設定するにあたり、以下のサイトさんを参考にさせてもらった。
SSL証明書を$9で購入し、Apacheサーバに設定してみました - たけぞうBLOG
Namecheapで$9のSSL(PositiveSSL)を購入してApache mod-sslに設定する | シドニーで働くプログラマーのBlog(今はIT会社の経営者)

手順は以下

(1) CSRをコピーする

Acount => Dashboard => Product Listから対象のSSLのActivateボタンを押す。

(2) Enter CSR箇所にCSRをペースト

ペーストすると、自動的に「Primary domain」の箇所が自動入力される。そして後Nextボタンを押す

(3) Server Typeを選択

自分の場合はNginx上に設定するので「Any other server (cPanel, Apache, NGINX, etc.)」を選択

(4) ドメイン管理者認証

証明書申請者がドメインの正式な所有者かどうかを認証する。方法は以下の3種類がある。

・メール認証
・HTTPベース認証
・DNSベース認証

上記の中では「メール認証」が一般的ではあるが、「Approver email」として指定できるのは当然のことながら「SSL証明書を設定するドメイン名」に紐付いたメールアドレスでないといけない。
ex) admin@example.com, administrator@example.com, postmaster@example.com, webmaster@example.com, hostmaster@example.com

本来ならばPostfixなどのメールサーバを予め設定しておいたり、Zohoメールなど設定を予め済ませておくのが良いのだろうが、
自分の場合は、未だにその設定をしていないため、このオプションは除外し、「DNSベース認証」を使用することにした。
この方法を選んだ場合、指定されたCNAMEレコードをDNSサーバに設定すればよいだけ。
ちなみにHTMLベースの認証は、指定されたファイルを特定のディレクトリに公開するという方法。
どっちでもよかったが、DNSベース認証のほうが、気持ち的に楽だったので、DNSベース認証にした。


ここで指定したメールアドレス宛に証明書が送られてくる



詳細は以下のページで。
How can I complete the domain control validation (DCV) for my SSL certificate? - SSL Certificates - Namecheap.com

10分ぐらいで、指定してメールアドレス宛に証明書が発行された旨のメールが届いた。
メールにはzipファイルが添付されており、解凍すると以下のファイルが入っている。

・ドメイン名.ca-bundle (ルート証明書と中間証明書が連結されたファイル。詳細:
What is CA bundle? - SSL Certificates - Namecheap.com
)
・ドメイン名.crt (SSL証明書)

またメール添付されているzipファイルはNamecheapの管理画面でいつでもダウンロード可能。
ちなみに中間証明書については以下のサイトさんの説明が良かった。

https://knowledge.digicert.com/ja/jp/solution/SO22877
秘密鍵は削除したらダメ?!SSL化に必要なファイルの種類を詳しく解説 | さくらのSSL

4) 秘密鍵と証明書を設置し、Nginx設定変更する

まずは3)で取得したca-budleファイルとcarファイルを連結する。
やり方は以下のサイトを参照。
Installing an SSL certificate on Nginx - Hosting - Namecheap.com

$ cat your_domain.crt your_domain.ca-bundle >> your_domain_chain.crt

その後、1)の秘密鍵と、証明書を連結したファイルをサーバに設置し、Nginxの設定をそれに併せて変更する。

server {
    listen 80;
    server_name example.com;
    # httpsにリダイレクト処理
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    # 自己署名証明書
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    # 暗号化鍵
    ssl_certificate_key /etc/nginx/ssl/private.key;
}

最後に秘密鍵や証明書が入っているディレクトリ内のファイル全てに対し権限設定を行う。

$ chmod 600 /etc/nginx/ssl/*

[参考]
NginxでSSL(HTTPS)設定!オレオレ(自己署名)証明書を作成しよう! | キツネの惑星
自己証明書でnginxにSSL(TLS)対応する - Qiita

備考

自己署名証明書(オレオレ証明書)の作成方法
以下のサイトを参考
CentOS7.2 64bit OpenSSLを使用して秘密鍵と自己署名のSSLサーバー証明書を同時に作成 - Kakiro-Web カキローウェブ

以下のコマンドだけで、秘密鍵と証明書を生成してくれる。

$ openssl req -x509 -newkey rsa:2048 -nodes -keyout server.key -sha256 -days 3650 -out server.crt

※3650というのは、期限なので、この場合は10年という事になる

また対話形式の質問は「Common Name」以外は全てEnterでスキップしてもOK

ちなみにMac Catalina経由でChromeからアクセスすると、「NET::ERR_CERT_INVALID」のエラーが表示されるようになった。
以下のサイトさんのように、Safari経由で見ることで、証明書をキーチェーンにダウンロードし、その設定を「常に信頼」へ変更することで
アクセスできるようになる。

macOS CatalinaでChromeからオレオレ証明書のHTTPSサイトにアクセスできない場合の対処法 - Qiita
https://sig9.hatenablog.com/entry/2020/01/04/000000
Self-Signed SSL Certificate - Luke Armstrong


[その他参考]
SSLって何?意味や仕組みをわかりやすく解説! | さくらのSSL
https://help.arena.ne.jp/hc/ja/articles/360039176533-CSR%E3%81%AE%E4%BD%9C%E6%88%90%E6%96%B9%E6%B3%95%E3%81%8C%E7%9F%A5%E3%82%8A%E3%81%9F%E3%81%84-VPS%E5%85%A8%E8%88%AC-
個人でSSL証明書を取得してHTTPS化してみた話 | 😁planet-green.com
秘密鍵は削除したらダメ?!SSL化に必要なファイルの種類を詳しく解説 | さくらのSSL

↓ Apacheの場合
さくらのSSLで、SSL証明書を取得してHTTPS対応 – gomokulog