はじめに
Google Cloud ArmorはDDoS攻撃などの様々な脅威からアプリケーションを保護するためのGCPのサービスです。
Google Cloud Armorではセキュリティーポリシーというものを設定できます。このセキュリティーポリシーには IPアドレスやリクエストヘッダーによる条件によってトラフィックを制限するルールを設定することができます。
今回、ワークフローエンジンであるDigdagに対して、Github Actionsでdigdag push
をするワークフローを作成する必要がありました。このDigdagサーバーはGoogle Cloud Armorで保護されています。Github Actionsは実行のたびにIPが変わるため、単一のIPをGoogle Cloud Armorのセキュリティーポリシールールに設定することはできません。
もし仮にGithub ActionsのIPを固定にすることができ、セキュリティールールに設定することが出来ても、特定のIPが常に許可された状態になるため、セキュリティー的によくありません。
そこで、Github Actionsを実行するタイミングにGoogle Cloud Armorのセキュリティーポリシーの許可ルールにGithub ActionsのIPを一時的に追加することで、この問題を解決しました。この方法について紹介します。
実装
Github Acitonsのワークフロー定義です。
Google Cloud Armorのセキュリティーポリシー変更に関わるstep部分のみを記述しています。
事前準備として、Github Actions用GCPサービスアカウントを作成します。このサービスアカウントには**Compute セキュリティ管理者(roles/compute.securityAdmin)**のロールが必要です。
Github ActionsのsecretsにGCP_SERVICE_ACCOUNT_KEY
というキー名でGithub Actions用GCPサービスアカウントの秘密鍵が設定されている想定です。
allow-policy
という名前のGoogle Cloud Armorセキュリティーポリシーに対してルールを一時的に追加します。
jobs:
digdag-push:
steps:
- name: Setup gcloud
uses: google-github-actions/setup-gcloud@master
with:
project_id: gcp-sample-project
service_account_key: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}
export_default_credentials: true
- name: Digdag push
run: |
IP=$(curl -f -s http://whatismyip.akamai.com)
trap "gcloud compute security-policies rules delete 1000 --security-policy allow-policy --quiet" 0 1 2 3 15
gcloud compute security-policies rules create 1000 --action allow --security-policy allow-policy --description "GithubActions IP" --src-ip-ranges ${IP}
(digdag pushの処理)
解説
Setup gcloud
というステップでgcloudコマンドが使えるように設定をします。
そして今回の肝となる、Google Cloud Armorのセキュリティーポリシーの許可ルールにGithub ActionsのIPを一時的に追加するための実装は以下の部分です。
IP=$(curl -f -s http://whatismyip.akamai.com)
trap "gcloud compute security-policies rules delete 1000 --security-policy allow-policy --quiet" 0 1 2 3 15
gcloud compute security-policies rules create 1000 --action allow --security-policy allow-policy --description "GithubActions IP" --src-ip-ranges ${IP}
一行ずつ解説します。
IPアドレスの取得
IP=$(curl -f -s http://whatismyip.akamai.com)
1行目では環境変数IPにGithub Actionsが実行されているインスタンスのIPを設定します。
http://whatismyip.akamai.com にGETリクエストを送ることで自身のIPがわかります。curlコマンドには-f(--fail)
と-s(--silent)
のオプションを指定しています。-f(--fail)
はリクエスト失敗時に異常終了します。-s(--silent)
はリクエストの進捗状況を非表示にするためです。
セキュリティポリシールールの追加
gcloud compute security-policies rules create 1000 --action allow --security-policy allow-policy --description "GithubActions IP" --src-ip-ranges ${IP}
先に3行目について説明します。ここではgcloudコマンドを使って、セキュリティポリシールールの追加をしています。
ここでは、allow-policy
という名前のGoogle Cloud AromorセキュリティポリシーにGihub Actionsからのアクセスを許可するルールを追加しています。
気をつけてほしいのは、crateのあとの1000という数字です。これはルールの優先度を指定しています。優先度は低いものが優先されます。今回は優先度1000にしていますが、ここは環境にあった優先度を設定してください。
セキュリティポリシールールの削除
trap "gcloud compute security-policies rules delete 1000 --security-policy allow-policy --quiet" 0 1 2 3 15
2行目では、セキュリティポリシールールを削除しています。
まず先にこの行で使っているtrapコマンドについて説明します。
trapコマンドとは、シグナルを受け取った際の動作を指定するためのコマンドです。 trap 'コマンド' シグナル1 シグナル2 ...
というフォーマットで記述します
シグナルとは実行中のプロセスに対するイベント通知に利用されるものです。具体例をあげると、プロセス実行中にCtrl + c
を押すと、プロセスに対してSIGINT
という割り込みイベントを通知します。
その他にも様々なイベントがあります。また、それぞれのイベントには番号が割り当てられています。
以上、trapコマンドについて説明した上で、この行でやっていることは、EXIT(0)・HUP(1)・INT(2)・QUIT(3)・TERM(15)というシグナルを受け取ったときに、優先度1000のセキュリティポリシーを削除するというものです。
指定しているシグナルについての説明は省略しますが、EXIT(0)・SIGHUP(1)・SIGINT(2)・SIGQUIT(3)・SIGTERM(15)をtrapコマンドのシグナルに指定することで、step内の処理が正常終了または途中終了した場合でもセキュリティポリシールール削除の処理が実施されます。
stepの最後でそのままgcloud compute security-policies rules delete
を実行してしまうと、それ以前に処理が異常終了してしまった場合に、セキュリティポリシーの許可ルールが設定されたままになってしまいます。これを防ぐためにtrapコマンドを使っています
さいごに
Google Cloud Armorのセキュリティーポリシーの許可ルールにGithub ActionsのIPを一時的に追加する方法について紹介しました。
外部からGoogle Cloud Armorで保護されたリソースへのアクセスを許可する際に参考になれば幸いです。
参考資料
https://cloud.google.com/armor/docs/configure-security-policies
https://shellscript.sunone.me/signal_and_trap.html