Snowflake 

SnowAlertではじめる Snowflakeのセキュリティチェック

SnowAlertとは?

SnowAlertとは、Snowflakeでのセキュリティインシデントやポリシー違反を検出するセキュリティ分析フレームワークです。
Snowflakeを使用するにあたって、ユーザーにMFA(多要素認証)を設定する等、セキュリティポリシーに沿って様々な対応を実施されているかと思います。 では、セキュリティポリシーが守られているか、どのようにチェックされているでしょうか? もし、違反が発生しているのであれば、一刻も速く発見したいのではないでしょうか。
SnowAlertを用いて、Snowflakeアカウントで発生したセキュリティ問題をアラートとして検出することができます。 Snowflakeへのアクセス履歴やアカウントでの操作履歴をもとにセキュリティ分析を行い、発見したアラートや違反の内容をSnowflake内に保存します。 アラートとして検出する項目はビューで定義されており、必要に応じてカスタマイズすることが可能です。
この記事では、SnowAlertのインストール方法とアラート検出の方法をご紹介します。

SnowAlertのインストール

公式ドキュメントのGetting Started に従って進めます。
あらかじめ、インストールに必要な次の情報を準備してください:
・SnowflakeアカウントのURLまたはアカウント名
・ユーザー名とパスワード(ACCOUNTADMINロールを利用可能なこと)

次のコマンドでインストールを実行します。

$ docker run -it  snowsec/snowalert ./install

以下、インストールは対話型で進みます。<account>.<region>.<provider> はお使いのアカウントのURLまたはアカウント名に、 <user_name> は使用するユーザー名に、<user_password> はパスワードに置き換えてください。

Starting installer for SnowAlert.
Snowflake account where SnowAlert can store data, rules, and results (URL or account name): <account>.<region>.<provider>
Next, authenticate installer --
Snowflake username: <user_name>
Password [leave blank for SSO for authentication]: <user_password> ※入力文字列は見えません
Authenticating to Snowflake.. ✓
Use role accountadmin... ✓
Creating warehouse... ✓
Creating database... ✓
Creating role and user..... ✓
Granting role to user... ✓
Granting account level privileges to SA role.... ✓
Use database snowalert... ✓
Creating schemas..... ✓
Creating alerts & violations tables....... ✓
Creating standard UDTFs......... ✓
Creating standard data views...................... ✓
Retrieving sample data share(s)... ✓
Creating sample data view.... ✓
Creating sample alert...... ✓
Creating sample violation... ✓
Granting object level privileges to SA role.......... ✓

次に、アラートをJiraに連携するか選択します。今回は省略します。

Would you like to integrate Jira with SnowAlert (y/N)? N  ※省略

--- DB setup complete! Now, let's prep the runners... ---

次に、SnowAlert用ユーザーにRSA鍵を割り当てます。<key_passphase> にはSnowAlert用ユーザーに割り当てるRSA鍵に対するパスフレーズを指定してください。

The access key for SnowAlert's Snowflake account can have a passphrase, if you wish.
RSA key passphrase [blank for none, '.' for random]: <key_passphase> ※入力文字列は見えません
Generated random passphrase.

Additionally, you may use Amazon Web Services for encryption and audit.
Enter IAM KMS KeyId or 'alias/{KeyAlias}' [blank for none, '.' for new]: ※省略
Setting auth key on snowalert user... ✓

--- ...all done! Next, run... ---

cat <<END_OF_FILE > snowalert-<account>.envs
SNOWFLAKE_ACCOUNT=<account>
SA_USER=snowalert
SA_ROLE=snowalert
SA_DATABASE=snowalert
SA_WAREHOUSE=snowalert
REGION=<region>.<provider>
PRIVATE_KEY=XXXXXXXXXX
PRIVATE_KEY_PASSWORD=<key_passphase>
END_OF_FILE

### ...and then... ###

docker run --env-file snowalert-<account>.envs snowsec/snowalert ./run all

--- ...the end. ---

インストールが完了しました。
Snowflakeアカウントには、次のようにSnowAlert用のユーザー・ロール・ウェアハウス・データベースが作成されます。

ユーザー

SnowAlertではじめる Snowflakeのセキュリティチェック_1

ロール

SnowAlertではじめる Snowflakeのセキュリティチェック_2

ウェアハウス

SnowAlertではじめる Snowflakeのセキュリティチェック_3

データベース

SnowAlertではじめる Snowflakeのセキュリティチェック_4

主なスキーマは次のとおりです。

スキーマ概要
RULESアラート検出ルール
RESULTSアラート検出結果
DATAアラート検出結果のサマリ
その他、アラート検出クエリで使用するビュー・関数など

アラート検出

インストールが完了したら、アラート検出を実行してみましょう。

