【CentOS + Apache】Let’s Encryptで無料SSL証明書の取得&自動更新をする


■環境

CentOS 7.3
Apache 2.4.6


Let’s Encryptで無料SSL証明書を取得し、自動更新する設定をします。

########## 2017/04/05追記 ##########
Certbotというツールが公開されており、
本手順を実施するよりも、そちらを利用した方が簡単です。
https://certbot.eff.org
設定方法はこちら
【Let’sEncrypt】Certbotの使い方(CentOS7 + nginx)
################################

■前提

対象サーバがインターネット網に公開しているサーバであること。
→証明書発行時に認証のためLet’s Encrypt側からアクセスがあるようです。
 そのため、ファイアーウォールなどで外部からのアクセスを遮断している環境では証明書発行ができません。
 2017/1/19現在、アクセス時のIPアドレスも公開しておりません。
 https://letsencrypt.jp/faq/#IP

設定手順

※以下手順はroot権限で実施しています。

まず、サーバー上の任意のディレクトリにLet’s Encryptから証明書を取得するツールをダウンロードします。
サーバにgitが入っていない場合は、ローカルでダウンロードしたものをFTPなどでアップしても良いと思います。

# git clone https://github.com/letsencrypt/letsencrypt

ダウンロードしたら、ツールの初期構築をします。
以下コマンドにて必要なソフトウェアのインストールなどが走り、完了したらletsencrypt-autoのヘルプが表示されます。

# cd letsencrypt  
# ./letsencrypt-auto --help --debug

次にツールを実行し、実際に証明書を取得します。
その際、443ポートを利用しているプロセスがあるとエラーとなるので、この瞬間はApacheを止める必要がありました。

# systemctl stop httpd  
# ./letsencrypt-auto certonly --standalone -d your-domain.com  
# systemctl start httpd

※上記の「your-domain.com」には証明書を生成するドメインを入力してください。

これで証明書が生成できました。
以下のディレクトリ配下に証明書や秘密鍵(のシンボリックリンク)が生成されているので、
Apacheの設定ファイルへ記載します。
■生成されるディレクトリ

/etc/letsencrypt/live/your-domain.com/

■生成されるファイル

cert.pem : SSL証明書本体  
chain.pem : チェイン証明書  
fullchain.pem : SSL証明書本体とチェイン証明書を結合したもの  
privkey.pem : 秘密鍵

これらをApacheの設定ファイル(一般的に/etc/httpd/conf.d/ssl.conf)に設定する。
・設定パターン1

SSLCertificateFile /etc/letsencrypt/live/your-domain.com/cert.pem  
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem  
SSLCertificateChainFile /etc/letsencrypt/live/your-domain.com/chain.pem

・設定パターン2

SSLCertificateFile /etc/letsencrypt/live/your-domain.com/cert.pem  
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem  
SSLCertificateChainFile /etc/letsencrypt/live/your-domain.com/chain.pem

※Apacheのバージョンが2.4.8以上の場合は「SSLCertificateChainFile」の設定はできないので、
 「SSLCertificateKeyFile」にfullchain.pemを設定すること。

ここで生成した証明書は3ヶ月間しか有効期限がないので、定期的に更新が必要です。
証明書を更新するコマンドは以下です。

./letsencrypt-auto renew

ただし、更新は有効期限が残り30日を切らないと実行されないらしく、
上記コマンドを実行しても何も更新せずに終わります。

「Apache停止→証明書更新→Apache起動」を実施するシェルを作ります。
70日以内に生成した証明書が存在する場合は何もしません。

#!/bin/bash  
serchResult=`find /etc/letsencrypt/archive/your-domain.com/ -mtime -70 -regex ".*cert[0-9]?\.pem"`  
if [ -n "$serchResult" ]; then  
    echo "certs are not due for renewal yet"  
else  
    systemctl stop httpd && /opt/git/letsencrypt/letsencrypt-auto renew && systemctl start httpd  
    if [ $? != 0 ]; then  
        # just to be sure  
        systemctl restart httpd  
    fi  
fi

※上記はツールをopt配下に配置した場合です。

このシェルをcronで毎日深夜に実行するよう設定します。

# SSL update  
5 0 * * * sh /etc/letsencrypt/renew.sh

※上記はシェルを/etc/letsencrypt/renew.shに作った場合の例です。

これで設定完了です。