🐙
GCPでIP制限しているVMインスタンスのSSL証明書自動更新
前提
- Dockerを使用してアプリ構築している
- docker、docker-composeコマンドが使用できる
- すでにLet's Encryptから証明書を発行している
- OS:Ubuntu20.04LTS
仕組み
IP制限をしていると、証明書を更新できないので更新する前に80番ポートからの通信を許可するファイヤーウォールを作成し、VMインスタンスに割り当てる。更新が終わったらファイヤーウォールを削除するようにする。
手順
VMインスタンス側の設定
- Google Cloud コンソール画面> Compute Engine> VMインスタンス>設定するVMインスタンスの編集画面を開く
- ネットワークタグに任意のタグを登録する
- http通信を一時的にアクセスするために使用するので、このタグをターゲットタグとしたファイヤーウォールは作成しない
- アクセススコープで「すべてのCloud APIに完全アクセス権を許可」にチェックをつける
- 保存ボタンを押下して設定を保存する
VMインスタンス内でgcloudコマンドを使用できるようにする
- Google Cloud コンソール画面> Compute Engine> VMインスタンス>設定するVMインスタンスのSSHを押下してVMインスタンス内に入る
- インスタンス内で以下のコマンド実行
sudo gcloud init
- 以下のようなログが出てきたら1を押下
Your current configuration has been set to: [default]
You can skip diagnostics next time by using the following flag:
gcloud init --skip-diagnostics
Network diagnostic detects and fixes local network connection issues.
Checking network connection...done.
Reachability Check passed.
Network diagnostic passed (1/1 checks passed).
Choose the account you would like to use to perform operations for this configuration:
[1] XXXXXXXXXXX-compute@developer.gserviceaccount.com
[2] Log in with a new account
- Cloud resource manager APIをGCPのプロジェクトで有効にしていない場合は以下のように有効にするか質問されるが、今回は使用しなくてもよいのでNを押下
API [cloudresourcemanager.googleapis.com] not enabled on project [XXXXXXXXXXX]. Would you like to enable and
retry (this will take a few minutes)? (y/N)?
- 以下のようなWarningが出てくるが今回の作業には支障ない
WARNING: Listing available projects failed: PERMISSION_DENIED: Cloud Resource Manager API has not been used in project XXXXXXXXXXX before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/overview?project=XXXXXXXXXXX then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
- '@type': type.googleapis.com/google.rpc.Help
links:
- description: Google developers console API activation
url: https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/overview?project=XXXXXXXXXXX
- '@type': type.googleapis.com/google.rpc.ErrorInfo
domain: googleapis.com
metadata:
consumer: projects/XXXXXXXXXXX
service: cloudresourcemanager.googleapis.com
reason: SERVICE_DISABLED
- プロジェクトIDを入力するように求められるので入力する
- 以下の質問が聞かれたらYを押下
Do you want to configure a default Compute Region and Zone? (Y/n)?
- RegionとZoneの一覧が表示されるので任意のものを選択
- 以下のコマンドを実行してエラーにならなければgcloudコマンドの初期設定完了
gcloud compute firewall-rules list
cronファイルを作成する
- cronに登録する用のファイルを作成する(ファイル名は任意だが、拡張子は不要)
-
firewallname
は任意のファイヤーウォール名にする -
--target-tags=tagname
のtagnameの部分はVMインスタンスに登録したネットワークタグ名と合わせる -
cd /docker/app/
は環境に合わせてdocker-compose.ymlファイルがある場所に変更する -
/snap/bin/gcloud
はwhich cloud
をVMインスタンス内で実行して、gcloudコマンドのパスを調べて、それに合わせて変更する- ユーザーがgcloudコマンドを実行する際にはコマンドのパスは不要だが、cronから実行する場合はパスがないとnot foundエラーになる
cronファイル
#!/bin/sh
{
echo "---- start renew-cert $(date '+%Y-%m-%d %H:%M:%S')"
/snap/bin/gcloud compute firewall-rules create firewallname --direction=INGRESS \
--action=ALLOW --rules=tcp:80 --source-ranges=0.0.0.0/0 \
--target-tags=tagname
cd /docker/app/ || exit 1
gjdipuzmwd=$(docker-compose run --rm certbot renew --verbose --post-hook='echo gjdipuzmwd' 2>&1)
echo "${gjdipuzmwd}"
if echo "${gjdipuzmwd}" | grep -q "gjdipuzmwd"; then
docker-compose exec -T proxyserver nginx -s reload
fi
/snap/bin/gcloud compute firewall-rules delete certbot --quiet
} > /var/log/renew-cert.log 2>&1
- ファイルをVMインスタンス内の
/etc/cron.weekly/
に配置 - 以下のコマンドを実行してファイルに実行権限を付ける
chmod 755 /etc/cron.weekly/ファイル名
-
/etc/crontab
に記載されている実行タイミングで定期実行されるようになる
Discussion