このドキュメントでは、Cloud Storage にアップロードされたファイルのマルウェア スキャンを自動化するのアーキテクチャをデプロイする方法について説明します。
このデプロイガイドは、次のテクノロジーの基本機能を理解していることを前提としています。
アーキテクチャ
次の図は、このチュートリアルで作成するデプロイ アーキテクチャを示しています。
この図は、このアーキテクチャで管理される次の 2 つのパイプラインを示しています。
- ファイル スキャン パイプライン。アップロードされたファイルにマルウェアが含まれていないかどうかを確認します。
- ClamAV マルウェア データベースのミラー更新パイプライン。ClamAV が使用するマルウェア データベースの最新のミラーを維持します。
アーキテクチャの詳細については、Cloud Storage にアップロードされたファイルのマルウェア スキャンを自動化するをご覧ください。
目標
Cloud Storage バケットに ClamAV マルウェア定義データベースのミラーを構築する。
次の機能を使用して Cloud Run サービスをビルドする。
- ClamAV を使用して Cloud Storage バケット内のファイルをスキャンしてマルウェアの有無を確認し、スキャン結果に応じてクリーンなバケットまたは隔離バケットにスキャン済みファイルを移動する。
- Cloud Storage で ClamAV マルウェア定義データベースのミラーを管理する。
ファイルが Cloud Storage にアップロードされたときにマルウェア スキャン サービスをトリガーする Eventarc トリガーを作成する。
マルウェア スキャン サービスをトリガーして Cloud Storage のマルウェア定義データベースのミラーを更新する Cloud Scheduler ジョブを作成する。
費用
このアーキテクチャでは、課金対象である次の Google Cloudコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
始める前に
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry, Cloud Build, Resource Manager, Cloud Scheduler, Eventarc, Logging, Monitoring, Pub/Sub, Cloud Run, and Service Usage APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles. -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry, Cloud Build, Resource Manager, Cloud Scheduler, Eventarc, Logging, Monitoring, Pub/Sub, Cloud Run, and Service Usage APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles. -
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
このデプロイでは、すべてのコマンドを Cloud Shell から実行します。
Cloud Shell を使用する:
Google Cloud CLI
コマンドライン ツールを使用してソリューションの各コンポーネントがデプロイおよび構成される方法を確認する場合は、この方法を使用します。このデプロイ方法を使用する場合は、Cloud Shell を使用してデプロイするの手順に沿って操作します。
Terraform CLI を使用する: この方法は、手動の手順をできるだけ少なくしてソリューションをデプロイする場合に使用します。この方法では、Terraform を使用して個々のコンポーネントをデプロイして構成します。
このデプロイ方法を使用するには、Terraform CLI を使用してデプロイするの手順に沿って操作します。
Cloud Shell で、リージョンやロケーションなどの一般的なシェル変数を設定します。
REGION=us-central1 LOCATION=us PROJECT_ID=PROJECT_ID SERVICE_NAME="malware-scanner" SERVICE_ACCOUNT="${SERVICE_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
PROJECT_ID
は、実際のプロジェクト ID に置き換えます。プロジェクト ID を使用して
gcloud
環境を初期化します。gcloud config set project "${PROJECT_ID}"
一意の名前で 3 つの Cloud Storage バケットを作成します。
gcloud storage buckets create "gs://unscanned-${PROJECT_ID}" --location="${LOCATION}" gcloud storage buckets create "gs://quarantined-${PROJECT_ID}" --location="${LOCATION}" gcloud storage buckets create "gs://clean-${PROJECT_ID}" --location="${LOCATION}"
${PROJECT_ID}
は、バケット名が一意となるようにするために使用されます。この 3 つのバケットは、ファイル スキャン パイプラインのさまざまな段階でアップロードされたファイルを保持します。
unscanned-PROJECT_ID
: スキャンする前のファイルを保持します。ユーザーがこのバケットにファイルをアップロードします。quarantined-PROJECT_ID
: マルウェア スキャナ サービスでスキャンされ、マルウェアが含まれていると判断されたファイルを保持します。clean-PROJECT_ID
: マルウェア スキャナ サービスでスキャンされ、感染していないと判断されたファイルを保持します。
4 つ目の Cloud Storage バケットを作成します。
gcloud storage buckets create "gs://cvd-mirror-${PROJECT_ID}" --location="${LOCATION}"
${PROJECT_ID}
は、バケット名を一意の名前にするために使用されます。このバケット
cvd-mirror-PROJECT_ID
は、マルウェア定義データベースのローカルミラーを維持するために使用されます。これにより、ClamAV CDN によってレート制限がトリガーされなくなります。malware-scanner
サービス アカウントを作成します。gcloud iam service-accounts create ${SERVICE_NAME}
バケットにオブジェクト管理者ロールを付与します。これにより、サービスは未スキャン バケットからのファイルの読み取りと削除、隔離バケットとクリーンなバケットへのファイルの書き込みができるようになります。
gcloud storage buckets add-iam-policy-binding "gs://unscanned-${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" --role=roles/storage.objectAdmin gcloud storage buckets add-iam-policy-binding "gs://clean-${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" --role=roles/storage.objectAdmin gcloud storage buckets add-iam-policy-binding "gs://quarantined-${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" --role=roles/storage.objectAdmin gcloud storage buckets add-iam-policy-binding "gs://cvd-mirror-${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" --role=roles/storage.objectAdmin
指標の書き込みのロールを付与します。これにより、サービスは Monitoring に指標を書き込めるようになります。
gcloud projects add-iam-policy-binding \ "${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" \ --role=roles/monitoring.metricWriter
- サービス、Node.js ランタイム、Google Cloud SDK、ClamAV バイナリを含むコンテナ イメージをビルドするための
Dockerfile
。 - マルウェア スキャナ Cloud Run サービスの TypeScript ファイル。
- Cloud Storage バケット名を指定する
config.json
構成ファイル。 - Cloud Storage の ClamAV マルウェア定義データベース ミラーを更新する
updateCvdMirror.sh
シェル スクリプト。 - インスタンスの起動時に必要なサービスを実行する
bootstrap.sh
シェル スクリプト。 Cloud Shell で、コードファイルを含む GitHub リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/docker-clamav-malware-scanner.git
cloudrun-malware-scanner
ディレクトリに移動します。cd docker-clamav-malware-scanner/cloudrun-malware-scanner
GitHub リポジトリの
config.json.tmpl
テンプレート ファイルに基づいてconfig.json
構成ファイルを作成します。sed "s/-bucket-name/-${PROJECT_ID}/" config.json.tmpl > config.json
上記のコマンドは、検索と置換のオペレーションを使用して、プロジェクト ID に基づいた一意の名前を Cloud Storage バケットに付けます。
省略可: 更新された構成ファイルを表示します。
cat config.json
Cloud Storage の ClamAV マルウェア データベース ミラーへの初期データ取り込みを行います。
python3 -m venv pyenv . pyenv/bin/activate pip3 install crcmod cvdupdate ./updateCvdMirror.sh "cvd-mirror-${PROJECT_ID}" deactivate
これらのコマンドは、
CVDUpdate
ツールをローカルにインストールし、updateCvdMirror.sh
スクリプトを実行します。このスクリプトはCVDUpdate
を使用して、ClamAV マルウェア データベースを前の手順で作成したcvd-mirror-PROJECT_ID
バケットにコピーします。ミラーバケットの内容を確認できます。
gcloud storage ls "gs://cvd-mirror-${PROJECT_ID}/cvds"
このバケットには、マルウェア データベース全体を含む複数の CVD ファイル、毎日の差分更新を含む複数の
.cdiff
ファイル、構成と状態に関する情報を含む 2 つの JSON ファイルが含まれている必要があります。以前の手順で作成したサービス アカウントを使用して、Cloud Run サービスを作成してデプロイします。
gcloud beta run deploy "${SERVICE_NAME}" \ --source . \ --region "${REGION}" \ --no-allow-unauthenticated \ --memory 4Gi \ --cpu 1 \ --concurrency 20 \ --min-instances 1 \ --max-instances 5 \ --no-cpu-throttling \ --cpu-boost \ --timeout 300s \ --service-account="${SERVICE_ACCOUNT}"
このコマンドは、1 つの vCPU を持ち、4 GiB の RAM を使用する Cloud Run インスタンスを作成します。このサイズはこのデプロイでは許容されます。ただし本番環境では、インスタンスにより大きな CPU とメモリサイズを選択し、また大きな
--max-instances
パラメータを選択することをおすすめします。必要となる可能性があるリソースサイズは、サービスが処理する必要があるトラフィックの量によって異なります。このコマンドの仕様は次のとおりです。
--concurrency
パラメータは、各インスタンスが処理できる同時リクエストの数を指定します。--no-cpu-throttling
パラメータを指定すると、インスタンスがマルウェア定義の更新などのオペレーションをバックグラウンドで実行します。--cpu-boost
パラメータを指定すると、インスタンスの起動時に vCPU の数が 2 倍になり、起動レイテンシが短縮されます。- 各インスタンスの起動時間が比較的長いため、
--min-instances 1
パラメータを指定すると、少なくとも 1 つのインスタンスがアクティブな状態で維持されます。 --max-instances 5
パラメータは、サービスが過度にスケールアップされないようにします。
プロンプトが表示されたら「
Y
」と入力して、サービスをビルドしてデプロイします。ビルドとデプロイには 10 分ほどかかります。完了すると、次のメッセージが表示されます。Service [malware-scanner] revision [malware-scanner-UNIQUE_ID] has been deployed and is serving 100 percent of traffic. Service URL: https://malware-scanner-UNIQUE_ID.a.run.app
デプロイ コマンドの出力の
Service URL
値をシェル変数に格納します。この値は、後で Cloud Scheduler ジョブを作成するときに使用します。SERVICE_URL="SERVICE_URL"
省略可: 実行中のサービスと ClamAV のバージョンを確認するには、次のコマンドを実行します。
curl -D - -H "Authorization: Bearer $(gcloud auth print-identity-token)" \ ${SERVICE_URL}
出力は次のサンプルのようになります。マルウェア スキャナ サービスのバージョン、ClamAV のバージョン、マルウェア定義のバージョンと最終更新日が表示されます。
gcs-malware-scanner version 3.2.0 Using Clam AV version: ClamAV 1.4.1/27479/Fri Dec 6 09:40:14 2024
2021 年 4 月 8 日より前に作成された既存のプロジェクトを使用している場合は、Pub/Sub サービス アカウントに
iam.serviceAccountTokenCreator
ロールを追加します。PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)") PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\ --role='roles/iam.serviceAccountTokenCreator'
このロールは、古いプロジェクトにのみ追加する必要があります。このロールによって、Pub/Sub が Cloud Run サービスを呼び出すことができるようになります。
Cloud Shell で、Cloud Storage サービス アカウントに Pub/Sub パブリッシャーのロールを付与します。
STORAGE_SERVICE_ACCOUNT=$(gcloud storage service-agent --project="${PROJECT_ID}") gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member "serviceAccount:${STORAGE_SERVICE_ACCOUNT}" \ --role "roles/pubsub.publisher"
malware-scanner
サービス アカウントで Cloud Run サービスを呼び出し、Eventarc イベント レシーバーとして機能できるようにします。gcloud run services add-iam-policy-binding "${SERVICE_NAME}" \ --region="${REGION}" \ --member "serviceAccount:${SERVICE_ACCOUNT}" \ --role roles/run.invoker gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member "serviceAccount:${SERVICE_ACCOUNT}" \ --role "roles/eventarc.eventReceiver"
スキャンされていない Cloud Storage バケット内のファイナライズされたオブジェクト イベントをキャプチャして、Cloud Run サービスに送信する Eventarc トリガーを作成します。このトリガーは
malware-scanner
サービス アカウントを認証に使用します。BUCKET_NAME="unscanned-${PROJECT_ID}" gcloud eventarc triggers create "trigger-${BUCKET_NAME}-${SERVICE_NAME}" \ --destination-run-service="${SERVICE_NAME}" \ --destination-run-region="${REGION}" \ --location="${LOCATION}" \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=${BUCKET_NAME}" \ --service-account="${SERVICE_ACCOUNT}"
次のいずれかのエラーが発生した場合は、1 分待ってからコマンドを再度実行します。
ERROR: (gcloud.eventarc.triggers.create) INVALID_ARGUMENT: The request was invalid: Bucket "unscanned-PROJECT_ID" was not found. Please verify that the bucket exists.
ERROR: (gcloud.eventarc.triggers.create) FAILED_PRECONDITION: Invalid resource state for "": Permission denied while using the Eventarc Service Agent. If you recently started to use Eventarc, it may take a few minutes before all necessary permissions are propagated to the Service Agent. Otherwise, verify that it has Eventarc Service Agent role.
Eventarc トリガーにより使用される、基盤となる Pub/Sub サブスクリプションでメッセージの確認応答期限を 5 分に変更します。大きなファイルまたは負荷が高い場合、デフォルト値の 10 秒は短すぎます。
SUBSCRIPTION_NAME=$(gcloud eventarc triggers describe \ "trigger-${BUCKET_NAME}-${SERVICE_NAME}" \ --location="${LOCATION}" \ --format="get(transport.pubsub.subscription)") gcloud pubsub subscriptions update "${SUBSCRIPTION_NAME}" --ack-deadline=300
トリガーはすぐに作成されますが、トリガーが完全に機能するまでに 2 分ほどかかることがあります。
マルウェア定義データベース ミラーを更新するコマンドを使用して、Cloud Run サービスに対して HTTP
POST
リクエストを実行する Cloud Scheduler ジョブを作成します。同じ時間枠を使用するクライアントが多くなりすぎないように、ClamAV では、10 の倍数以外の 3~57 のランダムな分数でジョブをスケジュールする必要があります。while : ; do # set MINUTE to a random number between 3 and 57 MINUTE="$((RANDOM%55 + 3))" # exit loop if MINUTE isn't a multiple of 10 [[ $((MINUTE % 10)) != 0 ]] && break done gcloud scheduler jobs create http \ "${SERVICE_NAME}-mirror-update" \ --location="${REGION}" \ --schedule="${MINUTE} */2 * * *" \ --oidc-service-account-email="${SERVICE_ACCOUNT}" \ --uri="${SERVICE_URL}" \ --http-method=post \ --message-body='{"kind":"schedule#cvd_update"}' \ --headers="Content-Type=application/json"
--schedule
コマンドライン引数は、unix-cron 文字列形式を使用してジョブが実行されるタイミングを定義します。指定された値は、2 時間ごとにランダムに生成された特定の分でジョブが実行されることを示しています。Cloud Shell で、コードと Terraform ファイルを含む GitHub リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/docker-clamav-malware-scanner.git
Cloud Shell で、リージョンやロケーションなどの一般的なシェル変数を設定します。
REGION=us-central1 LOCATION=us PROJECT_ID=PROJECT_ID
PROJECT_ID
は、実際のプロジェクト ID に置き換えます。プロジェクト ID を使用して
gcloud CLI
環境を初期化します。gcloud config set project "${PROJECT_ID}"
GitHub リポジトリの
config.json.tmpl
テンプレート ファイルに基づいてconfig.json
構成ファイルを作成します。sed "s/-bucket-name/-${PROJECT_ID}/" \ docker-clamav-malware-scanner/cloudrun-malware-scanner/config.json.tmpl \ > docker-clamav-malware-scanner/cloudrun-malware-scanner/config.json
上記のコマンドは、検索と置換のオペレーションを使用して、プロジェクト ID に基づいた一意の名前を Cloud Storage バケットに付けます。
省略可: 更新された構成ファイルを表示します。
cat docker-clamav-malware-scanner/cloudrun-malware-scanner/config.json
Terraform 変数を構成します。
config.json
構成ファイルの内容はTF_VAR_config_json
変数を使用して Terraform に渡されるため、Terraform は作成する Cloud Storage バケットを認識します。この変数の値は、サービスを構成するために Cloud Run にも渡されます。TF_VAR_project_id=$PROJECT_ID TF_VAR_region=us-central1 TF_VAR_bucket_location=us TF_VAR_config_json="$(cat docker-clamav-malware-scanner/cloudrun-malware-scanner/config.json)" TF_VAR_create_buckets=true export TF_VAR_project_id TF_VAR_region TF_VAR_bucket_location TF_VAR_config_json TF_VAR_create_buckets
Cloud Shell で、次のコマンドを実行してベース インフラストラクチャをデプロイします。
gcloud services enable \ cloudresourcemanager.googleapis.com \ serviceusage.googleapis.com cd docker-clamav-malware-scanner/terraform/infra terraform init terraform apply
プロンプトが表示されたら、
yes
と入力します。この Terraform スクリプトは、次のタスクを実行します。
- サービス アカウントを作成します
- Artifact Registry を作成します
- Cloud Storage バケットを作成します
- 適切なロールと権限を設定する
- ClamAV マルウェア定義データベースのミラーを含む Cloud Storage バケットの初期データ取り込みを実行します。
Cloud Shell で次のコマンドを実行して、Cloud Build ジョブを起動し、サービスのコンテナ イメージを作成します。
cd ../../cloudrun-malware-scanner gcloud builds submit \ --region="$TF_VAR_region" \ --config=cloudbuild.yaml \ --service-account="projects/$PROJECT_ID/serviceAccounts/malware-scanner-build@$PROJECT_ID.iam.gserviceaccount.com" \ .
ビルドが完了するまで数分待ちます。
Cloud Shell で次のコマンドを実行して、Cloud Run サービスをデプロイします。
cd ../terraform/service/ terraform init terraform apply
プロンプトが表示されたら、
yes
と入力します。サービスのデプロイと開始には数分かかることがあります。
この Terraform スクリプトは、次のタスクを実行します。
- ビルドしたコンテナ イメージを使用して Cloud Run サービスをデプロイします。
unscanned
Cloud Storage バケットに Eventarc トリガーを設定します。トリガーはすぐに作成されますが、トリガーが完全に機能するまでに 2 分ほどかかることがあります。- ClamAV マルウェア定義ミラーを更新する Cloud Scheduler ジョブを作成します。
次のいずれかのエラーでデプロイが失敗した場合は、1 分待ってから
terraform apply
コマンドを再度実行して、Eventarc トリガーの作成を再試行します。Error: Error creating Trigger: googleapi: Error 400: Invalid resource state for "": The request was invalid: Bucket "unscanned-PROJECT_ID" was not found. Please verify that the bucket exists.
Error: Error creating Trigger: googleapi: Error 400: Invalid resource state for "": Permission denied while using the Eventarc Service Agent. If you recently started to use Eventarc, it may take a few minutes before all necessary permissions are propagated to the Service Agent. Otherwise, verify that it has Eventarc Service Agent role..
省略可: 実行中のサービスと使用中の ClamAV のバージョンを確認するには、次のコマンドを実行します。
MALWARE_SCANNER_URL="$(terraform output -raw cloud_run_uri)" curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" \ "${MALWARE_SCANNER_URL}"
出力は次のサンプルのようになります。マルウェア スキャナ サービスのバージョン、ClamAV のバージョン、マルウェア定義のバージョンと最終更新日が表示されます。
gcs-malware-scanner version 3.2.0 Using Clam AV version: ClamAV 1.4.1/27479/Fri Dec 6 09:40:14 2024
サンプル テキスト ファイルを作成するか、既存のクリーンなファイルを使用して、パイプライン プロセスをテストします。
Cloud Shell で、サンプルデータ ファイルを未スキャン バケットにコピーします。
gcloud storage cp FILENAME "gs://unscanned-${PROJECT_ID}"
FILENAME
を、クリーンなテキスト ファイルの名前に置き換えます。マルウェア スキャナ サービスは、各ファイルを検査し、ファイルを適切なバケットに移動します。このファイルはクリーンなバケットに移動されます。パイプラインでのファイルの処理には数秒かかります。その後、クリーンなバケットをチェックして、処理されたファイルがあるかどうかを確認します。
gcloud storage ls "gs://clean-${PROJECT_ID}" --recursive
未スキャン バケットからファイルが削除されたことを確認できます。
gcloud storage ls "gs://unscanned-${PROJECT_ID}" --recursive
EICAR 標準のマルウェア対策テスト署名を含む
eicar-infected.txt
というファイルを、未スキャン バケットにアップロードします。echo -e 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' \ | gcloud storage cp - "gs://unscanned-${PROJECT_ID}/eicar-infected.txt"
このテキスト文字列には、テスト目的でマルウェア スキャナをトリガーする署名があります。このテストファイルは広く使用されているテストであり、実際のマルウェアではなく、ワークステーションには無害です。マルウェア スキャナがインストールされているコンピュータでこの文字列を含むファイルを作成しようとすると、アラートがトリガーされます。
数秒待ってから、隔離バケットをチェックし、ファイルがパイプラインを正常に通過したかどうかを確認します。
gcloud storage ls "gs://quarantined-${PROJECT_ID}" --recursive
また、マルウェアに感染したファイルが検出されると、Logging のログエントリが記録されます。
未スキャン バケットからファイルが削除されたことを確認できます。
gcloud storage ls "gs://unscanned-${PROJECT_ID}" --recursive
Cloud Shell で Cloud Scheduler ジョブを強制的に実行して、更新のチェックをトリガーします。
gcloud scheduler jobs run "${SERVICE_NAME}-mirror-update" --location="${REGION}"
このコマンドの結果は、詳細なログにのみ表示されます。
Google Cloud コンソールで、Cloud Logging のログ エクスプローラ ページに移動します。
[ログのフィールド] フィルタが表示されない場合は、[ログのフィールド] をクリックします。
[ログのフィールド] フィルタで、[Cloud Run のリビジョン] をクリックします。
[ログのフィールド] フィルタの [サービス名] セクションで、[malware-scanner] をクリックします。
- 処理されたクリーンなファイルの数:
workload.googleapis.com/googlecloudplatform/gcs-malware-scanning/clean-files
- 処理された感染ファイルの数:
workload.googleapis.com/googlecloudplatform/gcs-malware-scanning/infected-files
- 無視され、スキャンされなかったファイルの数:
workload.googleapis.com/googlecloudplatform/gcs-malware-scanning/ignored-files
- ファイルのスキャンにかかった時間:
workload.googleapis.com/googlecloudplatform/gcs-malware-scanning/scan-duration
- スキャンされた合計バイト数:
workload.googleapis.com/googlecloudplatform/gcs-malware-scanning/bytes-scanned
- 失敗したマルウェア スキャンの数:
workload.googleapis.com/googlecloudplatform/gcs-malware-scanning/scans-failed
- CVD ミラーの更新チェックの数:
workload.googleapis.com/googlecloudplatform/gcs-malware-scanning/cvd-mirror-updates
Google Cloud コンソールで、Cloud Monitoring の [Metrics Explorer] ページに移動します。
[指標を選択] フィールドをクリックして、フィルタ文字列「
malware
」を入力します。[Generic Task] リソースを開きます。
[Googlecloudplatform] カテゴリを開きます。
[googlecloudplatform/gcs-malware-scanning/clean-files] 指標を選択します。グラフには、クリーンなファイルがスキャンされた時点を示すデータポイントが表示されます。
source_bucket
destination_bucket
clam_version
cloud_run_revision
ZERO_LENGTH_FILE
:ignoreZeroLengthFiles
構成値が設定されていて、ファイルが空の場合。FILE_TOO_LARGE
: ファイルがスキャン上限サイズ(500 MiB)を超えている場合。REGEXP_MATCH
: ファイル名がfileExclusionPatterns
で定義されているパターンのいずれかと一致する場合。FILE_SIZE_MISMATCH
: 検査中にファイルサイズが変更された場合。Cloud Storage の未スキャン バケット、クリーンなバケット、隔離バケットを作成し、一意の名前を付けます。
各バケットの
malware-scanner
サービス アカウントに適切なロールを付与します。config.json
構成ファイルを編集して、各構成のバケット名を指定します。{ "buckets": [ { "unscanned": "unscanned-bucket-1-name", "clean": "clean-bucket-1-name", "quarantined": "quarantined-bucket-1-name" }, { "unscanned": "unscanned-bucket-2-name", "clean": "clean-bucket-2-name", "quarantined": "quarantined-bucket-2-name" } ], "ClamCvdMirrorBucket": "cvd-mirror-bucket-name" }
未スキャン バケットごとに Eventarc トリガーを作成します。各バケットに対して一意のトリガー名を作成してください。
Cloud Storage バケットは、Eventarc トリガーと同じプロジェクトとリージョンに存在する必要があります。
- Cloud Run サービスのリクエスト タイムアウトは 5 分です
- Pub/Sub のサブスクリプション メッセージの確認応答期限は 5 分です。
- Scanner コードには
MAX_FILE_SIZE
定数(500 MiB)があります。 - ClamAV サービス構成の
StreamMaxLength
、MaxScanSize
、MaxFileSize
の設定は 512 MB です。これらの設定はbootstrap.sh
スクリプトによって設定されます。 - In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
- Cloud Storage のドキュメントを確認する。
- Cloud アーキテクチャ センターで、リファレンス アーキテクチャ、図、ベスト プラクティスを確認する。
アーキテクチャをデプロイする
このドキュメントで説明するアーキテクチャは、次のいずれかの方法でデプロイできます。
Cloud Shell を使用してデプロイする
このドキュメントで説明するアーキテクチャを手動でデプロイするには、次のサブセクションの手順を完了します。
環境を準備する
このセクションでは、デプロイ全体で使用される値(リージョンやゾーンなど)の設定を行います。このデプロイでは、Cloud Run サービスのリージョンとして us-central1
を使用し、Eventarc トリガーと Cloud Storage バケットのロケーションとして us
を使用します。
マルウェア スキャナ サービスのサービス アカウントを設定する
このセクションでは、マルウェア スキャナ サービスに使用するサービス アカウントを作成します。次に、サービス アカウントが Cloud Storage バケットに対する読み取りと書き込みの権限を持つように、サービス アカウントに適切なロールを付与します。これらのロールにより、アカウントに最小限の権限が付与され、必要なリソースにのみアクセスできるようになります。
Cloud Run にマルウェア スキャン サービスを作成する
このセクションでは、Cloud Run にマルウェア スキャナ サービスをデプロイします。このサービスは、次の内容を含む Docker コンテナで実行されます。
このサービスをデプロイするには、次の操作を行います。
Cloud Run サービスでは、すべての呼び出しの認証を行う必要があり、認証 ID にはサービスに対する run.routes.invoke
権限が必要です。次のセクションでこの権限を追加します。
Eventarc Cloud Storage トリガーを作成する
このセクションでは、Eventarc が Cloud Storage イベントをキャプチャし、これらのイベントを Cloud Run malware-scanner
サービスに送信するためのトリガーを作成できるようにする権限を追加します。
ClamAV データベース ミラーの更新をトリガーする Cloud Scheduler ジョブを作成する
このジョブでは、Cloud Storage 内の ClamAV ミラーのみが更新されます。Cloud Run の各インスタンスの ClamAV freshclam デーモンは、30 分ごとにミラーで新しい定義をチェックし、ClamAV デーモンを更新します。
Terraform CLI を使用してデプロイする
このセクションでは、Terraform CLI を使用して、このドキュメントで説明するアーキテクチャをデプロイする方法について説明します。
GitHub リポジトリのクローンを作成する
環境を準備する
このセクションでは、デプロイ全体で使用される値(リージョンやゾーンなど)の設定を行います。このデプロイでは、Cloud Run サービスのリージョンとして us-central1
を使用し、Eventarc トリガーと Cloud Storage バケットのロケーションとして us
を使用します。
ベース インフラストラクチャのデプロイ
サービスのコンテナをビルドする
サービスとトリガーをデプロイする
ファイルをアップロードしてパイプラインをテストする
パイプラインをテストするには、クリーンな(マルウェアのない)ファイルと、感染したファイルを模倣したテストファイルを 1 つずつアップロードします。
マルウェア定義データベースの更新メカニズムをテストする
サービスをモニタリングする
Cloud Logging と Cloud Monitoring を使用してサービスをモニタリングできます。
詳細なログを表示する
ログクエリの結果には、このサービスからのログが表示されます。これには、アップロードした 2 つのファイルのスキャン リクエストとステータスを示す行がいくつか含まれています。
Scan request for gs://unscanned-PROJECT_ID/FILENAME, (##### bytes) scanning with clam ClamAV CLAMAV_VERSION_STRING
Scan status for gs://unscanned-PROJECT_ID/FILENAME: CLEAN (##### bytes in #### ms)
...
Scan request for gs://unscanned-PROJECT_ID/eicar-infected.txt, (69 bytes) scanning with clam ClamAV CLAMAV_VERSION_STRING
Scan status for gs://unscanned-PROJECT_ID/eicar-infected.txt: INFECTED stream: Eicar-Signature FOUND (69 bytes in ### ms)
出力には、ClamAV のバージョン、マルウェア データベースの署名のリビジョン、感染テストファイルのマルウェア名が表示されます。これらのログメッセージを使用して、マルウェアが検出されたときまたはスキャン中に障害が発生したときのアラートを設定できます。
出力には、マルウェア定義のミラー更新ログも表示されます。
Starting CVD Mirror update
CVD Mirror update check complete. output: ...
ミラーが更新された場合、出力には追加の行が表示されます。
CVD Mirror updated: DATE_TIME - INFO: Downloaded daily.cvd. Version: VERSION_INFO
freshclam の更新ログは 30 分ごとに表示されます。
DATE_TIME -> Received signal: wake up
DATE_TIME -> ClamAV update process started at DATE_TIME
DATE_TIME -> daily.cvd database is up-to-date (version: VERSION_INFO)
DATE_TIME -> main.cvd database is up-to-date (version: VERSION_INFO)
DATE_TIME -> bytecode.cvd database is up-to-date (version: VERSION_INFO)
データベースが更新された場合、freshclam のログ行は次のようになります。
DATE_TIME -> daily.cld updated (version: VERSION_INFO)
指標を表示
このサービスでは、モニタリングとアラートの目的で次の指標が生成されます。
これらの指標は、Cloud Monitoring の Metrics Explorer で確認できます。
指標を使用して、パイプラインをモニタリングし、マルウェアが検出された場合とファイルの処理に失敗した場合のアラートを作成できます。
生成される指標には次のラベルがあります。これらのラベルをフィルタリングと集計に使用することで、Metrics Explorer でよりきめ細かい詳細を表示できます。
ignored_files
指標では、次の reason
ラベルでファイルが無視される理由を定義します。
詳細構成
以降のセクションでは、より高度なパラメータを使用してスキャナを構成する方法について説明します。
複数のバケットを処理する
マルウェア スキャナ サービスは、複数のソースバケットのファイルをスキャンし、クリーンなバケットと隔離バケットにスキャン済みファイルを送信できます。この高度な構成はこのデプロイの範囲外ですが、必要な手順の概要は次のとおりです。
Terraform デプロイを使用している場合、更新された config.json
構成ファイルを Terraform 構成変数 TF_VAR_config_json
で渡すと、このセクションの手順が自動的に適用されます。
一時ファイルを無視する
SFTP から Cloud Storage ゲートウェイなどの一部のアップロード サービスでは、アップロード プロセス中に 1 つ以上の一時ファイルが作成されます。アップロードが完了すると、これらのサービスはファイルの名前を最終的なファイル名に変更します。
スキャナの通常の動作では、これらの一時ファイルが書き込まれるとすぐに、それらを含むすべてのファイルがスキャンされて移動されます。これにより、アップローダ サービスが一時ファイルを見つけられず、失敗する可能性があります。
config.json
構成ファイルの fileExclusionPatterns
セクションでは、正規表現を使用して、無視するファイル名パターンのリストを指定できます。これらの正規表現に一致するファイルは unscanned
バケットに残ります。
このルールがトリガーされると、ignored-files
カウンタが増加し、パターンに一致するファイルが無視されたことを示すメッセージがログに記録されます。
次のコードサンプルは、fileExclusionPatterns
リストが .tmp
で終わるファイルまたは .partial_upload.
という文字列を含むファイルを無視するように設定された config.json
構成ファイルを示しています。
{
"buckets": [
{
"unscanned": "unscanned-bucket-name",
"clean": "clean-bucket-name",
"quarantined": "quarantined-bucket-name"
},
],
"ClamCvdMirrorBucket": "cvd-mirror-bucket-name",
"fileExclusionPatterns": [
"\\.tmp$",
"\\.partial_upload\\."
]
}
正規表現で \
文字を使用する場合は、JSON ファイルで別の \
を使用してエスケープする必要があるため、注意してください。たとえば、正規表現でリテラル .
を指定するには、記号を 2 回エスケープする必要があります。1 回は正規表現用、もう 1 回は JSON ファイルのテキスト用です。したがって、前のコードサンプルの最後の行のように、\\.
になります。
長さが 0 のファイルを無視する
一時ファイルと同様に、一部のアップロード サービスでは、Cloud Storage に長さ 0 のファイルを作成し、後でこのファイルをより多くのコンテンツで更新します。
これらのファイルは、config.json
パラメータ ignoreZeroLengthFiles
を true
に設定することで無視することもできます。
{
"buckets": [
{
"unscanned": "unscanned-bucket-name",
"clean": "clean-bucket-name",
"quarantined": "quarantined-bucket-name"
},
],
"ClamCvdMirrorBucket": "cvd-mirror-bucket-name",
"ignoreZeroLengthFiles": true
}
このルールがトリガーされると、ignored-files
指標が増加し、長さがゼロのファイルが無視されたことを示すメッセージがログに記録されます。
最大スキャン ファイルサイズ
スキャンするファイルのデフォルトの最大サイズは 500 MiB です。このサイズのスキャンには約 5 分かかるため、このサイズが選択されています。
500 MiB を超えるファイルは無視され、unscanned
バケットに残されます。files-ignored
指標が増加し、メッセージがログに記録されます。
この上限を増やす必要がある場合は、新しい最大ファイルサイズとスキャン時間の値に対応するように、次の上限を更新します。
クリーンアップ
次のセクションでは、このデプロイで使用したGoogle Cloud プロジェクトについて、今後料金が発生しないようにする方法について説明します。
Google Cloud プロジェクトを削除する
このデプロイで使用したリソースについて、 Google Cloud アカウントに課金されないようにするには、 Google Cloud プロジェクトを削除します。