Comment se faire des amis python avec Internet Invisible? Les bases du développement d'applications I2P en Python et asyncio


Le projet Internet invisible (ci-après simplement I2P) fournit aux développeurs une plate-forme pour développer des applications avec des exigences de confidentialité des utilisateurs améliorées. Il s'agit d'un réseau virtuel au-dessus d'Internet normal où les nœuds peuvent échanger des données sans divulguer leur véritable adresse IP. Au lieu d'adresses IP à l'intérieur d'Internet invisible, des connexions se produisent entre des adresses virtuelles appelées I2P Destination. Vous pouvez avoir n'importe quel nombre de ces adresses et les modifier même pour chaque connexion, elles ne fournissent à l'autre partie aucune information sur la véritable adresse IP du client.


Cet article décrit les éléments de base que vous devez savoir pour écrire des applications I2P. Des exemples de code sont fournis en Python à l'aide du cadre asynchrone intégré asyncio.


Activation de l'API SAM et installation d'i2plib


I2P propose plusieurs API pour interagir avec les applications clientes. Pour les applications Java, I2CP est utilisé; pour les applications client-serveur normales, les proxys I2PTunnel, HTTP et Socks peuvent être utilisés. Nous allons créer une application en Python, alors choisissez SAM . Par défaut, dans le client Java d'origine, l'API SAM est désactivée, vous devez donc l'activer. Accédez à la console Web du routeur I2P, page "Internes I2P" -> "Clients". Cochez la case "Exécuter au démarrage" et cliquez sur "Démarrer", puis "Enregistrer la configuration client".



En C ++, le client SAM i2pd est déjà activé par défaut.


Pour faciliter l'utilisation de l'API SAM, j'ai écrit la bibliothèque Python i2plib . Vous pouvez l'installer via pip ou télécharger le code source depuis GitHub.


pip install i2plib 

Étant donné que cette bibliothèque fonctionne avec le framework asyncio asyncio intégré , gardez à l'esprit que des exemples de code sont également tirés de fonctions asynchrones (coroutines) qui fonctionnent dans la boucle d'événements. Des exemples d'utilisation supplémentaires se trouvent dans le référentiel .


Création de destination et de session


À la base, I2P Destination est un ensemble de clés de chiffrement et de signature de données. Les clés publiques de ce bundle sont publiées sur le réseau I2P et sont utilisées à la place de l'adresse IP pour créer des connexions.


Nous générerons i2plib.Destination , que nous utiliserons à l'avenir:


 dest = await i2plib.new_destination() print(dest.base32 + ".b32.i2p") #  base32  

L'adresse base32 est le hachage auquel les autres pairs peuvent trouver votre destination sur le réseau. Si vous prévoyez d'utiliser cette destination dans votre programme de façon continue, enregistrez le contenu de dest.private_key.data dans un fichier local.


Vous pouvez maintenant créer une session SAM, ce qui signifie littéralement rendre cette destination en ligne en ligne:


  session_nickname = "test-i2p" #      nickname _, session_writer = await i2plib.create_session(session_nickname, destination=dest) 

Il est important de noter que la destination sera en ligne tant que le socket session_writer est ouvert. Si vous souhaitez "désactiver" cette destination à partir du réseau, appelez session_writer.close ().


Établir des connexions sortantes


Maintenant que Destination est en ligne, nous pouvons l'utiliser pour communiquer avec d'autres nœuds. Par exemple, connectez-vous au nœud "udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p", envoyez une demande HTTP GET et lisez la réponse (il existe un serveur Web "i2p-projekt.i2p"):


 remote_host = "udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p" reader, writer = await i2plib.stream_connect(session_nickname, remote_host) writer.write("GET /en/ HTTP/1.0\nHost: {}\r\n\r\n".format(remote_host).encode()) buflen, resp = 4096, b"" while 1: data = await reader.read(buflen) if len(data) > 0: resp += data else: break writer.close() print(resp.decode()) 

Accepter les connexions entrantes


Lorsque vous vous connectez à un autre hôte, comme vous pouvez le voir, tout est simple, mais avec l'acceptation de l'arrivée, il y a une nuance. Lorsqu'un nouveau client se connecte à vous, SAM envoie au socket ASCII une chaîne avec la destination de ce client. Étant donné que la destination et les données peuvent venir en une seule pièce, vous devez tenir compte de cela.


Voici à quoi ressemble un simple serveur PING-PONG, qui accepte une connexion entrante, enregistre le client de destination dans la variable remote_destination et renvoie le PONG:


 async def handle_client(incoming, reader, writer): """  """ dest, data = incoming.split(b"\n", 1) remote_destination = i2plib.Destination(dest.decode()) if not data: data = await reader.read(BUFFER_SIZE) if data == b"PING": writer.write(b"PONG") writer.close() #  ,        while True: reader, writer = await i2plib.stream_accept(session_nickname) incoming = await reader.read(BUFFER_SIZE) asyncio.ensure_future(handle_client(incoming, reader, writer)) 

En savoir plus


Il décrit l'utilisation du protocole Streaming, qui remplit les fonctions TCP / IP sur un réseau I2P. L'API SAM offre également la possibilité d'envoyer et de recevoir des datagrammes anonymes, similaires au protocole UDP. Cette fonctionnalité n'est pas encore disponible dans i2plib et sera ajoutée ultérieurement.


Ce ne sont que les informations les plus élémentaires, mais elles suffisent déjà pour démarrer votre projet dans I2P. L'Internet invisible est adapté à l'écriture de diverses applications dans lesquelles il est tout d'abord important de maintenir la confidentialité des utilisateurs. Le réseau n'impose aucune restriction aux développeurs, il peut s'agir d'un client-serveur ou d'une application P2P.


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


All Articles