Snowflake Proxy gegen Zensur im Internet

Der Zugang zu freien Informationen ist nicht in jedem Land ohne Weiteres möglich. Gerade durch die Zensur des Internets kann der Zugang und Austausch von Informationen sehr stark eingeschränkt werden. Mit einem nicht zensierten Internetzugang und Snowflake kann man jedoch selbst aktiv etwas gegen Zensur im Internet tun. Die Einrichtung von Snowflake ist dabei auch ohne technische Kenntnisse sehr einfach möglich.

Was ist Snowflake?

Snowflake wird vom Tor-Projekt entwickelt und wie folgt beschrieben:

Snowflake is a system to defeat internet censorship. People who are censored can use Snowflake to access the internet. Their connection goes through Snowflake proxies, which are run by volunteers.

https://snowflake.torproject.org/

Snowflake ist ein Pluggable Transport welcher immer dann zum Einsatz kommt wenn der direkte Zugang zum Tor-Netzwerk blockiert wird. Mit Snowflake kann durch Freiwillige eine Brücke zum Tor-Netzwerk zur Verfügung gestellt werden und damit ein indirekter Zugang zum Tor-Netzwerk angeboten werden. Snowflake ist als Browser-Erweiterung für Chromium-Browser (Google Chrome, Microsoft Edge, Chromium) sowie für Mozilla Firefox erhältlich. Snowflake kann aber auch als eigenständiger Proxy betrieben oder über eine HTML-Einbettung aktiviert werden.

Dadurch entsteht ein sehr dynamisches Netz aus Snowflake Proxys welches nur sehr schwer durch Zensurmaßnahmen bekämpft werden kann. Sollte ein Snowflake Proxy blockiert werden stehen viele weitere Proxys zur Verfügung.

Wie funktioniert Snowflake?

Snowflake besteht aus drei Komponenten:

  • Client: Der Benutzer eines Tor-Browsers welcher auf das Tor-Netzwerk und darüber auf das nicht zensierte Internet zugreifen möchte.
  • Freiwillige Betreiber von Snowflake Proxys
  • Broker: Eine Vermittlungsstelle welche dem Benutzer des Tor-Browsers einen Snowflake Proxy vermittelt.