まず、インストール実行時に出力された cat コマンドをターミナルにコピー&ペーストして、snowalert-<account>.envs ファイルを作成します。

cat <<END_OF_FILE > snowalert-<account>.envs
SNOWFLAKE_ACCOUNT=<account>
SA_USER=snowalert
SA_ROLE=snowalert
:
END_OF_FILE

アラート検出を実行します。インストールと同じくDocker コマンドで実行します。

$ docker run --env-file snowalert-<account>.envs snowsec/snowalert ./run all

アラート検出は自動で行われます。

running in docker container-like environment
[8] STARTING RUN WITH ID 60388b0951534502aba341a0a323a0a4
[8] got command all
[8] Loaded 5 views, 1 were 'VIOLATION_QUERY' rules.
[8] NO_VIOLATION_QUERIES_IN_TOO_LONG_VIOLATION_QUERY processing...
[8] NO_VIOLATION_QUERIES_IN_TOO_LONG_VIOLATION_QUERY created 0 rows.
[8] NO_VIOLATION_QUERIES_IN_TOO_LONG_VIOLATION_QUERY metadata recorded.
[8] NO_VIOLATION_QUERIES_IN_TOO_LONG_VIOLATION_QUERY done.
[8] RUN metadata recorded.
[8] Loaded 5 views, 0 were 'VIOLATION_SUPPRESSION' rules.
[8] RUN metadata recorded.
[8] Loaded 5 views, 3 were 'ALERT_QUERY' rules.
[38] SNOWFLAKE_LOGIN_WITHOUT_MFA_ALERT_QUERY processing...
[37] ACTIVITY_BY_ADMIN_ALERT_QUERY processing...
[38] SNOWFLAKE_LOGIN_WITHOUT_MFA_ALERT_QUERY created 1, updated 0 rows.
[39] SNOWFLAKE_RESOURCE_CREATION_ALERT_QUERY processing...
[37] ACTIVITY_BY_ADMIN_ALERT_QUERY created 0, updated 0 rows.
[39] SNOWFLAKE_RESOURCE_CREATION_ALERT_QUERY created 0, updated 0 rows.
[38] SNOWFLAKE_LOGIN_WITHOUT_MFA_ALERT_QUERY metadata recorded.
[38] SNOWFLAKE_LOGIN_WITHOUT_MFA_ALERT_QUERY done.
[37] ACTIVITY_BY_ADMIN_ALERT_QUERY metadata recorded.
[37] ACTIVITY_BY_ADMIN_ALERT_QUERY done.
[39] SNOWFLAKE_RESOURCE_CREATION_ALERT_QUERY metadata recorded.
[39] SNOWFLAKE_RESOURCE_CREATION_ALERT_QUERY done.
[8] RUN metadata recorded.
[8] Loaded 5 views, 1 were 'ALERT_SUPPRESSION' rules.
[8] SINGLE_FACTOR_EXCEPTIONS_ALERT_SUPPRESSION processing...
[8] SINGLE_FACTOR_EXCEPTIONS_ALERT_SUPPRESSION updated 0 rows.
[8] SINGLE_FACTOR_EXCEPTIONS_ALERT_SUPPRESSION metadata recorded.
[8] SINGLE_FACTOR_EXCEPTIONS_ALERT_SUPPRESSION done.
[8] All suppressions done, 1 remaining alerts marked suppressed=FALSE.
[8] RUN metadata recorded.
[8] the correlation id for alert bd6f9815-f5cd-4745-8828-c7724adc7ee7 is 89358d67612142cea9c68276e368c52d
[8] correlation id successfully updated
[8] Found 1 new alerts to handle.

アラートが1つ発見されていますね。理由はこのあたりから読み解けそうです。

[38] SNOWFLAKE_LOGIN_WITHOUT_MFA_ALERT_QUERY created 1, updated 0 rows.

SNOWFLAKE_LOGIN_WITHOUT_MFA_ALERT_QUERY は、MFAが設定されていないユーザーがログインしたことを検出するルールです。RULES スキーマにビューで定義されています。

SnowAlertではじめる Snowflakeのセキュリティチェック_6

定義は次のとおりです。

CREATE OR REPLACE VIEW SNOWALERT.RULES.SNOWFLAKE_LOGIN_WITHOUT_MFA_ALERT_QUERY COPY GRANTS
  comment = 'Alerts on someone logging into Snowflake without MFA\n  @id 386cd552d3054474b8dec3d9bb7b7e96\n  @tags snowflake, mfa requirements' 
AS
SELECT 'Successful Snowflake login without MFA' AS title
     , ARRAY_CONSTRUCT('successful_snowflake_logins') AS sources
     , user_name AS object
     , 'SnowAlert' AS environment
     , event_timestamp AS event_time
     , CURRENT_TIMESTAMP() AS alert_time
     , reported_client_type || ' logging in as ' || user_name || ' from ' || client_ip AS description
     , user_name AS actor
     , 'login' AS action
     , 'SnowAlert' AS detector
     , OBJECT_CONSTRUCT(*) AS event_data
     , 'low' AS severity
     , '386cd552d3054474b8dec3d9bb7b7e96' AS query_id
