
Haute vitesse / Faible coût CommonCrawl RegExp sur Node.js
Image
WARCannon a été conçu pour simplifier et réduire le coût du processus de 'grep sur Internet'.
Avec WARCannon, vous pouvez :
WARCannon exploite une utilisation intelligente des technologies AWS pour passer à l'échelle horizontalement à n'importe quelle capacité, minimiser les coûts grâce aux flottes spot et au transfert de données dans la même région, extraire des données de S3 à des vitesses incroyables (jusqu'à 100 Gbps par nœud), paralléliser sur des centaines de cœurs CPU, rapporter l'état via DynamoDB et CloudFront, et stocker les résultats via S3.
Au total, WARCannon peut traiter plusieurs expressions régulières sur 400 To en quelques heures pour environ 30 $.
Le moyen le plus rapide et le plus simple de commencer est d'utiliser AWS CloudShell. Collez simplement cette commande en une ligne :
source <(curl https://raw.githubusercontent.com/c6fc/warcannon/master/cloudshell/deploy.sh)
Si vous souhaitez utiliser une branche non-master de WARCannon, tapez simplement :
export GIT_BRANCH=branch_name
source <(curl https://raw.githubusercontent.com/c6fc/warcannon/$GIT_BRANCH/cloudshell/deploy.sh)
Remarque : Le déploiement via CloudShell utilise un stockage éphémère, ce qui signifie que les motifs d'expressions régulières personnalisés seront perdus lorsque CloudShell se fermera. Si vous prévoyez d'utiliser WARCannon fréquemment, je vous recommande d'utiliser l'installation locale ci-dessous.
WARCannon nécessite que vous ayez installé les éléments suivants :
Astuce : Pour garder les choses propres et distinctes d'autres éléments que vous pourriez avoir dans AWS, il est FORTEMENT recommandé de déployer WARCannon dans un nouveau compte. Vous pouvez créer un nouveau compte facilement depuis la console 'Organizations' dans AWS. Par 'FORTEMENT recommandé', j'entends 'sérieusement, n'installez pas ceci à côté d'autres choses'.
D'abord, clonez le dépôt et copiez les paramètres d'exemple.
$ git clone [email protected]:c6fc/warcannon.git
$ cd warcannon
warcannon$ cp settings.json.sample settings.json
Modifiez settings.json à votre goût :
Paramètres requis
nodeInstanceType : Un tableau de types d'instances à utiliser pour le traitement parallèle. Les types 'c' sont les meilleurs pour cela, et n'importe quelle taille peut être utilisée. ["c5n.18xlarge"] est la valeur recommandée pour les vraies campagnes.nodeCapacity : Le nombre de nœuds à demander lors du traitement parallèle. Les nœuds résultants seront une distribution arbitraire des nodeInstanceTypes que vous spécifiez.nodeParallelism : Le nombre de WARCs simultanés à traiter par vCPU. 2 est un bon nombre ici. Si les nœuds n'ont pas assez de RAM pour fonctionner à ce niveau de parallélisme (comme avec les instances de type 'c'), ils fonctionneront au parallélisme sûr le plus élevé à la place.nodeMaxDuration : La durée de vie maximale des nœuds de calcul en secondes. Les nœuds seront automatiquement terminés après ce temps si le travail n'est pas encore terminé. La valeur par défaut est de 24 heures.Paramètres optionnels (laissez-les complètement de côté si non utilisés)
sshKeyName : Le nom d'une clé SSH EC2 qui existe déjà dans us-east-1.allowSSHFrom : Un masque CIDR pour autoriser SSH. Typiquement ce sera <votreipublique>/32Pour installer, exécutez ceci :
$ npm install
$ npm link
$ warcannon deploy
Lancer une campagne dans WARCannon utilise un flux de travail simple et facile à suivre, qui peut être décrit en quelques étapes :
warcannon deploywarcannon testLocal -swarcannon testwarcannon list 2022warcannon populate 2022-21warcannon firewarcannon syncResultsLisez la suite pour une compréhension plus détaillée de chaque étape.
WARCannon est alimenté par Common Crawl via le programme AWS Open Data. Common Crawl est unique en ce sens que les données récupérées par leurs spiders capturent non seulement le texte du site web, mais aussi d'autres contenus textuels comme JavaScript, TypeScript, HTML complet, CSS, etc. En construisant des expressions régulières appropriées capables d'identifier des composants uniques, les chercheurs peuvent identifier les sites web par les technologies qu'ils utilisent, et ce sans jamais toucher au site web lui-même. Le problème est que cela nécessite d'analyser des centaines de téraoctets de données, ce qui est un défi de taille, quels que soient les ressources dont vous disposez. Heureusement, WARCannon propose plusieurs outils pour y parvenir !
Faire un grep sur Internet n'est pas pour les âmes sensibles, mais commencer par un tamis efficace est la première étape. WARCannon facilite cela en permettant la vérification locale des expressions régulières sur des données réelles de Common Crawl. D'abord, ouvrez lambda_functions/warcannon/matches.js et modifiez l'objet regex_patterns pour inclure les expressions régulières que vous souhaitez utiliser au format name: pattern. Voici un exemple de l'ensemble de recherche par défaut :
exports.regex_patterns = {
"access_key_id": /(\'A|"A)(SIA|KIA|IDA|ROA)[JI][A-Z0-9]{14}[AQ][\'"]/g,
};
Les chaînes correspondant à cette expression seront sauvegardées sous la clé correspondante dans les résultats ; access_key_id dans ce cas. Astuce : Utilisez RegExr avec le format 'JavaScript' pour construire et tester des expressions régulières sur des correspondances connues.
Vous avez également la possibilité de ne capturer que les résultats de domaines spécifiés. Pour ce faire, il suffit de remplir le tableau domains avec les FQDN que vous souhaitez inclure. Il est recommandé de laisser ce tableau vide [] car cela n'est presque jamais rentable (l'effort de traitement économisé est très faible), mais cela peut être utile dans certains cas particuliers.
exports.domains = ["example1.com", "example2.com"];
Une fois que le fichier matches.js est rempli, exécutez la commande suivante :
warcannon$ warcannon testLocal -s
Vous pouvez éventuellement ajouter un chemin vers un WARC dans le bucket S3 commoncrawl si vous le souhaitez, mais une valeur par défaut codée en dur sera utilisée sinon.
WARCannon traitera le fichier WARC en streaming (ou le téléchargera entièrement si vous omettez -s) pour trouver les correspondances configurées. WARCannon sauvegardera les résultats dans le dossier ~/.warcannon/ lorsque vous interromprez avec ctrl+c ou lorsque le traitement se termine. Cela permet de tester rapidement les correspondances courantes avec un minimum de bande passante.
En plus de tout cela, WARCannon tentera d'évaluer le coût total de calcul de vos expressions régulières lorsqu'elles sont exécutées localement. Ainsi, vous pouvez être informé si une expression régulière donnée aura un impact significatif sur les performances avant d'exécuter votre campagne.

Parfois, un simple motif d'expression régulière ne suffit pas à lui seul et vous avez besoin d'étapes supplémentaires pour vous assurer de renvoyer les bonnes informations. Dans ce cas, ajouter simplement une fonction à l'objet exports.custom_functions avec le même nom de clé vous permet d'effectuer tout traitement supplémentaire que vous jugez approprié.
exports.regex_patterns = {
"access_key_id": /(\'A|"A)(SIA|KIA|IDA|ROA)[JI][A-Z0-9]{14}[AQ][\'"]/g,
};
exports.custom_functions = {
"access_key_id": function(match) {
// Ignore matches with 'EXAMPLE' in the text, since this is common for documentation.
if (match.text(/EXAMPLE/) != null) {
// Returning a boolean 'false' discards the match.
return false
}
}
}
Remarque : WARCannon est conçu pour traiter du texte à des vitesses stupéfiantes. Bien qu'il soit certainement possible d'effectuer tout type d'opération souhaitée, l'ajout de fonctions personnalisées à haute latence telles que des appels réseau peut augmenter considérablement le temps de traitement et les coûts. Les appels réseau pourraient également entraîner de NOMBREUX appels vers un site web, ce qui pourrait vous causer des problèmes. Soyez malin dans l'utilisation de ces fonctions.
Les coûts d'AWS peuvent être anxiogènes, surtout lorsque vous cherchez seulement à faire des recherches. WARCannon est conçu pour permettre à la fois des exécutions ponctuelles et des campagnes complètes, afin que vous puissiez être confiant dans les résultats que vous obtiendrez. Une fois que vous êtes satisfait des résultats obtenus avec testLocal, vous pouvez déployer vos correspondances mises à jour et exécuter facilement un test dans le cloud :
warcannon$ warcannon deploy
warcannon$ warcannon test
Encore une fois, vous pouvez éventuellement inclure un chemin vers un WARC si vous le souhaitez, bien que ce ne soit pas obligatoire.
Cela exécutera de manière synchrone une fonction Lambda avec les expressions régulières que vous avez configurées, et retournera immédiatement les résultats. Ce processus prend environ 2,5 minutes, alors n'ayez pas peur d'attendre pendant qu'il opère sa magie.
Une fois que vous êtes satisfait des résultats obtenus dans Lambda, vous êtes prêt à faire un vrai grep sur Internet. Nous allons d'abord passer en revue quelques tâches de maintenance de base, puis lancer le processus.
WARCannon utilise AWS Simple Queue Service pour distribuer le travail aux nœuds de calcul. Pour garantir que vos résultats ne soient pas contaminés par des exécutions précédentes, vous pouvez demander à WARCannon de vider la file d'attente :
warcannon$ warcannon emptyQueue
[+] Cleared [ 15 ] messages from the queue
Vous pouvez ensuite vérifier l'état de la file d'attente :
warcannon$ warcannon status
Deployed: [ YES ]; SQS Status: [ EMPTY ]
Job Status: [ INACTIVE ]
Active job url: https://d201offlnmhkmd.cloudfront.net
Vérifiez les points suivants avant de continuer :
Afin de créer les messages de la file d'attente que les nœuds de calcul consommeront, vous devez d'abord alimenter SQS avec les données de crawl. WARCannon propose plusieurs commandes pour vous aider, en commençant par la possibilité d'afficher les scans disponibles. Dans ce cas, regardons les scans disponibles pour l'année 2021 :
warcannon$ warcannon list 2021
CC-MAIN-2021-04
CC-MAIN-2021-10
Nous avons deux scans correspondant à la chaîne "2021" avec lesquels travailler. Nous pouvons maintenant demander à WARCannon d'alimenter la file d'attente en fonction de l'un de ces scans. Cette fois, nous devons fournir un paramètre qui identifie de manière unique l'un des scans. "2021-04" fera l'affaire. Nous pourrions choisir de ne peupler qu'un scan partiel en spécifiant également un nombre de chunks et une taille de chunk, mais nous allons ignorer cela pour l'instant.
warcannon$ warcannon populate 2021-04
{Created 799 chunks of 100 from 79840 available segments"
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
Lors du déploiement, WARCannon provisionne automatiquement une base de données (warcannon_commoncrawl) et un groupe de travail (warcannon) dans Athena qui peuvent être utilisés pour interroger rapidement les informations de CommonCrawl. Cela peut être particulièrement utile pour alimenter des campagnes clairsemées basées sur certaines requêtes. Par exemple, la requête suivante recherchera les WARCs qui contiennent des réponses de 'example.com'
SELECT
warc_filename,
COUNT(url_path) as num
FROM
warcannon_commoncrawl.ccindex
WHERE
subset = 'warc' AND
url_host_registered_domain IN ('example.com') AND
crawl = 'CC-MAIN-2021-04'
GROUP BY warc_filename
ORDER BY num DESC
Vous pouvez utiliser la console Athena pour affiner vos résultats, mais vous devez exécuter la requête depuis la ligne de commande WARCannon si vous avez l'intention d'alimenter un travail avec celle-ci :
warcannon queryAthena "SELECT warc_filename, COUNT(url_path) as num FROM warcannon_commoncrawl.ccindex WHERE subset = 'warc' AND url_host_registered_domain IN ('example.com') AND crawl = 'CC-MAIN-2021-04' GROUP BY warc_filename ORDER BY num DESC"
[+] Query Exec Id: 0319486e-1846-491c-badf-2e23ae213974 .. SUCCEEDED
WARCannon peut ensuite utiliser les résultats d'une requête pour alimenter la file d'attente, et le fait en se basant sur la colonne warc_filename du jeu de résultats. En tant que tel, il est recommandé de soit group by cette colonne, soit d'utiliser distinct() pour éviter les doublons. WARCannon générera une erreur si ce champ n'est pas présent. Alimentez la file d'attente avec les résultats d'Athena en passant l'ID d'exécution de la requête à la commande populateAthena.
warcannon populateAthena 0319486e-1846-491c-badf-2e23ae213974
{Created 26 chunks of 10 from 251 available segments"
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
Remarque : Bien que l'alimentation d'un travail clairsemé pour un seul domaine puisse sembler une bonne idée, ce n'est souvent pas le cas. Les réponses d'un seul domaine ont tendance à être largement réparties sur un grand sous-ensemble de WARCs. Cela peut être clairement observé en utilisant l'exemple de requête ci-dessus pour voir que sur les ~150 000 enregistrements dans chaque WARC, le plus grand nombre de hits pour des sites de taille modérée peut être de l'ordre de quelques unités.
Une fois la file d'attente alimentée, nous sommes prêts à tirer. WARCannon effectuera quelques vérifications de cohérence pour s'assurer que tout est en ordre, puis vous montrera la configuration de la campagne et vous donnera une dernière opportunité d'abandonner avant de finaliser la commande.
warcannon$ warcannon fire
[!] This will request [ 6 ] spot instances of type [ m5n.24xlarge, m5dn.24xlarge ]
lasting for [ 86400 ] seconds.
To change this, edit your settings in settings.json and run warcannon deploy
--> Ready to fire? [Yes]:
Déclenchez le tir en répondant 'Oui'.
--> Ready to fire? [Yes]: Yes
{
"SpotFleetRequestId": "sfr-03dd32b8-51f7-4c8e-802b-a702fc3c8c95"
}
[+] Spot fleet request has been sent, and nodes should start coming online within ~5 minutes.
Monitor node status and progress at https://d201offlnmhkmd.cloudfront.net
La réponse inclut un lien vers votre URL de statut unique, où vous pouvez surveiller la progression de votre campagne et les performances de chaque nœud.

Les résultats de WARCannon sont stockés dans S3 au format JSON, répartis par chaque nœud responsable de la production des résultats. Les résultats d'Athena sont stockés dans le même bucket sous le préfixe /athena/. Vous pouvez synchroniser les résultats d'une campagne dans le dossier ~/.warcannon/ de votre machine locale à l'aide de la commande syncResults.
warcannon syncResults
sync: s3://warcannon-results-202...
sync: s3://warcannon-results-202...
sync: s3://warcannon-results-202...
...
Vous pouvez ensuite vider les buckets de résultats avec clearResults
warcannon clearResults
delete: s3://warcannon-results-202...
delete: s3://warcannon-results-202...
delete: s3://warcannon-results-202...
...
[+] Deleted [ 21 ] files from S3.
Vous avez des questions, besoin d'aide, envie de contribuer ou de vous vanter d'une victoire ? Venez traîner sur Discord !