Google Cloud Armor : filtrage d'adresses IP et filtrage géographique

Media CDN utilise Google Cloud Armor pour assurer la compatibilité avec les listes d'autorisation et de blocage d'adresses IP ainsi qu'avec les contrôles de filtrage basé sur des codes de pays et codes régionaux (emplacement géographique). Vous pouvez :

  • Refuser les requêtes en vous basant sur des adresses et plages d'adresses (CIDR) IPv4 et IPv6.
  • Autoriser ou refuser les requêtes en vous basant sur le code pays (zone géographique).
  • Autoriser les requêtes en vous basant sur des adresses et plages d'adresses (CIDR) IPv4 et IPv6.

Ces fonctionnalités vous permettent de limiter les téléchargements de contenu aux utilisateurs situés dans des emplacements spécifiques où des restrictions de licence de contenu sont appliquées, de n'autoriser que les adresses IP d'entreprise à accéder aux points de terminaison de test ou de préproduction, et de refuser une liste d'adresses connues associées à des clients malveillants.

Les stratégies Google Cloud Armor s'appliquent à tout le contenu diffusé à partir de Media CDN, y compris les contenus mis en cache et les défauts de cache (miss).

Les stratégies basées sur l'adresse IP et l'emplacement géographique sont configurées individuellement pour chaque service de cache périphérique (EdgeCacheService) : toutes les requêtes destinées à l'adresse IP (ou aux noms d'hôte) du service appliquent la stratégie de sécurité de manière cohérente. Différents services peuvent appliquer différentes stratégies de sécurité, et vous pouvez créer plusieurs services pour différentes zones géographiques si nécessaire.

Pour une protection plus précise du contenu au niveau de l'utilisateur, nous vous recommandons d'utiliser des URL signées et des cookies signés conjointement avec une stratégie Google Cloud Armor.

Configurer les stratégies de sécurité

Utilisez les instructions suivantes pour configurer une stratégie de sécurité.

Avant de commencer

Pour associer une stratégie de sécurité Google Cloud Armor à un service de cache périphérique, vous devez :

Vous devez également disposer des autorisations IAM (Identity and Access Management) suivantes pour autoriser, créer et associer des stratégies de sécurité à un service de cache périphérique :

  • compute.securityPolicies.addAssociation
  • compute.securityPolicies.create
  • compute.securityPolicies.delete
  • compute.securityPolicies.get
  • compute.securityPolicies.list
  • compute.securityPolicies.update
  • compute.securityPolicies.use

Les utilisateurs qui doivent associer un certificat existant à un service de cache périphérique ne nécessitent que les autorisations IAM suivantes :

  • compute.securityPolicies.get
  • compute.securityPolicies.list
  • compute.securityPolicies.use

Le rôle roles/networkservices.edgeCacheUser inclut toutes ces autorisations.

Créer une stratégie de sécurité

Les stratégies de sécurité Google Cloud Armor sont composées de plusieurs règles, chaque règle définissant un ensemble de critères de correspondance de requête (une expression) ainsi qu'une action. Par exemple, une expression peut contenir une logique de correspondance pour les clients situés en Inde avec une action associée consistant à autoriser la requête. Si une requête ne correspond pas à la règle, l'évaluation passe à la règle suivante jusqu'à ce que toutes les règles aient été évaluées.

Les stratégies de sécurité incluent une règle par défaut dont l'action consiste à autoriser la requête. La règle par défaut autorise les requêtes qui ne correspondent pas aux règles précédentes. Vous pouvez modifier cette règle pour en faire une règle de refus (deny) lorsque vous souhaitez n'autoriser (allow) que les requêtes qui correspondent aux règles précédentes et rejeter toutes les autres.

L'exemple suivant montre comment créer une règle qui bloque tous les clients géolocalisés en Australie avec un code HTTP 403 et autorise toutes les autres requêtes.

gcloud

Pour créer une stratégie de type CLOUD_ARMOR_EDGE, exécutez la commande suivante :

gcloud compute security-policies create block-australia \
    --type="CLOUD_ARMOR_EDGE" --project="PROJECT_ID"

Cela crée une stratégie avec une règle d'autorisation par défaut associée à la priorité la plus basse (priority: 2147483647) :

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/securityPolicies/block-australia].

