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用のユーザー・ロール・ウェアハウス・データベースが作成されます。
ユーザー

ロール

ウェアハウス

データベース

主なスキーマは次のとおりです。
| スキーマ | 概要 |
| 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 スキーマにビューで定義されています。

定義は次のとおりです。
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用ユーザーには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;ルールが追加されました。

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

怒られたログが 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 を見てみましょう。

先に起こしておいたアクセス制御エラーが、しっかり検出されています。
このように、クエリでアラート検出ルールをカスタマイズすることができます。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