Skip to content

Instantly share code, notes, and snippets.

@DaikiSuganuma
Last active December 25, 2025 05:00
Show Gist options
  • Select an option

  • Save DaikiSuganuma/f0b5cf86e8f980101f5b106b4f467004 to your computer and use it in GitHub Desktop.

Select an option

Save DaikiSuganuma/f0b5cf86e8f980101f5b106b4f467004 to your computer and use it in GitHub Desktop.
[CentOS Stream 10にstep-cliをインストールして別サーバーのstep-caで署名](https://blog.dksg.jp/2025/10/centos-stream-10step-clistep-ca.html)
#!/bin/bash
#================================================================================
#
# Step CA 証明書 発行・更新スクリプト
#
# 概要:
# Step CAサーバーから証明書を新規発行、または既存の証明書を更新します。
# 引数の数によって動作を切り替えます。
#
# 【新規発行】
# 使い方: ./step-cert.sh <ドメイン名> <ワンタイムトークン>
# 実行例: ./step-cert.sh dev.saitama-kk.org eyJhbGciOiJ...
#
# 【更新】
# 使い方: ./step-cert.sh <ドメイン名>
# 実行例: ./step-cert.sh dev.saitama-kk.org
#
#================================================================================
# --- モード判定と引数チェック ---
# 引数が2つの場合は「新規発行」、1つの場合は「更新」モードとして動作します。
if [ "$#" -eq 2 ]; then
MODE="ISSUE" # 新規発行モード
DOMAIN="$1"
TOKEN="$2"
elif [ "$#" -eq 1 ]; then
MODE="RENEW" # 更新モード
DOMAIN="$1"
else
# 引数が0個または3個以上の場合はエラー
echo "エラー: 引数の数が正しくありません。"
echo "【新規発行】: $0 <ドメイン名> <ワンタイムトークン>"
echo "【更新】 : $0 <ドメイン名>"
exit 1
fi
# --- 共通の変数の設定 ---
SSL_PARENT_DIR="/etc/nginx/ssl"
SSL_DIR="${SSL_PARENT_DIR}/${DOMAIN}"
CERT_FILE="${SSL_DIR}/fullchain.pem"
KEY_FILE="${SSL_DIR}/privkey.pem"
# --- 実行前チェック ---
if ! command -v step > /dev/null; then
echo "エラー: 'step' コマンドが見つかりません。step-cliをインストールしてください。"
exit 1
fi
# ============================================
# 新規発行モードの処理
# ============================================
if [ "${MODE}" = "ISSUE" ]; then
echo "ドメイン '${DOMAIN}' の証明書【新規発行】処理を開始します..."
# 1. ディレクトリ作成
echo "[1/5] 証明書ディレクトリを作成します: ${SSL_DIR}"
sudo mkdir -p "${SSL_DIR}" || { echo "エラー: ディレクトリ作成に失敗しました。"; exit 1; }
# 2. 証明書と秘密鍵の取得
echo "[2/5] CAサーバーから証明書と秘密鍵を取得します..."
sudo step ca certificate "${DOMAIN}" "${CERT_FILE}" "${KEY_FILE}" --token "${TOKEN}" --force || { echo "エラー: 証明書の取得に失
敗しました。"; exit 1; }
# 3. chain.pem (中間証明書) の取得
echo "[3/5] 中間証明書 (chain.pem) を取得します..."
# fullchain.pem から中間証明書を抜き出して chain.pem を作成します。
# awkコマンドで、fullchain.pem内の2つ目の "-----BEGIN CERTIFICATE-----" 以降を抽出します。
if ! (sudo awk '/-----BEGIN CERTIFICATE-----/{c++} c>=2' "${CERT_FILE}" > "${SSL_DIR}/chain.pem.tmp" && sudo mv "${SSL_DIR}/chain.pem.tmp" "${SSL_DIR}/chain.pem"); then
echo "エラー: 中間証明書の作成に失敗しました。"
exit 1
fi
# 4. パーミッション設定
echo "[4/5] ファイルのパーミッションを設定します..."
sudo chmod 644 "${SSL_DIR}"/*.pem
sudo chmod 600 "${KEY_FILE}"
# 5. 完了報告
echo "[5/5] 新規発行処理が正常に完了しました。"
echo "証明書は以下の場所に保存されました:"
sudo ls -l "${SSL_DIR}"
echo ""
echo "Nginxをリロードまたは再起動して、設定を反映させてください。"
fi
# ============================================
# 更新モードの処理
# ============================================
if [ "${MODE}" = "RENEW" ]; then
echo "ドメイン '${DOMAIN}' の証明書【更新】処理を開始します..."
# 1. ファイル存在チェック
echo "[1/3] 更新対象の証明書ファイルを確認します..."
if [ ! -f "${CERT_FILE}" ] || [ ! -f "${KEY_FILE}" ]; then
echo "エラー: 更新対象の証明書ファイルが見つかりません。"
echo "パス: ${CERT_FILE}"
exit 1
fi
# 2. 証明書の更新
echo "[2/3] CAサーバーに証明書の更新をリクエストします..."
# --force オプションで有効期間が残っていても強制的に更新します
sudo step ca renew "${CERT_FILE}" "${KEY_FILE}" --force || { echo "エラー: 証明書の更新に失敗しました。"; exit 1; }
# 3. Nginxのリロード
echo "[3/3] Nginxをリロードして新しい証明書を適用します..."
if sudo systemctl reload nginx; then
echo "Nginxのリロードに成功しました。"
else
echo "エラー: Nginxのリロードに失敗しました。" >&2
exit 1
fi
echo "証明書の更新処理が正常に完了しました。"
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment