MENU

さくらのウェブアクセラレータにおけるSSL自動更新

今回は、さくらのウェブアクセラレータへのSSL証明書アップロードを自動化してみます。
前提として、ウェブアクセラレータの標準機能として、Let’s EncryptによるSSL証明書の自動取得・更新が可能です。
ですが、各認証局で発行されたSSL証明書をウェブアクセラレータに更新させたい場合は、
現時点では手動によるアップロードしかないので、さくらのAPIを通して自動化を行いたいと思います。

※本記事ではcertbotによるSSL証明書の発行方法やAPIキーの発行方法は案内していないので、
発行方法はこちらの記事を参考にしてください。
また、発行したAPIキーに「さくらのウェブアクセラレータ」のアクセス権を付与してください。

目次

ウェブアクセラレータの作成

さくらのクラウドのホーム画面より、「さくらのウェブアクセラレータ」をクリックします。

左タブの「サイト追加」をクリックし、必要事項を入力し、サイトを作成。
ドメインやオリジンサーバは、環境に併せて入力してください。

作成されたら、リソースIDという、ウェブアクセラレータの識別子が発行されるので、控えておきます。

SSL証明書の手動アップロード

certbotでSSL証明書を発行しているサーバ上で、下記コマンドを実施して、リクエストが通るか確認します。
このとき、APIキー発行時に取得した「アクセストークン」と「アクセストークンシークレット」及びウェブアクセラレータのリソースIDを指定してください。

# curl -sS -u "アクセストークン":"アクセストークンシークレット" \
> https://secure.sakura.ad.jp/cloud/zone/is1a/api/webaccel/1.0/site/リソースID/certificate

{"Certificate":[],"is_ok":true}

証明書はないので、”is_ok”:trueと表示されていれば、動作は問題ないです。

では、適用したい証明書と秘密鍵を指定して、実際にアップロードしてみましょう。
certの後にはサイト証明書と中間証明書が連結している証明書パス(certbot標準ではfullchain.pem)、keyの後には秘密鍵パス(certbot標準ではprivkey.pem)を入力してください。

# jq -n \
--rawfile cert /etc/letsencrypt/live/tnagai-wp.click/fullchain.pem \
--rawfile key /etc/letsencrypt/live/tnagai-wp.click/privkey.pem \
'{
    "Certificate": {
      "CertificateChain": $cert,
      "Key": $key
    }
  }' \
| curl -sS \
-u "アクセストークン":"アクセストークンシークレット" \
-H "Content-Type: application/json" \
-X POST \
--data-binary @- \
https://secure.sakura.ad.jp/cloud/zone/is1a/api/webaccel/1.0/site/リソースID/certificate


{"Certificate":{"Current":{"ID":"19378","SiteID":"113801001595","CertType":"0","CertificateChain":"-----BEGIN CERTIFICATE-----

・・・・(証明書が出力されるため、略)

"SerialNumber":"05:15:AC:6E:1E:C1:EA:39:1E:1A:31:DC:A9:CA:B6:05:12:23","NotBefore":"1775190836000","NotAfter":"1782966835000","Issuer":{"Country":"US","Organization":"Let\u0027s Encrypt","OrganizationalUnit":"","CommonName":"E8"},"Subject":{"Country":"","Organization":"","OrganizationalUnit":"","Locality":"","Province":"","StreetAddress":"","PostalCode":"","SerialNumber":"","CommonName":"tnagai-wp.click"},"DNSNames":["tnagai-wp.click","www.tnagai-wp.click"],"SHA256Fingerprint":"59:19:D0:42:85:1B:53:B2:02:DE:95:C5:A7:77:31:4D:95:CC:44:06:D3:9A:8F:4E:EF:44:12:BF:DA:9C:EE:00","CreatedAt":"2026-05-04T16:21:34+09:00","UpdatedAt":"2026-05-04T16:21:34+09:00"}},"Success":"Created","is_ok":true}

“Success”:”Created”,”is_ok”:trueのように表示されていれば、問題なくアップロードできています。

ウェブアクセラレータのCNAME先をドメインのALIASレコードに設定し、ウェブアクセラレータを有効化したところ、
無事にhttpsでの通信が可能になりました。

