Vous n'aimez pas les .oignons ? Vous avez Tor
Je me souviens dans mon expérience passée qu’un collègue m’avait parlé d’un truc incroyable (surtout la 2).
Son client était régulièrement visité par des robots scrappeur utilisant des adresses en provenance de Tor.
(Tor est un outil qui permet d’échanger des informations de manière plus sécurisée que le web normal en passant par un réseau parallèle chiffré parano)
Comme j’aime les trucs parfaitement idiots, j’ai décidé de bricoler un bouzin qui fait absolument l’inverse et ne laissera passer sur mon load balancer que les IP en provenance de Tor.
Installe-toi confortablement, aujourd’hui c’est crouton et grosse soupe à l’oignon.🤪
Encore un truc statique rafraîchit dynamiquement sérieusement ?
Comme les IP de Tor sont mouvantes, on va rafraîchir le truc à intervalles réguliers. Ouais, je sais, encore un truc statique à rafraîchissement dynamique. Le recyclage, c’est dans l’ère du temps.
Tu es qui pour me dire de pas le faire hein ? Je fais ce que je veux 😈😈
C’est pour rigoler hein, vous amusez pas à héberger un site Tor avec du contenu illicite sur GCP. Ils vous trouveront rapidement après y’aura du pénal et tout, le truc chiant quoi 🤷.
Utilisez plutôt OVH, avec un peu de chance votre machine va cramer avant de vous faire prendre 🤭🤭🤭
Et après ce n’est pas mes .oignon 🤪
Et comme je suis un cyberpunk à chien et que je ne surveille jamais rien, on va essayer de construire un truc un peu costaud et un minimum tolérant à la panne.
Et pas cher parce que je suis aussi radin, comme vous le savez bien 😂
fait pas le cron Jim, t’as une infra et des enfants
Bon une fois n’est pas coutume, on part sur un backend isolé, le scheduler de Google et un terraform dans ton container 🤪
Un cron, un bout de python, c’est le début du bonheur. Article sponsorisé par python cuisine
Pour les IP de Tor je triche un peu, je pourrais chercher un moyen dynamique et compliqué de le faire, mais la flemme.
https://github.com/SecOps-Institute/Tor-IP-Addresses
Merci monsieur, liste dynamiquement rafraîchie à interval régulier, un coup de git, un coup de terraform, je mets mes pantoufles, j’allume la télé et terminé, bon soir.
Pas de credentials qui trainent, des services account accrochés sur les bons objets. croquant crado, rapido gourmand 🤷
explication détaillée du diagramme
sur la partie en bas à gauche
On a notre backend qui va être chargé de dynamiquement rafraichir notre firewall cloud armor. Github contiendra nos ip rafraichies à intervalles réguliers, on s’en occupe pas c’est pas notre problème, on pique juste les ips qui sont dedans.
Le cloud run contiendra une image docker avec python git et terraform voici un algo rapide de sa logique.
on event
git pull ip list
put deny all in first firewall rule terraform file
for ip in list
add allow ip list iun firewall rule terraform file
tf init
tf apply autoapprove
Le remote bucket est garant de l’état précédent du state Enfin le scheduler google est chargé de déclencher l’évènement cloudrun à intervalles réguliers en mode cronjob http.
Vous voyez un peu la sauvagerie du truc ? on écrase systématiquement le fichier terraform et apply auto approve sur les règles de firewall.
C’est un peu dangereux si on crash le terraform, mais on s’en fout, on met pas ça en prod héhé. Effet sympa, si des ips sortent de la liste, elle seront automatiquement delete par terraform. Effet moins sympa, l’ordre de la liste peut poser des conflits et forcer la reconstruction de l’index terraform sur tous ou quelques objets.
sur la partie en haut
On a un tank qui représente mes haters du clean web, qui prendront une règle deny si ils arrivent avec des ips qui ne sont pas des ips de ma liste.
À droite du tank on a les gothiques qui mangent des oignons à ne pas confondre avec les vampires, qui eux utilisent les IPs de ma liste et sont donc les seuls autorisés à passer le firewall, et consulter mon compte onlyRage.
Voilà pour la théorie
un peu de code avec ça ? (prank, ça tourne mal)
Quand j’ai commencé ce projet, j’étais saucé de fou, la réalité de la vie m’a offert un gros parpaing dans la gueule.
Je vous propose de vous montrer ce que j’ai commencé à faire et après je propose une alternative.
Mais PUTAIN DE BORDEL DE MERDE, oui, je le dis, j’ai la rage contre GCP.
|
|
Putain mais qu’est-ce que c’est que ce gros code de merde ?
Et bien ça c’est ce qui arrive quand on utilise python pour templater du terraform de facon crade, le pire c’est que je n’en ai pas honte.
ça fait quoi et pourquoi CKC ?
- lire le fichier Tor-IP-Addresses/tor-exit-nodes.lst qui contient les IPs de tor
- récupérer les IPs et les mettre dans un tableau
- ouvrir un socket pour voir si l’ip répond ou pas
- templater le fichier terraform avec une poutre IPN en guise de chausse pied.
C’était moche et rapide, le terraform plan passe, bonne vibe quoi, j’étais presque content de mon coup
Et la PAF, CKC à cause des quotas de GCP.
Pas plus de 100 rules, maximum 10 ips par rule, mais on est où là ? Mais putain, je paye, laisse moi faire de la merde non ?
J’étais content, c’était moche et rapide, le terraform plan passe, et l’apply casse (je vous ai déjà dit que je déteste terraform ? )
c’est con j’avais que environs 1800 IPs à rentrer, franchement, une broutille, quel indignité …
google_compute_security_policy.policy_allow_tor: Still creating... [10s elapsed]
╷
│ Error: Error waiting for Creating SecurityPolicy "allow-tor-ips": Quota 'SECURITY_POLICY_RULES' exceeded. Limit: 100.0 globally.
bon manifestement c’est pas le bon outil pour faire ça, du coup on va plutôt faire un reverse proxy avec tonton nginx.
repli stratégique, ça part en compute
un truc bête un peu comme ça mais genre avec 1800 lignes, rien de bien méchant, hein cloud armor ?
|
|
Le templating sera bien moins compliqué et dégueux sans terraform.
On va trouver un truc pour templater la conf et la balancer dans gcs. Une fois dans gcs on peut tirer la conf sur 1..N compute et scale si on veut plusieurs frontaux pour des questions d’HA
On va faire un compute de ringard, quitte à être dans la loose.
On pourrait mettre nginx dans cloudrun, mais c’est pas terrible pour plusieurs raisons:
- les colds start du container apportent une latence qui peut être importante. On veut éviter au maximum les latences sur un reverse proxy
- on veux charger une conf nginx avec un fichier énorme et marginal
- cloudrun managé ne prend pas en charge les configmaps (seulement cloudrun sur anthos)
- les variables d’env Linux ont une taille maximum de caractères qui inclut l’ensemble des envs donc ça ne scale pas à l’infini
- c’est raymond qui le dit https://devblogs.microsoft.com/oldnewthing/20100203-00/?p=15083
- un gros compute réduit la baisse de perf apportée par docker
|
|
le code dans mon cloudrun
|
|
Du coup on a recyclé le précèdent code pour faire un template plus simple et on balance tout ça dans un bucket gcs, l’astuce c’est que cloudrun a le droit de lire et d’écrire dans les buckets GCS du projet. On lui donne une variable d’env avec le nom du bucket et c’est parti.
On choisi le mode authenticated et seul cloud scheduler pourra le contacter pour lancer le scrap des nouvelles ips. J’ai laissé la conf par defaut nginx dans mon template mais ça s’adapte facilement, démerde toi 🤷
dernière étape, récupération de la conf dans mon compute nginx
Dernier truc un peu sale, on reload la conf en mode cron tous les jours dans le compute. On aurait pu mettre du Ansible directement dans le cloudrun et appliquer la conf à chaud au moment du scrap.
Je ne le fais pas pour les raisons suivantes:
- on veux éviter un fort couplage avec les computes
- des conf en dur dans ansible avec les ips de machines
- ça scale mal si on met plus de compute ou qu’on construit/détruit souvent
On garde une infra découplée des frontaux nginx et cloisonnement de responsabilité.
On pose un cron dans root avec ça dans le script. Il vous faut gcloud avec un SA qui a le droit de faire du gcs.
|
|
et paf tu rentre pas
|
|
Conclusion
Donc on a appris quoi aujourd’hui ?
- les oignons c’est bon, mais faut en manger avec modération
- cloud Armor est un outil super con, et super limité
- l’important quand on chute c’est de tomber dans une poubelle pas trop loin
- le darknet ce n’est pas que pour les gothiques, c’est aussi pour les robots
- on peut faire des trucs complètement cons mais techniquement corrects 🤷
- gcp est parfois décevant 😿