Vous pouvez ensuite ajouter une règle avec une priorité plus élevée :

gcloud compute security-policies rules create 1000 \
    --security-policy=block-australia --description "block AU" \
    --expression="origin.region_code == 'AU'" --action="deny-403"

Le résultat est le suivant :

Updated [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/securityPolicies/block-australia].

Terraform

resource "google_compute_security_policy" "default" {
  name        = "block-australia"
  type        = "CLOUD_ARMOR_EDGE"
  description = "block AU"

  rule {
    action      = "deny(403)"
    description = "block AU"
    priority    = "1000"
    match {
      expr {
        expression = "origin.region_code == 'AU'"
      }
    }
  }
  rule {
    action   = "allow"
    priority = "2147483647"
    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = ["*"]
      }
    }
    description = "default rule"
  }
}

Si vous inspectez la stratégie, vous pouvez voir deux règles : la première règle bloque les requêtes provenant d'Australie (origin.region_code == 'AU') et la deuxième règle, dont la priorité est plus faible, autorise tout le trafic ne correspondant pas à la ou aux règles de priorité supérieure.

kind: compute#securityPolicy
name: block-australia
rules:
- action: deny(403)
  description: block AU
  kind: compute#securityPolicyRule
  match:
    expr:
      expression: origin.region_code == 'AU'
  preview: false
  priority: 1000
- action: allow
  description: default rule
  kind: compute#securityPolicyRule
  match:
    config:
      srcIpRanges:
      - '*'
    versionedExpr: SRC_IPS_V1
  preview: false
  priority: 2147483647
  ruleNumber: '1'
type: CLOUD_ARMOR_EDGE

Pour associer cette stratégie à votre Media CDN, consultez la section suivante.

Associer une stratégie à un service

Pour associer une stratégie Google Cloud Armor existante nommée us-only-delivery-policy à un service Edge Cache appelé prod-media-service :

gcloud

gcloud edge-cache services update prod-media-service \
    --edge-security-policy=us-only-delivery-policy

Afficher une association de stratégie

Pour afficher les stratégies associées à un service existant, inspectez (décrivez) ce service :

gcloud

gcloud edge-cache services describe MY_SERVICE

Le champ edgeSecurityPolicy du service décrit la stratégie associée :

name: "MY_SERVICE"
edgeSecurityPolicy: "SECURITY_POLICY

Supprimer une stratégie

Pour supprimer une stratégie existante, mettez à jour le service associé et transmettez une chaîne vide comme stratégie :

gcloud

gcloud edge-cache services update MY_SERVICE \
  --edge-security-policy=""

Le champ edgeSecurityPolicy est désormais omis dans le résultat de la commande gcloud edge-cache services describe MY_SERVICE.

Identifier les requêtes bloquées

Vous devez activer la journalisation pour le service de cache périphérique pour que les requêtes bloquées soient consignées.

Les requêtes autorisées ou refusées par une stratégie de filtrage sont consignées dans Logging. Pour filtrer les requêtes refusées, la requête Logging suivante pour la configuration prod-video-service ressemblerait à ceci :

resource.type="edge_cache_service"
jsonPayload.statusDetails="denied_by_security_policy"

Personnaliser les codes de réponse

Les règles Google Cloud Armor peuvent être configurées pour que leur action associée consiste à renvoyer un code d'état spécifique. Dans la plupart des cas, il est préférable de renvoyer un code HTTP 403 (deny-403) pour indiquer clairement que le client a été bloqué par la règle.

Les codes d'état compatibles sont les suivants :

  • HTTP 403 (interdit)
  • HTTP 404 (introuvable)
  • HTTP 502 (passerelle incorrecte)

L'exemple suivant montre comment configurer le code d'état renvoyé :

gcloud

Pour spécifier l'une des valeurs [allow | deny-403 | deny-404 | deny-502] comme action associée à la règle, exécutez la commande suivante. Cet exemple configure la règle pour qu'elle renvoie une réponse HTTP 502.

gcloud compute security-policies rules create 1000 \
    --security-policy=block-australia --description "block AU" \
    --expression="origin.region_code == 'AU'" --action="deny-502"

Chaque règle d'une stratégie de sécurité peut définir une réponse de code d'état différente.

Examples

Voici plusieurs cas d'utilisation détaillés fournis à titre d'exemple.

