Freenet: Difference between revisions
(Tabelle zu Schlüsseln vervollständigt) |
|||
(7 intermediate revisions by the same user not shown) | |||
Line 32: | Line 32: | ||
=== Schlüssel === |
=== Schlüssel === |
||
Dateien werden in Freenet durch verschiedene Schlüssel identifiziert. Bei allen Schlüsseln wird eine modifizierte bas64-Kodierung verwendet, bei der nur die Zeichen a-z, A-Z, -, ~ verwendet werden. |
Dateien werden in Freenet durch verschiedene Schlüssel identifiziert. Bei allen Schlüsseln wird eine modifizierte bas64-Kodierung verwendet, bei der nur die Zeichen a-z, A-Z, -, ~ verwendet werden. |
||
==== Content Hash Key (CHK) ==== |
|||
{| cellpadding="2" border="1" style="border: 1px solid black; border-collapse:collapse" |
{| cellpadding="2" border="1" style="border: 1px solid black; border-collapse:collapse" |
||
! Schlüssel |
|||
| Content Hash Key (CHK) |
|||
| Signed Subspace Key (SSK) |
|||
| Keyword Signed Key (KSK) |
|||
|- valign="top" |
|||
! Beschreibung |
! Beschreibung |
||
| CHKs sind die eindeutigen Bezeichner von Dateien in Freenet, vergleichbar mit Inodes in Dateisystemen. |
| CHKs sind die eindeutigen Bezeichner von Dateien in Freenet, vergleichbar mit Inodes in Dateisystemen. |
||
| SSKs bieten einen persönlichen Namensraum, in dem jeder lesen jedoch nur der Autor schreiben kann. Ein Subspace (eines Autors) wird durch ein Public-Private-Keypair identifiziert, den der Autor einmalig generieren muss. |
|||
Dateien werden mit dem privaten Schlüssel des Autors signiert und diese Signatur sowie der Public-Key zusammen mit der Datei im Netzwerk gespeichert. Beim Einfügen und Herunterladen von Dateien wird diese Signatur überprüft. |
|||
| KSKs stellen eine Möglichkeit dar, Dateien in menschenlesbarer Form an Hand eines (frei) wählbaren Namens zu referenzieren. Eine Zugangskontrolle wird dabei nicht gewährleistet. |
|||
|- |
|- |
||
! Verschlüsselung |
! Verschlüsselung |
||
| Beim Einstellen von Dateien mittels FProxy werden diese mit einem Schlüssel verschlüsselt, der sich (scheinbar) aus dem Inhalt der Datei ermittelt. So wird auch verhindert, dass 2 Dateien gleichen Inhalts mit unterschiedlichen Verschlüsselungen 2 verschiedene CHKs erhalten. |
| Beim Einstellen von Dateien mittels FProxy werden diese mit einem Schlüssel verschlüsselt, der sich (scheinbar) aus dem Inhalt der Datei ermittelt. So wird auch verhindert, dass 2 Dateien gleichen Inhalts mit unterschiedlichen Verschlüsselungen 2 verschiedene CHKs erhalten. |
||
| Zur Verschlüsselung der Datei wird die Beschreibung (zusammen mit der optionalen Entropie (einer zufällige Zeichenkette)) genutzt. Dabei beeinflusst die Entropy lediglich die Verschlüsselung, nicht aber die SSK. |
|||
| Als Public-Key wird der Hash des gewählten Dokumentnamens benutzt. Daraus wird ein Private-Key ermittelt, der zur Entschlüsselung und Signierung der Datei benuzt wird. |
|||
|- |
|- |
||
! Aufbau (intern) |
! Aufbau (intern) |
||
| Ein CHK ist ein base64-kodierter SHA1-Hash des Inhalts der (verschlüsselten) Datei. |
| Ein CHK ist ein base64-kodierter SHA1-Hash des Inhalts der (verschlüsselten) Datei. |
||
| Ein SSK ist ein base64-kodierter SHA1-Hash vom ''Hash des Public-Key und dem Hash des Dokumentnamens''. |
|||
| Ein KSK ist ein base64-kodierter SHA1-Hash vom zugewiesenen Public-Key (= Hash des Dokumentnamens). |
|||
|- |
|- |
||
! Verlinkung einer Datei |
! Verlinkung einer Datei |
||
| Beim Referenzieren von CHKs wird der Schlüssel zum Entschlüsseln der Datei mit angegeben und optional kann auch noch ein Dateiname vergeben werden, den der Browser bzw. FProxy dann beim Speichern der Datei benutzen kann. Diese zusätzlichen Informationen werden aber nicht beim Suchen / Einstellen von Dateien übertragen. |
| Beim Referenzieren von CHKs wird der Schlüssel zum Entschlüsseln der Datei mit angegeben und optional kann auch noch ein Dateiname vergeben werden, den der Browser bzw. FProxy dann beim Speichern der Datei benutzen kann. Diese zusätzlichen Informationen werden aber nicht beim Suchen / Einstellen von Dateien übertragen. |
||
| Zum Referenzieren von Dateien wird der Public-Key und der Dokumentenname (bzw. Beschreibung des Dokuments) benötigt, aus dem sich dann der SSK ermitteln lässt. Nur diese wird dann beim Suchen im Netzwerk übertragen. |
|||
| Zur Verlinkung einer Datei ist lediglich der Dokumentname erforderlich. Aus diesem lässt sich die KSK ermitteln (SHA1-Hash davon) sowie der Private-Key zum Entschlüsseln. |
|||
|- |
|- |
||
! Beispiel |
! Beispiel |
||
| |
|||
| ''CHK@AGP9Hnwh5q7lA3SEBd0N0eNvfwMKAwI,l1-Yast1r9sOB5DqH0CFsA'' |
|||
CHK@AGP9Hnwh5q7lA3SEBd0N0eNvfwMKAwI,l1-Yast1r9sOB5DqH0CFsA |
|||
| ''SSK@rBjVda8pC-Kq04jUurIAb8IzAGcPAgM/TFE//'' |
|||
| ''KSK@gpl.txt'' |
|||
|- |
|- |
||
! Aufbau (Referenz auf Datei) |
! Aufbau (Referenz auf Datei) |
||
| |
|||
| ''CHK@<hash(encrypted data)>,<Encryption Key>[/filename.ext]'' |
|||
CHK@<hash(encrypted data)>,<Encryption Key>[/filename.ext] |
|||
| ''SSK@<public key>PAgM[Entropy]/<Description>'' |
|||
| ''KSK@Description'' |
|||
|- valign="top" |
|- valign="top" |
||
Line 84: | Line 68: | ||
* keine Größenbeschränkung der referenzierten Datei |
* keine Größenbeschränkung der referenzierten Datei |
||
* einfache Verifikation der Datei möglich |
* einfache Verifikation der Datei möglich |
||
|- valign="top" |
|||
! Nachteile |
|||
| |
|||
* CHK ist erst nach dem einfügen bekannt |
|||
* CHK ist nicht menschenlesbar (und insb. schlecht zu merken) |
|||
* keine Updates von Dateien möglich, da die CHK sich aus dem Hash des Inhaltes ergibt und sich dann ändert |
|||
|} |
|||
==== Signed Subspace Key (SSK) ==== |
|||
{| cellpadding="2" border="1" style="border: 1px solid black; border-collapse:collapse" |
|||
! Beschreibung |
|||
| SSKs bieten einen persönlichen Namensraum, in dem jeder lesen jedoch nur der Autor schreiben kann. Ein Subspace (eines Autors) wird durch ein Public-Private-Keypair identifiziert, den der Autor einmalig generieren muss. |
|||
Dateien werden mit dem privaten Schlüssel des Autors signiert und diese Signatur sowie der Public-Key zusammen mit der Datei im Netzwerk gespeichert. Beim Einfügen und Herunterladen von Dateien wird diese Signatur überprüft. |
|||
|- |
|||
! Verschlüsselung |
|||
| Zur Verschlüsselung der Datei wird die Beschreibung (zusammen mit der optionalen Entropie (einer zufällige Zeichenkette)) genutzt. Dabei beeinflusst die Entropy lediglich die Verschlüsselung, nicht aber die SSK. |
|||
|- |
|||
! Aufbau (intern) |
|||
| Ein SSK ist ein base64-kodierter SHA1-Hash vom ''Hash des Public-Key und dem Hash des Dokumentnamens''. |
|||
|- |
|||
! Verlinkung einer Datei |
|||
| Zum Referenzieren von Dateien wird der Public-Key und der Dokumentenname (bzw. Beschreibung des Dokuments) benötigt, aus dem sich dann der SSK ermitteln lässt. Nur diese wird dann beim Suchen im Netzwerk übertragen. |
|||
|- |
|||
! Beispiel |
|||
| |
|||
SSK@rBjVda8pC-Kq04jUurIAb8IzAGcPAgM/TFE// |
|||
|- |
|||
! Aufbau (Referenz auf Datei) |
|||
| |
|||
SSK@<public key>PAgM[Entropy]/<Description> |
|||
|- valign="top" |
|||
! Vorteile |
|||
| |
| |
||
* für Menschen lesbare und verwertbare Informationen zum erwarteten Dateiinhalt |
* für Menschen lesbare und verwertbare Informationen zum erwarteten Dateiinhalt |
||
Line 89: | Line 115: | ||
* geringe Wahrscheinlichkeit von Kollisionen (aufpassen: Entropy beeinflusst die SSK nicht) |
* geringe Wahrscheinlichkeit von Kollisionen (aufpassen: Entropy beeinflusst die SSK nicht) |
||
* ermöglichen (theoretisch) Updates von Dateien, da der SSK nicht vom Dateiinhalt abhängig ist |
* ermöglichen (theoretisch) Updates von Dateien, da der SSK nicht vom Dateiinhalt abhängig ist |
||
|- valign="top" |
|||
! Nachteile |
|||
| |
| |
||
* referenzierte Dateien dürfen nur 32KB groß sein |
|||
* Einfügeoperationen sind komplizierter (dabei helfen dann Tools) |
|||
|} |
|||
==== Keyword Signed Key (KSK) ==== |
|||
{| cellpadding="2" border="1" style="border: 1px solid black; border-collapse:collapse" |
|||
! Beschreibung |
|||
| KSKs stellen eine Möglichkeit dar, Dateien in menschenlesbarer Form an Hand eines (frei) wählbaren Namens zu referenzieren. Eine Zugangskontrolle wird dabei nicht gewährleistet. |
|||
|- |
|||
! Verschlüsselung |
|||
| Als Public-Key wird der Hash des gewählten Dokumentnamens benutzt. Daraus wird ein Private-Key ermittelt, der zur Entschlüsselung und Signierung der Datei benuzt wird. |
|||
|- |
|||
! Aufbau (intern) |
|||
| Ein KSK ist ein base64-kodierter SHA1-Hash vom zugewiesenen Public-Key (= Hash des Dokumentnamens). |
|||
|- |
|||
! Verlinkung einer Datei |
|||
| Zur Verlinkung einer Datei ist lediglich der Dokumentname erforderlich. Aus diesem lässt sich die KSK ermitteln (SHA1-Hash davon) sowie der Private-Key zum Entschlüsseln. |
|||
|- |
|||
! Beispiel |
|||
| |
|||
KSK@gpl.txt |
|||
|- |
|||
! Aufbau (Referenz auf Datei) |
|||
| |
|||
KSK@Description |
|||
|- valign="top" |
|||
! Vorteile |
|||
| |
|||
* KSKs sind unabhängig vom Inhalt der Datei |
* KSKs sind unabhängig vom Inhalt der Datei |
||
* jeder kann Dateien zu einer gegebenen KSK einfügeb (ermöglicht ''Nearly Instant Messaging'') |
* jeder kann Dateien zu einer gegebenen KSK einfügeb (ermöglicht ''Nearly Instant Messaging'') |
||
Line 96: | Line 161: | ||
|- valign="top" |
|- valign="top" |
||
! Nachteile |
! Nachteile |
||
| |
|||
* CHK ist erst nach dem einfügen bekannt |
|||
* CHK ist nicht menschenlesbar (und insb. schlecht zu merken) |
|||
* keine Updates von Dateien möglich, da die CHK sich aus dem Hash des Inhaltes ergibt und sich dann ändert |
|||
| |
|||
* referenzierte Dateien dürfen nur 32KB groß sein |
|||
* Einfügeoperationen sind komplizierter (dabei helfen dann Tools) |
|||
| |
| |
||
* referenzierte Dateien dürfen nur 32KB groß sein |
* referenzierte Dateien dürfen nur 32KB groß sein |
||
Line 111: | Line 169: | ||
=== Routing === |
=== Routing === |
||
Jeder Knoten im Freenet besitzt eine Routingtabelle, in der er speichert, welcher seiner Nachbarknoten zu welchem Schlüssel zuletzt eine Anfrage erfolgreich beantworten konnte. So entsteht jeweils eine Zuordnung Schlüssel <-> Knoten, bei der nicht zwangsläufig jedem Schlüssel ein Knoten zugeordnet wird. |
|||
Freenet geht davon aus, dass '''ein Knoten, der bereits in der Vergangenheit eine Anfrage zu einem ähnlichen Thema (Key) erfolgreich beantwortet hat, auch zu dem gesuchten Thema erfolgreich antworten kann''' oder die Anfrage zumindest einen Schritt weiter in die richtige Richtung leiten kann. |
|||
Anfragen besitzen dabei einen Hops-to-live-Wert (HTL) <= 20. Diese Obergrenze ist fest in FProxy einprogrammiert. Weiterhin besteht die Möglichkeit, dass ein Knoten im Falle eines HTL > 20 die Anfrage ablehnt. Passiert eine Anfrage einen Knoten, wird dieser Wert um 1 reduziert. |
|||
Dadurch, dass sich die Routingtabelle erst mit den Anfragen aufbaut, dauert es eine Weile, bis ein neuer Knoten genügend Informationen über das Netz weiß, um selbst erfolgreich Anfragen senden zu können. Mindestens 30 Minuten sollten man (erfahrungsgemäß) schon verbunden sein. Dann ist die eigene Routingtabelle groß genug, um Anfragen zuverlässig abzusenden und der eigene Rechner im Netz bekannt genug, um seine Routingtabelle durch steigende Anzahl Anfragen durch den eigenen Knoten entsprechend zu vergrößern und damit günstigere (und kürzere) Pfade zu Dateien zu finden. |
|||
==== Dateien suchen ==== |
|||
[[Image:Freenet-anfrage.png|thumb|450px|right|Beispiel einer Suchanfrage]] |
|||
Der Suchalgorithmus lässt sich am Besten an Hand eines Beispiels verdeutlichen: |
|||
In diesem Beispiel sucht Knoten a eine Datei mit dem Schlüssel h. Die Namen der Knoten seien in diesem Beispiel so gewählt, dass der jeweilige Knoten bei seinen Nachbarn unter dem Schlüssel in der Routingtabelle eingetragen ist, der sein Name ist. Nachbarn sind durch Pfeil verbundene Knoten. |
|||
Knoten b hat also folgende Routingtabelle: |
|||
{| cellpadding="2" border="1" style="border: 1px solid black; border-collapse:collapse" |
|||
! Schlüssel |
|||
! Knoten |
|||
|- align="center" |
|||
| a |
|||
| a |
|||
|- align="center" |
|||
| i |
|||
| i |
|||
|- align="center" |
|||
| e |
|||
| e |
|||
|- align="center" |
|||
| j |
|||
| j |
|||
|} |
|||
# Knoten a sucht zunächst in seinem eigenen Datenbestand, findet er die Datei dort nicht, wird die Anfrage an denjenigen seiner Nachbarknoten weitergeleitet, der in seiner Routingtabelle am nächsten zum angefragten Schlüssel steht, in dem Fall Knoten b als einziger in der Routingtabelle. |
|||
# Die HTL wird um 1 reduziert und wenn diese nun noch größer als 0 ist, fragt b den nächsten passenden Knoten: i (h liegt näher an i als h an j oder e liegt). Dabei ist bei Knoten i nicht zu erkennen, ob a die Anfrage gestartet hat, oder b. Denn er weiß nur, dass er eine Anfrage von b erhalten hat. |
|||
# Da Knoten i keine weiteren Nachbarn hat und die Datei nicht besitzt, wird einer Fehlermeldung an Knoten b übermitelt, woraufhin dieser den nächstbesten Knoten (j) auswählt und die Suchanfrage an ihn übermittelt. |
|||
... |
|||
Schleifen werden dabei erkannt und so wird schließlich die Datei auf Knoten d gefunden. |
|||
Nun wird die Datei entlang aller (an dieser erfolgreichen Suchroute) beteiligten Knoten zu a übermittelt. Jeder Knoten kennt dabei lediglich den Nachbarn, der nach die Datei bei ihm angefragt hat. Entlang dieses Strecke können die Knoten die Datei jeweils in ihrem Data Store speichern - so verteilen sich beliebte Dateien schnell im Netz. |
|||
==== Dateien einfügen ==== |
|||
Damit Dateien effizient gefunden werden können, funktioniert das Enifügen ähnlich zum Suchen: |
|||
# Key berechnen (CHK, SSK oder KSK) |
|||
# Insert-Nachricht an den eigenen Knoten senden, HTL festlegen |
|||
# der Knoten sucht im eigenen Data Store nach dem Key |
|||
#* Key wird gefunden: eine ''key kollision'' wird zurückgegeben |
|||
#* Key wird nicht gefunden: HTL wird um 1 reduziert, Einfügenachricht wird an den Knoten weitergeleitet, der dem ähnlichsten Key (im Vergleich zum einzufügenden Key) zugeordnet ist |
|||
# ist HTL auf 0 gesunken (keine Kollisionen), dann: |
|||
## eine ''all clear'' nachricht wird an den Sender entlang der Einfügekette geschickt |
|||
## dieser sendet die Datei entland dieses Pfades |
|||
## jeder Server im Pfad speichert die Datei im Data Store |
|||
## beim Weiterreichen der Datei können die Knoten jeweils die "Datenquelle" auf sich umsetzen oder einen beliebigen anderen Knoten (um Anonymität des Autors sicher zu stellen) |
|||
# geht die Anfrage (per Backtracking) zum Absender zurück, dann wird dem User mitgeteilt, dass nicht ausreichend Knoten (wie in HTL angegeben) kontaktiert werden konnten |
|||
=== Netztopologie === |
=== Netztopologie === |
||
==== Einfügen eines Knotens ==== |
|||
Will ein User am Freenet teilnehmen, so muss sich sein Knoten zunächst mit einem anderen Knoten, der bereits im Freenet ist, verbinden. Dieser Erstkontakt wird durch eingebaute Serverlisten oder Listen auf Internetseiten vermittelt, der erste Knoten muss also bekannt sein. |
|||
Der neue Knoten muss sich nun bei den anderen Knoten im Freenet bekannt machen, damit durch ihn Anfragen geleitet werden, wodurch sich die Routingtabelle aufbaut. Damit Anfragen durch den neuen Knoten geleitet werden, muss dieser in den Routingtabellen der anderen Knoten auftauchen. Um effizientes Routing zu gewährleisten, sollten alle Knoten, bei denen er sich bekannt macht, ihm den selben Key in ihrer Routingtabelle zuweisen. Weiterhin sollte sich der Knoten nicht selbst einen Key zuweisen können, da es sonst möglich wäre, Kontrolle über bestimmte Schlüsselbereiche zu erlangen. |
|||
Um diesen Anforderungen zu entsprechen, benutzt Freenet ein kryptografisches Protokoll, welches wie folgt abläuft: |
|||
# der neue Knoten erstelle ein Public-Private-Keypair und |
|||
# sendet eine ''announcement message'' mit dem Public Key und seiner Adresse an den bekannten Knoten im Freenet (mit einer wählbaren HTL) |
|||
# dieser Knoten reduziert die HTL um 1 und leitet die Nachricht an einen zufällig gewählten anderen Knoten weiter, was solange wiederholt wird, bis ein Hops-to-Live von 0 erreicht wurde |
|||
# alle Knoten in dieser Nachrichtenkette weisen dem neuen Knoten nun (zusammen) einen Key zu (kryptografisches Protokoll zur Zufallszahlengeneration) und |
|||
# fügen ihren Routingtabellen den neuen Eintrag hinzu |
|||
Das Verfahren stellt sicher, dass kein Teilnehmer das Endergebnis beeinflussen kann. Sämtliche Kommunikation wird dabei AES-verschlüsselt. Das erstellte Public-Private-Schlüsselpaar dient zur Idenfikation des Knoten unabhängig von der IP. Es wird zur Signatur der physikalischen Adresse benutzt. |
|||
==== Entstehende Topologie ==== |
|||
Durch die Spezifika des Routingprotokolls entsteht ein Netzwerk, dass sich in seinen Verbindungen untereinander nach dem Power-Law-Modell verhält, welches ähnlich dem Small-World-Modell ist: |
|||
Es geht dabei von sozialen Bindungen zwischen Menschen aus und versucht damit die Verhaltensweisen in solchen Netzen zu beschreiben. Jeder Mensch kennt viele Menschen in seinem (lokalen) Umfeld (Cliquenbildung), aber auch einige weiter entfernte (sog. Abkürzungen in der Bekanntschaftsrelation). Weiterhin gibt es einige sozial überdurchschnittlich aktive Menschen mit vielen Bekanntschaften. |
|||
[[Image:Power-Law.png|thumb|none|550px|Pareto-Verteilung]] |
|||
Das trifft auch auf das Freenet zu: Ein Rechner bildet seine Clique mit den anfangs bekannten Knoten. Knoten, die in den (einprogrammierten) Serverlisten auftauchen, sind (z.B.) diejenigen mit überdurchschnittlich vielen Verbindungen. Diese Verteilung (Pareto-Verteilung - engl. "Power Law") ermöglicht um Durchschnitt kürzere Pfadlängen und snid generell weniger anfällig gegen den Ausfall vieler Knoten, so es denn nicht die stark verbundenen Knoten sind. Sollten diese dennoch ausfallen, so können sich Anfragen dennoch von Knoten zu Knoten durchhangeln, nur ohne diese Abkürzungen könnte dieser Pfad länger sein. |
|||
== Diskussion == |
== Diskussion == |
Latest revision as of 10:37, 9 March 2006
Gliederung
Einleitung
Geschichte
Kurze Zusammenfassung der wichtigsten Daten
- 1999 Erstes Paper: "Freenet: A Distributed Anonymous Information Storage and Retrieval System" von Ian Clarke, Oskar Sandberg, Brandon Wiley, Theodore W. Hong
- 2000 Version 0.1 der Implementatierung in Java (GPL)
- 2002 gemeinnützige "The Freenet Project Inc." beschäftigt einen Vollzeitprogrammierer -- finanziert durch Spenden
- 2006 Version 0.7: komplette Neuimplementierung
- bisher mehr als 2 Mio Downloads, aber wahrscheinlich deutlich weniger aktive Teilnehmer
- sehr aktive Weiterentwicklung
Philosophie und Ziele
Die Allgemeine Erklärung der Menschenrechte, Artikel 19
Jeder hat das Recht auf Meinungsfreiheit und freie Meinungsäußerung; dieses Recht schließt die Freiheit ein, Meinungen ungehindert anzuhängen sowie über Medien jeder Art und ohne Rücksicht auf Grenzen Informationen und Gedankengut zu suchen, zu empfangen und zu verbreiten.
Negativbeispiele hierbei sind autoritäre Staaten wie China, Indonesien,... Anonyme Kommunikation ist dort Voraussetzung für freie Meinungsäußerung und freien Informationszugriff, weil nur so ein Schutz vor Verfolgung sicher gestellt werden kann.
Aber auch in der EU gibt es bedenkliche Bestrebungen: Die Richtlinie zur Vorratsdatenspeicherung von Telekommunikatiosverbindungsdaten wird, sobald umgesetzt, unter dem Vorwand der Terrorismusbekämpfung das Fernmeldegeheimnis quasi aushebeln und die Unschuldsvermutung umkehren, da die Daten aller Bürger vorsorglich für 6 Monate gespeichert werden.
Motivation des Projektes
Ziele:
- Anonymität: Schutz von Erzeuger, Konsumenten und beteiligten Dritten (Zwischenstationen) vor Verfolgung durch Verschlüsselung und Routing
- Pseudonymität durch digitale Signaturen
- Resistenz gegen Zensur (Löschung von Dokumenten soll unmöglich sein), Verfügbarkeit und Zuverlässigkeit durch Dezentralisierung und Redundanz (Robustheit bei bösartigen / ausfallenden Knoten)
- effizient und skalierbar bei Speicherung und Routing -- Performance zweitrangig, aber soll gut skalieren und sich an Nachfrage nach best. Daten anpassen
Freenet will und kann aber keine Konkurrenz zu "traditionellen" Filesharing-Netzen sein.
Architektur
Übersicht
Freenet ist ein verteiltes Speichersystem mit Replizierung der Daten. Es besteht aus Knoten, die jeweils einen (verschlüsselten) Cache für zu speichernde Dateien bereithalten, den sog. Date Store. Dabei werden dort (im Gegensatz zu Tauschbörsen) nicht nur Dateien gespeichert, die der User selbst angefordert bzw. eingefügt hat. Auch hat der User keinen Einfluss darauf, was bei ihm gespeichert wird und weiß das auch nicht unmittelbar (der Date Store ist verschlüsselt!).
Schlüssel
Dateien werden in Freenet durch verschiedene Schlüssel identifiziert. Bei allen Schlüsseln wird eine modifizierte bas64-Kodierung verwendet, bei der nur die Zeichen a-z, A-Z, -, ~ verwendet werden.
Content Hash Key (CHK)
Beschreibung | CHKs sind die eindeutigen Bezeichner von Dateien in Freenet, vergleichbar mit Inodes in Dateisystemen. |
---|---|
Verschlüsselung | Beim Einstellen von Dateien mittels FProxy werden diese mit einem Schlüssel verschlüsselt, der sich (scheinbar) aus dem Inhalt der Datei ermittelt. So wird auch verhindert, dass 2 Dateien gleichen Inhalts mit unterschiedlichen Verschlüsselungen 2 verschiedene CHKs erhalten. |
Aufbau (intern) | Ein CHK ist ein base64-kodierter SHA1-Hash des Inhalts der (verschlüsselten) Datei. |
Verlinkung einer Datei | Beim Referenzieren von CHKs wird der Schlüssel zum Entschlüsseln der Datei mit angegeben und optional kann auch noch ein Dateiname vergeben werden, den der Browser bzw. FProxy dann beim Speichern der Datei benutzen kann. Diese zusätzlichen Informationen werden aber nicht beim Suchen / Einstellen von Dateien übertragen. |
Beispiel |
CHK@AGP9Hnwh5q7lA3SEBd0N0eNvfwMKAwI,l1-Yast1r9sOB5DqH0CFsA |
Aufbau (Referenz auf Datei) |
CHK@<hash(encrypted data)>,<Encryption Key>[/filename.ext] |
Vorteile |
|
Nachteile |
|
Signed Subspace Key (SSK)
Beschreibung | SSKs bieten einen persönlichen Namensraum, in dem jeder lesen jedoch nur der Autor schreiben kann. Ein Subspace (eines Autors) wird durch ein Public-Private-Keypair identifiziert, den der Autor einmalig generieren muss.
Dateien werden mit dem privaten Schlüssel des Autors signiert und diese Signatur sowie der Public-Key zusammen mit der Datei im Netzwerk gespeichert. Beim Einfügen und Herunterladen von Dateien wird diese Signatur überprüft. |
---|---|
Verschlüsselung | Zur Verschlüsselung der Datei wird die Beschreibung (zusammen mit der optionalen Entropie (einer zufällige Zeichenkette)) genutzt. Dabei beeinflusst die Entropy lediglich die Verschlüsselung, nicht aber die SSK. |
Aufbau (intern) | Ein SSK ist ein base64-kodierter SHA1-Hash vom Hash des Public-Key und dem Hash des Dokumentnamens. |
Verlinkung einer Datei | Zum Referenzieren von Dateien wird der Public-Key und der Dokumentenname (bzw. Beschreibung des Dokuments) benötigt, aus dem sich dann der SSK ermitteln lässt. Nur diese wird dann beim Suchen im Netzwerk übertragen. |
Beispiel |
SSK@rBjVda8pC-Kq04jUurIAb8IzAGcPAgM/TFE// |
Aufbau (Referenz auf Datei) |
SSK@<public key>PAgM[Entropy]/<Description> |
Vorteile |
|
Nachteile |
|
Keyword Signed Key (KSK)
Beschreibung | KSKs stellen eine Möglichkeit dar, Dateien in menschenlesbarer Form an Hand eines (frei) wählbaren Namens zu referenzieren. Eine Zugangskontrolle wird dabei nicht gewährleistet. |
---|---|
Verschlüsselung | Als Public-Key wird der Hash des gewählten Dokumentnamens benutzt. Daraus wird ein Private-Key ermittelt, der zur Entschlüsselung und Signierung der Datei benuzt wird. |
Aufbau (intern) | Ein KSK ist ein base64-kodierter SHA1-Hash vom zugewiesenen Public-Key (= Hash des Dokumentnamens). |
Verlinkung einer Datei | Zur Verlinkung einer Datei ist lediglich der Dokumentname erforderlich. Aus diesem lässt sich die KSK ermitteln (SHA1-Hash davon) sowie der Private-Key zum Entschlüsseln. |
Beispiel |
KSK@gpl.txt |
Aufbau (Referenz auf Datei) |
KSK@Description |
Vorteile |
|
Nachteile |
|
Routing
Jeder Knoten im Freenet besitzt eine Routingtabelle, in der er speichert, welcher seiner Nachbarknoten zu welchem Schlüssel zuletzt eine Anfrage erfolgreich beantworten konnte. So entsteht jeweils eine Zuordnung Schlüssel <-> Knoten, bei der nicht zwangsläufig jedem Schlüssel ein Knoten zugeordnet wird.
Freenet geht davon aus, dass ein Knoten, der bereits in der Vergangenheit eine Anfrage zu einem ähnlichen Thema (Key) erfolgreich beantwortet hat, auch zu dem gesuchten Thema erfolgreich antworten kann oder die Anfrage zumindest einen Schritt weiter in die richtige Richtung leiten kann.
Anfragen besitzen dabei einen Hops-to-live-Wert (HTL) <= 20. Diese Obergrenze ist fest in FProxy einprogrammiert. Weiterhin besteht die Möglichkeit, dass ein Knoten im Falle eines HTL > 20 die Anfrage ablehnt. Passiert eine Anfrage einen Knoten, wird dieser Wert um 1 reduziert.
Dadurch, dass sich die Routingtabelle erst mit den Anfragen aufbaut, dauert es eine Weile, bis ein neuer Knoten genügend Informationen über das Netz weiß, um selbst erfolgreich Anfragen senden zu können. Mindestens 30 Minuten sollten man (erfahrungsgemäß) schon verbunden sein. Dann ist die eigene Routingtabelle groß genug, um Anfragen zuverlässig abzusenden und der eigene Rechner im Netz bekannt genug, um seine Routingtabelle durch steigende Anzahl Anfragen durch den eigenen Knoten entsprechend zu vergrößern und damit günstigere (und kürzere) Pfade zu Dateien zu finden.
Dateien suchen
Der Suchalgorithmus lässt sich am Besten an Hand eines Beispiels verdeutlichen:
In diesem Beispiel sucht Knoten a eine Datei mit dem Schlüssel h. Die Namen der Knoten seien in diesem Beispiel so gewählt, dass der jeweilige Knoten bei seinen Nachbarn unter dem Schlüssel in der Routingtabelle eingetragen ist, der sein Name ist. Nachbarn sind durch Pfeil verbundene Knoten.
Knoten b hat also folgende Routingtabelle:
Schlüssel | Knoten |
---|---|
a | a |
i | i |
e | e |
j | j |
- Knoten a sucht zunächst in seinem eigenen Datenbestand, findet er die Datei dort nicht, wird die Anfrage an denjenigen seiner Nachbarknoten weitergeleitet, der in seiner Routingtabelle am nächsten zum angefragten Schlüssel steht, in dem Fall Knoten b als einziger in der Routingtabelle.
- Die HTL wird um 1 reduziert und wenn diese nun noch größer als 0 ist, fragt b den nächsten passenden Knoten: i (h liegt näher an i als h an j oder e liegt). Dabei ist bei Knoten i nicht zu erkennen, ob a die Anfrage gestartet hat, oder b. Denn er weiß nur, dass er eine Anfrage von b erhalten hat.
- Da Knoten i keine weiteren Nachbarn hat und die Datei nicht besitzt, wird einer Fehlermeldung an Knoten b übermitelt, woraufhin dieser den nächstbesten Knoten (j) auswählt und die Suchanfrage an ihn übermittelt.
... Schleifen werden dabei erkannt und so wird schließlich die Datei auf Knoten d gefunden.
Nun wird die Datei entlang aller (an dieser erfolgreichen Suchroute) beteiligten Knoten zu a übermittelt. Jeder Knoten kennt dabei lediglich den Nachbarn, der nach die Datei bei ihm angefragt hat. Entlang dieses Strecke können die Knoten die Datei jeweils in ihrem Data Store speichern - so verteilen sich beliebte Dateien schnell im Netz.
Dateien einfügen
Damit Dateien effizient gefunden werden können, funktioniert das Enifügen ähnlich zum Suchen:
- Key berechnen (CHK, SSK oder KSK)
- Insert-Nachricht an den eigenen Knoten senden, HTL festlegen
- der Knoten sucht im eigenen Data Store nach dem Key
- Key wird gefunden: eine key kollision wird zurückgegeben
- Key wird nicht gefunden: HTL wird um 1 reduziert, Einfügenachricht wird an den Knoten weitergeleitet, der dem ähnlichsten Key (im Vergleich zum einzufügenden Key) zugeordnet ist
- ist HTL auf 0 gesunken (keine Kollisionen), dann:
- eine all clear nachricht wird an den Sender entlang der Einfügekette geschickt
- dieser sendet die Datei entland dieses Pfades
- jeder Server im Pfad speichert die Datei im Data Store
- beim Weiterreichen der Datei können die Knoten jeweils die "Datenquelle" auf sich umsetzen oder einen beliebigen anderen Knoten (um Anonymität des Autors sicher zu stellen)
- geht die Anfrage (per Backtracking) zum Absender zurück, dann wird dem User mitgeteilt, dass nicht ausreichend Knoten (wie in HTL angegeben) kontaktiert werden konnten
Netztopologie
Einfügen eines Knotens
Will ein User am Freenet teilnehmen, so muss sich sein Knoten zunächst mit einem anderen Knoten, der bereits im Freenet ist, verbinden. Dieser Erstkontakt wird durch eingebaute Serverlisten oder Listen auf Internetseiten vermittelt, der erste Knoten muss also bekannt sein.
Der neue Knoten muss sich nun bei den anderen Knoten im Freenet bekannt machen, damit durch ihn Anfragen geleitet werden, wodurch sich die Routingtabelle aufbaut. Damit Anfragen durch den neuen Knoten geleitet werden, muss dieser in den Routingtabellen der anderen Knoten auftauchen. Um effizientes Routing zu gewährleisten, sollten alle Knoten, bei denen er sich bekannt macht, ihm den selben Key in ihrer Routingtabelle zuweisen. Weiterhin sollte sich der Knoten nicht selbst einen Key zuweisen können, da es sonst möglich wäre, Kontrolle über bestimmte Schlüsselbereiche zu erlangen.
Um diesen Anforderungen zu entsprechen, benutzt Freenet ein kryptografisches Protokoll, welches wie folgt abläuft:
- der neue Knoten erstelle ein Public-Private-Keypair und
- sendet eine announcement message mit dem Public Key und seiner Adresse an den bekannten Knoten im Freenet (mit einer wählbaren HTL)
- dieser Knoten reduziert die HTL um 1 und leitet die Nachricht an einen zufällig gewählten anderen Knoten weiter, was solange wiederholt wird, bis ein Hops-to-Live von 0 erreicht wurde
- alle Knoten in dieser Nachrichtenkette weisen dem neuen Knoten nun (zusammen) einen Key zu (kryptografisches Protokoll zur Zufallszahlengeneration) und
- fügen ihren Routingtabellen den neuen Eintrag hinzu
Das Verfahren stellt sicher, dass kein Teilnehmer das Endergebnis beeinflussen kann. Sämtliche Kommunikation wird dabei AES-verschlüsselt. Das erstellte Public-Private-Schlüsselpaar dient zur Idenfikation des Knoten unabhängig von der IP. Es wird zur Signatur der physikalischen Adresse benutzt.
Entstehende Topologie
Durch die Spezifika des Routingprotokolls entsteht ein Netzwerk, dass sich in seinen Verbindungen untereinander nach dem Power-Law-Modell verhält, welches ähnlich dem Small-World-Modell ist:
Es geht dabei von sozialen Bindungen zwischen Menschen aus und versucht damit die Verhaltensweisen in solchen Netzen zu beschreiben. Jeder Mensch kennt viele Menschen in seinem (lokalen) Umfeld (Cliquenbildung), aber auch einige weiter entfernte (sog. Abkürzungen in der Bekanntschaftsrelation). Weiterhin gibt es einige sozial überdurchschnittlich aktive Menschen mit vielen Bekanntschaften.
Das trifft auch auf das Freenet zu: Ein Rechner bildet seine Clique mit den anfangs bekannten Knoten. Knoten, die in den (einprogrammierten) Serverlisten auftauchen, sind (z.B.) diejenigen mit überdurchschnittlich vielen Verbindungen. Diese Verteilung (Pareto-Verteilung - engl. "Power Law") ermöglicht um Durchschnitt kürzere Pfadlängen und snid generell weniger anfällig gegen den Ausfall vieler Knoten, so es denn nicht die stark verbundenen Knoten sind. Sollten diese dennoch ausfallen, so können sich Anfragen dennoch von Knoten zu Knoten durchhangeln, nur ohne diese Abkürzungen könnte dieser Pfad länger sein.
Diskussion
Performance
Als wichtigstes Maß für die Performance dient die Anzahl der Hops, die eine Anfrage bis zum Ziel (und die gefundene Datei zurück zum Suchenden) benötigt.
Auf Grund des (gewollten) Aufbaus des Netzwerkes ist es relativ schwierig, diese zuverlässig zu bestimmen: Einerseits sind formale Komplexitäts-Beweise auf Grund der komplizierten Struktur schwierig, andererseits entzieht sich das existierende Netzwerk im Internet sehr erfolgreich dem Blick seiner Schöpfer. Aus diesen Gründen ist die Simulation das vielversprechendste Mittel, um einen globalen Einblick zu erhalten.
Die Simulation ergab eine Komplexität von etwa . Danach sollte Freenet für eine Million Knoten eine mittlere Pfadlänge von 30 Hops erreichen. Praktisch kann dieser Wert in beide Richtungen variieren, da einerseits von Dateien möglicherweise mehr Replikate vorkommen als in der Simulation (das würde die Länge verkürzen), andererseis könnten zu volle Routing-Tabellen die Pfadlängen erhöhen.
Security
Anonymiät
Die gewährleistete Anonymität ist grundsätzlich schwächer als bei z.B. Onion Routing (siehe [Mixmaster]), wenn ein Angreifer hinreichend viele Nachbarknoten des Ziels kontrolliert.
Um zweifelsfrei zu beweisen, dass ein bestimmter Knoten eine bestimmte Datei angefordert oder eingefügt hat, muss der Angreifer jedoch alle empfangenen und Nachrichten kennen, denn da das Quellfeld eine Anfrage gelegentlich auf die Adresse eines routenden gesetzt Knotens wird, ist sonst nicht zweifelsfrei klar, ob der Zielknoten wirklich der Ursprung einer Anfrage ist.
Wegen der Transportverschlüsselung müsste er alle Nachbarknoten kontrollieren, bloßes Mitlesen des Traffics genügt nicht. Die Verschleierung der Nachrichtengröße durch Padding verhindert Schlüsse aus der Nachrichtenlönge. Da zudem der Inhalt der Dateien verschlüsselt ist, kann der Angreifer selbst bei Überwindung der Transportverschlüsselung keine Analyse des Inhaltes o.ä. vornehmen, sondern muss vorneweg die Keys der von ihm gesuchten Dateien kennen.
Die reine Teilnahme am Netz kann jedoch (noch) nicht (durch Steganographie o.ä.) verschleiert werden, was z.B. in China ein Problem darstellt.
Für zukünftige Versionen ist es geplant, Onion Routing als Feature zur Überwindung der ersten Nachbarknoten hinzuzufügen.
Verfügbarkeit und Integrität
Die Verfügbarkeit von Dateien ist nur einschränkbar, wenn der Angreifer über Resourcen etwa in der Größenordnung (Bandbreite, Anzahl Knoten) des gesamten Netzes verfügt.
Das gezielte Entfernen einer unerwünschten Datei ist nicht möglich, denkbar wäre es aber, das Netzwerk mit sehr viel "Müll", d.h. unsinnigen Dateien zu fluten und selbige durch enorm viele Requests zu verteilen und damit andere Dateien aus den Knoten zu verdrängen (Cache Replacement). Das könnte man jedoch durch Mittel wie [HashCash] erschweren.
Da individuelle Knotenbetreiber natürlich Kontrolle darüber haben, welche Dateien (Keys) ihre Knoten anbieten, wäre Zensur auf Basis eines allgemeinen Konsens (Key-Blacklists) dennoch möglich.
Anzumerken wäre noch, dass die Robustheit des Netzes im Gegensatz zu z.B. proprietären Filesharing-Netzen nicht auf dem Prinzip "Security by Obscurity", d.h. geheimen Protokollen, basiert, sondern bewusst pessimistischen Annahmen (was natürlich nicht ausschließt, dass in Zukunft Verwundbarkeiten bekannt werden).
Selbst wenn ein Drittel der Knoten plötzlich ausfällt, ist der Großteil der Dateien immernoch verfügbar.
Probleme
Freenet befindet sich, obwohl es durchaus benutzbar ist und benutzt wird, immernoch in einer frühen Entwicklunsphase. Deshalb sollte man sich auch einiger bisher offener Probleme bewusst sein:
- es gibt bisher keine "Suchmaschine" und wird sie auch in absehbarer Zeit nicht geben. Als Behelf dienen regelmäßig aktualisierte Verzeichnisse (Index-Freesites) oder die Weitergabe von Keys auf einem externen Weg (z.B. persönlich).
- Dateien können nicht gelöscht werden, auch nicht vom "Eigentümer" (ist aber auch eine gewollte Eigenschaft)
- von Gegnern wird oft angeführt, dass Freenet ein "Hort" für ungewollten Content wie bspw. Kinderpornografie, Bombenbauanleitungen u.ä. ist
- Updates von Dateien sind nur über etwas unschöne Umwege möglich (Date Based Redirects)
Zudem gibt es in der praktischen Benutzung noch einige kleinere, aber umgehbare Schwierigkeiten, die jedoch neuen Benutzern den Einstieg erschweren
- eine vertrauenswürdige initiale Knotenliste ist überaus wichtig, damit neue Nutzer nicht in ein separates, kontrolliertes Netz 'entführt' werden. Bisher wird die Liste aber von der Projekthomepage [[1]] zentral abgeholt. Besser wäre es, die Liste von einer vertrauenswürdigen Person zu beziehen.
- die langen Ladezeiten (Minutenbereich) erschweren die Benutzung des Webinterfaces FProxy, da die meisten Browser in der Werkseinstellung nur recht wenige gleichzeitige Verbindungen öffnen (<20)
- Freenet ist gerade am Anfang oft sehr langsam, wenn der neue Knoten nur wenige Bekanntschaften hat. Dies kann durch eine große initiale Knotenliste abgefedert werden (die Knoten in der zentralen Knotenliste auf der Projektseite sind jedoch oft überlastet).
momentaner Status
Im Moment (März 2006) wird in naher Zukunft Version 0.7 erwartet, die einige größere Neuerungen mitbringt:
- es wird möglich sein ein skalierbares sog. Darknet aufzubauen, bei dem der eigene Knoten nur mit auserwählten, vertrauenswürdigen Knoten kommuniziert
- es soll ein schneller Broadcast implementiert werden für anonyme Chats / RSS Feeds
- die Datei/Block-größen werden festgelegt auf 1kByte oder 32kBytes. Größere Dateien werden auf mehrere Keys aufgeteilt (wei bisher schon)
- Die Schlüssellänge wird von 128bit auf 256bit erhöht
weitere Features sind geplant, aber noch nicht in Sichtweite:
- Pre-Mix-Routing: Anfragen werden nach dem Onion-Routing-Prinzip zuerst über einige Knoten weiter geleitet, bevor sie als offizielle Freenet-Anfrage starten. Damit kennt der erste Nachbar zwar den Sender aber nicht den Inhalt, der letzte in der Kette zwar den Inhalt aber nicht die Quelle.
- Steganographie zum Verstecken des Freenet-Protokolls
ergänzende Links
Auf dem 22C3 haben Oskar Sandberg und Ian Clake einen Vortrag über die Neuerungen in Version 0.7 gehalten. Dazu gibt es
- Slides (pdf.bz2)
- eine Java-Demo des Prinzips des neuen Routing Algorithmus.
- In der deutschen Wikipedia gibt es einen sehr ausführlichen Eintrag zu Freenet.