FROM data.successful_snowflake_logins_v // information_schema からログイン成功履歴を抽出するビュー
WHERE 1=1
  AND second_authentication_factor IS NULL
  AND DATEDIFF(MINUTE, event_timestamp, CURRENT_TIMESTAMP()) < 60
;

検出したアラートの情報は RESULTS.ALERTS に蓄積されます。調べてみましょう。

SnowAlertではじめる Snowflakeのセキュリティチェック_7

SnowAlert用ユーザーにはMFAを設定していないので、アラート検出を実行する際、自身がアラートに引っかかってしまったようです。

このようにして、アラートの検出が行われます。
ここで確認したMFA未設定ユーザーに対する検出ルールは、SnowAlertにデフォルトで設定されているものでした。次に、アラート検出ルールのカスタマイズ方法について説明します。

アラート検出ルールのカスタマイズ

アラート検出ルールは、Snowflakeのワークシート、SnowSQLまたはSnowAlert WebUIでカスタマイズすることができます。
今回は簡単な例として、SnowAlertクエリパックというサンプルクエリのうち「権限不足のために失敗したクエリ実行を検知する」ルールを追加してみます。
ワークシートで、次のクエリを実行します。

CREATE OR REPLACE VIEW rules.snowflake_authorization_error_alert_query COPY GRANTS AS
SELECT
      OBJECT_CONSTRUCT('cloud', 'Snowflake', 'account', current_account()) AS environment
    , ARRAY_CONSTRUCT('snowflake') AS sources
    , 'Snowflake Query' AS object
    , 'Snowflake Access Control Error' AS title
    , START_TIME AS event_time
    , current_timestamp() AS alert_time
    , 'User ' || USER_NAME || ' received ' || ERROR_MESSAGE AS description
    , 'SnowAlert' AS detector
    , ERROR_MESSAGE AS event_data
    , USER_NAME AS actor
    , 'Received an authorization error' AS action
    , 'Low' AS severity
    , 'b0724d64b40d4506b7bc4e0caedd1442' AS query_id
    , 'snowflake_authorization_error_alert_query' AS query_name
from snowflake.account_usage.query_history
WHERE 1=1
  AND error_code in (1063, 3001, 3003, 3005, 3007, 3011, 3041)
order by
  EVENT_TIME desc
;

GRANT SELECT ON VIEW rules.snowflake_authorization_error_alert_query TO ROLE snowalert;

ルールが追加されました。

SnowAlertではじめる Snowflakeのセキュリティチェック_8

次に、アラートを出すために一度怒られておきます。

SnowAlertではじめる Snowflakeのセキュリティチェック_9

怒られたログが SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY に記録されるまでしばらく待った後、再びアラート検出を実行します。

$ docker.exe run --env-file snowalert-nn20886.envs snowsec/snowalert ./run all
running in docker container-like environment
[7] STARTING RUN WITH ID e07835e0c3aa4be6a77b1ec5056395c9
[7] got command all
:(中略)
[37] SNOWFLAKE_AUTHORIZATION_ERROR_ALERT_QUERY created 1, updated 0 rows.
:(中略)
[7] Found 1 new alerts to handle.

追加したルールに、何か引っかかっていますね。 RESULTS.ALERTS を見てみましょう。

SnowAlertではじめる Snowflakeのセキュリティチェック_10

先に起こしておいたアクセス制御エラーが、しっかり検出されています。
このように、クエリでアラート検出ルールをカスタマイズすることができます。Snowflakeユーザーとしては、書きなれたSQLだけでルール設定ができるのはありがたいですね。

さいごに

Snowflakeのセキュリティ分析フレームワークであるSnowAlertについて、インストールと簡単な使い方をご紹介しました。
今回ご紹介した機能の他にも、アラートを検出したとき自動的にJiraに起票したりSlackに連携することができる連携機能や、アラート検出ルールを管理するWebアプリケーションであるSnowAlert WebUIなど、便利な機能があります。
この記事が、Snowflakeのセキュリティ分析でお悩みの方のために、少しでもお役に立てば幸いです。

参考記事

SnowAlert: Security Analytics on Snowflake
SNOWALERT! DATA DRIVEN SECURITY ANALYTICS USING SNOWFLAKE CLOUD DATA PLATFORM



DATUM STUDIOは、クライアントの事業成長と経営課題解決を最適な形でサポートする、データ・ビジネスパートナーです。
データ分析の分野でお客様に最適なソリューションをご提供します。まずはご相談ください。

このページをシェアする: