服务网络

使用 Snowpark Container Services 服务时,需要考虑三种网络类型:

  • 入口网络:如何从 Snowflake 外部连接到您的服务。
  • 出口网络:服务如何连接到 Snowflake 外部的资源。
  • Snowpark Container Services 中的服务间通信。

以下部分说明如何配置每种网络。

配置服务入口

要允许任何内容通过互联网与服务交互,请在服务规范文件中将服务侦听的网络端口声明为端点。这些端点控制入口。

By default, service endpoints are private. Only service functions and service-to-service communications can make requests to the private endpoints. You can declare an endpoint as public to allow requests to an endpoint from the internet as shown in the following example service specification.

Note

创建公共端点是一项权限操作,服务的所有者角色必须对账户拥有 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>
        ...

For an example, see Tutorial 1.

当您公开端点时,Snowflake 会为公共端点分配唯一的主机名。Snowflake 将具有该主机名的传入请求发送到服务。

If you want to expose multiple service endpoints behind a single host name, you can create a gateway. A gateway routes ingress requests to one or more service endpoints, based on the gateway configuration. For more information about gateways and scenarios for creating a gateway, see Use Gateways to route ingress requests to multiple endpoints

入口连接超时

入口端点的超时时间为 90 秒。如果入口端点的连接在 90 秒内无活动,Snowflake 将终止该连接。如果您的应用程序需要更长连接时间,请使用轮询或 WebSockets。

入口网页浏览器身份验证注销

If you’re building a web app that runs as a service, you have the option to allow users to log out from your app by directing them to /sfc-endpoint/logout.

注销后,用户需要重新对 Snowflake 进行身份验证,才能访问服务的公共端点。

入口和 Web 应用程序安全性

您可以使用公共端点支持(网络入口)创建用于 Web 托管的 Snowpark Container Services。为了提高安全性,Snowflake 采用代理服务来监控从客户端到服务的传入请求以及从服务到客户端的传出响应。本节介绍代理的作用以及它如何影响部署到 Snowpark Container Services 的服务。

Note

When you test a service locally, you are not using the Snowflake proxy and therefore there will be differences between your experience running a service locally as opposed to when deployed in Snowpark Container Services. Review this section and update your local setup for better testing.

例如:

  • 如果请求使用了被禁止的 HTTP 方法,代理不会转发传入的 HTTP 请求。
  • 如果响应中的 Content-Type 标头指出响应包含可执行文件,则代理会向客户端发送 403 响应。

此外,代理还可以在请求和响应中注入新的标头并更改现有标头,同时兼顾容器和数据安全性。

例如,在收到请求后,服务可能会在响应中,将 HTML、JavaScript、CSS 以及其他网页内容发送到客户端浏览器。浏览器中的网页是服务的一部分,充当用户界面。出于安全原因,如果服务有限制(例如,限制与其他站点建立网络连接),您可能还希望服务网页具有同样的限制。

By default, services have limited permissions to access the internet. The browser should also restrict the client app from accessing the internet and potentially sharing data in most cases. If you set up an External Access Integration (EAI) to allow your service to access example.com (see 配置服务出口), the web page for your service should also be able to access example.com through your browser.

The Snowflake proxy applies the same network restrictions on the service and the web page by adding a Content-Security-Policy (CSP) header in the response. By default, the proxy adds a baseline CSP in the response to protect against common security threats. Browser security is a best effort to balance functionality with security, it is a shared responsibility to ensure this baseline is appropriate for your use case. In addition, if your service is configured to use an EAI, the proxy applies the same network rules from the EAI to the CSP for the web page. This CSP enables the web page in the browser to access the same sites that the service can access.

Snowflake 提供 CORS 支持,您可在服务规范中对其进行配置。

Snowflake 代理会返回服务规范中定义的 CORS 设置。请注意,代理会删除服务返回的任何 CORS 标头。

以下 CORS 标头为默认设置:

  • Access-Control-Expose-Headers header always reports the following header names, in addition to headers configured in the service specification for the endpoint.

    • 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 is set to two hours.

  • Access-Control-Allow-Credentials is set to true.

In addition, Snowflake sets the Vary header with the value Origin to indicate to the browser that based on the value of the Origin, the value to Access-Control-Allow-Origin might be different.

The Authorization header is required to make the CORS request. You can specify a programmatic access token (PAT) in this header (Authorization: "Snowflake Token=\"${patToken}\""). For information on generating a programmatic access token, see Using programmatic access tokens for authentication.

以下各节介绍了 Snowflake 代理如何处理对服务的传入请求,并修改服务对客户端的传出响应。

传入服务的请求

当请求到达时,代理会先执行以下操作,然后再将请求转发到服务:

  • 采用禁止的 HTTP 方法的传入请求: 如果传入 HTTP 请求使用以下任意被禁止的 HTTP 方法,代理不会将请求转发到服务:

    • TRACE
    • CONNECT
  • 标头擦除: Snowflake 代理会移除以下请求标头(如果存在):

    • X-SF-SPCS-Authorization
    • Authorization: Only removed if it contains a Snowflake token; otherwise, it is passed through to your service.

传出到客户端的响应

Snowflake 代理会先将这些修改应用于服务发送的响应,然后再将响应转发到客户端。

  • 标头清理: Snowflake 代理会删除这些响应标头(如果存在):

    • X-XSS-Protection
    • Server
    • X-Powered-By
    • Public-Key-Pins
  • CORS headers manipulation: See 入口和 CORS 注意事项.

  • Content-Type response header: If your service response includes the Content-Type header with any of the following MIME type values (that indicate an executable), Snowflake proxy does not forward that response to the client. Instead, the proxy sends a 403 Forbidden response.

    • application/x-msdownload: Microsoft executable.
    • application/exe: Generic executable.
    • application/x-exe: Another generic executable.
    • application/dos-exe: DOS executable.
    • application/x-winexe: Windows executable.
    • application/msdos-windows: MS-DOS Windows executable.
    • application/x-msdos-program: MS-DOS executable.
    • application/x-sh: Unix shell script.
    • application/x-bsh: Bourne shell script.
    • application/x-csh: C shell script.
    • application/x-tcsh: Tcsh shell script.
    • application/batch: Windows batch file.
  • X-Frame-Options response header: To prevent clickjacking attacks, the Snowflake proxy sets this response header to DENY, preventing other web pages from using an iframe to the web page for your service.

  • Cross-Origin-Opener-Policy (COOP) response header: Snowflake sets the COOP response header to same-origin to prevent referring cross-origin windows from accessing your service tab.

  • Cross-Origin-Resource-Policy (CORP) response header: Snowflake sets the CORP header to same-origin to prevent external sites from loading resources exposed by the ingress endpoint (for example, in an iframe).

  • X-Content-Type-Options response header: Snowflake proxy sets this header to nosniff to ensure the clients do not change the MIME type stated in the response by your service.

  • Cross-Origin-Embedder-Policy (COEP) response header: Snowflake proxy sets the COEP response header to credentialless, which means when loading a cross-origin object such as an image or a script, if the remote object does not support Cross-Origin Resource Sharing (CORS) protocol, Snowflake does not send the credentials when loading it.

  • Content-Security-Policy-Report-Only response header: Snowflake proxy replaces this response header with a new value directing the client to send the CSP reports to Snowflake.

  • Content-Security-Policy (CSP) response header: By default the Snowflake proxy adds the following baseline CSP to protect against common web attacks.

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

有两个内容安全策略注意事项:

  • In addition to the baseline content security policy that proxy adds, the service itself can explicitly add a CSP in the response. A service might choose to enhance security by adding a stricter CSP. For example, a service might add the following CSP to allow scripts only from self.

    script-src 'self'

在发送给客户端的结果响应中,将有两个 CSP 标头。收到响应后,客户端浏览器将应用最严格的内容安全策略,其中包括每个策略指定的其他限制。

  • If you configure an External Access Integration (EAI) to allow your service to access an external site (配置服务出口), the Snowflake proxy creates a CSP that allows your web page to access that site. For example, suppose a network rule associated with an EAI allows your service egress access to example.com. Then, Snowflake proxy adds this CSP response header:

    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';

    Browsers honor the content access policy received in the response. In this example, browsers allow the app access to example.com but not other sites.

入口和 CORS 注意事项

默认情况下,浏览器会阻止一个服务器上的 Web 应用程序向另一个不同主机名的服务器发送请求。例如,如果您在 Snowpark Container Services 之外托管一个 Web 应用程序,而该应用程序需要与部署在 Snowpark Container Services 内的后端服务进行交互,则适用此限制。

CORS(跨源资源共享)使 Snowpark Container Services 能够告诉浏览器允许来自其环境外托管的 Web 应用程序的请求。您可以配置每个公共端点,指定它如何响应 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

当以下任一情况为 true 时,Snowflake 代理不会在响应中包含任何此类 CORS 标头:

  • CORS is not configured for the service endpoint. That is, there no corsSettings in the service specification
  • CORS is configured for the service endpoint, but the Origin header in the request doesn’t match the specified Access-Control-Allow-Origin field in the service specification

In the service specification, you can configure CORS settings for each public endpoint. When the origin header in the request matches the Access-Control-Allow-Origin field specified for the endpoint in the specification, the proxy includes in the response the CORS headers defined in the specification, with the following adjustments:

  • Access-Control-Allow-Origin: Returns the Origin header from the request.
  • Access-Control-Expose-Headers: Merges the list of allowed headers you configured with these always-exposed 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: Is set to two hours.
  • Access-Control-Allow-Credentials: Is set to true.

入口和您的身份提供商 (IdP) 注意事项

账户管理员可以配置所有入口 URLs,以便在未经身份验证的查看者访问应用程序时重定向到您的身份提供商 (IdP)。此过程省略了客户在登录页面选择 IdP 的额外步骤,从而减少点击次数,提供更顺畅的登录体验。

To redirect unauthenticated users from ingress URLs to your IdP, use the ALTER ACCOUNT SQL command to set the LOGIN_IDP_REDIRECT account property to include SPCS:

ALTER ACCOUNT SET LOGIN_IDP_REDIRECT = (SPCS = <your_security_integration>);

For a full overview of LOGIN_IDP_REDIRECT, including the procedure for reaching the Snowflake sign-in page when the IdP is unavailable, see Automatically redirecting users to your identity provider.

有关配置 Snowflake 账户以使用 IdP 的更多信息,请参阅以下主题:

入口和 SSO 注意事项

当从互联网访问公共端点时,您可能会发现用户名/密码身份验证正常,但 SSO 导致空白页或错误:“OAuth client integration with the given client ID is not found.”

This happens when you’re using the old style of federated authentication (SSO) with Snowflake instead of the newer security integration version as explained in Configuring Snowflake to use federated authentication. Do the following to verify:

  1. 运行以下查询:

    SHOW PARAMETERS LIKE 'SAML_IDENTITY_PROVIDER' IN ACCOUNT;

如果您设置了此参数,那么在某些时候您使用的是旧版本的联合身份验证。

  1. If the preceding parameter was set, run the following query to see if you have a SAML security integration:

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

如果您没有任何 SAML2 类型的集成,那么您使用的是旧版本的联合身份验证。

In this case, the solution is to migrate from the old-style federated authentication to the new integration-style federated authentication. For more information, see Migrating to a SAML2 security integration.

配置服务出口

Your application code might require access to the internet. By default, application containers don’t have permission to access the internet. You need to enable internet access using External Access Integrations (EAIs).

通常,您希望账户管理员创建 EAIs 来管理允许通过服务(包括作业服务)进行的外部访问。然后,账户管理员可以向开发者用于运行服务的特定角色授予 EAI 使用量。

以下示例概述了创建 EAI 的步骤,这允许出口流量流向使用网络规则制定的特定目的地。然后,您可以在创建服务时引用 EAI 以允许对特定互联网目的地的请求。

示例

假设您希望应用程序代码将请求发送到以下目的地:

  • 向 translation.googleapis.com 发出 HTTPS 请求
  • 向 google.com 发出 HTTP 和 HTTPS 请求

按照以下步骤操作,使服务能够访问互联网上的这些域:

  1. Create an External Access Integration (EAI). This requires appropriate permissions. For example, you can use ACCOUNTADMIN role to create an EAI. This is a two-step process:
    1. Use the CREATE NETWORK RULE command to create one or more egress network rules listing external destinations you want to allow access to. You can accomplish this example with one network rule, but for illustration, we create two network rules:

      1. Create a network rule named translate_network_rule:

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

        This rule allows TCP connections to the translation.googleapis.com destination. The domain in the VALUE_LIST property does not specify the optional port number, so the default port 443 (HTTPS) is assumed. This allows your application to connect to any URL that starts with https://translation.googleapis.com/.

      2. Create a network rule named google_network_rule:

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

        This allows your application to connect to any URL that starts with http://google.com/ or https://google.com/.

      Note

      For the VALUE_LIST parameter, you must provide a full host name. Wildcards (for example, *.googleapis.com) are not supported.

Snowpark Container Services 仅支持允许端口 22、80、443 和 1024+ 的网络规则。如果引用的网络规则允许访问其他端口,则服务创建将失败。如果您需要使用其他端口,请联系客户代表。

Note

要允许服务向互联网上的任何目的地发送 HTTP 或 HTTPS 请求,请指定“0.0.0.0”作为 VALUE_LIST 属性。以下网络规则允许在互联网上的任何位置发送“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');
  1. Create an external access integration (EAI) that specifies that the preceding two egress network rules are allowed:

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

现在,账户管理员可以向开发者授予集成使用量,以允许他们运行可以访问互联网上特定目的地的服务。

GRANT USAGE ON INTEGRATION google_apis_access_integration TO ROLE test_role;
  1. Create the service by providing the EAI as shown in the following examples. The owner role that is creating the service needs the USAGE privilege on the EAI and READ privilege on the secrets referenced. Note that you cannot use the ACCOUNTADMIN role to create a service.
    • 创建服务:

      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
        $$;

此示例 CREATE SERVICE 请求使用内联服务规范,并指定可选的 EXTERNAL_ACCESS_INTEGRATIONS 属性以纳入 EAI。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/"
      $$;

此示例 EXECUTE JOB SERVICE 命令指定内联规范和可选的 EXTERNAL_ACCESS_INTEGRATIONS 属性以纳入 EAI。这允许从作业到 EAI 允许的网络规则中指定的目的地的出口流量。

使用专用连接的网络出口

Instead of routing network egress via the public internet, you might opt to direct your service’s egress traffic through a private connectivity endpoint.

You first need to create the private connectivity endpoint in your Snowflake account. Then configure a network rule to permit outgoing traffic to use private connectivity. The process for setting up an External Access Integration (EAI) remains the same as described in the preceding section.

Note

专用通信要求 Snowflake 和客户的云账户使用相同的云提供商和相同的区域。

例如,如果您想通过专用连接启用服务对 Amazon S3 桶的出站互联网访问,请执行以下操作:

  1. Enable the private link connectivity for the self-maintained endpoint service (Amazon S3). For step-by-step instructions, see AWS Private Link for Amazon S3 (https://docs.aws.amazon.com/AmazonS3/latest/userguide/privatelink-interface-endpoints.html).

  2. Call the SYSTEM$PROVISION_PRIVATELINK_ENDPOINT system function to provision a private connectivity endpoint in your Snowflake VNet. This enables Snowflake to connect to the external service (in this example, Amazon S3) using private connectivity.

    USE ROLE ACCOUNTADMIN;
    
    SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
      'com.amazonaws.us-west-2.s3',
      '*.s3.us-west-2.amazonaws.com'
    );
  3. In the cloud provider account, approve the endpoint. In this example, for Amazon AWS, see Accept or reject connection requests (https://docs.aws.amazon.com/vpc/latest/privatelink/configure-endpoint-service.html#accept-reject-connection-requests) in the AWS documentation. Also, to approve the endpoint in Azure, see the Azure documentation (https://learn.microsoft.com/en-us/azure/private-link/manage-private-endpoint?tabs=manage-private-link-powershell#private-endpoint-connections).

  4. Use the CREATE NETWORK RULE command to create an egress network rule specifying the external destinations that you want to allow access to.

    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');

    The TYPE parameter value is set to PRIVATE_HOST_PORT. It indicates that the network rule allows outgoing network traffic to use private connectivity.

  5. The rest of the steps to create an EAI and use it to create a service are the same as explained in the preceding section (see 配置服务出口).

有关使用专用连接端点的更多信息,请参阅以下内容:

配置服务之间通信时的注意事项

有两个注意事项:

  • Communications between containers of a service instance: If a service instance runs multiple containers, these containers can communicate with each other over localhost (there is no need to define endpoints in the service specification).
  • Communication between containers across multiple services or multiple service instances: Containers belonging to different services (or different instances of the same service) can communicate using endpoints defined in specification files. For more information, see Service-to-service communications.