Exemple : Refuser les clients situés en dehors d'un pays, à l'exception des adresses IP autorisées

Un cas d'utilisation courant de diffusion de contenus multimédias consiste à refuser les connexions de clients situés en dehors de la région pour laquelle vous disposez de licences de contenu ou de mécanismes de paiement.

Par exemple, vous pouvez autoriser uniquement les clients situés en Inde, ainsi que toutes les adresses IP autorisées (les partenaires de contenu et vos propres employés) dans la plage 192.0.2.0/24, et refuser toutes les autres requêtes.

L'expression suivante permet d'obtenir ce résultat en utilisant le langage de règles personnalisées de Google Cloud Armor :

origin.region_code == "IN" || inIpRange(origin.ip, '192.0.2.0/24')

Cette expression est configurée en tant que règle allow, avec une règle deny par défaut configurée pour être mise en correspondance avec tous les autres clients. Les stratégies de sécurité ont toujours une règle par défaut. Vous configurez généralement cette option pour refuser par défaut (default deny) tout trafic que vous n'autorisez pas explicitement. Dans d'autres cas, vous pouvez choisir de bloquer une partie du trafic et d'autoriser par défaut (default allow) tout le trafic restant.

Dans la sortie de stratégie de sécurité, notez les points suivants :

  • La règle ayant la priorité la plus élevée (priority: 0) autorise le trafic provenant de l'Inde OU de la liste d'adresses IP définie.
  • La règle de priorité la plus basse refuse par défaut (default deny) tout le trafic. Le moteur de règles refuse tous les clients que les règles de priorité supérieure n'évaluent pas comme "true".
  • Vous pouvez relier plusieurs règles à l'aide d'opérateurs booléens.

La stratégie suivante autorise le trafic provenant des clients en Inde, autorise les clients provenant d'une plage d'adresses IP définie et refuse tout le trafic restant :

gcloud

Exécutez la commande security-policies describe suivante :

gcloud compute security-policies describe allow-india-only

Cette opération génère une stratégie Google Cloud Armor semblable à celle-ci :

kind: compute#securityPolicy
name: allow-india-only
type: "CLOUD_ARMOR_EDGE"
rules:
- action: allow
  description: ''
  kind: compute#securityPolicyRule
  match:
    expr:
      expression: origin.region_code == "IN" || inIpRange(origin.ip, '192.0.2.0/24')
  preview: false
  priority: 0
- action: deny(403)
  description: Default rule, higher priority overrides it
  kind: compute#securityPolicyRule
  match:
    config:
      srcIpRanges:
      - '*'
    versionedExpr: SRC_IPS_V1
  preview: false
  priority: 2147483647

Vous pouvez également définir un en-tête de réponse personnalisé avec la variable d'en-tête {region_code}. Cet en-tête peut être inspecté avec JavaScript et reflété au client.

Exemple : Bloquer les clients malveillants en utilisant des adresses IP et des plages d'adresses IP

L'expression suivante permet d'obtenir ce résultat en utilisant le langage de règles personnalisées de Google Cloud Armor :

inIpRange(origin.ip, '192.0.2.2/32') || inIpRange(origin.ip, '192.0.2.170/32')

Vous pouvez bloquer les plages d'adresses IP jusqu'à un masque /8 en IPv4 et /32 en IPv6. Un cas d'utilisation courant pour les plates-formes de streaming consiste à bloquer les plages d'adresses IP de sortie des proxys ou des fournisseurs VPN afin de minimiser le contournement des licences de contenu :

inIpRange(origin.ip, '192.0.2.0/24') || inIpRange(origin.ip, '198.51.100.0/24') || inIpRange(origin.ip, '203.0.113.0/24') || inIpRange(origin.ip, '2001:DB8::B33F:2002/64')

Les plages d'adresses IPv4 et IPv6 sont toutes deux acceptées.

Exemple : N'autoriser qu'une liste fixe de zones géographiques

Si vous disposez d'une liste de codes pays, vous pouvez utiliser l'opérateur booléen OR || pour enchaîner des conditions de correspondance.

L'expression suivante permet d'autoriser les utilisateurs identifiés comme provenant d'Australie ou de Nouvelle-Zélande en utilisant le langage de règles personnalisées de Google Cloud Armor :

origin.region_code == "AU" || origin.region_code == "NZ"

