Sortie du proxy MTProto non officiel en Python, fonctionnalités du protocole

image

Récemment, les développeurs de Telegram ont publié le code source d'un serveur proxy qui s'exécute sur le protocole MTProto. Les articles sur les caractéristiques de son assemblage et le reconditionnement du conteneur docker avec celui - ci ont été publiés sur le hub . Le serveur proxy officiel, écrit en C, surprend par la quantité de code - environ 23 mille lignes. En même temps, et parfois un peu plus tôt, plusieurs implémentations alternatives sont sorties, mais aucune d'entre elles n'a soutenu la possibilité de faire la publicité de sa chaîne.

Dans cet article, je voudrais, premièrement, parler des fonctionnalités peu connues du protocole de communication d'un serveur proxy avec des serveurs externes et, deuxièmement, parler de notre propre développement - l'implémentation d'un serveur proxy en Python, qui vient de sortir et est accessible à tous sous Licence MIT gratuite.

Caractéristiques de l'interaction du serveur proxy avec des serveurs externes


  1. Le serveur proxy officiel n'interagit pas directement avec les serveurs de télégramme, mais utilise au moins une couche proxy supplémentaire pour cela. Nous les appellerons proxy intermédiaire , leur liste est disponible sur core.telegram.org/getProxyConfig et core.telegram.org/getProxyConfigV6 . La connexion IPv6 n'est pas encore prise en charge par le serveur proxy officiel.
  2. Pour crypter les données entre le serveur proxy et le proxy intermédiaire, une clé est utilisée qui est obtenue à partir des adresses IP des deux nœuds. Par conséquent, le serveur proxy pour la connexion au proxy intermédiaire doit connaître son adresse IP externe, sinon les clés de chiffrement de l'un et de l'autre côté seront différentes. De plus, les numéros de port des deux nœuds et le secret partagé, disponibles sur core.telegram.org/getProxySecret, participent à la formation de la clé. Les développeurs de télégrammes recommandent de mettre à jour ce secret une fois par jour.
  3. Lors de la connexion d'un serveur proxy à un proxy intermédiaire, le premier transfère son heure. Si l'heure diffère de plus de quelques minutes, le deuxième côté ferme la connexion.
  4. Lors de l'envoi d'un message du client au proxy intermédiaire, le message est encapsulé dans un appel RPC au protocole MTProto. Dans chacun de ces appels RPC, le proxy ajoute plusieurs arguments: ip et port des deux nœuds, un identifiant de connexion aléatoire, ainsi que la balise du serveur proxy utilisée pour afficher le canal publicitaire dans l'application. Ces arguments supplémentaires occupent environ 96 octets. En raison de cette fonctionnalité, il ne sera pas possible d'afficher des canaux publicitaires lorsque vous travaillez directement, pas via un proxy intermédiaire.
  5. Les serveurs de télégramme «croient» aux informations sur le client ip reçues du serveur proxy. Ces adresses sont visibles dans les informations de session (le rectangle est dessiné):
    image

  6. Une connexion TCP entre le serveur proxy et le proxy intermédiaire envoie des messages de différents utilisateurs. Dans les demandes et les réponses, il y a un argument «identifiant de connexion aléatoire», qui est nécessaire pour que les données parviennent au bon client.
  7. Un serveur proxy ne peut pas déchiffrer les données client, mais il peut distinguer les messages réguliers des fichiers transmis. De plus, il connaît la taille de chaque message.

Pouf, j'espère ne pas en avoir assez des détails techniques. Maintenant, il devrait être clair pourquoi dans de nombreux mandataires alternatifs, il n'y a pas de support publicitaire - ils envoient des messages directement aux serveurs de télégramme, contournant le proxy intermédiaire. Cela s'avère beaucoup plus facile. La deuxième partie de l'article décrit la première implémentation non officielle d'un serveur proxy qui fonctionne via un proxy intermédiaire. Pour le moment, dans le domaine public, vous pouvez trouver trois implémentations de ce type: officielles, sur Erlang et celle-ci.

Implémentation du proxy Python


Initialement, un serveur proxy a été écrit afin de comprendre les caractéristiques du protocole et a été le développement d'un autre projet - un proxy de chaussettes asynchrones, écrit, à son tour, pour «toucher» async / attendre en Python.

Progressivement, le projet a commencé à avoir des utilisateurs inondés de questions, de rapports de bogues et de demandes de fonctionnalités. Après des améliorations, le projet est entré dans la phase de test bêta et de stabilisation, qui a duré environ une semaine et a impliqué cinq serveurs de configurations différentes.

Avant de parler des fonctionnalités que le serveur proxy officiel n'a pas encore, mais que le proxy alternatif a (et garder le silence sur les fonctions que le proxy officiel n'a pas sur l'alternative), je vais parler de la chose à laquelle beaucoup de gens pensent en premier lorsqu'ils mentionnent le mot Python .

Performances


Pour les tests de performances, une machine virtuelle a été utilisée dans un cloud de configuration minimale: 1 CPU, 1024 Mo de RAM.

Lors des tests synthétiques, le serveur proxy a pu transmettre environ 240 mégabits / sec ou 3000 messages / sec. Lors de l'utilisation d'une implémentation alternative de la boucle d'événements en C, appelée uvloop, et également lors de l'utilisation de l'interpréteur PyPy, les données de performances sont différentes (toutes les mesures sont par seconde):
image

