Let's Encryptってなに?

非営利団体の ISRG (Internet Security Research Group) が運営している「SSL/TLSサーバ証明書」を無料で発行するサービスです。シスコ(Cisco Systems)、Akamaiなど大手企業がスポンサーとなっています。2016年6月に400万枚を超える証明書発行枚数となっています。

Let's Encrypt Stats

Let's Encryptの特徴

  • 無料でSSL証明書を発行してくれるサービスです
  • 米大手認証局(CA)である IdenTrust のルート証明書によってクロス署名されているので、ほとんどのブラウザに対応している
  • 即時発行可能
  • 有効期限は90日間(更新可能)
  • 証明書のタイプはドメイン認証のみ(EV証明書の発行する予定はありません)
  • ワイルドカードの証明書は発行不可(将来的にはワイルドカード証明書を発行するようになるかも)

Let’s Encryptは万能か?

ドメイン認証のみなので、商用サイトには向きません。しかし、常時SSL化が当たり前となっている昨今、個人Blogや、無料のWebサービスを提供するときには大活躍です。有効期限が短いので、自動更新を前提としたサービスとなっています。ロードバランサーのI/Fが無くて自動更新が出来ない!というようなケースがありますが、そのような場合はおとなしく有料証明書を使用しましょう。

参考:有料証明書の価格比較(2017.05 時点)

SSL証明書発行ブランド ドメイン認証 企業認証 EV認証
1年 2年 3年 1年 2年 3年 1年 2年
DigiTrust ¥14,000 ¥25,200 ¥35,700
EcoCert ¥2,000 ¥3,600 ¥5,400
日本ベリサイン ¥49,800 ¥99,000 ¥126,500 ¥229,000
RapidSSL ¥4,300 ¥7,525 ¥10,750
SECOM ¥55,000 ¥104,500 ¥156,750 ¥135,000
GlobalSign(旧GeoTrust) ¥34,800 ¥66,000 ¥96,400 ¥59,800 ¥114,000 ¥167,000 ¥128,000 ¥244,000
日本コモド ¥9,600 ¥17,200 ¥22,900 ¥25,800 ¥45,800 ¥61,500 ¥71,500 ¥127,000
Starfield ¥10,000 ¥19,000 ¥27,000 ¥25,000 ¥47,500 ¥67,500 ¥35,000 ¥63,000

CentOS6+Apacheの設定

Let's Encryptをgit clone

cd /usr/local/src
git clone https://github.com/certbot/certbot

Python 2.7 環境をインストール

sudo yum install centos-release-scl
sudo yum install python27 python27-python-tools
sudo scl enable python27 bash

SSL証明書を発行

./letsencrypt-auto certonly --renew-by-default --webroot -w ${DOCUMENT_ROOT} -d ${DOMAIN}

/etc/letsencrypt/live/ドメイン名/
に証明書が出力されます。

apacheのSSL設定を下記のように編集します。
SSLCertificateFile /etc/letsencrypt/live/ドメイン名/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/ドメイン名/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/ドメイン名/chain.pem

SSL証明書の自動更新スクリプト

#!/bin/sh
 
# update resource
cd /usr/local/src/certbot
git stash clear
git stash
git pull
 
# create SSL certification
source /opt/rh/python27/enable
./letsencrypt-auto certonly --renew-by-default --webroot -w ${DOCUMENT_ROOT} -d ${DOMAIN}
 
# apache restart
/etc/init.d/httpd restart

注意点:有効期限が残り1ヶ月未満にならないと証明書の更新が行われないので、cron設定を調整してください。また7日間に5回までの実行制限が掛かっているので実行し過ぎないように注意しましょう。

SSL証明書の有効期限確認スクリプト

自動更新に失敗する可能性もあるので、下記のようにSSL証明書のチェックをSlack通知するように設定してみました。URLとTARGETSのところを書きかえて使用します。

#!/bin/sh
set -eu
 
# WebHookのURL
URL=''
# 送信先のチャンネル
CHANNEL=${CHANNEL:-'#cert-check'}
# botの名前
BOTNAME=${BOTNAME:-'cert-check-bot'}
# 絵文字
EMOJI=${EMOJI:-':lock:'}
 
## validate_certs - Check SSL certificate expiration date
WARN_DAYS=15
TARGETS=(
    "www.example.com"
)
 
function show_enddate()
{
    echo "" | openssl s_client -connect $1:443 2> /dev/null | openssl x509 -enddate -noout | sed 's/not
After\=//'
}
 
echo "SSL Certificate Expiration Checking ($(date -R))"
 
i_now=$(date "+%Y%m%d%H%M%S")
i_warn=$(date -d "$WARN_DAYS days" "+%Y%m%d%H%M%S")
for host in ${TARGETS[@]}; do
    enddate=$(LANG=C date -d"$(show_enddate $host)")
    i_enddate=$(date -d"$enddate" "+%Y%m%d%H%M%S")
    message=""
    if [ $i_now -ge $i_enddate ]; then
        message="[SEVERE]\n $host already expired on $enddate"
    elif [ $i_warn -ge $i_enddate ]; then
        message="[WARN]\n $host will expire on $enddate"
    fi
 
    if [ "$message" != "" ]; then
        # json形式に整形
        payload="payload={
            \"channel\": \"${CHANNEL}\",
            \"username\": \"${BOTNAME}\",
            \"icon_emoji\": \"${EMOJI}\",
            \"text\": \"${message}\"
        }"
        # 送信
        curl -s -S -X POST --data-urlencode "${payload}" ${URL} > /dev/null
    fi
done

参考:
SSL証明書の有効期限を確認するスクリプト
シェルスクリプトでSlackに通知を送る方法

あとがき

Let's Encryptを使ってみたものの、共有資料を作っていなかったので、ブログ形式で残すことにしました。ググると参考資料が一杯出てきますが、この記事が誰かの役に立てれば幸いです。

リバークレインでは、システムエンジニアを募集しています。