L'expression peut également être enchaînée avec des expressions origin.ip ou inIpRange(origin.ip, '...') afin d'autoriser les testeurs, les partenaires et les plages d'adresses IP de votre entreprise, même s'ils ne proviennent pas de l'une des zones géographiques spécifiées.

Il existe un nombre documenté de sous-expressions pour chaque règle avec une expression personnalisée. Si vous devez enchaîner plusieurs sous-expressions, définissez plusieurs règles au sein d'une même stratégie.

Exemple : Bloquer les clients d'un ensemble spécifique de pays

Un exemple moins courant peut consister à bloquer les clients d'un certain ensemble de pays, mais à autoriser par ailleurs les requêtes provenant de tous les autres pays.

Pour ce faire, vous devez créer une règle qui bloque à la fois le pays et les clients dont la région ne peut pas être déterminée, puis basculer sur une règle d'autorisation par défaut pour toutes les autres requêtes.

L'exemple suivant décrit une stratégie qui bloque les clients provenant du Canada ainsi que tous les clients dont l'emplacement est inconnu, mais qui autorise tout le trafic restant :

  kind: compute#securityPolicy
  name: block-canada
  type: "CLOUD_ARMOR_EDGE"
  rules:
  - action: deny(403)
    description: ''
    kind: compute#securityPolicyRule
    match:
      expr:
        expression: origin.region_code == "CA" || origin.region_code == "ZZ"
    preview: false
    priority: 0
  - action: allow
    description: Default rule, higher priority overrides it
    kind: compute#securityPolicyRule
    match:
      config:
        srcIpRanges:
        - '*'
      versionedExpr: SRC_IPS_V1
    preview: false
    priority: 2147483647

Journaliser les actions d'application

Chaque journal de requêtes fournit des détails sur la stratégie de sécurité appliquée et sur l'autorisation (ALLOW) ou le refus (DENY) de la requête.

Pour activer la journalisation, assurez-vous que logConfig.enable est défini sur true sur votre service. Les services sans journaux ne consignent pas les événements liés aux stratégies de sécurité.

Lorsqu'un client se trouve en dehors des États-Unis et qu'une stratégie de sécurité appelée deny-non-us-clients qui refuse les requêtes provenant de l'extérieur des États-Unis est appliquée, voici à quoi ressemble l'entrée de journal d'une requête refusée :

enforcedSecurityPolicy:
  name: deny-non-us-clients
  outcome: DENY

Les services sans stratégie Google Cloud Armor ont un enforcedSecurityPolicy.name défini sur no_policy et un outcome défini sur ALLOW. Par exemple, une entrée de journal de requêtes pour un service sans stratégie a les valeurs suivantes :

enforcedSecurityPolicy:
  name: no_policy
  outcome: ALLOW

Comprendre les classifications GeoIP

Media CDN s'appuie sur les sources de données de classification d'adresse IP internes de Google pour dériver un emplacement (région, état/province, ville) à partir d'une adresse IP. Si vous migrez ou répartissez le trafic entre plusieurs fournisseurs, un petit nombre d'adresses IP peut parfois être associé à des emplacements différents.

  • Google Cloud Armor utilise les codes de région ISO 3166-1 alpha 2 pour associer un client à un emplacement géographique.
  • Par exemple, US pour les États-Unis ou AU pour l'Australie.
  • Dans certains cas, une région correspond à un pays, mais ce n'est pas toujours le cas. Par exemple, le code US comprend tous les États des États-Unis, un district et six zones périphériques.
  • Pour plus d'informations, consultez la section unicode_region_subtag de la spécification Unicode Technical Standard.

  • Pour les clients pour lesquels l'emplacement ne peut pas être dérivé, origin.region_code est défini sur ZZ.

Vous pouvez ajouter des données géographiques aux en-têtes de réponse envoyés à un point de terminaison Media CDN (avec routing.routeRules[].headerActions[].responseHeadersToAdd[]) ou refléter les données géographiques fournies dans une fonction Cloud Function afin de valider les éventuelles différences entre les sources de données geoIP lors de l'intégration initiale et des tests.

En outre, les journaux de requêtes Media CDN incluent le clientRegion ainsi que d'autres données spécifiques au client que vous pouvez valider par rapport à vos sources de données existantes.

Étapes suivantes