Collecter les journaux DNS Cisco Umbrella
Ce document explique comment collecter des journaux DNS Cisco Umbrella dans un flux Google Security Operations à l'aide d'un bucket AWS S3. L'analyseur gère les journaux au format JSON et CSV. Il extrait les champs, les renomme pour qu'ils correspondent à l'UDM, gère différentes versions et différents formats de journaux (y compris les journaux de proxy et d'adresse IP), et applique une logique spécifique aux identités, aux catégories de sécurité et aux événements réseau, en fusionnant finalement les données extraites dans le schéma UDM.
Avant de commencer
- Assurez-vous de disposer d'une instance Google SecOps.
- Assurez-vous de disposer d'un accès privilégié à AWS IAM et S3.
- Assurez-vous de disposer d'un accès privilégié à Cisco Umbrella.
Configurer un bucket Amazon S3 géré par Cisco
- Connectez-vous au tableau de bord Cisco Umbrella.
- Accédez à Admin > Gestion des journaux.
- Sélectionnez l'option Utiliser un bucket Amazon S3 géré par Cisco.
- Fournissez les informations de configuration suivantes :
- Sélectionnez une région : sélectionnez une région plus proche de votre emplacement pour réduire la latence.
- Sélectionnez une durée de conservation : sélectionnez la période. La durée de conservation est de 7, 14 ou 30 jours. Passé le délai sélectionné, les données sont supprimées et ne peuvent pas être récupérées. Si votre cycle d'ingestion est régulier, utilisez une période plus courte. Vous pourrez modifier la durée de conservation ultérieurement.
- Cliquez sur Enregistrer.
- Cliquez sur Continuer pour confirmer vos sélections et recevoir une notification d'activation.
Dans la fenêtre Activation terminée qui s'affiche, les valeurs Clé d'accès et Clé secrète sont affichées. - Copiez les valeurs Clé d'accès et Clé secrète. Si vous perdez ces clés, vous devez les régénérer.
- Cliquez sur OK > Continuer.
- Une page récapitulative affiche la configuration et le nom de votre bucket. Vous pouvez activer ou désactiver la journalisation selon les besoins de votre organisation. Toutefois, les journaux sont supprimés en fonction de la durée de conservation, que de nouvelles données soient ajoutées ou non.
Facultatif : Configurer les clés d'accès utilisateur pour le bucket AWS S3 autogéré
- Connectez-vous à l'AWS Management Console.
- Créez un utilisateur en suivant ce guide de l'utilisateur : Créer un utilisateur IAM.
- Sélectionnez l'utilisateur créé.
- Sélectionnez l'onglet Informations d'identification de sécurité.
- Cliquez sur Créer une clé d'accès dans la section Clés d'accès.
- Sélectionnez Service tiers comme Cas d'utilisation.
- Cliquez sur Suivant.
- Facultatif : ajoutez un tag de description.
- Cliquez sur Créer une clé d'accès.
- Cliquez sur Télécharger le fichier CSV pour enregistrer la clé d'accès et la clé d'accès secrète pour une utilisation ultérieure.
- Cliquez sur OK.
- Sélectionnez l'onglet Autorisations.
- Cliquez sur Ajouter des autorisations dans la section Règles d'autorisation.
- Sélectionnez Ajouter des autorisations.
- Sélectionnez Joindre directement des règles.
- Recherchez et sélectionnez la règle AmazonS3FullAccess.
- Cliquez sur Suivant.
- Cliquez sur Ajouter des autorisations.
Facultatif : configurer un bucket Amazon S3 autogéré
Connectez-vous à l'AWS Management Console.
Accédez à S3.
Cliquez sur Créer un bucket.
Fournissez les informations de configuration suivantes :
- Nom du bucket : indiquez le nom du bucket Amazon S3.
- Région : sélectionnez une région.
Cliquez sur Créer.
Facultatif : Configurez une stratégie de bucket pour le bucket AWS S3 autogéré
- Cliquez sur le bucket que vous venez de créer pour l'ouvrir.
- Sélectionnez Propriétés> Autorisations.
- Dans la liste Autorisations, cliquez sur Ajouter une règle de bucket.
Saisissez la règle de bucket préconfigurée comme suit :
{ "Version": "2008-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::568526795995:user/logs" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::BUCKET_NAME/*" }, { "Sid": "", "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::568526795995:user/logs" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::BUCKET_NAME/*"}, { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::568526795995:user/logs" }, "Action": "s3:GetBucketLocation", "Resource": "arn:aws:s3:::BUCKET_NAME" }, { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::568526795995:user/logs" }, "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::BUCKET_NAME" } ] }
- Remplacez
BUCKET_NAME
par le nom du bucket Amazon S3 que vous avez fourni.
- Remplacez
Cliquez sur Enregistrer.
Facultatif : validation requise pour le bucket Amazon S3 autogéré
- Dans le tableau de bord Cisco Umbrella, sélectionnez Admin > Log management > Amazon S3.
- Dans le champ Nom du bucket, spécifiez le nom exact de votre bucket Amazon S3, puis cliquez sur Valider.
- Lors de la procédure de validation, un fichier nommé
README_FROM_UMBRELLA.txt
est importé de Cisco Umbrella vers votre bucket Amazon S3. Vous devrez peut-être actualiser votre navigateur pour que le fichier Readme s'affiche une fois importé. - Téléchargez le fichier
README_FROM_UMBRELLA.txt
et ouvrez-le à l'aide d'un éditeur de texte. - Copiez et enregistrez le jeton Cisco Umbrella unique du fichier.
- Accédez au tableau de bord Cisco Umbrella.
- Dans le champ Numéro de jeton, spécifiez le jeton, puis cliquez sur Enregistrer.
- Si l'opération réussit, un message de confirmation s'affiche dans votre tableau de bord pour indiquer que le bucket a bien été validé. Si vous recevez une erreur indiquant que votre bucket ne peut pas être validé, vérifiez à nouveau la syntaxe du nom du bucket et examinez la configuration.
Configurer un flux dans Google SecOps pour ingérer les journaux DNS Cisco Umbrella
- Accédez à Paramètres SIEM> Flux.
- Cliquez sur Ajouter.
- Dans le champ Nom du flux, saisissez un nom pour le flux (par exemple, Journaux DNS Cisco Umbrella).
- Sélectionnez Amazon S3 V2 comme type de source.
- Sélectionnez Cisco Umbrella DNS comme Type de journal.
- Cliquez sur Suivant.
Spécifiez les valeurs des paramètres d'entrée suivants :
- URI S3 : URI du bucket.
s3:/BUCKET_NAME/
- Remplacez
BUCKET_NAME
par le nom réel du bucket.
- Remplacez
- Options de suppression de la source : sélectionnez l'option de suppression de votre choix.
- URI S3 : URI du bucket.
Cliquez sur Suivant.
Vérifiez la configuration de votre nouveau flux sur l'écran Finaliser, puis cliquez sur Envoyer.
Table de mappage UDM
Champ de journal | Mappage UDM | Logique |
---|---|---|
action |
security_result.action_details |
La valeur est extraite du champ action si elle existe dans les journaux JSON, ou de column6 ou column7 dans les journaux CSV, et convertie en majuscules (ALLOW ou BLOCK). |
amp.disposition |
security_result.detection_fields[].key |
La valeur est ampDisposition . |
amp.disposition |
security_result.detection_fields[].value |
La valeur est extraite du champ amp.disposition . |
amp.malware |
security_result.detection_fields[].key |
La valeur est ampMalware . |
amp.malware |
security_result.detection_fields[].value |
La valeur est extraite du champ amp.malware . |
amp.score |
security_result.detection_fields[].key |
La valeur est ampScore . |
amp.score |
security_result.detection_fields[].value |
La valeur est extraite du champ amp.score . |
blocked_categories |
security_result.category_details |
La valeur est extraite du champ blocked_categories . |
blockedfiletype |
security_result.detection_fields[].key |
La valeur est egress type . |
blockedfiletype |
security_result.detection_fields[].value |
La valeur est extraite du champ blockedfiletype . |
bundleid |
additional.fields[].key |
La valeur est bundleid . |
bundleid |
additional.fields[].value.string_value |
La valeur est extraite du champ bundleid . |
categories[] |
security_result.category_details |
La valeur est extraite du champ categories[].label . |
column1 |
metadata.event_timestamp.seconds |
La valeur est analysée à partir du champ column1 en tant qu'horodatage. Pour les journaux de proxy, si les champs date et time existent, ils sont combinés et analysés en tant qu'horodatage. |
column10 |
network.http.user_agent |
La valeur est extraite du champ column10 . |
column10 |
additional.fields[].value.string_value |
La valeur est extraite du champ column10 . |
column11 |
target.port |
La valeur est extraite du champ column11 . |
column12 |
principal.resource.name |
La valeur est extraite du champ column12 . |
column13 |
security_result.rule_id |
La valeur est extraite du champ column13 . |
column14 |
security_result.action_details |
La valeur est extraite du champ column14 . |
column2 |
principal.user.user_display_name |
La valeur est extraite du champ column2 . |
column2 |
principal.user.userid |
La valeur est extraite du champ column2 . |
column2 |
principal.location.name |
La valeur est extraite du champ column2 . |
column3 |
principal.hostname |
La valeur est extraite du champ column3 . |
column3 |
principal.user.product_object_id |
La valeur est extraite du champ column3 . |
column3 |
principal.location.city |
La valeur est extraite du champ column3 . |
column3 |
additional.fields[].value.string_value |
La valeur est extraite du champ column3 . |
column4 |
principal.asset.ip |
La valeur est extraite du champ column4 . |
column4 |
principal.ip |
La valeur est extraite du champ column4 . |
column4 |
principal.port |
La valeur est extraite du champ column4 . |
column5 |
principal.asset.ip |
La valeur est extraite du champ column5 . |
column5 |
principal.ip |
La valeur est extraite du champ column5 . |
column5 |
target.asset.ip |
La valeur est extraite du champ column5 . |
column5 |
target.ip |
La valeur est extraite du champ column5 . |
column6 |
security_result.action_details |
La valeur est extraite du champ column6 . |
column6 |
target.port |
La valeur est extraite du champ column6 . |
column7 |
network.received_bytes |
La valeur est extraite du champ column7 . |
column7 |
additional.fields[].value.string_value |
La valeur est extraite du champ column7 . |
column8 |
principal.asset.ip |
La valeur est extraite du champ column8 . |
column8 |
principal.ip |
La valeur est extraite du champ column8 . |
column8 |
target.url |
La valeur est extraite du champ column8 . |
column9 |
principal.port |
La valeur est extraite du champ column9 . |
column9 |
network.http.referral_url |
La valeur est extraite du champ column9 . |
data_center_name |
principal.resource.name |
La valeur est extraite du champ data_center_name . |
datacenter.label |
security_result.detection_fields[].key |
La valeur est datacenter label . |
datacenter.label |
security_result.detection_fields[].value |
La valeur est extraite du champ datacenter.label . |
destinationip |
target.asset.ip |
La valeur est extraite du champ destinationip . |
destinationip |
target.ip |
La valeur est extraite du champ destinationip . |
direction |
network.direction |
La valeur est extraite du champ direction et convertie en majuscules. |
domain |
network.dns.questions[].name |
La valeur est extraite du champ domain , et le point de fin est supprimé s'il est présent. |
dstPort |
target.port |
La valeur est extraite du champ dstPort . |
dstip |
target.asset.ip |
La valeur est extraite du champ dstip . |
dstip |
target.ip |
La valeur est extraite du champ dstip . |
egress.ip |
security_result.detection_fields[].key |
La valeur est egress ip . |
egress.ip |
security_result.detection_fields[].value |
La valeur est extraite du champ egress.ip . |
egress.type |
security_result.detection_fields[].key |
La valeur est egress type . |
egress.type |
security_result.detection_fields[].value |
La valeur est extraite du champ egress.type . |
externalip |
principal.asset.ip |
La valeur est extraite du champ externalip . |
externalip |
principal.ip |
La valeur est extraite du champ externalip . |
forwardingmethod |
additional.fields[].key |
La valeur est forwardingmethod . |
forwardingmethod |
additional.fields[].value.string_value |
La valeur est extraite du champ forwardingmethod . |
granular_identity |
principal.user.user_display_name |
La valeur est extraite du champ granular_identity si granular_identity et most_granular_identity sont tous les deux présents. Sinon, elle est dérivée du champ _policy_identity et analysée plus en détail en fonction de identityType . |
granular_identity |
principal.user.email_addresses |
La valeur est extraite du champ granular_identity à l'aide d'une expression régulière. |
granular_identity |
principal.user.first_name |
La valeur est extraite du champ granular_identity à l'aide d'une expression régulière. |
granular_identity |
principal.user.last_name |
La valeur est extraite du champ granular_identity à l'aide d'une expression régulière. |
granular_identity |
principal.user.userid |
La valeur est extraite du champ granular_identity à l'aide d'une expression régulière. |
granular_identity |
principal.hostname |
La valeur est extraite du champ granular_identity . |
granular_identity |
principal.location.name |
La valeur est extraite du champ granular_identity . |
identity_types |
additional.fields[].value.string_value |
La valeur est extraite du champ identity_types . |
identities[] |
principal.user.product_object_id |
La valeur est extraite du champ identities[] . |
identities |
principal.user.product_object_id |
La valeur est extraite du champ identities . |
internalip |
principal.asset.ip |
La valeur est extraite du champ internalip . |
internalip |
principal.ip |
La valeur est extraite du champ internalip . |
isolated.fileaction |
security_result.detection_fields[].key |
La valeur est isolated fileaction . |
isolated.fileaction |
security_result.detection_fields[].value |
La valeur est extraite du champ isolated.fileaction . |
isolated.state |
security_result.detection_fields[].key |
La valeur est isolated state . |
isolated.state |
security_result.detection_fields[].value |
La valeur est extraite du champ isolated.state . |
most_granular_identity |
principal.user.identityType |
La valeur est extraite du champ most_granular_identity si granular_identity et most_granular_identity sont tous les deux présents. Sinon, il est extrait du champ _policy_identity_type . |
nat_destination_ip |
principal.asset.ip |
La valeur est extraite du champ nat_destination_ip . |
nat_destination_ip |
principal.ip |
La valeur est extraite du champ nat_destination_ip . |
odns_categories |
security_result.category_details |
La valeur est extraite du champ odns_categories . |
policy.ruleid |
security_result.rule_id |
La valeur est extraite du champ policy.ruleid . |
policy.rulesetid |
security_result.detection_fields[].key |
La valeur est rulesetid . |
policy.rulesetid |
security_result.detection_fields[].value |
La valeur est extraite du champ policy.rulesetid . |
policy.timebasedrule |
security_result.detection_fields[].key |
La valeur est timebasedrule . |
policy.timebasedrule |
security_result.detection_fields[].value |
La valeur est extraite du champ policy.timebasedrule . |
port |
target.port |
La valeur est extraite du champ port . |
query_type_name |
network.dns.questions[].type |
La partie numérique est extraite du champ query_type_name à l'aide d'une expression régulière et convertie en entier. |
query_type_name |
additional.fields[].value.string_value |
La partie de la chaîne entre parenthèses est extraite du champ query_type_name à l'aide d'une expression régulière. |
querytype |
network.dns.questions[].type |
La valeur est extraite du champ querytype et mappée à une valeur numérique en fonction du type d'enregistrement DNS. |
referer |
network.http.referral_url |
La valeur est extraite du champ referer . |
requestmethod |
network.http.method |
La valeur est extraite du champ requestmethod . |
requestsize |
network.sent_bytes |
La valeur est extraite du champ requestsize et convertie en entier non signé. |
response |
additional.fields[].value.string_value |
La valeur est extraite du champ response . |
responsecode |
network.http.response_code |
La valeur est extraite du champ responsecode . |
responsefilename |
target.file.names |
La valeur est extraite du champ responsefilename . |
responsesize |
network.received_bytes |
La valeur est extraite du champ responsesize et convertie en entier non signé. |
returncode |
network.dns.response_code |
La valeur est extraite du champ returncode et convertie en entier non signé. |
securityoverridden |
additional.fields[].key |
La valeur est securityoverridden . |
securityoverridden |
additional.fields[].value.string_value |
La valeur est extraite du champ securityoverridden . |
sha256 |
target.file.sha256 |
La valeur est extraite du champ sha256 . |
source_ip |
principal.asset.ip |
La valeur est extraite du champ source_ip s'il existe dans les journaux JSON, ou de column3 dans les journaux CSV. |
source_ip |
principal.ip |
La valeur est extraite du champ source_ip s'il existe dans les journaux JSON, ou de column3 dans les journaux CSV. |
srcPort |
principal.port |
La valeur est extraite du champ srcPort . |
statuscode |
network.http.response_code |
La valeur est extraite du champ statuscode . |
tenantcontrols |
additional.fields[].key |
La valeur est tenantcontrols . |
tenantcontrols |
additional.fields[].value.string_value |
La valeur est extraite du champ tenantcontrols . |
timestamp |
metadata.event_timestamp.seconds |
La valeur est analysée à partir du champ timestamp en tant qu'horodatage. |
tunnel_name |
additional.fields[].key |
La valeur est tunnel_name . |
tunnel_name |
additional.fields[].value.string_value |
La valeur est extraite du champ tunnel_name . |
tunnel_type |
metadata.product_event_type |
La valeur est extraite du champ tunnel_type . |
type |
additional.fields[].key |
La valeur est type . |
type |
additional.fields[].value.string_value |
La valeur est extraite du champ type . |
url |
target.url |
La valeur est extraite du champ url . |
useragent |
network.http.user_agent |
La valeur est extraite du champ useragent . |
verdict |
security_result.action_details |
La valeur est extraite du champ verdict . |
warnstatus |
security_result.detection_fields[].key |
La valeur est warnstatus . |
warnstatus |
security_result.detection_fields[].value |
La valeur est extraite du champ warnstatus . La valeur est DNS Lookup Type . La partie de la chaîne entre parenthèses est extraite du champ query_type_name à l'aide d'une expression régulière, ou il s'agit d'une chaîne vide si le champ n'est pas présent. La valeur est DNS request and response were made. . Elle est déterminée en fonction de la présence de certains champs : NETWORK_DNS si question.name est présent, NETWORK_CONNECTION si principal.ip et target.ip sont présents, STATUS_UPDATE si seul principal.ip est présent, ou GENERIC_EVENT dans le cas contraire. La valeur est UMBRELLA_DNS . La valeur est Umbrella DNS . La valeur est Cisco . La valeur est initialement définie sur DNS . Si requestmethod est une méthode HTTP valide, elle est remplacée par HTTP . La partie numérique est extraite du champ query_type_name à l'aide d'une expression régulière et convertie en nombre entier, ou elle est dérivée du champ querytype et mappée à une valeur numérique en fonction du type d'enregistrement DNS. La valeur est dérivée du champ useragent ou column10 à l'aide du filtre parseduseragent . La valeur est extraite de la dernière partie du champ column3 après avoir été divisée par des virgules, ou il s'agit d'une chaîne vide si le champ n'est pas présent. La valeur est extraite de la première partie du champ column3 après la division par des virgules, ou du champ column2 si column3 n'est pas présent. La valeur est extraite du champ column2 ou column3 à l'aide d'une expression régulière. La valeur est extraite du champ column2 ou column3 à l'aide d'une expression régulière. La valeur est extraite du champ column2 ou column3 à l'aide d'une expression régulière. La valeur est extraite du champ column2 ou column3 à l'aide d'une expression régulière. La valeur est dérivée du champ action , column6 , column7 ou verdict , puis convertie en majuscules (ALLOW ou BLOCK). La valeur est définie sur NETWORK_MALICIOUS si _categories contient Malware , ou sur NETWORK_SUSPICIOUS si _categories contient Potentially Harmful . |
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.