
Das Invisible Internet-Projekt (im Folgenden einfach I2P) bietet Entwicklern eine Plattform für die Entwicklung von Anwendungen mit erweiterten Anforderungen an den Datenschutz der Benutzer. Dies ist ein virtuelles Netzwerk über dem normalen Internet, in dem Knoten Daten austauschen können, ohne ihre reale IP-Adresse preiszugeben. Anstelle von IP-Adressen im unsichtbaren Internet treten Verbindungen zwischen virtuellen Adressen auf, die als I2P-Ziel bezeichnet werden. Sie können eine beliebige Anzahl solcher Adressen haben und diese auch für jede Verbindung ändern. Sie liefern der anderen Seite keine Informationen über die tatsächliche IP-Adresse des Clients.
Dieser Artikel beschreibt die grundlegenden Dinge, die Sie wissen müssen, um I2P-Anwendungen zu schreiben. Codebeispiele werden in Python mithilfe des in Asyncio integrierten asynchronen Frameworks bereitgestellt.
Aktivieren der SAM-API und Installieren von i2plib
I2P bietet mehrere APIs für die Interaktion mit Clientanwendungen. Für Java-Anwendungen wird I2CP verwendet, für reguläre Client-Server-Anwendungen können I2PTunnel-, HTTP- und Socks-Proxys verwendet werden. Wir werden eine Anwendung in Python erstellen, wählen Sie also SAM . Standardmäßig ist im ursprünglichen Java-Client die SAM-API deaktiviert, sodass Sie sie aktivieren müssen. Gehen Sie zur I2P-Router-Webkonsole, Seite "I2P-Interna" -> "Clients". Aktivieren Sie das Kontrollkästchen "Beim Start ausführen" und klicken Sie auf "Start" und dann auf "Client-Konfiguration speichern".

In C ++ ist der i2pd SAM- Client bereits standardmäßig aktiviert.
Zur Vereinfachung der Verwendung der SAM-API habe ich die i2plib Python-Bibliothek geschrieben. Sie können es über pip installieren oder den Quellcode von GitHub herunterladen.
pip install i2plib
Da diese Bibliothek mit dem integrierten Asyncio-Asyncio-Framework funktioniert , sollten Sie berücksichtigen, dass Codebeispiele auch aus asynchronen Funktionen (Coroutinen) stammen, die in der Ereignisschleife arbeiten. Weitere Verwendungsbeispiele befinden sich im Repository .
Ziel- und Sitzungserstellung
I2P Destination besteht im Kern aus einer Reihe von Verschlüsselungs- und Datensignaturschlüsseln. Öffentliche Schlüssel aus diesem Bundle werden im I2P-Netzwerk veröffentlicht und anstelle der IP-Adresse zum Herstellen von Verbindungen verwendet.
Wir werden i2plib.Destination generieren, das wir in Zukunft verwenden werden:
dest = await i2plib.new_destination() print(dest.base32 + ".b32.i2p")
Die base32-Adresse ist ein Hash, an dem andere Peers Ihr Ziel im Netzwerk finden können. Wenn Sie dieses Ziel fortlaufend in Ihrem Programm verwenden möchten, speichern Sie den Inhalt von dest.private_key.data in einer lokalen Datei.
Jetzt können Sie eine SAM-Sitzung erstellen, was wörtlich bedeutet, dass dieses Ziel online geschaltet wird:
session_nickname = "test-i2p"
Es ist wichtig zu beachten, dass das Ziel online ist, solange der Socket session_writer geöffnet ist. Wenn Sie dieses Ziel im Netzwerk "ausschalten" möchten, rufen Sie session_writer.close () auf.
Ausgehende Verbindungen herstellen
Nachdem das Ziel online ist, können wir es verwenden, um mit anderen Knoten zu kommunizieren. Stellen Sie beispielsweise eine Verbindung zum Knoten "udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p" her, senden Sie eine HTTP-GET-Anforderung und lesen Sie die Antwort (es gibt einen Webserver "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())
Akzeptieren Sie eingehende Verbindungen
Wie Sie sehen, ist bei der Verbindung mit einem anderen Host alles einfach, aber mit der Annahme eingehender Nachrichten gibt es eine Nuance. Wenn ein neuer Client eine Verbindung zu Ihnen herstellt, sendet SAM eine Zeichenfolge mit dem Ziel dieses Clients an den ASCII-Socket. Da Ziel und Daten in einem Stück vorliegen können, müssen Sie dies berücksichtigen.
So sieht ein einfacher PING-PONG-Server aus, der eine eingehende Verbindung akzeptiert, den Zielclient in der Variablen remote_destination speichert und den PONG zurücksendet:
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()
Es beschreibt die Verwendung des Streaming-Protokolls, das als TCP / IP in einem I2P-Netzwerk fungiert. Die SAM-API bietet auch die Möglichkeit, anonyme Datagramme zu senden und zu empfangen, ähnlich wie das UDP-Protokoll. Diese Funktionalität ist in i2plib noch nicht verfügbar und wird später hinzugefügt.
Dies sind nur die grundlegendsten Informationen, aber es reicht bereits aus, um Ihr Projekt in I2P zu starten. Das unsichtbare Internet eignet sich zum Schreiben verschiedener Anwendungen, bei denen es vor allem darauf ankommt, die Privatsphäre der Benutzer zu wahren. Das Netzwerk unterliegt keinen Einschränkungen für Entwickler. Es kann sich entweder um einen Client-Server oder eine P2P-Anwendung handeln.