nginxとLet's Encryptで1台のサーバーで複数のサイトをSSL化する

  • 20
    いいね
  • 0
    コメント

ここではLet's Encryptとnginxを使ってサイトをSSL化する方法と、さらにそのままnginxの機能を使って1台のサーバーで複数のサイトを運営し、それらのすべてSSL化した時にやったことをご紹介します。
nginxの設定ファイルを公開しましたので、詳細はこちらを参照してください。
https://github.com/TakuKobayashi/ActivatingNginxConf

SSLとは

SSLとはデータを暗号化して通信を行う仕組みです。
SSLを使うことができるようにすると、URLに以下のようにhttps://であったり(HTTPの場合)、wss://(Websocketの場合)といったURLを使うことができるようになります。
https.png

詳しくはこちらなど

SSL証明書

サーバーをSSLに対応させて通信を行えるようにするためにはSSL証明書というものが必要です。
SSL証明書は一般的に認証局と呼ばれる、信頼された第三者からお金を払って証明書を発行してもらう必要があります。
費用は年間数万円〜数十万円です。
高いです...

Let's Encryptとは

Let's EncryptとはSSL証明書を無料で発行してくれる認証局(団体・プロジェクト)です。

Let's Encryptを用いてSSL証明書を取得する

Let's Encryptを用いてSSL証明書を取得するにはPython2.7以上が入っている必要があるので、Python2.7以上をインストールする。
Pythonのバージョンを切り替えられるように、私はPyenvを入れた後Pythonをインストールしました。

Pythonをインストール

Pyenvを使うために必要なライブラリなどをインストール(CentOSの場合)

yum install gcc gcc-c++ make git openssl-devel bzip2-devel zlib-devel readline-devel sqlite-devel bzip2 sqlite
zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel

Pyenvをインストール

git clone git://github.com/yyuu/pyenv.git

Pyenvにパスを通す

cd pyenv/
vi ~/.bashrc

.bashrcにpyenvのある場所を調べて(ここでは/app/library/pyenvにある)、以下のように記述してパスを通す。

export PYENV_ROOT="/app/library/pyenv"
if [ -d "${PYENV_ROOT}" ]; then
    export PATH=${PYENV_ROOT}/bin:$PATH
    eval "$(pyenv init -)"
fi

設定したパスを有効にする。

source ~/.bashrc

そして

pyenv

を実行し、エラーが出なければパスが通りました。

インストール可能なPythonのバージョンを調べる

pyenv install --list

Pyenvを使ってPythonをインストール

ここではPython2.7.13をインストールします

pyenv install 2.7.13

インストールしたPythonを使えるようにする

pyenv global 2.7.13

これで

python

を実行し、エラーが出なければインストール完了です。

Let's EncryptからSSL証明書を取得する

証明書の確認のための専用のパスを作成する

この後行うcertbotを使って証明書を取得する際、サーバーが存在するか、チェックが行われます。このチェックに対応するために専用のパスを作成する必要があります。
今回はドキュメントルート以下にディレクトリを作成することで対応します。
Nginxを使います
Nginxの場合、ドキュメントルートは[nginxのルートディレクトリ]/conf.d/default.confで確認できます。今回の場合は以下に記載されている内容です。

 location / {
   root   /usr/share/nginx/html;
   index  index.html index.htm;
 }

よって以下のようにドキュメントルートからパスを設定するために空のディレクトリを作成します。

mkdir [nginxのルートディレクトリ]/html/.well-known

次に、作成したパスをnginx側で使えるようにするために、[nginxのルートディレクトリ]/nginx.confを編集します。

http{
  ...
  server {
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
  }
}

その後、nginxを再起動して、変更内容を適用させます。

service nginx restart

certbotを(Gitを使って)インストールする

certbotとはLet’s Encrypt が提供しているツールであり、Let’s Encrypt と通信するエージェント(クライアント)です。
Gitを使わない方法もありますが今回はGitを使った方法でインストールします。

git clone https://github.com/certbot/certbot

certbotを使って証明書を取得する

cd certbot/
./certbot-auto certonly

とすると以下のようなアナウンスがあるので各種設定していく。

How would you like to authenticate with the ACME CA?

1: Spin up a temporary webserver (standalone)

2: Place files in webroot directory (webroot)

Select the appropriate number [1-2] then enter: 2
Enter email address (used for urgent renewal and security notices) (Enter 'c' to

cancel):[メールアドレス]

Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree
in order to register with the ACME server at

https://acme-v01.api.letsencrypt.org/directory

(A)gree/(C)ancel: A



Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and

our work to encrypt the web, protect its users and defend digital rights.

(Y)es/(N)o: Y
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel):[ドメイン名](複数ドメイン設定したい場合は、カンマ区切りで列挙していきます。ここでは ue4yochi.net と設定します)
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for ue4yochi.net

Select the webroot for ue4yochi.net:

1: Enter a new webroot

Press 1 [enter] to confirm the selection (press 'c' to cancel): 1
Input the webroot for ue4yochi.net: (Enter 'c' to cancel):[上記で作成したディレクトリのパス]

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/ue4yochi.net/fullchain.pem. Your cert will
   expire on 2017-10-03. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot-auto again. To
   non-interactively renew all of your certificates, run
   "certbot-auto renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

