このページでは、Common Expression Language(CEL)と YAML を使用してカスタム モジュール定義をコーディングする方法について説明します。
Google Cloud CLI を使用して、カスタム モジュール定義を Security Health Analytics にアップロードします。
YAML ファイルでは、カスタム モジュール定義は、Security Health Analytics カスタム モジュールの次の要素を定義する、構造化された一連のプロパティで構成されています。
- スキャンするリソース。
- 使用する検出ロジック。
- 検出された問題を迅速に把握し、優先順位を付けて解決するために、セキュリティ チームに提供される情報。
YAML 定義を構成する特定の必須のプロパティとオプションのプロパティは、コーディングの手順に含まれています。
冗長な検出器の作成を避ける
検出結果の量を制御するには、冗長機能を含むモジュールを作成、実行しないでください。
たとえば、30 日後にローテーションされない暗号鍵を確認するカスタム モジュールを作成する場合は、90 日という値を使用する確認は不要であるため、組み込みの Security Health Analytics 検出器 KMS_KEY_NOT_ROTATED
を無効にすることを検討してください。
検出器の無効化の詳細については、検出器を有効または無効にするをご覧ください。
コーディング手順
Security Health Analytics のカスタム モジュールの定義を、一連の YAML プロパティとしてコーディングします。ここで、一部のプロパティは CEL 式を含んでいます。
カスタム定義モジュールをコーディングするには、次の手順に従います。
yaml
ファイル名拡張子を持つテキスト ファイルを作成します。テキスト ファイルで
resource_selector
プロパティを作成し、スキャンするカスタム モジュールに 1 ~ 5 個のリソースタイプを指定します。カスタム モジュール定義でリソースタイプを複数回指定できません。例:resource_selector: resource_types: ‐ cloudkms.googleapis.com/CryptoKey
指定するリソースタイプは Security Command Center でサポートされている必要があります。サポートされているリソースタイプの一覧については、サポートされているリソースタイプをご覧ください。
predicate
プロパティを作成し、スキャンするリソースタイプのプロパティを確認する 1 つ以上の CEL 式を指定します。CEL 式で参照するあらゆるプロパティは、resource_selector
で指定した各リソースタイプの Google Cloud API 定義に存在している必要があります。検出結果をトリガーするには、式をTRUE
に解決する必要があります。たとえば、次の式では、2592000s
より大きいrotationPeriod
値のみが検出結果をトリガーします。predicate: expression: resource.rotationPeriod > duration("2592000s")
CEL 式の作成のヘルプについては、次のリソースをご覧ください。
- サポートされるリソースタイプ各リソースをクリックすると、CEL 式で使用できるプロパティが表示されます。
- CEL 式の作成。
- カスタム モジュールのリソース プロパティとポリシー プロパティの参照。
カスタム モジュールが検出する脆弱性または構成ミスを説明する
description
プロパティを作成します。この説明は、調査員が検出された問題を理解できるように、各検出結果のインスタンスに表示されます。テキストは引用符で囲む必要があります。例:description: "The rotation period of the identified cryptokey resource exceeds 30 days, the maximum rotation period that our security guidelines allow."
検出された問題の解決方法を説明する
recommendation
プロパティを作成します。gcloud CLI では、引用符などの特定の文字の前にエスケープ文字が必要です。次の例では、引用符の各組をエスケープするバックスラッシュの使用法を示してします。recommendation: "To fix this issue go to https://console.cloud.google.com/security/kms. Click the key-ring that contains the key. Click the key. Click \"Edit rotation period\". Then set the rotation period to at most 30 days."
Google Cloud コンソールを使用してカスタム モジュールを作成または更新する場合、エスケープ文字は必要ありません。
severity
プロパティを作成し、このモジュールによって作成される検出結果のデフォルトの重大度を指定します。severity
プロパティでよく使用される値は、LOW
、MEDIUM
、HIGH
、CRITICAL
です。次に例を示します。severity: MEDIUM
必要に応じて、
custom_output
プロパティを作成し、各検出結果とともに返す追加情報を指定します。1 つ以上の名前と値のペアとして返す情報を指定します。スキャンされたリソースのプロパティ値とリテラル文字列のいずれかを返すことができます。プロパティはresource.PROPERTY_NAME
として指定する必要があります。リテラル文字列は引用符で囲む必要があります。次の例は、プロパティ値とスキャンされたCryptoKey
リソース内のrotationPeriod
の値の両方、およびテキスト文字列"Excessive rotation period for CryptoKey"
を返すcustom_output
定義を示しています。custom_output: properties: - name: duration value_expression: expression: resource.rotationPeriod - name: note value_expression: expression: "Excessive rotation period for CryptoKey"
gcloud CLI でアクセスできるロケーションにファイルを保存します。
次のコマンドで、定義を Security Health Analytics にアップロードします。
gcloud scc custom-modules sha create \ --organization=organizations/ORGANIZATION_ID \ --display-name="MODULE_DISPLAY_NAME" \ --enablement-state="ENABLED" \ --custom-config-from-file=DEFINITION_FILE_NAME.yaml
次の値を置き換えます。
ORGANIZATION_ID
は、カスタム モジュールの親組織の ID に置き換えます。または、--organization
フラグを--folders
と--project
のいずれかに置き換え、親のフォルダまたはプロジェクトの ID を指定します。MODULE_DISPLAY_NAME
は、カスタム モジュールが検出結果を返すときに、検出結果のカテゴリとして表示する名前に置き換えます。名前は 1~128 文字で、先頭は英小文字にします。それ以降は、英数字とアンダースコアのみを使用してください。DEFINITION_FILE_NAME
は、カスタム モジュールの定義を含む YAML ファイルのパスとファイル名に置き換えます。
Security Health Analytics カスタム モジュールの操作の詳細については、Security Health Analytics 用のカスタム モジュールの使用をご覧ください。
新しいカスタム モジュールのスキャン レイテンシ
カスタム モジュールを作成しても、新しいスキャンがトリガーされることはありません。
Security Health Analytics は、次のいずれかまでは、新しいカスタム モジュールの使用を開始しません。
- カスタム モジュール作成後の最初のバッチスキャン。バッチスキャン スケジュールでカスタム モジュールを作成するタイミングによっては、Security Health Analytics がカスタム モジュールの使用を開始するまでに最大 24 時間待つ必要がある場合があります。
- ターゲット リソースが変更されると、リアルタイム スキャンがトリガーされます。
カスタム モジュールの定義の例
次の例は、cloudkms.googleapis.com/CryptoKey
リソースの rotationPeriod
プロパティの値が 2,592,000 秒(30 日)より大きい場合に検出結果をトリガーする完全なカスタム モジュール定義を示しています。例では、custom_output
セクションに、resource.rotationPeriod
の値とテキスト文字列のメモの 2 つのオプションの値が返されます。
例では、次の要素をメモします。
- 確認するアセットまたはリソースのタイプは、
resource_types
の下のresource_selector
セクションに一覧表示されます。 - モジュールがリソースに対して実行するチェックと検出ロジックは、
expression
で始まるpredicate
セクションで定義されます。 custom_output
セクションには、duration
とviolation
の 2 つのカスタム ソース プロパティが定義されています。- 検出された問題の説明は
description
プロパティに指定されています。 - 検出された問題の修正に関するガイダンスは、
recommendation
プロパティに指定されています。ガイダンスには引用符があるため、各引用符の前にバックスラッシュのエスケープ文字が必要です。
severity: HIGH
description: "Regular key rotation helps provide protection against
compromised keys, and limits the number of encrypted messages available
to cryptanalysis for a specific key version."
recommendation: "To fix this issue go to
https://console.cloud.google.com/security/kms. Click the key-ring that
contains the key. Click the key. Click \"Edit rotation period\". Then
set the rotation period to at most 30 days."
resource_selector:
resource_types:
- cloudkms.googleapis.com/CryptoKey
predicate:
expression: resource.rotationPeriod > duration("2592000s")
custom_output:
properties:
- name: duration
value_expression:
expression: resource.rotationPeriod
- name: violation
value_expression:
expression:
"Excessive rotation period for CryptoKey"
カスタム モジュールのリソース プロパティとポリシー プロパティの参照
カスタム モジュールを作成する方法が、Google Cloud コンソールを使用するか、自分で定義を記述するかのいずれかにかかわらず、カスタム モジュールで評価できるプロパティを検索できる必要があります。また、カスタム モジュール定義でプロパティを参照する方法も理解する必要もあります。
リソースまたはポリシーのプロパティを確認する
Google Cloud リソースのプロパティは、リソースの API 定義で定義されます。この定義を確認するには、サポートされるリソースタイプでリソース名をクリックしてください。
ポリシーのプロパティは、IAM API リファレンス ドキュメントで確認できます。ポリシーのプロパティについては、ポリシーをご覧ください。
カスタム モジュール定義でリソース プロパティを参照する
カスタム モジュールを作成する場合、スキャンされるリソースのプロパティへの直接参照は resource
で始まり、その後に任意の親プロパティ、最後にターゲット プロパティが続く必要があります。プロパティは、JSON スタイルのドット表記を使用してピリオドで区切ります。
次に、リソース プロパティとそれらを取得する方法の例を示します。
resourceName
: Cloud Asset Inventory にリソースの完全な名前(たとえば、//cloudresourcemanager.googleapis.com/projects/296605646631
)が保存されます。resource.rotationPeriod
: ここで、rotationPeriod
はresource
のプロパティです。resource.metadata.name
: ここで、name
はmetadata
(resource
のサブプロパティ)のサブプロパティです。
IAM ポリシーのプロパティを参照する
リソースの IAM ポリシー プロパティを参照することで、リソースの IAM ポリシーを評価する CEL 式を作成できます。使用できるプロパティは、バインディングとバインディング内のロールのみです。
IAM ポリシー プロパティを参照する場合、policy
はトップレベル プロパティです。
次に、IAM ポリシーのプロパティとそれらを取得する方法の例を示します。
policy.bindings
: ここで、bindings
はpolicy
のプロパティです。policy.version
: ここで、version
はpolicy
のプロパティです。
その他の例については、CEL 式の例をご覧ください。
ポリシーのプロパティについては、ポリシーをご覧ください。
CEL 式の記述
カスタム モジュールを作成する場合、CEL 式を使用してスキャンされたリソースのプロパティを評価します。必要に応じて、CEL 式を使用して、カスタム name
-value
ペアを定義し、検出結果とともに追加情報を返すこともできます。
Google Cloud コンソールでカスタム モジュールを作成するか、YAML ファイルにカスタム モジュール定義を記述するかに関わらず、定義する CEL 式は同じです。
検出ロジックの CEL 式
カスタム モジュールの検出ロジックをコーディングするには、CEL 式で標準の CEL 演算子を使用し、スキャンされたリソースのプロパティを評価します。
式は、単一の値の単純なチェックのもの、あるいは複数の値または条件をチェックする複雑な複合式にできます。いずれの場合も、式をブール値 true
に解決して検出をトリガーする必要があります。
Google Cloud コンソールでカスタム モジュールを作成する場合は、[モジュールを構成する] ページの [式エディタ] でこれらの式を記述します。
カスタム モジュールを YAML ファイルにコーディングする場合は、これらの式を predicate
プロパティに追加します。
Google Cloud コンソールと YAML ファイルのどちらを使用するかに関わらず、リソース プロパティを評価する CEL 式は、次のルールに従う必要があります。
- リソースタイプの API 定義で定義されているように、CEL 式に指定するプロパティは、スキャンされたリソースのプロパティである必要があります。
カスタム モジュールで複数のリソースタイプが評価される場合、CEL 式で指定するプロパティは、カスタム モジュールが評価する各リソースタイプで共通している必要があります。
たとえば、
cloudkms.googleapis.com/CryptoKey
とcloudkms.googleapis.com/CryptoKeyVersion
の 2 つのリソースタイプをチェックするinvalid_cryptokey
というカスタム モジュールを定義する場合、CryptoKey
とCryptoKeyVersion
の両方のリソースタイプにname
プロパティが含まれているため、次の式を作成できます。predicate: resource.name.matches("projects/project1/locations/us-central1/keyRings/keyring1/cryptoKeys/.*")
ただし、式で評価する
importTime
とrotationPeriod
のプロパティは両方のリソースタイプで共有されないため、invalid_cryptokey
カスタム モジュールで次の式を指定できません。predicate: resource.importTime >= timestamp("2022-10-02T15:01:23Z") || resource.rotationPeriod > duration("2592000s")
CEL 式内のすべての列挙型は文字列として表す必要があります。たとえば、
cloudkms.googleapis.com/CryptoKeyVersion
リソースタイプの有効な式は次のとおりです。resource.state = "PENDING_GENERATION"
predicate
プロパティに定義した CEL 式の結果はブール値でなければなりません。検出結果は、結果がtrue
の場合にのみトリガーされます。
CEL の詳細については、以下をご覧ください。
CEL 式の例
次の表に、リソースのプロパティを評価するのに使用できる CEL 式を示します。これらは、Google Cloud コンソールと YAML カスタム モジュール定義の両方で使用できます。
リソースの種類 | 説明 | CEL 式 |
---|---|---|
IAM ポリシーを持つあらゆるリソース | 外部ドメインからのメンバーを識別するための IAM ポリシーの確認 | !policy.bindings.all(binding, binding.members.all(m ,!m.endsWith('@gmail.com'))) |
cloudkms.googleapis.com/CryptoKey |
Cloud KMS 鍵のローテーション期間の確認 | has(resource.rotationPeriod) && resource.rotationPeriod > duration('60h') |
単一のポリシーを持つ複数のリソースタイプ | リソースタイプに基づいて、リソース名が dev または devAccess で始まるかどうかを確認する |
(resource.type == 'compute.googleapis.com/Disk' &&
resource.name.startsWith('projects/PROJECT_ID/regions/
REGION/disks/devAccess')) || (resource.type ==
'compute.googleapis.com/Instance ' &&
resource.name.startsWith('projects/PROJECT_ID/zones/REGION/instances/dev-')) |
compute.googleapis.com/Network |
ネットワーク ピアに一致する Virtual Private Cloud ピアリング ルール | resource.selfLink.matches('https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/default') || resource.peerings.exists(p, p.network.matches('https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/shared$')) |
cloudfunctions.googleapis.com/CloudFunction |
Cloud Function 向けの内部上り(内向き)トラフィックのみを許可する | has(resource.ingressSettings) && resource.ingressSettings.matches('ALLOW_INTERNAL_ONLY') |
compute.googleapis.com/Instance |
リソース名とパターンの一致 | resource.name.matches('^gcp-vm-(linux|windows)-v\\d+$') |
serviceusage.googleapis.com/Service |
ストレージ関連の API の有効化のみを許可する | resource.state == 'ENABLED' && !( resource.name.matches('storage-api.googleapis.com') || resource.name.matches('bigquery-json.googleapis.com') || resource.name.matches('bigquery.googleapis.com') || resource.name.matches('sql-component.googleapis.com') || resource.name.matches('spanner.googleapis.com'))
|
sqladmin.googleapis.com/Instance
|
許可リストに登録されたパブリック IP のみが許可される | (resource.instanceType == 'CLOUD_SQL_INSTANCE' && resource.backendType == 'SECOND_GEN' && resource.settings.ipConfiguration.ipv4Enabled ) && !(resource.ipAddresses.all(ip, ip.type != 'PRIMARY' || ip.ipAddress.matches('IP_ADDRESS'))))
|
dataproc.googleapis.com/Cluster |
Dataproc クラスタのプロジェクト ID に部分文字列のテストまたは作成が含まれているかどうかを確認する | has(resource.projectId) && resource.projectId.contains('testing') || resource.projectId.contains('development') |
カスタム検出プロパティの CEL 式
検出結果クエリに使用できる検出結果ごとに追加情報を返すように、カスタム モジュールによって生成された検出結果とともに返すカスタム プロパティを 10 個まで定義できます。
カスタム プロパティは、JSON の検出結果のソース プロパティと、Google Cloud コンソールの検出結果の詳細の [ソース プロパティ] タブに表示されます。
カスタム プロパティは name
-value
ペアとして定義します。
Google Cloud コンソールでカスタム モジュールを作成する場合は、name
-value
ペアを、検出結果の詳細を定義するページのカスタム検出結果のプロパティセクションで定義します。
カスタム モジュールを YAML ファイルにコーディングする場合は、name
と value
のペアを custom_output
プロパティの下に properties
として記述します。
Google Cloud コンソールと YAML ファイルのどちらを使用しているかに関わらず、次のルールが適用されます。
name
を引用符なしのテキスト文字列として指定します。value
は次のいずれかとして指定します。プロパティの値を返すには、次の形式でプロパティを指定します。
RESOURCE_TYPE.PROPERTY.PROPERTY_TO_RETURN
例:
RESOURCE_TYPE
はresource
とpolicy
のいずれかにできます。PROPERTY
は、返す値を含むプロパティの 1 つ以上の親プロパティです。PROPERTY_TO_RETURN
は、返す値を含むプロパティです。テキスト文字列を返すには、文字列を引用符で囲みます。
次の例は、YAML ファイル内の custom_output
に適切に定義された 2 つの name
-value
ペアを示しています。
custom_output: properties: - name: duration value_expression: expression: resource.name - name: property_with_text value_expression: expression: "Note content"
次のステップ
カスタム モジュールをテスト、送信、表示、更新する方法については、次のページをご覧ください。
- カスタム モジュールをテストするには、Security Health Analytics のカスタム モジュールをテストするをご覧ください。
- カスタム モジュールをアップロード、表示、更新するには、Security Health Analytics のカスタム モジュールの作成と管理をご覧ください。