Télécharger à travers tor

outil 4 déc. 2020
Monster Hunter, Resident Evil, Devil May Cry, Street Fighter, Phoenix Wright, ...

Récemment, j'ai eu vent d'une histoire concernant Capcom qui aurait subi une attaque au ransomware, suivie de la diffusion du code source de quelques jeux. Etant développeur et plutôt curieux, j'ai donc cherché à en savoir plus, et à récupérer les archives contenant ces données. Trouver la source depuis laquelle télécharger les données était simple (je ne partagerai pas d'url ici), mais encore restait-il à récupérer les données. Et c'est là que c'est devenu intéressant.

Le Problème

En effet, chaque archive faisait environ 10Go, et le service derrière le nom de domaine en .onion ne délivrait qu'au maximum 20Ko/s de données en moyenne. Il était donc inenvisageable de passer par le navigateur embarquant tor pour télécharger ces fichiers. La solution n'est pas très compliquée une fois qu'on la connait, mais... il faut la trouver.

Il se trouve que j'ai chez moi un certain nombre de raspberry pis qui font des trucs, genre beaucoup de trucs.

Ca en fait des raspberry pis

Dans l'ordre, de haut en bas:

  • Un raspberry pi 2 me permettant de diffuser un réseau wifi avec hostapd pointant sur une interface tap d'un vpn que je positionne dans le pays de mon choix grâce à openvpn
  • Un raspberry pi 4 8Go hébergeant le jeu que nous développons à 4 (https://beastsofwanderia.com), ainsi que son forum associé (https://forum.beastsofwanderia.com/)
  • Un raspberry pi 4 8Go hébergeant tous les services nécessaires au développement du jeu, dont le service nginx faisant office de point d'entrée pour toute connexion HTTP/HTTPS, une instance Gitlab, une instance Taiga, et quelques autres

Je pouvais bien trouver parmis ces 3 raspberry pis un peu de bande passantes pour télécharger en tâche de fond de grandes quantités de données.

La Solution

Très simple, la solution consiste à utiliser trois programmes: screen, torsocks, et wget.

  • screen est un outil permettant de créer des terminaux virtuels qu'il est ensuite possible de détacher du processus parent. Cette dissociation permet de conserver le processus même après la mort du processus l'ayant créé. Un fois le screen créé, on peut s'en détacher grâce à la combinaison de touches CTRL+A suivi de D.
  • torsocks est un petit script permettant de configurer les variables d'environnement relatives au proxy avant de lancer la commande qui suit. Ces variables d'environnement relatives au proxy vont permettre de faire passer une requête HTTP par un circuit tor, et ainsi atteindre des noms de domaine en .onion, caractéristiques des noms de domaines tor et inatteignables depuis le réseau internet classique.
  • wget est un outil similaire à curl, servant à faire des requêtes HTTP, et à récupérer le résultat dans un fichier ou dans le flux standard

C'est bien gentil tout ce blabla, et les commandes alors? Voici ce qu'il y a à lancer depuis un terminal sur la machine depuis laquelle on souhaite télécharger un fichier provenant de tor:

$ screen -R download1
$ torsocks -i wget --tries=0 --retry-connrefused --retry-on-host-error -c http://HOSTNAME.ONION/FILE_TO_DOWNLOAD

Suivi de CTRL+A et D.

J'aime les chats mais pas les macs.

Les options

screen

  • -R sert à créer le terminal s'il n'existe pas, ou à récupérer celui existant (si il existe du coup)

torsocks

  • -i permet d'isoler les processus faisant appel à tor pour qu'ils n'utilisent pas les mêmes circuits

wget

  • --tries=0 sert ici à retenter indéfiniment le téléchargement
  • --retry-connrefused et --retry-on-host-error font en sorte qu'en cas d'arrêt du service tor/rédémarrage de ce dernier, la commande wget ne se termine pas en erreur, et considère cette situation comme récupérable
  • -c sert à demander à reprendre le téléchargement du fichier là où celui-ci s'est arrêté précédemment. Cela revient à envoyer dans la requête HTTP un header Range, spécifiant l'octet depuis lequel le téléchargement doit reprendre. Il est à noter que tous les serveurs HTTP n'acceptent pas forcément cet header

Le résultat

On a maintenant un terminal virtual nommé download1, qui télécharge le fichier de notre choix en tâche de fond. Afin de vérifier l'état de ce téléchargement, on peut lancer:

$ screen -r download1

Où l'option -r n'accède au terminal screen que si ce dernier a déjà été créé au préalable. Pour quitter et laisser le téléchargement se poursuivre en tâche de fond, il suffit d'effectuer à nouveau la combinaison de touches CTRL+A suivie de D pour se détacher du terminal créé par screen.

Il est ensuite possible de créer un deuxième terminal download2, de lui assigner une autre URL à télécharger, et ainsi laisser tourner des téléchargements en fond sans s'en soucier.

On ne fait pas toujours les bons choix

Le point que je vais aborder maintenant est probablement discutable, car il met en jeu l'intérêt de tor, à savoir rester anonyme sur internet. Cependant, dans le cas qui m'intéresse ici, c'est à dire la récupération d'archives sur un serveur très lent et obscur, il m'est arrivé à de nombreuses reprises de voir mon circuit tor mourir, et ne jamais être recréé. J'ai donc fait le choix, très discutable, de lancer un autre terminal via screen ayant comme objectif de relancer un nouveau circuit tor toutes les 30 minutes. J'ai tout d'abord créé un script renew dans ~/bin contenant ceci:

#!/bin/bash

(echo authenticate '""'; echo signal newnym; echo quit) | nc localhost 9051 # 1 Méthode douce
echo "$(date): Stopping tor"
sudo systemctl stop tor@default
#echo "$(date): Truncate tor state"
#sudo truncate -s 0 /var/lib/tor/state # 2 Méthode moins douce
echo "$(date): Starting tor"
sudo systemctl start tor@default

Ce script bash contient 2 méthodes de nettoyage des données tor:

  • une méthode douce, visant à demander au daemon une recherche de nouveau circuit de manière polie (le daemon est en droit de refuser si la demande est faite trop fréquemment)
  • une méthode moins polie, consistant à vider l'état de tor, forçant ainsi à récréer le circuit, et à chercher un nouveau noeud gardien. C'est cette recherche forcée de ce dernier qui peut être un problème dans la conservation de son anonymat

Une fois la méthode choisie en commentant/décommentant ce que l'on souhaite dans le script renew, la création d'un terminal avec screen se fait de la même façon qu'auparavant avec:

$ screen -R renew
$ watch -tn 1800 renew

Suivi de CTRL+A et D pour laisser le terminal screen en tâche de fond. Grâce à ce terminal, le circuit tor sera forcé à se renouveler toutes les 30 minutes.

A noter

Il est tout de même important de rappeler que tout ce dont je parle ici suppose que le serveur HTTP en face supporte l'option -c (--continue) de wget, correspondant à l'header HTTP Range: bytes=X-. Si le serveur ne supporte pas cet header, la solution consistant à récréer le circuit avec le script renew ne peut pas permettre de régler un problème de perte de circuit, et en cas de fermeture du lien TCP, le téléchargement ne pourra reprendre que depuis le tout départ.

Merci d'avoir lu, à vos téléchargements!

Mots clés

SOARES Lucas

30 ans, développeur C/Go/Kotlin/C++/Java (quel enfer)/Python