以上で、
/etc/letsencrypt/live/[ドメイン名]/
fullchain.pemprivkey.pem のファイルがあれば証明書を取得完了です。

取得した証明書を適用し、SSLを有効にする。

nginx.confファイルを以下のように編集します。

http{
  ...
  server {
    listen 443 ssl;
        server_name ドメインA;
    ...
    ssl_certificate     /etc/letsencrypt/live/[ドメイン名]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[ドメイン名]/privkey.pem;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
  }
}

その後、nginxを再起動して、変更内容を適用させます。

service nginx restart

これでサーバーが稼働していれば、
https://ドメインAにブラウザでアクセスすることができれば、SSL化完了です。

nginxを使って一台のサーバーで複数のサイトを運用し、かつ全てをSSL化

上記のnginxでのSSL化対応は1台のサーバーで複数のサイトを運用しようとする場合にも適用させることができます。
あまり、お金かけたくないので1台のサーバーで複数サイト運営できたらいいですよね♪
しかも、全てSSLに対応できたらうれしいですね♪
ただし、1台のサーバーで複数のサイトを運営するためには、ドメインを1個以上必要です。

nginxで1台のサーバーで複数のサイト(異なるドメイン)を運用する設定

ここまでで、すでにひとつのサイトの設定は完了しています。
まずは、2個目のサイトをcertbotで証明書を取得できるように、1個目同様にチェック可能なパスを作成します。
1個目の場合と同じものを使うこともできますが、それぞれ設定する必要があります。
以下のようにnginxの設定ファイルを記述します。

http{
  ...
  server {
    listen 443 ssl;
        server_name ドメインA;
    ...
    ssl_certificate     /etc/letsencrypt/live/[ドメイン名]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[ドメイン名]/privkey.pem;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
  }

  server {
    listen 443 ssl;
        server_name ドメインB;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
}

その後、nginxを再起動して、変更内容を適用させます。

service nginx restart

複数サイトで使えるSSL証明書の発行

上記の証明書取得手順と同様に以下のように入力する。

./certbot-auto certonly

この場合、すでに証明書を取得しており、新たにドメインを取得して証明書を追加する場合も同様に実行すれば適用できます。
出てきたアナウンスを読み進めていき、

...
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel):ドメインA,ドメインB,...
...

以上の質問がされたところで、複数種類のドメインを,で区切って並ることで複数のドメインに対応した証明書を発行することができます。
設定の際にそれぞれ、チェックする場所を尋ねられますが、同じものを指定するのでOKです。

nginxで取得した証明書をそれぞれに適用させる。

複数ドメインに対応した証明書は上記1個目の場合と同じ場所に同じファイルに設定されているので、複数のドメインに適用させる場合も同様になるようにnginx.confを以下のように修正します。

http{
  ...
  server {
    listen 443 ssl;
        server_name ドメインA;
    ...
    ssl_certificate     /etc/letsencrypt/live/[ドメイン名]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[ドメイン名]/privkey.pem;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
  }

  server {
    listen 443 ssl;
        server_name ドメインB;
    ssl_certificate     /etc/letsencrypt/live/[ドメイン名]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[ドメイン名]/privkey.pem;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
  }
}

その後、nginxを再起動して、変更内容を適用させます。

service nginx restart

これでサーバーが稼働していれば、
https://ドメインA
および
https://ドメインB
にブラウザでアクセスすることができれば、両方共SSL化完了です。

補足

上記の1台のサーバーで複数の異なるドメインを見ることができる設定をした場合、nginx.confに記述した上の方の設定が優先されます。例えば、以下のURLを入力した場合
https://[IPアドレス]

https://[DNS名]
を入力した場合、ドメインAのサイトが表示されます。

SSL証明書の自動更新

Let's Encryptで取得した証明書の有効期限は3ヶ月です。
よって、有効期限が切れる前に証明書の更新が必要です。
証明書の更新を自動で行う場合、cronを設定しておくことで自動的に更新させることができます。

crontab -e

でcronの設定を開き、以下のように設定します。

0 4 1 * * [certbot-autoがあるpass]/certbot-auto renew && service nginx reload

これでSSL証明書の更新及びnginxに設定を反映させる処理を自動的に行うことができます。
(上記の処理は1ヶ月に1回、証明書の更新がないか確認する)

参考

Nginx+リバースプロキシ環境でWebサーバを停止させずに Let's Encrypt (Certbot) のSSL証明書を自動更新する - Qiita
Nginxをリバースプロキシとして使ってるところにLet'sEncryptしようとしたらはまった話 - Qiita
Nginxで起動中のサーバーにLet's Encryptを導入してSSL証明書を発行する - UTALI
Let's Encrypt+NginxでSSL証明書発行、自動更新の設定方法 - Qiita
光の速さのWEBサーバー(nginx)をlet's encryptでSSL化及びHTTP/2化。ついでにセキュリティ評価をA+にする。 - Qiita
Let’s EncryptのSSL証明書で、安全なウェブサイトを公開 - さくらのナレッジ