Cette page s'applique à Apigee et à Apigee hybrid.
Ce document explique comment intégrer Apigee à Google Security Operations (Google SecOps). Si vous utilisez Google SecOps comme solution SIEM, suivez les étapes décrites dans ce document pour configurer Apigee afin qu'il envoie les données de journaux à SecOps.
Pour faciliter cette intégration, Google SecOps est compatible avec un analyseur Apigee permettant d'ingérer les données de journaux Apigee. Consultez également Ingérer des données Google Cloud dans Google Security Operations. Une fois les étapes de configuration de ce document effectuées, vos données de journaux Apigee seront transférées vers Google SecOps.
Pour savoir comment intégrer SecOps à d'autres solutions SIEM, consultez Intégrer Apigee à votre solution SIEM.
Audience
L'audience de ce document inclut :
- Les administrateurs d'API sont chargés d'assurer la sécurité des API, de gérer les configurations de la plate-forme, de favoriser l'efficacité opérationnelle et de respecter les exigences de conformité en matière de sécurité.
- Les analystes de sécurité se concentrent sur la détection et l'investigation proactives des incidents de sécurité liés aux API afin de minimiser les risques et de protéger les données sensibles.
Présentation de la configuration
La configuration décrite dans ce document utilise la règle MessageLogging d'Apigee pour envoyer un large éventail de données de journalisation Apigee, y compris des variables de flux spécifiques, à SecOps.
Google SecOps fournit un filtre Cloud Logging spécial qui peut envoyer des types de journaux spécifiques, y compris les journaux Apigee, à Google SecOps en temps réel. Google SecOps est compatible avec un analyseur Apigee permettant d'ingérer les données de journaux Apigee dans Google SecOps. Consultez également Ingérer des données Google Cloud dans Google Security Operations.
Prérequis
Une fois ces conditions préalables remplies, suivez les instructions de ce document pour intégrer Apigee à votre instance SecOps. Avant de commencer l'intégration, assurez-vous de disposer des éléments suivants :
- Un compte Apigee ou Apigee hybrid disposant de droits d'administrateur pour développer et déployer des proxys d'API
- Un compte Google SecOps
- Cloud Logging activé et expérience de configuration et d'utilisation de Cloud Logging
- Comprendre les variables de flux Apigee
- Comprendre la règle MessageLogging d'Apigee et l'utilisation et la configuration des règles en général
- (Facultatif) Comprendre comment les analyseurs Google SecOps sont utilisés pour interpréter les journaux ingérés. Les analyseurs SecOps sont intégrés par défaut pour analyser et comprendre les journaux Apigee ingérés par la règle MessageLogging.
- Autorisations Google Cloud IAM pour utiliser l'API Cloud Logging et attribuer des rôles IAM au compte de service SecOps
Intégrer Apigee à SecOps
Si vous utilisez Google SecOps comme solution SIEM, suivez ces étapes pour envoyer les données de journaux Apigee à SecOps. Voici les deux étapes de base :
- Configurer une règle MessageLogging pour envoyer les données de journaux Apigee à Cloud Logging
- Associer la règle MessageLogging à un proxy Apigee
Une fois la configuration de la règle MessageLogging décrite dans cette section terminée, les données de journaux Apigee envoyées à Cloud Logging seront analysées par SecOps. Pour en savoir plus sur l'analyseur et sur la façon dont les données des variables de flux Apigee sont mappées aux champs de données SecOps, consultez Intégrer Apigee à Google SecOps SIEM. Consultez également Collecter les journaux Apigee.
Suivez ces étapes pour intégrer Apigee à SecOps à l'aide de la règle MessageLogging :
Configurez une règle MessageLogging. Consultez Associer et configurer des règles dans l'UI.
Voici un exemple de règle MessageLogging qui envoie des données à Cloud Logging. La règle spécifie un grand nombre de variables de flux à envoyer à Cloud Logging. Vous pouvez ajouter ou supprimer des variables de flux à votre guise, en fonction des champs que vous jugez importants pour votre analyse SecOps. Pour savoir comment les données des variables de flux Apigee sont mappées aux champs de données SecOps, consultez Intégrer Apigee au SIEM Google SecOps.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <MessageLogging continueOnError="false" enabled="true" name="ML-CloudLoggingSecOps"> <DisplayName>ML-CloudLoggingSecOps</DisplayName> <CloudLogging> <LogName>projects/{organization.name}/logs/apigee-secops-integration-{environment.name}</LogName> <Message contentType="application/json">{ "apiproduct.name": "{apiproduct.name}", "app.name": "{developer.app.name}", "cachehit":"{cachehit}", "client.country": "{client.country}", "client.cn": "{client.cn}", "client.ip": "{proxy.client.ip}", "client.locality": "{client.locality}", "client.port": "{client.port}", "client.scheme": "{client.scheme}", "client.state": "{client.state}", "developer.email": "{developer.email}", "environment.name": "{environment.name}", "error":"{is.error}", "error.state":"{error.state}", "error.message":"{escapeJSON(error.message)}", "fault.name":"{fault.name}", "messageid":"{messageid}", "organization.name": "{organization.name}", "proxy.name": "{apiproxy.name}", "proxy.basepath": "{proxy.basepath}", "proxy.pathsuffix": "{proxy.pathsuffix}", "proxy.proxyendpoint.name": "{proxy.name}", "proxy.revision":"{apiproxy.revision}", "request.content-length":"{request_msg.header.content-length}", "request.content-type":"{request_msg.header.content-type}", "request.host":"{request_msg.header.host}", "request.httpversion": "{request.version}", "request.url": "{client.scheme}://{request_msg.header.host}{request_msg.uri}", "request.user-agent":"{request.header.user-agent}", "request.verb": "{request.verb}", "request.x-b3-traceid": "{request.header.x-b3-traceid}", "request.x-cloud-trace-context": "{request.header.x-cloud-trace-context}", "response.content-length":"{response.header.content-length}", "response.content-type":"{response.header.content-type}", "response.status.code": "{message.status.code}", "system.region.name": "{system.region.name}", "system.timestamp": "{system.timestamp}", "system.uuid": "{system.uuid}", "target.cn": "{target.cn}", "target.country": "{target.country}", "target.host": "{target.host}", "target.ip": "{target.ip}", "target.locality": "{target.locality}", "target.organization": "{target.organization}", "target.port": "{target.port}", "target.scheme": "{target.scheme}", "target.state": "{target.state}", "target.url": "{request.url}" } </Message> <ResourceType>api</ResourceType> </CloudLogging> </MessageLogging>
Associez la règle en tant qu'étape conditionnelle dans un proxy d'API. Une option consiste à associer la règle à une règle FaultRule dans PostFlow, où les erreurs liées à la sécurité sont généralement générées. Exemple :
<PostFlow name="PostFlow"> <Request> <Step> <Condition>flow.isError == true)</Condition> <Name>ML-CloudLoggingSecOps</Name> </Step> </Request> </PostFlow>
Désormais, lorsque le proxy d'API qui utilise cette règle s'exécute, les données de journaux Apigee sont transmises à Google SecOps.
Une autre pratique courante consiste à placer la règle MessageLogging dans le PostClientFlow de la réponse ProxyEndpoint.
Tenez compte des conseils suivants lorsque vous associez la règle MessageLogging à votre proxy d'API :
- Placez la règle dans une FaultRule. FaultRule est l'emplacement recommandé pour consigner les exceptions de sécurité et les cas de non-respect des règles.
- Placez la règle dans le PostFlow. PostFlow est un autre emplacement approprié pour consigner les problèmes de sécurité.
- Évitez de consigner les requêtes réussies. Pour la surveillance de la sécurité axée sur les menaces, vous enregistrez généralement les détails lorsqu'un problème survient (une erreur est signalée). La journalisation de chaque requête réussie avec le contenu complet du message peut générer un nombre excessif de journaux et augmenter les coûts.
- Envisagez d'utiliser des variables personnalisées pour certains cas d'utilisation. Par exemple, si vous devez capturer l'URI de la requête d'origine dans un flux d'erreur, vous pouvez utiliser la règle AssignMessage dans le PreFlow de la requête pour la copier dans une variable personnalisée (telle que
original.request.uri
), puis consigner cette variable dans la règle MessageLogging.
Bonnes pratiques
Tenez compte des bonnes pratiques suivantes lorsque vous configurez Apigee avec Google SecOps :
- Concentrez-vous sur le contexte de sécurité : n'enregistrez que les variables de flux qui fournissent un contexte utile pour la surveillance de la sécurité et la détection des menaces. Évitez la journalisation excessive de données non liées à la sécurité.
- Utilisez un format de journalisation cohérent : conservez un format de journalisation cohérent pour tous vos proxys d'API qui utilisent SecOps.
- Utilisez des comptes de service sécurisés : respectez les bonnes pratiques de sécurité pour gérer et sécuriser le compte de service Google Cloud utilisé pour l'ingestion SecOps. Si possible, limitez l'autorisation à la visionneuse de journaux.
- Surveillez le flux SecOps : vérifiez régulièrement l'état de votre flux SecOps pour vous assurer que les journaux sont ingérés correctement et sans erreur.
- Utilisez les règles et les tableaux de bord SecOps : une fois que les journaux liés à la sécurité sont dans SecOps, développez des règles et des tableaux de bord spécifiques pour détecter et visualiser les menaces de sécurité en fonction des informations détaillées que vous enregistrez.
Dépannage
Cette section décrit plusieurs problèmes que vous pouvez rencontrer lors de la configuration d'Apigee avec SecOps, ainsi que les éléments à vérifier.
Problème : les journaux des événements de sécurité n'apparaissent pas dans Cloud Logging
Points à vérifier :
- Vérifiez que votre règle MessageLogging est correctement configurée avec
Condition
pour se déclencher lorsqu'un événement de sécurité se produit. - Assurez-vous que la stratégie MessageLogging est associée au contexte de flux approprié, tel qu'une FaultRule ou un PostFlow.
- Vérifiez que Cloud Logging est activé dans votre projet Google Cloud.
- Examinez les éventuels messages d'erreur dans les journaux de votre proxy Apigee liés à la règle MessageLogging.
Problème : Les journaux d'événements de sécurité n'apparaissent pas dans SecOps
- Vérifiez que votre flux SecOps est correctement configuré avec l'ID de projet, le filtre de journaux (assurez-vous qu'il capture les journaux de votre règle de journalisation de la sécurité) et les identifiants du compte de service appropriés.
- Vérifiez l'état de votre flux SecOps dans l'UI SecOps pour détecter les éventuels messages d'erreur ou problèmes d'ingestion.
- Assurez-vous que le compte de service utilisé par SecOps dispose du rôle Lecteur de journaux dans votre projet Google Cloud.
Champs liés à la sécurité non analysés correctement dans SecOps
- Examinez la structure JSON de vos journaux dans Cloud Logging pour vous assurer qu'ils sont bien formés et qu'ils contiennent les noms de champs attendus.
- Vérifiez que l'analyseur Google Cloud approprié est activé.
- Si vous pensez qu'il existe un problème d'analyse, examinez un exemple d'entrée de journal dans les données brutes SecOps pour voir comment il a été ingéré avant l'analyse. Si des champs spécifiques ne sont pas extraits comme prévu, vous devrez peut-être consulter la documentation sur l'analyseur SecOps ou déterminer si un analyseur personnalisé est nécessaire.
Intégrer Apigee à Google SecOps SIEM
Le tableau suivant mappe les noms de variables de flux Apigee aux noms de champs SIEM Google SecOps équivalents. Par exemple, lorsque vous consultez les données de journaux Apigee dans Cloud Logging, la variable de flux client.id
correspond au champ SIEM SecOps appelé principle_ip
. Consultez également Collecter les journaux Apigee.
Variable de flux Apigee | Nom du champ SIEM SecOps | Description |
---|---|---|
client.country | principal.hostname | Adresse IP de l'hôte HTTP associée à la requête reçue par le ProxyEndpoint. |
client.host | principal.location.country_or_region | Pays spécifié dans le certificat TLS/SSL présenté par l'application cliente. Demande de proxy principal.location.country_or_region . |
client.ip | principle.ip | Adresse IP du client ou du système qui envoie le message à l'équilibreur de charge. Il peut s'agir, par exemple, de l'adresse IP du client d'origine ou d'une adresse IP d'équilibreur de charge. |
client.locality | principal.location.city | Localité (ville) du certificat TLS/SSL présenté par le client. |
client.port | principal.port | Port HTTP associé à la requête du client d'origine au ProxyEndpoint. |
client.state | principal.location.state | État spécifié dans le certificat TLS/SSL présenté par le client. |
organization.name | intermediary.cloud.project.name | Nom de l'organisation Apigee. |
proxy.client.ip | src.ip | Adresse X-Forwarded-For de l'appel entrant, qui correspond à l'adresse IP reçue par Apigee lors du dernier handshake TCP externe. Il peut s'agir du client à l'origine de l'appel ou d'un équilibreur de charge. |
proxy.name | intermediary.resource.name | Attribut de nom configuré pour le ProxyEndpoint. |
proxy.pathsuffix | intermediary.resource.attribute.labels[pathsuffix] | "Valeur du suffixe de chemin dans l'URL envoyée par le client et reçue au niveau du ProxyEndpoint. Le chemin de base est le composant de chemin le plus à gauche qui identifie de manière unique un proxy d'API au sein d'un groupe d'environnements. Supposons que vous ayez un point de terminaison de proxy d'API configuré avec un chemin de base /v2/weatherapi. Dans ce cas, une requête envoyée à https://myhost.example.net/v2/weatherapi/forecastrss?w=12797282, la variable proxy.pathsuffix contiendra la chaîne "/forecastrss". |
proxy.url | intermediary.url | "Récupère l'URL complète associée à la requête de proxy reçue par le ProxyEndpoint, y compris les paramètres de requête présents. Pour obtenir un exemple de construction d'URL de requête à l'aide de l'hôte de la requête d'origine (plutôt que l'hôte du routeur utilisé dans proxy.url), consultez la section "Accéder aux messages de requête". |
request.uri | target.resource.name | Nom de domaine du service cible qui renvoie la réponse au proxy d'API. |
request.verb | Verbe HTTP utilisé pour la requête. Par exemple, GET, PUT et DELETE. | |
response.content | Contenu de la charge utile du message de réponse renvoyé par la cible. | |
response.status.code | Code de réponse renvoyé pour une requête. Vous pouvez utiliser cette variable pour remplacer le code d'état de la réponse, stocké dans message.status.code. Pour en savoir plus, consultez message. | |
system.region.name | intermediary.location.name | Nom de la région du centre de données dans laquelle le proxy est exécuté. |
system.timestamp | Entier (long) de 64 bits représentant l'heure à laquelle cette variable a été lue. La valeur correspond au nombre de millisecondes écoulées depuis minuit, le 1er janvier 1970 UTC. Par exemple, 1534783015000. | |
system.uuid | intermediary.process.pid ou intermediary.process.product_specific_process_id | UUID du processeur de messages gérant le proxy. |
target.country | target.location.country_or_region | Pays du certificat TLS/SSL présenté par le serveur cible |
target.host | Nom de domaine du service cible qui renvoie la réponse au proxy d'API. | |
target.ip | Adresse IP du service cible qui renvoie la réponse au proxy d'API. | |
target.locality | target.location.city | Localité (ville) du certificat TLS/SSL présenté par le serveur cible |
target.organization | Organisation du certificat TLS/SSL présenté par le serveur cible. | |
target.port | Numéro de port du service cible renvoyant la réponse au proxy d'API. | |
target.scheme | Renvoie HTTP ou HTTPS en fonction du message de la requête. | |
target.state | target.location.state | État du certificat TLS/SSL présenté par le serveur cible. |
target.url | URL configurée dans le fichier XML du TargetEndpoint ou dans l'URL de la cible dynamique (si target.url est défini lors du flux de messages). La variable n'inclut aucun élément de chemin ni paramètre de requête supplémentaire. Renvoie la valeur "null" si elle est appelée hors du champ d'application ou non définie. Remarque : Utilisez une règle JavaScript associée au TargetEndpoint pour définir cette variable. |