Railsアプリのnginxを導入した、CentOS7 の環境で無料のSSL「Let's Encrypt」の導入を試してみました。
★関連記事
CentOS7 + Apache2.4 を 無料 の SSL 「Let’s Encrypt」でSSL化
CentOS6 + Apache2 を無料のSSL「Let’s Encrypt」でSSL化
「Let's Encrypt」の詳細や暗号強度などは上記のページで。
インストール
Let's Encryptで使うクライアントツールはACMEプロトコルに対応したCertbotというクライアントが必要です。
http://jxck.hatenablog.com/entry/letsencrypt-acme
CentOS7ではApache用のCertbotクライアントは、EPELリポジトリからインストールすることができます。
以下ではEPELのリポジトリも導入していますが、設定済みの方は上の行は必要ありません。
1 2 3 4 |
# yum -y install epel-release # yum -y install certbot python-certbot-nginx |
尚、nginx.conf は unicorn と連動させるため以下のようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
server { client_max_body_size 200M; listen 80; root /var/local/アプリ名/public; server_name ドメイン; location / { proxy_set_header X-Forwarded-Proto $scheme; if (-f $request_filename) { break; } proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass http://rails-unicorn; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/www; } } |
ここでcertbot コマンドを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# certbot certonly --non-interactive --agree-tos --webroot -w /var/local/アプリ名/public -d ドメイン名 --email foo@bar.jp Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org Obtaining a new certificate Performing the following challenges: http-01 challenge for ドメイン名 Using the webroot path /var/local/アプリ名/public for all unmatched domains. Waiting for verification... Cleaning up challenges Failed authorization procedure. ドメイン名 (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://ドメイン名/.well-known/acme-challenge/PiUlQ4yn0tqiLyvFrK8BpInTMCTgcWJdtsjkE53AJk0: "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html " IMPORTANT NOTES: - The following errors were reported by the server: Domain: ドメイン名 Type: unauthorized Detail: Invalid response from http://ドメイン名/.well-known/acme-challenge/PiUlQ4yn0tqiLyvFrK8BpInTMCTgcWJdtsjkE53AJk0: "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html " To fix these errors, please make sure that your domain name was entered correctly and the DNS A/AAAA record(s) for that domain contain(s) the right IP address. - 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. |
nginx.confで設定した「root /var/local/アプリ名/public」をディレクトリに設定したので失敗しました。
「http://ドメイン名/.well-known/acme-challenge/PiUlQ4yn0tqiLyvFrK8BpInTMCTgcWJdtsjkE53AJk0」のページが上記のrootパスに置いたファイルで見えないと言われています。
確かにドキュメントルートは「http://ドメイン名/public」として見えますので上のコマンドではNGですね。
certbot コマンドで証明書ファイルを作る前提は以下になります。
- 設定するSSLのドメインの名前で公開されている
- コマンドで作成した「.well-known」というフォルダのファイルを見て正当性をチェックしている
ということで、nginx.confに以下を追記しnginxを再起動します。
1 2 3 4 5 |
location ^~ /.well-known/acme-challenge/ { root /usr/share/nginx/html; } |
1 2 3 |
# systemctl restart nginx.service |
こちらの状態でディレクトリを「/usr/share/nginx/html」に変えてcertbot コマンドを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# certbot certonly --non-interactive --agree-tos --webroot -w /usr/share/nginx/html -d ドメイン名 --email foo@bar.jp Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org Obtaining a new certificate Performing the following challenges: http-01 challenge for ドメイン名 Using the webroot path /usr/share/nginx/html for all unmatched domains. upstream rails-unicorn { Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/ドメイン名/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/ドメイン名/privkey.pem Your cert will expire on 2019-02-02. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - 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 |
無事成功しています。
SSLを有効にするため、nginx.conf を書き換えてnginxの再起動を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
server { client_max_body_size 200M; listen 80; listen 443 default ssl; root /var/local/アプリ名/public; server_name ドメイン名; ssl_certificate /etc/letsencrypt/live/ドメイン名/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem; location / { proxy_set_header X-Forwarded-Proto $scheme; if (-f $request_filename) { break; } proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass http://rails-unicorn; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/www; } location ^~ /.well-known/acme-challenge/ { root /usr/share/nginx/html; } } |
自動更新の設定
最後に「Let's Encrypt」では証明書は90日で切れてしまいますので、cron などで定期的なクライアントのインストールを実行します。
1 2 3 4 5 6 |
# crontab -e -----------------------------追加 30 2 * * * /usr/bin/certbot renew >> /var/log/le-renew.log && systemctl reload nginx ----------------------------- |
上記のコマンドで証明書の有効期限が30日以内になると、再インストールを行います。
こちらで設定は完了です。
このブログは株式会社CoLabMixによる技術ブログです。
GCP、AWSなどでのインフラ構築・運用や、クローリング・分析・検索などを主体とした開発を行なっています。
Ruby on RailsやDjango、Pythonなどの開発依頼などお気軽にお声がけください。
開発パートナーを増やしたいという企業と積極的に繋がっていきたいです。