Invisible Internet Project (I2P), gizliliğe duyarlı uygulamalar geliştirmek için bir çatı sağlar. Sunucuların "gerçek" IP adreslerini açıklamadan veri alışverişi yapabildikleri, normal İnternet üzerinde çalışan sanal bir ağ yapısıdır. I2P ağı içindeki bağlantılar, I2P hedefleri olarak adlandırılan sanal adresler arasında kurulur. Bir kişi gerek duyduğu kadar hedefe sahip olabilir, hatta her bağlantı için yeni bir hedef kullanabilir. Gerçek IP adresi hakkında hiçbir bilgiyi diğer tarafa açık etmez.
Bu makale, I2P uygulamaları geliştirirken bilinmesi gereken temel kavramları açıkla. Kod örnekleri, yerleşik asenkron çatı asyncio kullanılarak Python üzerinde yazılmıştır.
SAM API kullanımı ve i2plib kurulumu
I2P, istemci uygulamalarına birçok farklı API sağlar. Normal istemci-sunucu uygulamaları I2PTunnel, HTTP ve Socks vekil sunucularını kullanabilir, Java uygulamaları genellikle I2CP kullanır. Python gibi diğer dillerle geliştirmek için en iyisi SAM seçeneğidir. SAM, özgün Java istemci uygulamasında varsayılan olarak devre dışıdır, bu nedenle etkinleştirmemiz gerekir. Yöneltici panosunda, "I2P bilgileri" -> "İstemciler" bölümüne gidin. "Başlangıçta çalıştır" seçeneğini işaretleyin ve "Başlat" üzerine ardından "İstemci yapılandırmasını kaydet" üzerine tıklayın.
`i2pd C++ uygulaması`_ üzerinde SAM varsayılan olarak etkinleştirilmiştir.
SAM API için 'i2plib'_ adlı kullanışlı bir Python kitaplığı geliştirdim. Pip ile kurabilir veya kaynak kodunu GitHub üzerinden el ile indirebilirsiniz.
pip install i2plib
Bu kitaplık Python yerleşik 'asenkron çatısı asyncio'_ ile çalışır. Bu nedenle lütfen kod örneklerinin olay döngüsü içinde çalışan asenkron işlevlerden (eşyordamlar) alındığını unutmayın. i2plib kullanımına ilişkin ek örnekler `kaynak kod deposu`_ üzerinde bulunabilir.
I2P hedefi ve oturumu oluşturmak
I2P hedefi, tam olarak bir şifreleme ve şifrelenmiş imza anahtarı kümesidir. Bu kümedeki herkese açık anahtarlar, I2P ağında yayınlanır ve bağlantı kurmak için IP adresleri yerine kullanılır.
i2plib.Destination ögesi şu şekilde oluşturulur:
dest = await i2plib.new_destination() print(dest.base32 + ".b32.i2p") # print base32 address
base32 adresi, ağdaki tam hedefinizi keşfetmek için diğer eşler tarafından kullanılan bir karmadır. Bu hedefi programınızda kalıcı bir adres olarak kullanmayı planlıyorsanız, dest.private_key.data içindeki binary verileri yerel bir dosyaya kaydedin.
Artık bir SAM oturumu oluşturabilirsiniz. Bu, tam olarak hedefi I2P ağında çevrimiçi yapmak anlamına gelir:
session_nickname = "test-i2p" # each session must have unique nickname _, session_writer = await i2plib.create_session(session_nickname, destination=dest)
Buradaki önemli not: session_writer soketi açık tutulurken hedef çevrimiçi kalır. Kapatmak isterseniz session_writer.close() işlevini çağırabilirsiniz.
Gidiş bağlantılarının kurulması
Artık hedef çevrimiçi olduğundan, onu diğer eşlere bağlanmak için kullanabilirsiniz. Örneğin, "udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p" adresine şu şekilde bağlantı kurulur, HTTP GET isteği gönderir ve yanıtı okursunuz ("i2p-projekt.i2p" site sunucusudur):
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())
Geliş bağlantılarının kabul edilmesi
Gidiş bağlantıları kurmak önemsiz olsa da, geliş bağlantılarını kabul ettiğinizde önemli bir ayrıntı vardır. Yeni bir istemci bağlandıktan sonra, SAM API, base64 ile kodlanmış istemcinin hedefi ile bir ASCII dizgesini sokete gönderir. Hedef ve veriler bir yığın halinde gelebileceğinden, bunun farkında olmalısınız.
Basit bir PING-PONG sunucusu böyle görünür. Geliş bağlantısını kabul eder, müşterinin hedefini bir remote_destination değişkenine kaydeder ve "PONG" dizgesini geri gönderir:
async def handle_client(incoming, reader, writer): """Client connection handler""" 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() # An endless loop which accepts connetions and runs a client handler while True: reader, writer = await i2plib.stream_accept(session_nickname) incoming = await reader.read(BUFFER_SIZE) asyncio.ensure_future(handle_client(incoming, reader, writer))
Diğer bilgiler
Bu makalede, TCP benzeri bir akış iletişim kuralının kullanımı anlatılmaktadır. SAM API ayrıca veri şemalarını göndermek ve almak için UDP benzeri bir iletişim kuralı sağlar. Bu özellik daha sonra i2plib içine eklenecek.
Bunlar yalnızca temel bilgilerdir. Ancak I2P kullanarak kendi projenizi başlatmanız için yeterlidir. Invisible Internet Project, her türlü gizliliğe duyarlı uygulamayı geliştirmek için harika bir araçtır. Ağ tarafında herhangi bir tasarım kısıtlaması yoktur. Bu uygulamalar P2P ya da istemci-sunucu yapısında olabilir.