サービスネットワーキング

Snowpark Container Servicesのサービスでは、次の3種類のネットワーキングがあります。

  • Ingressネットワーク:外部からサービスに接続する方法。

  • Ingress:サービスがインターネット上の他のサービスに接続する方法、またはプライベートリンクを介して接続する方法。

  • Snowpark Container Servicesにおけるサービス間通信。

次のセクションでは、各種類のネットワークの構成方法について説明します。

ネットワークイングレスの構成

インターネットからサービスとのやり取りできるようにするには、サービスがリッスンしているネットワークポートを、サービス仕様ファイルのエンドポイントとして宣言します。これらのエンドポイントはイングレスを制御します。

デフォルトでは、サービスエンドポイントはプライベートです。サービス関数サービス間通信 のみがプライベートエンドポイントにリクエストできます。エンドポイントをパブリックと宣言すると、インターネットからエンドポイントへのリクエストを許可することができます。パブリックエンドポイントの作成は権限操作であり、サービスの所有者ロールはアカウントで BIND SERVICE ENDPOINT 権限を持っている必要があります。

endpoints:
- name: <endpoint name>
  port: <port number>
  protocol : < TCP / HTTP >
  public: true
  corsSettings:                  # optional CORS configuration
    Access-Control-Allow-Origin: # required list of allowed origins
      - <origin>                 # for example, "http://example.com"
      - <origin>
        ...
    Access-Control-Allow-Methods: # optional list of HTTP methods
      - <method>
      - <method>
        ...
    Access-Control-Allow-Headers: # optional list of HTTP headers
      - <header-name>
      - <header-name>
        ...
    Access-Control-Expose-Headers: # optional list of HTTP headers
      - <header-name>
      - <header-name>
        ...
Copy

例については、 チュートリアル1 をご参照ください。

イングレス接続のタイムアウト

イングレスエンドポイントのタイムアウトは90秒です。イングレスエンドポイントへの接続に90秒間アクティビティがない場合、Snowflakeは接続を終了します。アプリケーションでもっと長く接続する必要がある場合は、ポーリングまたは WebSockets を使用します。

イングレスウェブブラウザー認証ログアウト

サービスとして動作するウェブアプリを構築している場合、ユーザーを /sfc-endpoint/logout に誘導してアプリからログアウトできるようにするオプションがあります。

ログアウト後、ユーザーはサービスのパブリックエンドポイントにアクセスするためにSnowflakeへの再認証が必要となります。

イングレスとウェブアプリのセキュリティ

パブリックエンドポイントサポート(ネットワークイングレス)を使用して、ウェブホスティング用のSnowpark Container Servicesサービスを作成できます。セキュリティを強化するために、Snowflakeはプロキシサービスを採用して、クライアントからサービスへの受信リクエストと、サービスからクライアントへの送信応答をモニターします。このセクションでは、プロキシが何を行い、Snowpark Container Servicesに展開されたサービスにどのような影響を与えるかを説明します。

注釈

ローカルでサービスをテストする場合はSnowflakeプロキシを使用しないため、Snowpark Container Servicesに展開した場合とローカルでサービスを実行した場合のエクスペリエンスに違いが生じます。このセクションを確認し、より良いテストのためにローカル設定を更新してください。

例:

  • 禁止されている HTTP メソッドをリクエストが使用する場合、プロキシは受信 HTTP リクエストを転送しません。

  • プロキシは、応答のContent-Typeヘッダーが実行可能ファイルを含むことを示す場合は、403応答をクライアントに送信します。

さらに、プロキシはリクエストと応答に新しいヘッダーを注入したり、既存のヘッダーを変更したりすることもできます。

たとえば、リクエストを受信すると、サービスは応答で HTML、 JavaScript、 CSS などのウェブページのコンテンツをクライアントのブラウザーに送信する可能性があります。ブラウザー上のウェブページはサービスの一部であり、ユーザーインターフェイスとして機能します。セキュリティ上の理由から、サービスに制限がある場合(他サイトへのネットワーク接続の制限など)に、サービスのウェブページにも同じ制限を設けたい場合があります。

デフォルトでは、サービスはインターネットにアクセスする権限が制限されている。ブラウザーでも、クライアントアプリがインターネットにアクセスし、データを共有する可能性を制限する必要があります。外部アクセス統合(EAI)を設定してサービスが example.comネットワークエグレスの構成 を参照)にアクセスできるようにすると、サービスのウェブページもブラウザーを通して example.com にアクセスできるようになります。

Snowflakeプロキシは、応答に Content-Security-Policy (CSP)ヘッダーを追加して、サービスとウェブページに同じネットワーク制限を適用します。デフォルトでは、プロキシは一般的なセキュリティの脅威から守るために、応答にベースライン CSP を追加します。ブラウザーのセキュリティは、機能性とセキュリティのバランスをとるためのベストエフォートであり、このベースラインがあなたのユースケースに適切であることを確認することは、共有された責任です。さらに、サービスが EAI を使用するように設定されている場合、プロキシはウェブページに対して EAI から CSP まで同じネットワークルールを適用します。この CSP により、ブラウザーのウェブページは、サービスがアクセスできるのと同じサイトにアクセスできるようになります。

Snowflakeは、サービス仕様で構成する CORS サポートを提供します。

Snowflakeプロキシは、サービス仕様で定義されている CORS 設定を返します。プロキシはサービスによって返された CORS ヘッダーをすべて削除することに注意してください。

以下の CORS ヘッダーはデフォルトでセットされています。

  • Access-Control-Expose-Headers ヘッダーは、エンドポイントのサービス仕様で構成されたヘッダーに加えて、常に以下のヘッダー名を報告します。

    • X-Frame-Options

    • Cross-Origin-Opener-Policy

    • Cross-Origin-Resource-Policy

    • X-Content-Type-Options

    • Cross-Origin-Embedder-Policy

    • Content-Security-Policy-Report-Only

    • Content-Security-Policy

  • Access-Control-Max-Age は2時間にセットされます。

  • Access-Control-Allow-Credentials はtrueにセットされます。

さらに、Snowflakeは、 Origin の値に基づいて、 Access-Control-Allow-Origin の値が異なる可能性があることをブラウザーに示すために、 Origin の値で Vary ヘッダーをセットします。

CORS リクエストを実行するには、 Authorization ヘッダーが必要です。このヘッダー(Authorization: "Snowflake Token=\"${patToken}\"")にプログラムによるアクセストークン(PAT)を指定できます。プログラムのアクセストークンを生成する方法については、 認証のためのプログラム アクセス トークンの使用 をご参照ください。

以下のセクションでは、Snowflakeプロキシがサービスに対する受信リクエストをどのように処理し、サービスからクライアントへの送信応答をどのように変更するかを説明します。

サービスへの受信リクエスト

リクエストを受信すると、プロキシはリクエストをサービスに転送する前に以下を実行します。

  • 禁止された HTTP メソッドを持つ受信リクエスト: 受信 HTTP リクエストが以下の禁止された HTTP メソッドのいずれかを使用する場合、プロキシはそのリクエストをサービスに転送しません。

    • TRACE

    • CONNECT

  • 受信リクエストヘッダーのスクラブ: Snowflakeプロキシは、以下のリクエストヘッダーが存在する場合は削除します。

    • X-SF-SPCS-Authorization

    • Authorization:Snowflakeトークンが含まれている場合のみ削除され、含まれていない場合はサービスに渡されます。

クライアントへの応答送信

