EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

さくらウェブアクセラレータで使うドメインのSSL証明書更新

弊社ではサイトのCDNとして「さくらウェブアクセラレータ」を利用していて、そのドメインの証明書はLet's Encryptで発行しています。 Let's Encryptの証明書は有効期限が90日なので、3ヶ月に一度くらい証明書の入れ替えが必要です。

運用を始めた頃は、実体のサーバーがCDNの背後にあるので、証明書発行を毎回DNS認証で行なっていたのですが、良く考えたらACMEでも認証tokenは毎回発行されるので、オリジンサーバー上でcertbotを実行することで発行することができるなあと思いました。

ネットで色々と調べて、結果、証明書の入れ替えまでを自動化できたので、その方法を記事にしたいと思います。

Let's Encryptの証明書発行

ACMEのためのwebサーバー設定

弊社のサイトのフロントエンドはnginxを使用しているのですが、ACMEのために.well-knownフォルダにアクセスできるようにオリジンサーバーのnginxのconfに以下の設定を追加します。

location /.well-known {
  root /var/www/nginx/certbot;
}

証明書発行

オリジンサーバー上で、以下のコマンドを実行します。

certbot-auto certonly --webroot -w /var/www/nginx/certbot -d ドメイン名 -m root@eatsmart.co.jp --agree-tos -n

これで、オリジンサーバーの/etc/letsencrypt/live/ドメイン名配下に証明書と鍵が生成されます。

証明書更新

さくらウェブアクセラレータのAPIを使用することで、証明書の更新を自動化することができます。

参考)
公開API | さくらのクラウド ドキュメント

まずは、以下のURLからAPIキー(アクセストークン、トークンシークレット)を発行する必要があります。

SAKURA internet Cloud - Home

サイトID取得

初回は、まず操作対象のサイトIDを取得する必要があります。 サイトIDは、以下のコマンドで確認できます。

$ curl -X GET --user "アクセストークン":"トークンシークレット" \
https://secure.sakura.ad.jp/cloud/zone/is1a/api/webaccel/1.0/site
{
    "Total": 3,
    "From": 0,
    "Count": 3,
    "Sites": [
        {
            "Index": 0,
            "ID": "XXXXXXXXXXXXXX",
            "Name": "cdn1.esimg.jp",
            "Domain": "cdn1.esimg.jp",
            "DomainType": "own_domain",
・・・
    ],
    "is_ok": true
}
(JSONを整形しています)

このIDの値を使用します。

証明書更新

更新は以下のコマンドでできます。

curl -X PUT --user  "アクセストークン":"トークンシークレット" \
https://secure.sakura.ad.jp/cloud/zone/is1a/api/webaccel/1.0/site/113000168864/certificate \
-d "{\"Certificate\": { \"CertificateChain\": \"$(perl -pe 's/\n/\\n/' /etc/letsencrypt/live/ドメイン名/fullchain.pem | perl -pe 's/\\n$//')\", \"Key\": \"$(perl -pe 's/\n/\\n/' /etc/letsencrypt/live/ドメイン名/privkey.pem | perl -pe 's/\\n$//')\" }}"

まとめ

上のふたつをまとめ、以下のようなシェルを作って更新するようにしました。

$ cat replace_cdn_cert.sh
#!/bin/sh

TARGET=$1
SITE_ID=$2
echo 'target:'$TARGET
echo 'siteId:'$SITE_ID

certbot-auto certonly --webroot -w /var/www/nginx/certbot -d $TARGET -m root@eatsmart.co.jp --agree-tos -n

curl -X PUT --user "アクセストークン":"トークンシークレット" \
https://secure.sakura.ad.jp/cloud/zone/is1a/api/webaccel/1.0/site/$SITE_ID/certificate \
-d "{\"Certificate\": { \"CertificateChain\": \"$(perl -pe 's/\n/\\n/' /etc/letsencrypt/live/$TARGET/fullchain.pem | perl -pe 's/\\n$//')\", \"Key\": \"$(perl -pe 's/\n/\\n/' /etc/letsencrypt/live/$TARGET/privkey.pem | perl -pe 's/\\n$//')\" }}"

$ ./replace_cdn_cert.sh cdn1.esimg.jp XXXXXXXXXXXXXX

これで、証明書更新の通知が憂鬱ではなくなりました!