Lors de tests sur de vrais utilisateurs, il s'est avéré qu'un tel serveur était suffisant pour desservir confortablement 4 000 utilisateurs ou 8 000 lors de l'utilisation de PyPy. (peut-être pour d'autres pays, le nombre d'utilisateurs servis simultanément différera). Cela ressemble à ceci:

image

J'ai demandé à plusieurs administrateurs d'autres serveurs - leur situation est la même. Cela est peut-être dû au fait qu'en Russie, le télégramme fonctionne bien sans serveurs proxy. En Iran, les serveurs de test ont été bloqués pour le public plusieurs heures après sa création.

image

Charge du serveur avec 2000 utilisateurs. Le moment du blocage du serveur pour les citoyens iraniens est clairement visible.

Par conséquent, les performances du processeur ne sont pas un goulot d'étranglement sur le nœud de test. Avec 10 000 clients, la mémoire risque de s'épuiser.

L'utilisation simultanée de plusieurs cœurs de CPU n'est pas implémentée (bonjour, GIL).

Fonctionnalités que le serveur proxy officiel n'a pas encore


Travail sur le protocole IPv6.
Un serveur proxy sans configuration supplémentaire peut utiliser IPv6 pour les connexions sortantes. Les connexions IPv6 ne sont pas bloquées en Russie (pour l'instant).

Mode de fonctionnement sans proxy intermédiaire
Si la publicité sur les chaînes n'est pas nécessaire, le proxy se connecte automatiquement directement aux serveurs de télégramme, en contournant le proxy intermédiaire. C'est plus rapide et plus fiable.

De plus, le " mode rapide " optionnel est implémenté lorsque les messages du serveur Telegram vers le proxy et du proxy vers le client sont cryptés avec la même clé. Ainsi, le proxy n'a pas besoin de rechiffrer les messages - il les envoie tels quels. Cela ne devrait pas affecter la sécurité. Dans tous les cas, l'administrateur proxy n'a pas accès aux messages des utilisateurs.

Mise à jour automatique de la liste des proxy intermédiaires et secret une fois par jour.
Le serveur proxy officiel pour la mise à jour de la liste des proxy intermédiaires recommande de redémarrer le conteneur Docker une fois par jour, ce qui réinitialise toutes les connexions. De nouvelles connexions peuvent ne pas être établies si, par exemple, un serveur est bloqué dans le pays. La version Python visite périodiquement le site et met à jour la liste.

Multiplateforme
Toutes les plates-formes exécutant Python sont prises en charge. Il s'est avéré qu'il fonctionnait même sur l'iPad, cependant, les connexions entrantes externes ont été bloquées par l'appareil. Windows est pris en charge séparément, j'ai été surpris de voir combien de personnes lancent des proxys sous ce système d'exploitation. Bien que sous Windows, vous pouvez exécuter le client officiel si vous utilisez des technologies de virtualisation ou un docker.

La possibilité de fonctionner facilement sans docker.
Si (soudainement) il y a ceux qui n'aiment pas docker, un proxy peut être lancé sans lui. Vous devez spécifier au moins deux paramètres dans le fichier de configuration: port et secret, vous pouvez également définir la balise publicitaire facultative, puis exécuter la commande: python3 mtprotoproxy.py. Cependant, dans ce cas, vous devrez penser à l'exécution automatique dans le système d'exploitation, par exemple, écrire un fichier unité pour systemd. Vous devrez également installer pycrypto ou pycryptodome, sans cela cela fonctionnera, mais très lentement.

Dans le cas de docker, le conteneur peut être reconstruit avec la commande docker-compose up --build.

Fonctionnalités prévues pour la prochaine version


Limiter la vitesse de téléchargement de gros fichiers.
Lors du téléchargement de fichiers volumineux, vous pouvez, au niveau TCP, «demander» au proxy intermédiaire ou au serveur Telegram d'envoyer les données plus lentement. Maintenant, cela se fait en définissant une petite valeur du tampon de réception, ce qui économise en outre la mémoire du serveur.

Messages en streaming.
Maintenant, tous les serveurs proxy connus fonctionnant avec un proxy intermédiaire lisent d'abord le message du client et le transmettent ensuite. La taille d'un message peut atteindre 1 Mo. Une mémoire est nécessaire pour son stockage et le délai de transmission est légèrement augmenté. Vous pouvez transférer le streaming de données. Cela compliquera le code, mais réduira la consommation de mémoire dans le pire des cas.

Modifiez la longueur des paquets pour contourner le filtre le long de la longueur du paquet .
Je n'ai pas réussi à entrer dans la version.

Installation et lancement


  1. git clone -b stable github.com/alexbers/mtprotoproxy.git; cd mtprotoproxy
  2. (facultatif, recommandé) spécifiez PORT , USERS et AD_TAG dans config.py
  3. docker-compose up --build -d (ou python3 mtprotoproxy.py, donc sans docker)
  4. (facultatif, affiche un lien du formulaire tg: //) journaux de composition de docker

image

Autres implémentations du proxy MTProto avec prise en charge de la publicité sur les chaînes:


Remerciements
seriyps - pour vous aider à tester sur de vrais utilisateurs
shifttstas - pour des conseils de docker
forst (github) - pour l'idée et la mise en œuvre des travaux sur IPv6
p1ratrulezzz (github) - pour des conseils et un article sur le projet
freekzy (github) - pour un correctif de bogue avec fuite de poignée

UPD: référentiel qui compile différentes implémentations du proxy MTProto : github.com/mtProtoProxy

Source: https://habr.com/ru/post/fr414139/


All Articles