Snowflakeプロキシは、クライアントに応答を転送する前に、サービスから送信された応答にこれらの修正を適用します。

  • ヘッダースクラビング: Snowflakeプロキシは、これらの応答ヘッダーを削除します(存在する場合)。

    • X-XSS-Protection

    • Server

    • X-Powered-By

    • Public-Key-Pins

  • CORS ヘッダー操作: 進入と CORS への配慮 を参照してください。

  • Content-Type応答ヘッダー: サービス応答でContent-Typeヘッダーに次の MIME 型の値(実行可能ファイルを示す)が含まれる場合、Snowflakeプロキシはその応答をクライアントに転送しません。代わりに、プロキシは 403 Forbidden 応答を送信します。

    • application/x-msdownload:Microsoftの実行可能ファイル。

    • application/exe: 汎用実行可能ファイル。

    • application/x-exe: 別の汎用実行可能ファイル。

    • application/dos-exe: DOS の実行可能ファイル。

    • application/x-winexe:Windowsの実行可能ファイル。

    • application/msdos-windows: MS-DOS Windows実行可能ファイル。

    • application/x-msdos-program: MS-DOS 実行可能ファイル。

    • application/x-sh:Unixシェルスクリプト。

    • application/x-bsh:Bourneシェルスクリプト。

    • application/x-csh:Cシェルスクリプト。

    • application/x-tcsh:Tcshシェルスクリプト。

    • application/batch:Windowsバッチファイル。

  • X-Frame-Options応答ヘッダー: クリックジャッキング攻撃を防ぐために、Snowflakeプロキシはこの応答ヘッダーを DENY に設定し、他のウェブページがサービスのウェブページにiframeを使用できないようにします。

  • Cross-Origin-Opener-Policy(COOP)応答ヘッダー: Snowflakeは COOP 応答ヘッダーを same-origin に設定し、参照元のクロスオリジンウィンドウがサービスタブにアクセスできないようにします。

  • Cross-Origin-Resource-Policy(CORP)応答ヘッダー: Snowflakeは CORP ヘッダーを same-origin に設定し、外部サイトが(iframeなどで)イングレスエンドポイントによって公開されたリソースをロードできないようにします。

  • X-Content-Type-Options応答ヘッダー: Snowflakeプロキシはこのヘッダーを nosniff に設定し、クライアントがサービスによって応答に記載された MIME 型を変更できないようにします。

  • Cross-Origin-Embedder-Policy(COEP)応答ヘッダー: Snowflakeプロキシは COEP 応答ヘッダーを credentialless に設定します。これは、画像やスクリプトなどのクロスオリジンオブジェクトをロードするときに、リモートオブジェクトがCross-Origin Resource Sharing(CORS)プロトコルをサポートしていない場合、Snowflakeはそれをロードするときに認証情報を送信しないことを意味します。

  • Content-Security-Policy-Report-Only応答ヘッダー: Snowflakeプロキシは、クライアントに CSP レポートをSnowflakeに送信するよう指示する新しい値で、この応答ヘッダーを置き換えます。

  • Content-Security-Policy(CSP)応答ヘッダー: デフォルトでは、Snowflakeプロキシは、一般的なウェブ攻撃から保護するために、以下のベースライン CSP を追加します。

    default-src 'self' 'unsafe-inline' 'unsafe-eval' blob: data:; object-src 'none'; connect-src 'self'; frame-ancestors 'self';
    
    Copy

    コンテンツセキュリティポリシーの考慮点は2つあります。

    • プロキシが追加するベースラインコンテンツセキュリティポリシーに加えて、サービス自身が応答に明示的に CSP を追加することができます。サービスは、より厳格な CSP を追加して、セキュリティを強化することを選択する場合があります。たとえば、サービスは CSP を追加して、 self からのスクリプトのみを許可する場合があります。

      script-src 'self'
      
      Copy

      結果としてクライアントに送られる応答には、2つの CSP ヘッダーがあります。応答を受信すると、クライアントブラウザーは、各ポリシーによって指定された追加制限を含む、最も厳格なコンテンツセキュリティポリシーを適用します。

    • サービスが外部サイト(ネットワークエグレスの構成)にアクセスできるように外部アクセス統合(EAI)を構成すると、Snowflakeプロキシは、ウェブページがそのサイトにアクセスできるようにする CSP を作成します。たとえば、 EAI に関連付けられているネットワークルールが、サービスに example.com へのエグレスアクセスを許可しているとします。次に、Snowflakeプロキシは以下の CSP 応答ヘッダーを追加します。

      default-src 'self' 'unsafe-inline' 'unsafe-eval' http://example.com https://example.com blob: data:; object-src 'none'; connect-src 'self' http://example.com https://example.com wss://example.com; frame-ancestors 'self';
      
      Copy

      ブラウザーは、応答で受け取ったコンテンツアクセスポリシーを尊重します。この例では、ブラウザーはアプリに example.com へのアクセスを許可しますが、他のサイトへのアクセスは許可しません。

進入と CORS への配慮

デフォルトでは、ブラウザーは、あるサーバーでホストされているウェブアプリが、ホスト名の異なる別のサーバーにリクエストを送信するのをブロックします。例えば、Snowpark Container Services内にデプロイされたバックエンドサービスとやり取りする必要があるウェブアプリをSnowpark Container Servicesの外でホストする場合、この制限が適用されます。

CORS (Cross-Origin Resource Sharing)により、Snowpark Container Servicesサービスは、その環境外でホストされているウェブアプリからのリクエストを許可するよう、ブラウザーに指示することができます。各パブリックエンドポイントを構成して、 CORS プリフライトリクエストと標準リクエストの両方への応答方法を指定できます。

Snowflakeプロキシは常に以下のレスポンスヘッダーを上書きします。

  • Access-Control-Allow-Origin

  • Access-Control-Allow-Methods

  • Access-Control-Allow-Headers

  • Access-Control-Expose-Headers

  • Access-Control-Max-Age

  • Access-Control-Allow-Credentials

Snowflakeプロキシは、以下のいずれかが真である場合、レスポンスにこれらの CORS ヘッダーを含めません。

  • CORS はサービスエンドポイントに構成されていません。つまり、サービス仕様に corsSettings はありません

  • CORS がサービスエンドポイントに構成されていますが、リクエストの Origin ヘッダーがサービス仕様の指定された Access-Control-Allow-Origin フィールドと一致しません

サービス仕様では、各パブリックエンドポイントに対して CORS の設定を行うことができます。リクエストの origin ヘッダーが、仕様でエンドポイントに指定されている Access-Control-Allow-Origin フィールドにマッチするとき、プロキシは以下の調整を加えて、仕様で定義されている CORS ヘッダーをレスポンスに含めます。

  • Access-Control-Allow-Origin: リクエストから Origin ヘッダーを返します。

  • Access-Control-Expose-Headers: 構成した許可ヘッダーのリストを、これらの常時公開ヘッダーとマージします: X-Frame-OptionsCross-Origin-Opener-PolicyCross-Origin-Resource-PolicyX-Content-Type-OptionsCross-Origin-Embedder-PolicyContent-Security-Policy-Report-OnlyContent-Security-Policy

  • Access-Control-Max-Age:2時間にセットされます。

  • Access-Control-Allow-Credentials: trueにセットされます。

進入と SSO への配慮

インターネットからパブリックエンドポイントにアクセスすると、ユーザー名/パスワード認証コードは機能しますが、 SSO では、空白のページが表示されるか、以下のエラーが表示されることがあります。「指定されたOAuth クライアントとの統合 ID が見つかりません。」

この現象は、 フェデレーション認証を使用するためのSnowflakeの構成 で説明されている新しいセキュリティ統合バージョンではなく、Snowflake で古いスタイルの統合認証 (SSO) を使用している場合に発生します。次のことを確認してください。

  1. 以下のクエリを実行します。

    SHOW PARAMETERS LIKE 'SAML_IDENTITY_PROVIDER' IN ACCOUNT;
    
    Copy

    このパラメーターがセットされている場合は、ある時点で旧式の認証コードを使用していたことになります。

  2. 前述のパラメーターがセットされている場合、以下のクエリを実行して、 SAML セキュリティ統合があるかどうかを確認します。

    SHOW INTEGRATIONS
      ->> SELECT * FROM $1 WHERE "type" = 'SAML2';
    
    Copy

    SAML2 タイプの統合がない場合は、旧式の認証コードを使用していることになります。

この大文字と小文字の場合、解決策は、旧式の統合認証から新しい統合形式の統合認証に移行することです。詳細については、 SAML2 セキュリティ統合への移行 をご参照ください。

ネットワークエグレスの構成

アプリケーションコードは、インターネットへのアクセスを必要とする場合があります。デフォルトでは、アプリケーションコンテナーはインターネットにアクセスする権限を持っていません。外部アクセス統合(EAIs) を使用してインターネットアクセスを有効にする必要があります。

通常、サービス(ジョブサービスを含む)から許可される外部アクセスを管理するために、アカウント管理者は EAIs を作成します。アカウント管理者は、開発者がサービスを実行するために使用する特定ロールに EAI の使用権限を付与できます。

次の例は、ネットワークルールを使用して指定された特定の宛先へのエグレストラフィックを許可する EAI を作成するステップの概要を示しています。その後、特定のインターネット宛先へのリクエストを許可するサービスを作成するときに、 EAI を参照します。

アプリケーションコードが、以下の宛先にリクエストを送信するとします。

  • HTTPS が、translation.googleapis.comにリクエストする

  • HTTP と HTTPS が、google.comにリクエストする

以下のステップに従って、サービスがインターネット上のこれらのドメインにアクセスできるようにします。

  1. 外部アクセス統合(EAI)を作成するこれには適切な権限が必要です。たとえば、 ACCOUNTADMIN ロールを使用して EAI を作成することができます。これは2段階のプロセスです。

    1. CREATE NETWORK RULE コマンドを使用して、アクセスを許可する外部宛先をリストした1つ以上のエグレスネットワークルールを作成します。この例は1つのネットワークルールで実現できますが、説明のために2つのネットワークルールを作成します。

      1. translate_network_rule という名前のネットワークルールを作成します。

        CREATE OR REPLACE NETWORK RULE translate_network_rule
          MODE = EGRESS
          TYPE = HOST_PORT
          VALUE_LIST = ('translation.googleapis.com');
        
        Copy

        このルールは、 translation.googleapis.com の宛先への TCP 接続を許可します。VALUE_LIST プロパティのドメインは、オプションのポート番号を指定しないため、デフォルトのポート443(HTTPS)が想定されます。これにより、アプリケーションは https://translation.googleapis.com/ で始まる任意の URL に接続できます。

      2. google_network_rule という名前のネットワークルールを作成します。

        CREATE OR REPLACE NETWORK RULE google_network_rule
          MODE = EGRESS
          TYPE = HOST_PORT
          VALUE_LIST = ('google.com:80', 'google.com:443');
        
        Copy

        これにより、アプリケーションは http://google.com/ または https://google.com/ で始まる任意の URL に接続できます。

      注釈

      VALUE_LIST パラメーターには、完全なホスト名を指定する必要があります。ワイルドカード(例: *.googleapis.com)はサポートされていません。

      Snowpark Container Servicesは、ポート22、80、443、1024+を許可するネットワークルールのみをサポートします。参照されているネットワークルールが他のポートへのアクセスを許可している場合、サービスの作成は失敗します。追加のポートが必要な場合は、担当者にお問い合わせください。

      注釈

      サービスが HTTP または HTTPS リクエストをインターネット上の任意の宛先に送信できるようにするには、 VALUE_LIST プロパティでドメインとして「0.0.0.0」を指定します。以下のネットワークルールは、インターネット上の任意の宛先に「HTTP」と「HTTPS」の両方のリクエストを送信することを許可します。「0.0.0.0」をサポートしているのは、ポート80または443のみです。

      CREATE NETWORK RULE allow_all_rule
        TYPE = 'HOST_PORT'
        MODE= 'EGRESS'
        VALUE_LIST = ('0.0.0.0:443','0.0.0.0:80');
      
      Copy
    2. 外部アクセス統合(EAI) を作成し、先行する2つのエグレスネットワークルールが許可されることを指定します。

      CREATE EXTERNAL ACCESS INTEGRATION google_apis_access_integration
        ALLOWED_NETWORK_RULES = (translate_network_rule, google_network_rule)
        ENABLED = true;
      
      Copy

      これで、アカウント管理者は、開発者に統合の使用権限を付与して、インターネット上の特定の宛先にアクセスできるサービスを実行できるようにすることができます。

      GRANT USAGE ON INTEGRATION google_apis_access_integration TO ROLE test_role;
      
      Copy
  2. 以下の例に示すように、 EAI を指定してサービスを作成します。サービスを作成する所有者ロールは、 EAI の USAGE 権限と、参照されるシークレットの READ 権限が必要です。ACCOUNTADMIN ロールを使用してサービスを作成することはできません。

    • サービスを作成します。

      USE ROLE test_role;
      
      CREATE SERVICE eai_service
        IN COMPUTE POOL MYPOOL
        EXTERNAL_ACCESS_INTEGRATIONS = (GOOGLE_APIS_ACCESS_INTEGRATION)
        FROM SPECIFICATION
        $$
        spec:
          containers:
            - name: main
              image: /db/data_schema/tutorial_repository/my_echo_service_image:tutorial
              env:
                TEST_FILE_STAGE: source_stage/test_file
              args:
                - read_secret.py
          endpoints:
            - name: read
              port: 8080
        $$;
      
      Copy

      この例の CREATE SERVICE リクエストは、インラインサービス仕様を使用し、 EAI を含むようにオプションの EXTERNAL_ACCESS_INTEGRATIONS プロパティを指定します。EAI は、サービスから特定の宛先へのエグレストラフィックを許可するネットワークルールを指定します。

    • ジョブサービスを実行します。

      EXECUTE JOB SERVICE
        IN COMPUTE POOL tt_cp
        NAME = example_job_service
        EXTERNAL_ACCESS_INTEGRATIONS = (GOOGLE_APIS_ACCESS_INTEGRATION)
        FROM SPECIFICATION $$
        spec:
          container:
          - name: curl
            image: /tutorial_db/data_schema/tutorial_repo/alpine-curl:latest
            command:
            - "curl"
            - "http://google.com/"
        $$;
      
      Copy

      この例の EXECUTE JOB SERVICE コマンドは、インライン仕様と、 EAI を含めるためのオプション EXTERNAL_ACCESS_INTEGRATIONS プロパティを指定します。これは、ジョブから EAI が許可するネットワークルールで指定された宛先への、エグレストラフィックを許可します。

プライベート接続を使用したネットワークエグレス

公衆インターネット経由でネットワークのイグレスをルーティングする代わりに、 プライベート接続エンドポイント を介してサービスのイグレス・トラフィックを誘導することを選択することもできます。

まず、Snowflakeアカウントでプライベート接続エンドポイントを作成する必要があります。次に、 プライベート接続 を使用する発信トラフィックを許可するネットワークルールを構成します。外部アクセス統合(EAI)のセットアップ手順は、前のセクションと同じです。

注釈

プライベート通信では、Snowflakeとお客様のクラウドアカウントの両方が同じクラウドプロバイダーと同じリージョンを使用する必要があります。

例えば、プライベート接続を介してAmazon S3バケットへのサービスのアウトバウンドインターネットアクセスを有効にしたい場合、次のようにします。

  1. 自営エンドポイントサービス(Amazon S3)のプライベートリンク接続を有効にします。ステップバイステップの手順については、 AWS Private Link for Amazon S3 をご参照ください。

  2. SYSTEM$PROVISION_PRIVATELINK_ENDPOINT システム関数を呼び出して、Snowflake VNet にプライベート接続エンドポイントをプロビジョニングします。これにより、Snowflakeはプライベート接続を使用して外部サービス(この例ではAmazon S3)に接続できるようになります。

    USE ROLE ACCOUNTADMIN;
    
    SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
      'com.amazonaws.us-west-2.s3',
      '*.s3.us-west-2.amazonaws.com'
    );
    
    Copy
  3. クラウドプロバイダーのアカウントで、エンドポイントを承認します。この例では、Amazon AWS の場合、 接続リクエストを受け入れるか拒否するか AWS ドキュメントの  を参照してください。 また、Azure でエンドポイントを承認するには、 Azure ドキュメント をご参照ください。

  4. CREATE NETWORK RULE コマンドを使用して、アクセスを許可する外部宛先を指定するエグレスネットワークルールを作成します。

    CREATE OR REPLACE NETWORK RULE private_link_network_rule
      MODE = EGRESS
      TYPE = PRIVATE_HOST_PORT
      VALUE_LIST = ('<bucket-name>.s3.us-west-2.amazonaws.com');
    
    Copy

    TYPE パラメーターの値は PRIVATE_HOST_PORT にセットされます。このネットワークルールは、発信ネットワークトラフィックが プライベート接続 を使用することを許可することを示します。

  5. EAI を作成し、それを使用してサービスを作成する残りの手順は、前のセクションで説明したのと同様です(ネットワークエグレスの構成 を参照)。

プライベート接続エンドポイントの操作については、以下を参照してください。

コンテナー間のネットワーク通信構成

次の2つを考慮します。

  • **サービスインスタンスのコンテナー間の通信

  • 複数のサービスまたは複数のサービスインスタンスにまたがるコンテナ間の通信: 異なるサービス(または同じサービスの異なるインスタンス)に属するコンテナは、仕様ファイルで定義されたエンドポイントを使用して通信できます。詳細については、 サービス間通信 をご参照ください。