¿Cómo hacer amigos python con Internet invisible? Los fundamentos del desarrollo de aplicaciones I2P en Python y asyncio


El proyecto Invisible Internet (en lo sucesivo, simplemente I2P) proporciona a los desarrolladores una plataforma para desarrollar aplicaciones con requisitos de privacidad de usuario mejorados. Esta es una red virtual sobre Internet normal donde los nodos pueden intercambiar datos sin revelar su dirección IP real. En lugar de direcciones IP dentro de Internet invisible, se producen conexiones entre direcciones virtuales llamadas Destino I2P. Puede tener cualquier número de tales direcciones y cambiarlas incluso para cada conexión, no proporcionan al otro lado ninguna información sobre la dirección IP real del cliente.


Este artículo describe las cosas básicas que necesita saber para escribir aplicaciones I2P. Los ejemplos de código se proporcionan en Python utilizando el marco asincrónico incorporado asyncio.


Habilitar la API de SAM e instalar i2plib


I2P ofrece varias API para interactuar con aplicaciones cliente. Para aplicaciones Java, se usa I2CP; para aplicaciones cliente-servidor normales, se pueden usar servidores proxy I2PTunnel, HTTP y Socks. Haremos una aplicación en Python, así que elija SAM . De forma predeterminada, en el cliente Java original, la API SAM está desactivada, por lo que debe habilitarla. Vaya a la consola web del enrutador I2P, página "Elementos internos I2P" -> "Clientes". Marque la casilla "Ejecutar al inicio" y haga clic en "Inicio", luego "Guardar configuración del cliente".



En C ++, el cliente SAM i2pd ya está habilitado de manera predeterminada.


Para facilitar el uso de la API SAM, escribí la biblioteca Python i2plib . Puede instalarlo a través de pip o descargar el código fuente de GitHub.


pip install i2plib 

Dado que esta biblioteca funciona con el marco asyncio asyncio incorporado , tenga en cuenta que los ejemplos de código también se toman de las funciones asincrónicas (corutinas) que funcionan en el bucle de eventos. Ejemplos de uso adicionales están en el repositorio .


Destino y creación de sesión


En esencia, I2P Destination es un conjunto de claves de cifrado y firma de datos. Las claves públicas de este paquete se publican en la red I2P y se utilizan en lugar de la dirección IP para crear conexiones.


Generaremos i2plib.Destination , que utilizaremos en el futuro:


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

La dirección base32 es el hash en el que otros pares pueden encontrar su Destino en la red. Si planea utilizar este Destino en su programa de manera continua, guarde el contenido de dest.private_key.data en un archivo local.


Ahora puede crear una sesión SAM, que literalmente significa hacer que este Destino en línea en línea:


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

Es importante tener en cuenta que Destination estará en línea siempre que el socket session_writer esté abierto. Si desea "desactivar" este Destino desde la red, llame a session_writer.close ().


Hacer conexiones salientes


Ahora que Destination está en línea, podemos usarlo para comunicarnos con otros nodos. Por ejemplo, conéctese al nodo "udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p", envíe una solicitud HTTP GET y lea la respuesta (hay un servidor 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()) 

Aceptar conexiones entrantes


Cuando se conecta a otro host, como puede ver, todo es simple, pero con la aceptación de la entrada hay un matiz. Cuando un nuevo cliente se conecta con usted, SAM envía al socket ASCII una cadena con el Destino de ese cliente. Dado que el destino y los datos pueden venir en una sola pieza, debe considerar esto.


Así es como se ve un servidor PING-PONG simple, que acepta una conexión entrante, guarda el cliente de Destino en la variable remote_destination y devuelve el 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)) 

Más información


Describe el uso del protocolo Streaming, que realiza las funciones de TCP / IP en una red I2P. La API SAM también brinda la capacidad de enviar y recibir datagramas anónimos, similar al protocolo UDP. Esta funcionalidad aún no está disponible en i2plib y se agregará más adelante.


Esta es solo la información más básica, pero ya es suficiente para comenzar su proyecto en I2P. La Internet invisible es adecuada para escribir diversas aplicaciones en las cuales es importante mantener la privacidad de los usuarios. La red no impone restricciones a los desarrolladores, puede ser un cliente-servidor o una aplicación P2P.


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


All Articles