今回はlet`sの証明書を適用しているので、意味がないと言えばないですが…

自動化スクリプト

手動でのアップロードが検証できたので、証明書更新時に自動的にアップロードするスクリプトを作成しました。

スクリプト本体(webaccel-cert-upload.sh)
#!/usr/bin/env bash
set -Eeuo pipefail

PATH=/usr/sbin:/usr/bin:/sbin:/bin

CONFIG_FILE="/etc/letsencrypt/.key/config"
NETRC_FILE="/etc/letsencrypt/.key/netrc"
API_BASE_URL="https://secure.sakura.ad.jp/cloud/zone/is1a/api/webaccel/1.0"
LOG_TAG="sakura-webaccel-cert-upload"

if [ ! -r "$CONFIG_FILE" ]; then
  logger -t "$LOG_TAG" "ERROR: config file is not readable: $CONFIG_FILE"
  exit 1
fi

if [ ! -r "$NETRC_FILE" ]; then
  logger -t "$LOG_TAG" "ERROR: netrc file is not readable: $NETRC_FILE"
  exit 1
fi

# shellcheck disable=SC1090
. "$CONFIG_FILE"

: "${SAKURA_WEBACCEL_SITE_ID:?SAKURA_WEBACCEL_SITE_ID is required}"

LINEAGE="${RENEWED_LINEAGE:-${SAKURA_LINEAGE_PATH:-}}"
DOMAINS="${RENEWED_DOMAINS:-}"

if [ -z "$LINEAGE" ]; then
  logger -t "$LOG_TAG" "ERROR: RENEWED_LINEAGE or SAKURA_LINEAGE_PATH is required"
  exit 1
fi

if [ ! -d "$LINEAGE" ]; then
  logger -t "$LOG_TAG" "ERROR: lineage directory does not exist: $LINEAGE"
  exit 1
fi

LINEAGE_NAME="$(basename "$LINEAGE")"

if [ -n "${RENEWED_LINEAGE:-}" ] && [ -n "${SAKURA_CERT_NAME:-}" ] && [ "$LINEAGE_NAME" != "$SAKURA_CERT_NAME" ]; then
  logger -t "$LOG_TAG" "SKIP: renewed lineage is $LINEAGE_NAME, target is $SAKURA_CERT_NAME"
  exit 0
fi

CERT_FILE="$LINEAGE/fullchain.pem"
KEY_FILE="$LINEAGE/privkey.pem"

if [ ! -r "$CERT_FILE" ]; then
  logger -t "$LOG_TAG" "ERROR: certificate file is not readable: $CERT_FILE"
  exit 1
fi

if [ ! -r "$KEY_FILE" ]; then
  logger -t "$LOG_TAG" "ERROR: private key file is not readable: $KEY_FILE"
  exit 1
fi

if ! command -v jq >/dev/null 2>&1; then
  logger -t "$LOG_TAG" "ERROR: jq command not found"
  exit 1
fi

if ! command -v curl >/dev/null 2>&1; then
  logger -t "$LOG_TAG" "ERROR: curl command not found"
  exit 1
fi

REQUEST_BODY="$(mktemp)"
RESPONSE_BODY="$(mktemp)"
trap 'rm -f "$REQUEST_BODY" "$RESPONSE_BODY"' EXIT

jq -n \
  --rawfile cert "$CERT_FILE" \
  --rawfile key "$KEY_FILE" \
  '{
    "Certificate": {
      "CertificateChain": $cert,
      "Key": $key
    }
  }' > "$REQUEST_BODY"

# テスト用。SAKURA_DRY_RUN=1 の場合はAPI送信しない。
if [ "${SAKURA_DRY_RUN:-0}" = "1" ]; then
  jq -e . "$REQUEST_BODY" >/dev/null
  logger -t "$LOG_TAG" "DRY-RUN: request body generated successfully for site_id=$SAKURA_WEBACCEL_SITE_ID lineage=$LINEAGE_NAME domains=$DOMAINS"
  exit 0
fi

HTTP_STATUS="$(
  curl -sS \
    -o "$RESPONSE_BODY" \
    -w '%{http_code}' \
    --netrc-file "$NETRC_FILE" \
    -H 'Content-Type: application/json' \
    -X PUT \
    --data-binary @"$REQUEST_BODY" \
    "$API_BASE_URL/site/$SAKURA_WEBACCEL_SITE_ID/certificate"
)"

if [ "$HTTP_STATUS" -lt 200 ] || [ "$HTTP_STATUS" -ge 300 ]; then
  logger -t "$LOG_TAG" "ERROR: API request failed. http_status=$HTTP_STATUS response=$(cat "$RESPONSE_BODY")"
  exit 1
fi

if jq -e '(.Success == true) or (.is_ok == true)' "$RESPONSE_BODY" >/dev/null 2>&1; then
  logger -t "$LOG_TAG" "SUCCESS: certificate uploaded. site_id=$SAKURA_WEBACCEL_SITE_ID lineage=$LINEAGE_NAME domains=$DOMAINS http_status=$HTTP_STATUS"
  exit 0
fi

logger -t "$LOG_TAG" "ERROR: API response did not indicate success. http_status=$HTTP_STATUS response=$(cat "$RESPONSE_BODY")"
exit 1

任意のディレクトリに上記スクリプトを設置し、/etc/letsencrypt/.key/netrcにはAPIキー情報、
/etc/letsencrypt/.key/configにはウェブアクセラレータのリソースIDとドメイン名を入力したファイルを用意します。

# mkdir /etc/letsencrypt/shell
# vi /etc/letsencrypt/shell/webaccel-cert-upload.sh
# chmod 700 /etc/letsencrypt/shell/webaccel-cert-upload.sh

・APIキー情報
# vi /etc/letsencrypt/.key/netrc
machine secure.sakura.ad.jp
  login アクセストークン
  password アクセストークンシークレット
# chmod 600 /etc/letsencrypt/.key/netrc

・ウェブアクセラレータ情報
# vi /etc/letsencrypt/.key/config
SAKURA_WEBACCEL_SITE_ID='リソースID'
SAKURA_CERT_NAME='tnagai-wp.click'
# chmod 600 /etc/letsencrypt/.key/config

あとは、証明書更新時(certbot renew)に–deploy-hookオプションにスクリプトパスを指定することで、
証明書更新時のみ、自動的にウェブアクセラレータの証明書も更新されます。

# certbot renew --force-renewal --deploy-hook /etc/letsencrypt/shell/webaccel-cert-upload.sh

実際に、サイトにアクセスすると証明書の更新が確認できました。

エンハンスドロードバランサでも同様のことができるのでぜひ試してみてください。
ではまた。

お問い合わせ

この記事をシェアする
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

猫とお酒好き
さくらのクラウド検定取得

目次