Schema eines Verbindungsaufbaus (https://snowflake.torproject.org/)

Das Schema zeigt den Ablauf eines Verbindungsaufbaus mit dem Tor-Netzwerk bzw. einer Website über einen Snowflake Proxy. Der Verbindungsaufbau findet in fünf Schritten statt:

  1. Der Tor-Browser stellt unter Verwendung von Domain Fronting eine Anfrage an den Broker.
  2. Der Snowflake Proxy teilt dem Broker mit dass der Proxy zur Verfügung steht.
  3. Der Broker teilt dem Tor-Browser einen verfügbaren Snowflake Proxy mit.
  4. Der Tor-Browser stellt über WebRTC eine Verbindung zum Snowflake Proxy her.
  5. Der Snowflake Proxy leitet die Anfragen an das Tor-Netzwerk weiter.

Das Ziel sieht dabei nicht die IP-Adresse des Snowflake Proxys, sondern immer die IP-Adresse des Tor-Exit-Nodes. Der Snowflake Proxy stellt nur die Brücke zum Tor-Netzwerk zur Verfügung und ist selbst kein Tor-Exit-Node.

Installieren eines eigenständigen Snowflake Proxys

Die Installation eines Snowflake Proxys ist sehr einfach und in wenigen Schritten erledigt. Der Snowflake Proxy kann dabei unter Docker oder auf einem Server oder Raspberry Pi installiert werden.

Installation in einem Docker Stack

Für die Installation in einem Docker Stack kann die Compose-Datei des Tor-Projekts verwendet werden. Diese Compose-Datei muss jedoch leicht angepasst werden damit diese auch zur Installation im Docker Stack verwendet werden kann:

version: "3.8"

services:
    snowflake-proxy:
        image: thetorproject/snowflake-proxy:latest

Mit dem folgenden Befehl kann der Snowflake Proxy im Docker Stack gestartet werden:

docker stack deploy -c docker-compose.yml snowflake

Installation mit Docker Compose

Für die Installation mit Docker Compose kann die Compose-Datei des Tor-Projekts direkt übernommen werden:

version: "3.8"

services:
    snowflake-proxy:
        network_mode: host
        image: thetorproject/snowflake-proxy:latest
        container_name: snowflake-proxy
        restart: unless-stopped

Mit dem folgenden Befehl kann der Snowflake Proxy mit Docker Compose gestartet werden:

docker-compose up -d snowflake-proxy

Überprüfen des Snowflake Proxys unter Docker

Wenn der Snowflake Proxy erfolgreich installiert wurde, sollte dieser nach einiger Zeit erste Verbindungen annehmen und weiterleiten. Dazu können die Log-Dateien mit dem folgenden Befehl ausgelesen werden. Es werden dabei nur Einträge eines Verbindungsaufbaus angezeigt.

# Docker Stack
docker service logs snowflake_snowflake-proxy 2>&1 | grep "Traffic throughput"

# Docker Compose
docker logs snowflake-proxy 2>&1 | grep "Traffic throughput"

Installation auf einem Server

Auch der Raspberry Pi kann als Server verwendet werden. Auf diesem Blog findest du bereits eine Anleitung wie Raspberry Pi OS auf dem Raspberry Pi installiert und eingerichtet werden kann. Im Anschluss kann der Snowflake Proxy wie nachfolgend beschrieben installiert werden. Um die Installation des Snowflake Proxy vornehmen zu können, sollte das Raspberry Pi OS mindestens in der Debian Version 11 (Bullseye) verwendet werden. Dort können alle Voraussetzungen direkt in der benötigten Version installiert werden.

Im ersten Schritt sollten die Repositories sowie die bereits installierten Pakete aktualisiert werden:

apt-get update
apt-get upgrade

Für die Installation des Snowflake Proxy wird Go (1.13+) und Git benötigt. Diese Abhängigkeiten können über den folgenden Befehl installiert werden:

apt-get install golang git

Nun kann der Quellcode des Snowflake Proxys direkt aus dem offiziellen Git-Repository des Tor-Projekts heruntergeladen werden:

git clone https://git.torproject.org/pluggable-transports/snowflake.git

Aus dem heruntergeladenen Quellcode muss jedoch noch eine Anwendung kompiliert werden. Dazu wechseln wir in das Verzeichnis mit dem Quellcode des Snowflake Proxys:

cd snowflake/proxy

… und kompilieren mit dem folgenden Befehl den Snowflake Proxy:

go build

Wenn der Snowflake Proxy erfolgreich kompiliert wurde kann dieser auch direkt gestartet werden. Mit dem folgenden Befehl wird der kompilierte Snowflake Proxy gestartet. Das Protokoll wird dabei in die Datei snowflake.log geschrieben. Dort wird auch eine Statistik zu vergangenen Verbindungen inkl. der übertragenen Datenmenge gespeichert.

nohup ./proxy > ./snowflake.log 2>&1 &

Snowflake Proxy auch ohne eigenen Server

Ein Snowflake Proxy kann auch ohne einen eigenen Server oder Raspberry Pi betrieben werden. Dafür kann eine Chrome-Erweiterung oder ein Mozilla Firefox Addon installiert werden. Der Proxy ist dabei immer dann aktiv wenn der entsprechende Browser geöffnet ist und der Proxy in der Erweiterung aktiviert wurde. Der Benutzer des Tor-Browsers welcher den Proxy verwendet sieht dabei nicht auf welche Seiten des Browsers zugegriffen wird, sondern nutzt den Browser mit der aktiven Erweiterung nur als Brücke. Die Erweiterungen findet man auf der offiziellen Projektseite von Snowflake. Diese müssen nur installiert und ggf. aktiviert werden.

Auch ohne die Browser-Erweiterung kann ein solcher Proxy betrieben werden. Voraussetzung dafür ist dass der Browser WebRTC unterstützt. Dies ist bei aktuellen Versionen eines Chromium-Browsers (Google Chrome, Microsoft Edge) oder Mozilla Firefox der Fall. Dazu einfach die Website https://snowflake.torproject.org/embed aufrufen und den Snowflake Proxy aktivieren. So lange der Tab mit aktiviertem Proxy geöffnet ist kann auch eine Verbindung mit dem Snowflake Proxy hergestellt werden.

Avatar for Sebastian Brosch

Sebastian Brosch

Ich bin gelernter Fachinformatiker für Anwendungsentwicklung und konnte bereits Erfahrungen in der Entwicklung von Desktop- und Web-Anwendungen sammeln. In diesem Blog schreibe ich über Probleme und Erfahrungen aus dem Gebiet der Anwendungsentwicklung. Ich werde hier meist Artikel aus den Bereichen .NET, Datenbanken (hauptsächlich T-SQL und MySQL), PHP, HTML, CSS und Docker schreiben.

7 Antworten

  1. Avatar for Andreas Fuchs Andreas Fuchs sagt:

    Habe es in Chrome installiert. Was passiert wenn ich den Browser schließe? Gibt es einen automatischen Switch? oder ist das nur für Stateless Sessions? Danke

    • Wenn der Browser vollständig (also alle Tabs) geschlossen wurde, ist auch der Snowflake Proxy nicht mehr aktiv. Im Task Manager ist keine Instanz des Google Chrome aktiv und damit auch die Erweiterung nicht mehr aktiv.

  2. Hallo Sebastian,
    kannst du etwas zu Snowflake in Zusammenspiel mit Firewalls sagen. Konkret habe ich eine Pfsense laufen und wollte über Portforwarding die Ports die Snowflake braucht freigeben. Leider ohne jeglichen Erfolg.

    • Zum Zusammenspiel zwischen dem Snowflake Proxy und der Firewall kann ich leider nicht viel sagen. Habe mich mal etwas umgeschaut und konnte ein paar Informationen (zum Einstieg) finden: Eine Freigabe bestimmter Ports sollte nicht zwingend notwendig sein. Allerdings sollen deutlich mehr Verbindungen mit dem Snowflake Proxy aufgebaut werden wenn Portfreigaben eingerichtet wurden. Der Snowflake Proxy verwendet nicht einen bestimmten Port sondern einen beliebigen UDP-Port aus dem Bereich 32768 bis 60999. Die Freigabe dieser UDP-Ports kann aus einem “restricted NAT” einen “unrestricted NAT” machen und damit zu mehr Verbindungen mit dem Snowflake Proxy führen.

      Quellen: A few questions about the standalone snowflake proxy und [tor-relays] snowflake incoming UDP ports

  3. Avatar for Benedikt Stratmann Benedikt Stratmann sagt:

    Hallo Sebastian,

    danke erstmal für die Anleitung einen eigenen Snowflake Proxy einzurichten.
    Die Installation auf einem Raspi3 hat problemlos funktioniert.
    Aber wie wird der Pi, der hinter meiner Fritzbox hängt, denn nach außen verfügbar gemacht?
    Gibt es konkrete Ports, die ich freigeben muss oder macht der Proxy das selbständig?

    Schönen Gruß
    Benedikt

  4. Avatar for Benedikt Stratmann Benedikt Stratmann sagt:

    Hallo nochmal 😉
    Meine Frage von vorhin hat sich von allein gelöst.
    Offensichtlich sind keine Veränderungen an den FritzBox-Einstellungen notwendig.
    Nachdem mein Proxy jetzt seit einer Stunde läuft, wurden laut Protokoll bereits 18 Verbindungen darüber aufgebaut.

  5. Avatar for Kurt Kurt sagt:

    Weil die FRITZ!Box sehr viel Umstand macht bei UDP-Port-Freigabe, hab ich sie mit Hilfe von Selenium (Firefox-PlugIn Selenium-IDE) dazu gebracht, jeden Port zwischen 32750 und 60100 als OFFENEN gegen UDP vorzuhalten. Snowflake meldet nun:
    tail -f snowflake/proxy/snowflake.log
    nohup: ignoring input
    22:54:25 Proxy starting
    22:54:32 NAT type: unrestricted
    23:54:25 In the last 1h0m0s, there were 48 connections. Traffic Relayed ↑ 217056 KB, ↓ 13064 KB.
    00:54:25 In the last 1h0m0s, there were 88 connections. Traffic Relayed ↑ 271272 KB, ↓ 35393 KB.

    Das ist nur etwa 20% mehr Durchsatz als zuvor, solang die FRITZ!Box nur 250 UDP-Ports offen hatte.

    Ich copy-paste mal das Selenium-Skript hierhin, es muss angepasst werden, denn ihr habt vielleicht nicht 192.168.178.1 als IP der FRITZ!Box, und habt hoffentlich nicht Goldjunge2 als Passwort.

    {
    "id": "e0dfde5e-2358-4627-9a13-086dca556e90",
    "version": "2.0",
    "name": "fboxUdpOeffneBis60999",
    "url": "http://192.168.178.1",
    "tests": [{
    "id": "b79866d2-326c-4159-a227-420d3e78aeb1",
    "name": "f3400",
    "commands": [{
    "id": "5f32e7b1-943c-4cc6-8103-e8106885de06",
    "comment": "",
    "command": "executeScript",
    "target": "return 32500",
    "targets": [],
    "value": "portbegin"
    }, {
    "id": "4c9885b7-6aa9-4227-96d0-e9e31c371495",
    "comment": "",
    "command": "executeScript",
    "target": "return ${portbegin} + 249",
    "targets": [],
    "value": "portUntil"
    }, {
    "id": "b4dd400b-7ed0-42b3-812f-7b3efabab860",
    "comment": "",
    "command": "store",
    "target": "snowflake_",
    "targets": [],
    "value": "baseAname"
    }, {
    "id": "c3d61913-9991-4a3e-b141-563fb85b4120",
    "comment": "",
    "command": "store",
    "target": "Goldjunge2",
    "targets": [],
    "value": "meinFritzPasswort"
    }, {
    "id": "7642de25-a51a-4eec-811e-ca14de2dc8ec",
    "comment": "",
    "command": "open",
    "target": "/",
    "targets": [],
    "value": ""
    }, {
    "id": "f5a987ee-abe3-4a11-b819-1cd65c1084ce",
    "comment": "",
    "command": "setWindowSize",
    "target": "930x803",
    "targets": [],
    "value": ""
    }, {
    "id": "c55ca7dc-27af-4dd5-8a94-bbb5dd2929a4",
    "comment": "",
    "command": "type",
    "target": "id=uiPass",
    "targets": [
    ["id=uiPass", "id"],
    ["name=uiPass", "name"],
    ["css=#uiPass", "css:finder"],
    ["xpath=//input[@id='uiPass']", "xpath:attributes"],
    ["xpath=//form[@id='loginForm']/div/div[2]/div/input", "xpath:idRelative"],
    ["xpath=//input", "xpath:position"]
    ],
    "value": "${meinFritzPasswort}"
    }, {
    "id": "420d1062-1b4d-4291-9908-0c83c9427d20",
    "comment": "",
    "command": "click",
    "target": "id=submitLoginBtn",
    "targets": [
    ["id=submitLoginBtn", "id"],
    ["css=#submitLoginBtn", "css:finder"],
    ["xpath=//button[@id='submitLoginBtn']", "xpath:attributes"],
    ["xpath=//form[@id='loginForm']/div[2]/button", "xpath:idRelative"],
    ["xpath=//button", "xpath:position"],
    ["xpath=//button[contains(.,'Anmelden')]", "xpath:innerText"]
    ],
    "value": ""
    }, {
    "id": "c1bc2b80-f9f7-45af-ba1f-42550a94de0d",
    "comment": "",
    "command": "click",
    "target": "id=blueBarLogo",
    "targets": [
    ["id=blueBarLogo", "id"],
    ["css=#blueBarLogo", "css:finder"],
    ["xpath=//div[@id='blueBarLogo']", "xpath:attributes"],
    ["xpath=//header[@id='blueBarBox']/div", "xpath:idRelative"],
    ["xpath=//header/div", "xpath:position"]
    ],
    "value": ""
    }, {
    "id": "15050419-44d7-46f6-96f5-a2973b0d24e9",
    "comment": "",
    "command": "click",
    "target": "id=inet",
    "targets": [
    ["id=inet", "id"],
    ["linkText=Internet", "linkText"],
    ["css=#inet", "css:finder"],
    ["xpath=//a[contains(text(),'Internet')]", "xpath:link"],
    ["xpath=//a[@id='inet']", "xpath:attributes"],
    ["xpath=//div[@id='navigationMenu']/div/a[2]", "xpath:idRelative"],
    ["xpath=//a[contains(@href, '/?sid=a4cd389bf916c536&lp=inet')]", "xpath:href"],
    ["xpath=//a[2]", "xpath:position"],
    ["xpath=//a[contains(.,'Internet')]", "xpath:innerText"]
    ],
    "value": ""
    }, {
    "id": "01e763de-0084-4e57-af17-c6c24134b475",
    "comment": "",
    "command": "click",
    "target": "id=shares",
    "targets": [
    ["id=shares", "id"],
    ["linkText=Freigaben", "linkText"],
    ["css=#shares", "css:finder"],
    ["xpath=//a[contains(text(),'Freigaben')]", "xpath:link"],
    ["xpath=//a[@id='shares']", "xpath:attributes"],
    ["xpath=//div[@id='inetsub']/a[5]", "xpath:idRelative"],
    ["xpath=//a[contains(@href, '/?sid=a4cd389bf916c536&lp=shares')]", "xpath:href"],
    ["xpath=//a[5]", "xpath:position"],
    ["xpath=//a[contains(.,'Freigaben')]", "xpath:innerText"]
    ],
    "value": ""
    }, {
    "id": "7d63ec96-1a16-4f75-b68c-4042369a6855",
    "comment": "",
    "command": "",
    "target": "",
    "targets": [],
    "value": ""
    }, {
    "id": "4f4b9411-35cd-4fb1-95bb-f9d0cefc0fd0",
    "comment": "",
    "command": "while",
    "target": "${portbegin} button:nth-child(1)", "css:finder"],
    ["xpath=//button[@name='apply']", "xpath:attributes"],
    ["xpath=//div[@id='uiContentOverview']/div[3]/button", "xpath:idRelative"],
    ["xpath=//div[3]/button", "xpath:position"],
    ["xpath=//button[contains(.,'Übernehmen')]", "xpath:innerText"]
    ],
    "value": ""
    }, {
    "id": "0a6208a5-846e-48bb-99b9-c72e708f8408",
    "comment": "",
    "command": "end",
    "target": "",
    "targets": [],
    "value": ""
    }]
    }],
    "suites": [{
    "id": "ec816e70-19b1-45f4-9de8-aedfd3500c68",
    "name": "Default Suite",
    "persistSession": false,
    "parallel": false,
    "timeout": 300,
    "tests": ["b79866d2-326c-4159-a227-420d3e78aeb1"]
    }],
    "urls": ["http://fritz.box/", "http://192.168.178.1/"],
    "plugins": []
    }

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert