Mise en réseau des services¶
Avec les services Snowpark Container Services, il y a trois types de mise en réseau à prendre en compte :
Mise en réseau d’entrée : Comment se connecter depuis l’extérieur à votre service.
Entrée : Comment votre service se connecte à d’autres services sur Internet ou via votre lien privé.
Communications de service à service dans Snowpark Container Services
Les sections suivantes expliquent comment configurer chaque type de mise en réseau.
Configuration de l’entrée du réseau¶
Pour permettre à quiconque d’interagir avec votre service depuis Internet, vous déclarez les ports réseau sur lesquels votre service écoute en tant que points de terminaison dans le fichier de spécification du service. Ces points de terminaison contrôlent l’entrée.
Par défaut, les points de terminaison de service sont privés. Seules les fonctions de service et les communications de service à service peuvent adresser des requêtes aux points de terminaison privés. Vous pouvez déclarer un point de terminaison comme étant public afin d’autoriser les requêtes vers un point de terminaison depuis Internet. La création d’un point de terminaison public est une opération privilégiée et le rôle de propriétaire du service doit disposer du privilège BIND SERVICE ENDPOINT sur le compte.
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>
...
Pour un exemple, voir le tutoriel 1.
Délai d’expiration de la connexion d’entrée¶
Les points de terminaison ont un délai d’expiration de 90 secondes. S’il n’y a aucune activité sur une connexion à un point de terminaison d’entrée pendant 90 secondes, Snowflake met fin à la connexion. Si votre application a besoin d’une connexion plus longue, utilisez l’interrogation ou WebSockets.
Déconnexion de l’authentification du navigateur web d’entrée¶
Si vous créez une application Web qui fonctionne en tant que service, vous avez la possibilité de permettre aux utilisateurs de se déconnecter de votre application en les dirigeant vers /sfc-endpoint/logout.
Après s’être déconnecté, l’utilisateur devra s’authentifier à nouveau auprès de Snowflake pour accéder au point de terminaison public du service.
Entrée et sécurité des applications web¶
Vous pouvez créer un service Snowpark Container Services pour l’hébergement web en utilisant la prise en charge de point de terminaison public (entrée réseau). Pour plus de sécurité, Snowflake utilise un service proxy pour contrôler les requêtes entrantes des clients vers votre service et les réponses sortantes de votre service vers les clients. Cette section explique ce que fait le proxy et comment il affecte un service déployé dans Snowpark Container Services.
Note
Lorsque vous testez un service localement, vous n’utilisez pas le proxy Snowflake et il y aura donc des différences entre votre expérience d’exécution d’un service en local et celle d’un service déployé dans Snowpark Container Services. Passez en revue cette section et mettez à jour votre configuration locale pour améliorer les tests.
Par exemple :
Le proxy ne transmet pas une requête HTTP entrante si la requête utilise une méthode HTTP interdite.
Le proxy envoie une réponse 403 au client si l’en-tête Content-Type de la réponse indique qu’elle contient un exécutable.
En outre, le proxy peut également injecter de nouveaux en-têtes et modifier les en-têtes existants dans la demande et la réponse, en tenant compte de votre conteneur et de la sécurité des données.
Par exemple, à la réception d’une requête, votre service peut envoyer du contenu HTML, JavaScript, CSS et d’autres contenus d’une page web au navigateur du client dans la réponse. La page web dans le navigateur fait partie de votre service et agit en tant qu’interface utilisateur. Pour des raisons de sécurité, si votre service est soumis à des restrictions (par exemple, l’interdiction d’établir des connexions réseau avec d’autres sites), vous voudrez peut-être que la page web de votre service soit soumise aux mêmes restrictions.
Par défaut, les services disposent d’autorisations limitées pour accéder à Internet. Le navigateur doit également empêcher l’application cliente d’accéder à Internet et de partager potentiellement des données dans la plupart des cas. Si vous avez mis en place une intégration d’accès externe (EAI) pour permettre à votre service d’accéder à example.com (voir Configuration de la sortie réseau), la page web de votre service devrait également être en mesure d’accéder à example.com via votre navigateur.
Le proxy Snowflake applique les mêmes restrictions de réseau au service et à la page web en ajoutant un en-tête Content-Security-Policy (CSP) dans la réponse. Par défaut, le proxy ajoute une CSP de base dans la réponse pour se protéger contre les menaces de sécurité courantes. La sécurité du navigateur est le meilleur effort pour équilibrer la fonctionnalité et la sécurité. Il s’agit d’une responsabilité partagée qui garantit que cette base de référence est appropriée à votre cas d’utilisation. En outre, si votre service est configuré pour utiliser une EAI, le proxy applique les mêmes règles de réseau du EAI à la CSP pour la page web. Cette CSP permet à la page web du navigateur d’accéder aux mêmes sites que ceux auxquels le service peut accéder.
Snowflake fournit l’assistance CORS que vous configurez dans la spécification du service.
Le proxy Snowflake renvoie les paramètres CORS définis dans la spécification du service. Notez que le proxy supprime les en-têtes CORS renvoyés par le service.
Les en-têtes CORS suivants sont définis par défaut :
L’en-tête
Access-Control-Expose-Headerssignale toujours les noms d’en-têtes suivants, en plus des en-têtes configurés dans la spécification de service pour le point de terminaison.X-Frame-OptionsCross-Origin-Opener-PolicyCross-Origin-Resource-PolicyX-Content-Type-OptionsCross-Origin-Embedder-PolicyContent-Security-Policy-Report-OnlyContent-Security-Policy
Access-Control-Max-Ageest défini sur deux heures.Access-Control-Allow-Credentialsest défini sur true.
En outre, Snowflake définit l’en-tête Vary avec la valeur Origin pour indiquer au navigateur qu’en fonction de la valeur de Origin, la valeur de Access-Control-Allow-Origin peut être différente.
L’en-tête Authorization est nécessaire pour effectuer la requête CORS. Vous pouvez spécifier un jeton d’accès programmatique (PAT) dans cet en-tête (Authorization: "Snowflake Token=\"${patToken}\""). Pour plus d’informations sur la génération d’un jeton d’accès programmatique, voir Utilisation de jetons d’accès programmatique pour l’authentification.
Les sections suivantes expliquent comment le proxy Snowflake gère les requêtes entrantes pour votre service et modifie les réponses sortantes de votre service aux clients.
Requêtes reçues par le service¶
Lorsqu’une requête arrive, le proxy effectue les opérations suivantes avant de transmettre la requête au service :
Requêtes entrantes avec des méthodes HTTP interdites : Si une requête HTTP entrante utilise l’une des méthodes HTTP interdites suivantes, le proxy ne transmet pas la requête à votre service :
TRACECONNECT
Nettoyage des en-têtes des requêtes entrantes : Le proxy Snowflake supprime les en-têtes des requêtes suivants s’ils sont présents :
X-SF-SPCS-AuthorizationAuthorization: Uniquement supprimé s’il contient un jeton Snowflake Services ; sinon, il est transmis à votre service.
Réponses envoyées aux clients¶
Le proxy Snowflake applique ces modifications à la réponse envoyée par votre service avant de la transmettre au client.
Nettoyage des en-têtes : le proxy Snowflake supprime ces en-têtes de réponse, s’ils sont présents :
X-XSS-ProtectionServerX-Powered-ByPublic-Key-Pins
Manipulation des en-têtesCORS : Voir Considérations sur les entrées et CORS.
En-tête de réponse Content-Type : Si la réponse de votre service inclut l’en-tête Content-Type avec l’une des valeurs de type MIME suivantes (qui indiquent un exécutable), le proxy Snowflake ne transmet pas cette réponse au client. Au lieu de cela, le proxy envoie une réponse
403 Forbidden.application/x-msdownload: exécutable Microsoft.application/exe: exécutable générique.application/x-exe: autre exécutable générique.application/dos-exe: exécutable DOS.application/x-winexe: exécutable Windows.application/msdos-windows: exécutable Windows MS-DOS.application/x-msdos-program: exécutable MS-DOS.application/x-sh: script shell Unix.application/x-bsh: script shell Bourne.application/x-csh: script shell C.application/x-tcsh: script shell Tcsh.application/batch: fichier batch Windows.
En-tête de réponse X-Frame-Options : Pour prévenir les attaques par détournement de clics, le proxy Snowflake définit cet en-tête de réponse sur
DENY, empêchant d’autres pages web d’utiliser un iframe vers la page web de votre service.En-tête de réponse Cross-Origin-Opener-Policy (COOP) : Snowflake définit l’en-tête de réponse COOP sur
same-originpour empêcher les fenêtres cross-origin d’accéder à votre onglet de service.En-tête de réponse Cross-Origin-Resource-Policy (CORP) : Snowflake définit l’en-tête CORP sur
same-originpour empêcher les sites externes de charger les ressources exposées par le point de terminaison d’entrée (par exemple, dans un iframe).En-tête de réponse X-Content-Type-Options : Snowflake proxy définit ce header sur
nosniffpour s’assurer que les clients ne changent pas le type MIME indiqué dans la réponse par votre service.En-tête de réponse Cross-Origin-Embedder-Policy (COEP) : le proxy Snowflake définit l’en-tête de réponse COEP sur
credentialless, ce qui signifie que lors du chargement d’un objet cross-origin tel qu’une image ou un script, si l’objet distant ne prend pas en charge le protocole Cross-Origin Resource Sharing (CORS), Snowflake n’envoie pas les identifiants de connexion lors du chargement de l’objet.En-tête de réponse Content-Security-Policy-Report-Only : le proxy Snowflake remplace cet en-tête de réponse par une nouvelle valeur indiquant au client d’envoyer les rapports CSP à Snowflake.
En-tête de réponse Content-Security-Policy (CSP) : par défaut, le proxy Snowflake ajoute la CSP de base suivante pour se protéger contre les attaques web courantes.
default-src 'self' 'unsafe-inline' 'unsafe-eval' blob: data:; object-src 'none'; connect-src 'self'; frame-ancestors 'self';
Il existe deux considérations relatives à la politique de sécurité du contenu :
En plus de la politique de sécurité du contenu de base que le proxy ajoute, le service lui-même peut explicitement ajouter une CSP dans la réponse. Un service peut choisir de renforcer la sécurité en ajoutant une CSP plus stricte. Par exemple, un service peut ajouter la CSP suivante pour n’autoriser que les scripts provenant de
self.script-src 'self'
La réponse envoyée au client contiendra deux en-têtes CSP. Lorsqu’ils reçoivent la réponse, les navigateurs clients appliquent alors la politique de sécurité du contenu la plus stricte qui inclut les restrictions supplémentaires spécifiées par chaque politique.
Si vous configurez une intégration d’accès externe (EAI) pour permettre à votre service d’accéder à un site externe (Configuration de la sortie réseau), le proxy Snowflake crée une CSP qui permet à votre page web d’accéder à ce site. Par exemple, supposons qu’une règle de réseau associée à un EAI permette à votre service d’accéder à la sortie
example.com. Ensuite, le proxy Snowflake ajoute cet en-tête de réponse 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';
Les navigateurs respectent la politique d’accès au contenu reçue dans la réponse. Dans cet exemple, les navigateurs autorisent l’application à accéder à
example.commais pas à d’autres sites.
Considérations sur les entrées et CORS¶
Par défaut, les navigateurs empêchent les applications web hébergées sur un serveur d’envoyer des requêtes à un autre serveur dont le nom d’hôte est différent. Par exemple, si vous hébergez une application Web en dehors de Snowpark Container Services qui doit interagir avec un service backend déployé au sein de Snowpark Container Services, cette restriction s’applique.
CORS (Cross-Origin Resource Sharing) permet à un service Snowpark Container Services d’indiquer aux navigateurs d’autoriser les requêtes provenant d’applications Web hébergées en dehors de son environnement. Vous pouvez configurer chaque point de terminaison public pour spécifier la manière dont il répond aux requêtes de contrôle en amont et aux requêtes standard CORS.
Le proxy Snowflake remplace toujours les en-têtes de réponse suivants :
Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-HeadersAccess-Control-Expose-HeadersAccess-Control-Max-AgeAccess-Control-Allow-Credentials
Le proxy Snowflake n’inclut aucun de ces en-têtes CORS dans la réponse lorsque l’une des conditions suivantes s’applique :
CORS n’est pas configuré pour le point de terminaison du service. C’est-à-dire qu’il n’y a pas de
corsSettingsdans la spécification du serviceCORS est configuré pour le point de terminaison du service, mais l’en-tête
Originde la requête ne correspond pas au champAccess-Control-Allow-Originspécifié dans la spécification du service
Dans la spécification du service, vous pouvez configurer les paramètres de CORS pour chaque point de terminaison public. Lorsque l’en-tête origin de la requête correspond au champ Access-Control-Allow-Origin spécifié pour le point de terminaison dans la spécification, le proxy inclut dans la réponse les en-têtes CORS définis dans la spécification, avec les ajustements suivants :
Access-Control-Allow-Origin: Renvoie l’en-têteOriginde la requête.Access-Control-Expose-Headers: Fusionne la liste des en-têtes autorisés que vous avez configurés avec ces en-têtes toujours exposés :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-Ageest défini sur deux heures.Access-Control-Allow-Credentialsest défini sur true.
Considérations sur les entrées et SSO¶
Lorsque vous accédez au point de terminaison public depuis Internet, vous pouvez constater que l’authentification par nom d’utilisateur/mot de passe fonctionne, mais que SSO aboutit à une page blanche ou à l’erreur : « L’intégration du clientOAuth avec l’ID de client donné est introuvable. »
Cela se produit lorsque vous utilisez l’ancien style d’authentification fédérée (SSO) avec Snowflake au lieu de la nouvelle version d’intégration de sécurité comme expliqué dans Configuration de Snowflake pour l’utilisation de l’authentification fédérée. Procédez comme suit pour vérifier :
Exécutez la requête suivante :
SHOW PARAMETERS LIKE 'SAML_IDENTITY_PROVIDER' IN ACCOUNT;
Si ce paramètre est défini, c’est que vous avez utilisé l’ancienne méthode d’authentification fédérée.
Si le paramètre précédent a été défini, exécutez les requêtes suivantes pour voir si vous avez une intégration de sécurité SAML :
SHOW INTEGRATIONS ->> SELECT * FROM $1 WHERE "type" = 'SAML2';
Si vous n’avez pas d’intégration du type SAML2, vous utilisez l’ancienne méthode d’authentification fédérée.
Dans ce cas, la solution consiste à passer de l’ancienne authentification fédérée à la nouvelle authentification fédérée de type intégration. Pour plus d’informations, voir Migration d’une intégration de sécurité SAML2.
Configuration de la sortie réseau¶
Le code de votre application peut nécessiter un accès à Internet. Par défaut, les conteneurs d’application n’ont pas la permission d’accéder à Internet. Vous devez activer l’accès à Internet en utilisant les intégrations d’accès externe (EAIs).
En règle générale, vous souhaitez qu’un administrateur de compte crée des EAIs pour gérer l’accès externe autorisé à partir des services (y compris des services de tâche). Les administrateurs de comptes peuvent alors accorder l’utilisation d’EAI à des rôles spécifiques que les développeurs utilisent pour exécuter des services.
L’exemple suivant décrit les étapes de la création d’une EAI qui autorise le trafic de sortie vers des destinations spécifiques spécifiées à l’aide de règles de réseau. Vous vous référez ensuite à l’EAI lorsque vous créez un service pour autoriser des requêtes vers des destinations Internet spécifiques.
Exemple
Supposons que vous souhaitiez que le code de votre application envoie des requêtes aux destinations suivantes :
Requêtes HTTPS vers translation.googleapis.com
Requêtes HTTP et HTTPS vers google.com
Suivez ces étapes pour permettre à votre service d’accéder à ces domaines sur Internet :
Créez une intégration d’accès externe (EAI). Pour ce faire, il faut disposer des autorisations nécessaires. Par exemple, vous pouvez utiliser le rôle ACCOUNTADMIN pour créer une EAI. Il s’agit d’un processus en deux étapes :
Utilisez la commande CREATE NETWORK RULE pour créer une ou plusieurs règles de réseau de sortie répertoriant les destinations externes auxquelles vous souhaitez autoriser l’accès. Vous pouvez réaliser cet exemple avec une seule règle de réseau, mais pour l’illustration, nous créons deux règles de réseau :
Créez une règle de réseau nommée
translate_network_rule:CREATE OR REPLACE NETWORK RULE translate_network_rule MODE = EGRESS TYPE = HOST_PORT VALUE_LIST = ('translation.googleapis.com');
Cette règle autorise les connexions TCP vers la destination
translation.googleapis.com. Le domaine dans la propriété VALUE_LIST ne spécifie pas le numéro de port optionnel, de sorte que le port par défaut 443 (HTTPS) est supposé. Cela permet à votre application de se connecter à n’importe quelle URL qui commence parhttps://translation.googleapis.com/.Créez une règle de réseau nommée
google_network_rule:CREATE OR REPLACE NETWORK RULE google_network_rule MODE = EGRESS TYPE = HOST_PORT VALUE_LIST = ('google.com:80', 'google.com:443');
Cela permet à votre application de se connecter à n’importe quelle URL qui commence par
http://google.com/ouhttps://google.com/.
Note
Pour le paramètre
VALUE_LISTvous devez fournir un nom d’hôte complet. Les caractères génériques (par exemple,*.googleapis.com) ne sont pas pris en charge.Snowpark Container Services ne prend en charge que les règles de réseau qui autorisent les ports 22, 80, 443 et 1024+. Si une règle de réseau référencée autorise l’accès à d’autres ports, la création du service échouera. Contactez votre représentant de compte si vous avez besoin d’utiliser des ports supplémentaires.
Note
Pour permettre à votre service d’envoyer des requêtes HTTP ou HTTPS à n’importe quelle destination sur Internet, vous spécifiez « 0.0.0.0 » comme domaine dans la propriété VALUE_LIST. La règle de réseau suivante permet d’envoyer des requêtes « HTTP » et « HTTPS » n’importe où sur Internet. Seuls les ports 80 ou 443 sont pris en charge avec « 0.0.0.0 ».
CREATE NETWORK RULE allow_all_rule TYPE = 'HOST_PORT' MODE= 'EGRESS' VALUE_LIST = ('0.0.0.0:443','0.0.0.0:80');
Créez une intégration d’accès externe (EAI) qui spécifie que les deux règles de réseau de sortie précédentes sont autorisées :
CREATE EXTERNAL ACCESS INTEGRATION google_apis_access_integration ALLOWED_NETWORK_RULES = (translate_network_rule, google_network_rule) ENABLED = true;
L’administrateur du compte peut désormais accorder l’utilisation de l’intégration aux développeurs pour leur permettre d’exécuter un service qui peut accéder à des destinations spécifiques sur Internet.
GRANT USAGE ON INTEGRATION google_apis_access_integration TO ROLE test_role;
Créez le service en fournissant l’EAI comme indiqué dans les exemples suivants. Le rôle de propriétaire qui crée le service a besoin du privilège USAGE sur l’EAI et du privilège READ sur les secrets référencés. Notez que vous ne pouvez pas utiliser le rôle ACCOUNTADMIN pour créer un service.
Créez un 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 $$;
Cet exemple de requête CREATE SERVICE utilise une spécification de service en ligne et spécifie la propriété facultative EXTERNAL_ACCESS_INTEGRATIONS pour inclure l’EAI. L’EAI spécifie les règles de réseau qui autorisent le trafic de sortie du service vers les destinations spécifiques.
Exécuter un service de tâche :
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/" $$;
Cet exemple de commande EXECUTE JOBSERVICE spécifie la spécification en ligne et la propriété facultative EXTERNAL_ACCESS_INTEGRATIONS pour inclure l’EAI. Cela autorise le trafic de sortie de la tâche vers les destinations spécifiées dans les règles de réseau que l’EAI autorise.
Sortie réseau par connectivité privée¶
Au lieu de router la sortie réseau via l’internet public, vous pouvez choisir de diriger le trafic de sortie de votre service vers un point de terminaison de connectivité privée.
Vous devez d’abord créer le point de terminaison de connectivité privée dans votre compte Snowflake. Configurez ensuite une règle de réseau pour autoriser le trafic sortant à utiliser la connectivité privée. Le processus de paramétrage d’une intégration d’accès externe (EAI) reste le même que celui décrit dans la section précédente.
Note
La communication privée exige que Snowflake et le compte Cloud du client utilisent le même fournisseur de Cloud et la même région.
Par exemple, si vous souhaitez activer l’accès internet sortant de votre service à un compartiment Amazon S3 via une connectivité privée, vous procédez comme suit :
Activez la connectivité du lien privé pour le service de point de terminaison autonome (Amazon S3). Pour obtenir des instructions étape par étape, consultez AWS Private Link pour Amazon S3.
Appelez la fonction du système SYSTEM$PROVISION_PRIVATELINK_ENDPOINT pour provisionner un point de terminaison de connectivité privée dans votre VNet Snowflake. Cela permet à Snowflake de se connecter au service externe (dans cet exemple, Amazon S3) en utilisant une connectivité privée.
USE ROLE ACCOUNTADMIN; SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT( 'com.amazonaws.us-west-2.s3', '*.s3.us-west-2.amazonaws.com' );
Dans le compte du fournisseur Cloud, approuvez le point de terminaison. Dans cet exemple, pour Amazon AWS, voir Accepter ou rejeter les requêtes de connexion dans la documentation AWS. Par ailleurs, pour approuver le point de terminaison dans Azure, consultez la documentation Azure.
Utilisez la commande CREATE NETWORK RULE pour créer une règle de réseau de sortie spécifiant les destinations externes auxquelles vous souhaitez autoriser l’accès.
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');
La valeur du paramètre TYPE est définie sur PRIVATE_HOST_PORT. Elle indique que la règle de réseau autorise le trafic réseau sortant à utiliser la connectivité privée.
Le reste des étapes pour créer un EAI et l’utiliser pour créer un service sont les mêmes que celles expliquées dans la section précédente (voir Configuration de la sortie réseau).
Pour plus d’informations sur l’utilisation des points de terminaison de connectivité privée, reportez-vous à ce qui suit :
Configuration des communications réseau entre les conteneurs¶
Il y a deux considérations à prendre en compte :
Communications entre les conteneurs d’une instance de service : si une instance de service utilise plusieurs conteneurs, ces conteneurs peuvent communiquer entre eux via localhost (il n’est pas nécessaire de définir des points de terminaison dans la spécification du service).
Communication entre les conteneurs appartenant à différents services ou plusieurs instances de services : les conteneurs appartenant à différents services (ou à différentes instances d’un même service) peuvent communiquer en utilisant des points de terminaison définis dans des fichiers de spécification. Pour plus d’informations, voir Communications de service à service.