ここではLet's Encryptとnginxを使ってサイトをSSL化する方法と、さらにそのままnginxの機能を使って1台のサーバーで複数のサイトを運営し、それらのすべてSSL化した時にやったことをご紹介します。
nginxの設定ファイルを公開しましたので、詳細はこちらを参照してください。
https://github.com/TakuKobayashi/ActivatingNginxConf
SSLとは
SSLとはデータを暗号化して通信を行う仕組みです。
SSLを使うことができるようにすると、URLに以下のようにhttps://
であったり(HTTPの場合)、wss://
(Websocketの場合)といったURLを使うことができるようになります。
詳しくはこちらなど
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.pem と privkey.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証明書で、安全なウェブサイトを公開 - さくらのナレッジ