Die Open-Source-Software Neko ist ein schlankes Werkzeug zur Virtualisierung von Browsern, Applikationen und Desktops unter Linux. Es erlaubt den Zugriff lokal oder über das Netzwerk. Neko kombiniert dazu Docker-Container mit dem Streaming über den offenen Standard WebRTC. Unser Artikel wirft einen Blick auf den technischen Unterbau und zeigt die Inbetriebnahme.
Isolierte, fernsteuerbare Browserumgebungen decken zahlreiche praktische Anwendungsfälle ab – sei es sicheres Surfen mit Fokus auf der Wahrung der Privatsphäre und Schutz vor Malware, Entwicklung und Tests von Webanwendungen mit verschiedenen Browsern oder auch die kollaborative Arbeit an Webseiten. Das Bundesamt für Sicherheit in der Informationstechnik (BSI) prägte bereits vor fast 20 Jahren den Begriff eines "Remote-Controlled Browsers Systems" (ReCoBS). Mit ihrem ursprünglichen Ansatz sahen die Sicherheitsexperten speziell gesicherte Terminalserver vor, umgeben von zusätzlichen Komponenten wie Firewalls und Sicherheitsgateways.
Doch Installation und Betrieb einer Terminalserver-Farm mit sicherem Zugriff sind aufwendig und benötigen Zeit sowie Ressourcen. Hier kommt nun das Open-Source-Projekt Neko ins Spiel, das Browser wie auch weitere Linux-Applikationen und -Desktops ressourcenschonend in Docker-Container verpackt und ihre grafische Benutzeroberfläche per Web Real-Time Communication (WebRTC) streamt [1]. Treibende Kraft hinter dem Projekt ist der Entwickler Miroslav Šedivý, der auch das zugehörige Repository auf der Plattform GitHub verwaltet [2].
Fertige Images für zahlreiche Browser
Neko (teilweise auch n.eko) positioniert sich für eine Vielzahl von Anwendungsfällen, allen voran das sichere Surfen in isolierten Umgebungen. Administratoren können Nutzern temporäre Browsersitzungen bereitstellen, ohne lokale Systeme zu gefährden. Im Regelfall sind diese Sessions nicht-persistent und beim Beenden des jeweiligen Containers lässt ein solcher Wegwerfbrowser keine persönlichen Daten zurück. Weitere Szenarien sind der gemeinsame Remotezugriff auf Webanwendungen für Schulungen oder Support sowie Kiosk- und Terminalbetrieb als abgesicherter Browser in öffentlichen oder eingeschränkten Umgebungen.
Isolierte, fernsteuerbare Browserumgebungen decken zahlreiche praktische Anwendungsfälle ab – sei es sicheres Surfen mit Fokus auf der Wahrung der Privatsphäre und Schutz vor Malware, Entwicklung und Tests von Webanwendungen mit verschiedenen Browsern oder auch die kollaborative Arbeit an Webseiten. Das Bundesamt für Sicherheit in der Informationstechnik (BSI) prägte bereits vor fast 20 Jahren den Begriff eines "Remote-Controlled Browsers Systems" (ReCoBS). Mit ihrem ursprünglichen Ansatz sahen die Sicherheitsexperten speziell gesicherte Terminalserver vor, umgeben von zusätzlichen Komponenten wie Firewalls und Sicherheitsgateways.
Doch Installation und Betrieb einer Terminalserver-Farm mit sicherem Zugriff sind aufwendig und benötigen Zeit sowie Ressourcen. Hier kommt nun das Open-Source-Projekt Neko ins Spiel, das Browser wie auch weitere Linux-Applikationen und -Desktops ressourcenschonend in Docker-Container verpackt und ihre grafische Benutzeroberfläche per Web Real-Time Communication (WebRTC) streamt [1]. Treibende Kraft hinter dem Projekt ist der Entwickler Miroslav Šedivý, der auch das zugehörige Repository auf der Plattform GitHub verwaltet [2].
Fertige Images für zahlreiche Browser
Neko (teilweise auch n.eko) positioniert sich für eine Vielzahl von Anwendungsfällen, allen voran das sichere Surfen in isolierten Umgebungen. Administratoren können Nutzern temporäre Browsersitzungen bereitstellen, ohne lokale Systeme zu gefährden. Im Regelfall sind diese Sessions nicht-persistent und beim Beenden des jeweiligen Containers lässt ein solcher Wegwerfbrowser keine persönlichen Daten zurück. Weitere Szenarien sind der gemeinsame Remotezugriff auf Webanwendungen für Schulungen oder Support sowie Kiosk- und Terminalbetrieb als abgesicherter Browser in öffentlichen oder eingeschränkten Umgebungen.
Entwickler können zudem manuell oder auch automatisiert Tests in realitätsnahen Browserumgebungen durchführen, ohne alle gewünschten Browser installieren zu müssen. Neben Mozilla Firefox und dessen Fork Waterfox bringt Neko fertige Docker-Images für den Tor-Browser, Chromium, Chrome mit und ohne Google-Integration, Microsoft Edge, Brave, Vivaldi sowie Opera mit. Weiterhin stehen der Mediaplayer VLC, der Remote-Desktop-Client Remmina wie auch die Desktopumgebungen Xfce und KDE Plasma bereit.
Die meisten Images sind nicht auf AMD-64-Architekturen beschränkt, sondern harmonieren auch mit ARM64-Prozessoren und sogar vergleichsweise leistungsschwachen 32-Bit-Systemen auf ARMv7-Basis, wie dem Raspberry Pi 3 oder dem Raspberry Pi Zero. Am anderen Ende des Leistungsspektrums können die AMD64-Images von Firefox, Chromium, Google Chrome, Microsoft Edge sowie Brave die Hardwarebeschleunigung einer Nvidia GPU nutzen.
Bewusst gesetzte Grenzen
Neko startet somit simpel und schnell virtuelle Browser, andere Applikationen oder Desktops, stellt aber keine ausgewachsene Umgebung für viele gleichzeitige Sitzungen im Sinne einer Terminalserver-Farm oder Virtual Desktop Infrastructure (VDI) dar. Insbesondere bringt Neko nur ein einfaches Berechtigungsmodell mit, das zwischen den Profilen von Admins und nicht privilegierten Nutzern unterscheidet.
Die Webseite des Projekts benennt zudem explizit, welche Ziele die Entwicklung nicht verfolgt. So möchte sich Neko nicht zu einem Dienst wandeln, der mehrere Arbeitsbereiche, Räume und Browser bedient – wenngleich ein zusätzliches Projekt genau dieses Vorhaben unterstützt, doch dazu im weiteren Verlauf mehr. Neko beschränkt sich weiterhin auf Linux als offiziell unterstützte Plattform.
Auch wenn WebRTC clientseitige Webcams und Mikrofone integriert, tritt die Software nicht primär für Voice-Chat, Videokonferenzen oder Screensharing an. Dafür verweist der Entwickler auf spezialisierte Dienste wie Discord, Jitsi und Screego. Auch optimiert Neko die Darstellung und Bedienung nicht für mobile Endgeräte, sondern unterstützt solche Clients nur nach dem Best-Effort-Prinzip.
Docker und WebRTC als Basis
Neko setzt auf eine einfache, aber effektive Architektur. Ein Docker-Container kapselt die gewünschte Applikation samt all ihrer Abhängigkeiten, ein integrierter WebRTC-Server streamt die grafische Oberfläche in Echtzeit an einen oder mehrere Clients. Anwender steuern die entfernte Anwendung per Maus und Tastatur über ihren lokalen Browser fern. Audio- und Videoübertragung sind dabei ebenfalls möglich. Die Kommunikation zwischen Client und Container läuft als direkte Peer-to-Peer-Verbindung über WebRTC.
Neko integriert dazu mit Pion [3]ein weiteres Open-Source-Projekt, eine Implementierung von WebRTC in der Programmiersprache Go. Bei WebRTC wiederum handelt es sich um einen offenen Standard an dessen Entwicklung Google im Rahmen eines anderen Open-Source-Projekts maßgeblich mitwirkt. Arbeitsgruppen des World Wide Web Consortium (W3C) und der Internet Engineering Task Force (IETF) kümmern sich um die Standardisierung.
Inzwischen unterstützen neben Google alle etablierten Browser von Apple, Microsoft wie auch Mozilla die auf HTML5 und JavaScript basierende Technologie [4]. Google nutzt die Technik etwa für die hauseigene Videokonferenzanwendung Google Meet sowie den Google Chrome Remote Desktop (CRD). Wer mehr über die Interna und Funktionsweise von WebRTC erfahren möchte, findet detaillierte Informationen auf den Webseiten der beiden Projekte sowie im ebenfalls frei verfügbaren Buch "WebRTC For The Curious" [5].
Mit oder ohne Vermittlungsserver
WebRTC ermöglicht die direkte Peer-to-Peer-Kommunikation zwischen Browsern sowie mobilen Anwendungen. Das Framework unterstützt Audio-, Video- und Datenübertragungen zwischen den Kommunikationspartnern. Doch bevor die Partner auf direktem Weg miteinander kommunizieren können, müssen sie im Rahmen des Internet Connectivity Establishment (ICE) erst zueinander finden.
Im einfachsten Modus "ICE Lite" ist ein Server mit den für WebRTC benötigten Ports unter einer öffentlichen IP-Adresse direkt erreichbar, serverseitig ohne NAT oder eine Firewall, die UDP blockiert. In komplexeren Netzwerktopologien, etwa beim Betrieb des Servers hinter NAT, Firewalls oder in heterogenen Netzen, kann die direkte Verbindung per "ICE Lite" scheitern. In solchen Fällen hilft der Modus "Full ICE". Die Kontaktaufnahme erfolgt dann über zusätzliche Server mittels "Session Traversal Utilities for NAT" (STUN) oder dessen Weiterentwicklung "Traversal Using Relay NAT" (TURN) mit dem Vorteil, dass entsprechende Verbindungen komplikationslos Grenzen von Netzwerken und Firewalls überwinden. Ein STUN-Server hilft dabei, die öffentliche IP-Adresse des Clients zu ermitteln, um eine direkte Verbindung zwischen dem Client und dem Server herzustellen. Ein TURN-Server fungiert als Relay, um Daten zwischen dem Client und dem Server weiterzuleiten, wenn eine direkte Verbindung nicht zustande kommt.
Neko kann öffentlich verfügbare STUN-Server von Google verwenden. Die Online-Dokumentation des Projekts beschreibt für komplexere Szenarien alternativ auch die Integration mit selbstgehosteten Servern auf Basis von Coturn [6], einem weiteren Open-Source-Projekt, das einen freien STUN- und TURN-Server implementiert. In unseren folgenden Beispielen bleiben wir im Modus "ICE Lite" und gehen davon aus, dass Clients die UDP-Ports des Servers direkt erreichen können, damit die Konfiguration nicht zu komplex gerät.
Testszenario mit Firefox
Für erste Gehversuche mit Neko benötigen Sie lediglich ein Linux-System mit der Container-Virtualisierung Docker. Wir nutzen im Rahmen dieses Workshops ein System unter Ubuntu 24.04.2 LTS, auf dem wir die Software entsprechend der offiziellen Dokumentation von Docker installiert und unseren Benutzer zur Ausführung von Docker-Befehlen berechtigt haben. Erstellen Sie nun ein Verzeichnis mit optionalem Unterverzeichnis und erzeugen Sie darin eine Konfiguration für Docker Compose:
mkdir -p neko/profile
cd neko
nano docker-compose.yml
Im Editor fügen Sie nun eine Konfiguration wie im Listing-Kasten ein. Diese definiert einen Service für Neko, der das aktuelle Image für Firefox startet. Alle Neko-Images stellt der Entwickler über die GitHub-Container-Registry bereit. Entsprechend lautet etwa der Pfad für Chromium "ghcr.io / m1k1o / neko / chromium:latest".
Für das Webinterface von Neko kommt der TCP-Port 8080 zum Einsatz, für WebRTC der Bereich der UDP-Ports von 52.000 bis 52.100. Das optionale Volume verbindet einen lokalen Pfad mit dem Profil-Pfad des Browsers im Container und ermöglicht so das persistente Speichern von Browserdaten. Sie können auf diesen Eintrag und das entsprechende Unterverzeichnis verzichten, wenn Sie lediglich einen Wegwerfbrowser wünschen, der mit jedem Neustart des Containers sämtliche Informationen vergisst.
Die Environment-Variablen legen die Auflösung und Frame-Rate für die grafische Oberfläche der Anwendung fest, weiterhin komplexe Passwörter für Benutzer und Admins, auf deren Funktion wir gleich zurückkommen – ersetzen Sie diese durch Passwörter Ihrer Wahl. Die weiteren Variablen definieren den Portbereich für WebRTC, der mit dem oben genannten UDP-Ports übereinstimmen muss und aktivieren ICE Lite.
Zu guter Letzt nimmt die Variable "NAT1TO1" die IP-Adresse ihres Servers im lokalen Netz auf. Auch diese Variable ist optional und Sie benötigen die Zeile nur, wenn Ihre Clients direkt im Netz des Servers oder per VPN verbunden auf Neko zugreifen sollen. Auch ein komplett lokaler Zugriff mit dem Clientbrowser und Neko auf ein und derselben Maschine damit ist möglich. Tragen Sie in diesem Fall einfach die lokale Loopback-Adresse "127.0.0.1" ein. Speichern Sie die Konfiguration und starten Sie den Container mittels
docker compose up -d
Docker lädt das Neko-Image für Firefox herunter und erzeugt den Container, der anschließend auf dem TCP-Port 8080 sein Webinterface anbietet. Nun können Sie per Browser unter "http://<IP-Adresse-des-Servers>:8080" darauf zugreifen. Neko präsentiert Ihnen das Webinterface mit dem Login, an dem Sie sich nun wahlweise mit dem Admin- oder Benutzerpasswort aus Ihrer Konfigurationsdatei anmelden.
Session konfigurieren und nutzen
Mit dem Multi-User Provider, den Neko standardmäßig zur Authentifizierung verwendet, unterscheidet der Container keine namentlich benannten Benutzer, sondern erzeugt Benutzer und ihre Sitzungen dynamisch. Sie können in der Loginmaske jeden beliebigen Namen eingeben und sich damit anmelden, solange nur das Passwort stimmt. Nach dem Passwort richtet sich, welches Profil Ihr Benutzer erhält (Administrator oder regulärer Benutzer ohne erweiterte Berechtigungen). Basierend auf diesen Profilen generiert Neko die Benutzer bei der Anmeldung auf Abruf und löscht sie bei der Abmeldung auch wieder. Intern stellt der Container jedem Benutzernamen fünf zufällige Zeichen voran, um Konflikte zu vermeiden, wenn mehrere Anwender dieselben Credentials verwenden.
Nach der Anmeldung sehen Sie den im Container laufenden Browser eingebettet in die Neko-Benutzeroberfläche. Mit dem Tastatursymbol am unteren Rand des Fensters können Sie die Kontrolle übernehmen und den Browser fernsteuern, weiterhin die Lautstärke einer aus der Sitzung übertragenen Tonspur regulieren. Der Menübutton oben rechts auf der Seite blendet eine Seitenleiste mit dem Chat und weiteren Einstellungen ein. Darüber konfigurieren Sie die Sitzung, etwa die Scroll-Empfindlichkeit oder das Tastaturlayout innerhalb der Sitzung. Zudem haben Sie die Option, den Inhalt der Sitzung auch als Liveübertragung per Real Time Messaging Protocol (RTMP) auf Plattformen wie YouTube oder Twitch zu streamen.
Auch ohne einen Livestream sehen alle gleichzeitig am Container angemeldeten Benutzer in Echtzeit den Bildschirminhalt. Die User können wechselseitig die Steuerung übernehmen: Doch nur Admins dürfen die Steuerung erzwingen oder blockieren, generell den Login verhindern, andere Benutzer aus der Sitzung herauswerfen sowie deren IP-Adresse sperren (Bild 1).
Bild 1: Neko streamt einen Browser und andere Linux-Applikationen und -Desktops per WebRTC.
Über den Chat in der Seitenleiste kommunizieren die Benutzer miteinander. Es handelt sich hierbei aber nur um eine grundlegende Funktion, über die alle mit allen kommunizieren. Die Anwender sind nicht in der Lage, sich gegenseitig mit @-Erwähnungen gezielt anzusprechen oder private Chats zu starten. Sie können sich aber nach Belieben anmelden, wieder abmelden und mit demselben oder einem anderen Benutzernamen erneut anmelden. Die Browsersitzung existiert so lange weiter, wie der Container läuft. Dank des persistenten Volumes bleiben Einstellungen im Benutzerprofil des Browsers auch über einen Neustart des Containers hinweg erhalten.
Als Alternativen zum Multi-User-Provider unterstützt Neko auch File-Provider und Object-Provider. Ersterer liest die Benutzer und ihre Passwörter aus einer JSON-Datei, Letzterer speichert die User nur im Arbeitsspeicher. In diesen Fällen können Sie die Anwender, die sich anmelden dürfen, namentlich benennen und ihre Berechtigungen festlegen. Der Unterschied zum Multi-User-Anbieter besteht darin, dass Neko die Benutzer nicht bei Bedarf generiert und Sie genau festlegen können, welche davon sich mit ihren Passwörtern und Profilen anmelden dürfen. Es ist dabei nicht mehr möglich, sich zweimal mit demselben Benutzernamen parallel anzumelden [7].
Absichern per Reverse-Proxy
Da Neko sein Webinterface ohne Weiteres unverschlüsselt per HTTP bereitstellt, verbietet es sich, den TCP-Port 8080 im Internet zu veröffentlichen. Neben der Absicherung per VPN oder SSH-Tunnel beschreibt die Dokumentation die Integration mit den Reverse-Proxy-Diensten Traefik, Nginx, Apache, HAProxy sowie Caddy. Wir verwenden exemplarisch Letzteren, da Caddy sehr schnell eingerichtet ist und sich automatisch um ein TLS-Zertifikat kümmert. Zunächst entfernen Sie die letzte Zeile mit der Variable "NAT1TO1" aus der Konfiguration für Neko und tragen stattdessen dort "NEKO_SERVER_PROXY: true" ein. Dies sorgt dafür, dass Neko den von einem Proxy übertragenen Headern "X-Forwarded-For" und "X-Real-IP" vertraut. Starten Sie nun den Container neu:
docker compose down
docker compose up -d
Anschließend wechseln Sie im Dateisystem eine Ebene höher, erstellen ein Verzeichnis für Caddy und legen auch darin eine YAML-Datei für Docker Compose an. Dabei können Sie ohne Anpassungen die Konfiguration aus der Online-Dokumentation übernehmen [8]:
mkdir -p caddy/conf
cd caddy
nano docker-compose.yaml
Im Unterverzeichnis erstellen Sie schließlich eine einfache Konfiguration für den Proxy in der Datei "Caddyfile":
cd conf
nano Caddyfile
und füllen diese mit Inhalt:
https://neko.example.com {
reverse_proxy localhost:8080
}
Ersetzen Sie dabei den Hostnamen durch den DNS-Namen Ihres Servers, erlauben Sie den Zugriff auf den Server von extern über die TCP-Ports 80 sowie 443 und starten Sie dann den Container:
cd ..
docker compose up -d
Caddy startet nun im Hintergrund und versorgt sich automatisch mit einem auf den DNS-Namen Ihres Servers ausgestellten TLS-Zertifikat der Zertifizierungsstelle Let’s Encrypt. Dann veröffentlicht es das Webinterface von Neko per HTTPS gesichert, sodass Sie von extern ohne den Umweg über den ungesicherten TCP-Port 8080 darauf zugreifen können. Die Bereitstellung von Browsern, Apps oder Desktops gelingt so bereits mit geringem Aufwand.
Nachteilig ist allerdings, dass Neko ohne Weiteres nur einen Container mit einem Image bereitstellt. Möchten Sie einen anderen Browser veröffentlichen, gelingt das nur, indem Sie per Shell oder mithilfe eines grafischen Werkzeugs wie Portainer den laufenden Container stoppen und einen neuen mit einem anderen Image starten. Wenn Sie im Rahmen der Entwicklung von Webanwendungen schnell mit verschiedenen Browsern testen möchten, fehlt es hier an Flexibilität. Doch der Entwickler von Neko sorgt mit seinem separaten Projekt "Neko Rooms" [9], das ebenfalls auf GitHub bereitsteht, für Abhilfe.
Parallele Instanzen mit Neko Rooms
Neko Rooms schaltet ein zusätzliches Webinterface vor, mit dem Sie mehrere Instanzen von Neko auf ein und demselben Docker-Host parallel veröffentlichen. Und das Beste daran ist, dass Sie im Repository des Projekts ein Installationsskript finden, das eine komplette Umgebung weitestgehend ohne manuelles Zutun erzeugt.
Das Skript kümmert sich um alles und installiert sogar Docker, falls die Container-Virtualisierung noch nicht auf dem Host vorhanden sein sollte. Um dies nachzuvollziehen, stoppen Sie die bisher genutzten Container von Neko und Caddy oder starten Sie mit einem frischen Linux-System. Nun erzeugen Sie ein neues Verzeichnis und führen darin die Kommandos zur Installation von Neko Rooms aus:
Anders als unser vorheriger Versuchsaufbau nutzt das Skript den Reverse-Proxy Traefik, um dessen Konfiguration Sie sich aber nicht sorgen müssen. Auch in diesem Fall muss der Host aber über einen öffentlichen DNS-Namen verfügen und über die TCP-Ports 80 sowie 443 erreichbar sein, da das Skript Traefik automatisch mit einem Zertifikat von Let’s Encrypt versorgt.
Standardmäßig verwendet die Installation für WebRTC die UPD-Ports im Bereich von 59.000 bis 59.100, die ebenfalls offen sein müssen. Sie können im Rahmen der Installation aber auch einen anderen Bereich festlegen. Weiterhin erfragt das Skript den DNS-Namen Ihres Hosts sowie eine E-Mail-Adresse zum Bezug des Zertifikats. Sie haben die Option, einen oder mehrere Benutzer nebst Passwörtern zum Zugriff auf das Webinterface festzulegen. Um alles Weitere kümmert sich das Skript und startet passend konfigurierte Docker-Container für Traefik und Neko Rooms. Anschließend melden Sie sich als einer der benannten Benutzer am Frontend an.
Bis zum Redaktionsschluss war Neko Rooms noch nicht in der Lage, benötigte Docker-Images automatisch herunterzuladen. Sie müssen daher im ersten Schritt mittels der Schaltfläche "Pull Neko Images" die Abbilder der Browser und Apps, die Sie bereitstellen möchten, manuell herunterladen.
Bild 2: Mit Neko Rooms lässt sich eine Neko-Instanz grafisch und ohne Editieren von YAML-Dateien konfigurieren.
Neko grafisch konfigurieren
Nun starten Sie über die Schaltflächen oben rechts ein oder mehrere Neko-Instanzen. Die Schaltfläche "Quick Room" erzeugt aus einem wählbaren Image eine Instanz mit zufälligem Namen und Standardeinstellungen. Mittels "Add Room" richten Sie viele der Einstellungen für den Container grafisch ein (Bild 2). Beim ersten Aufruf meldet sich Neko Rooms mit einer Warnmeldung, da Storage zum persistenten Speichern fehlt. Wie Sie Storage nachrüsten, beschreibt die Dokumentation von Neko Rooms [10]. Zunächst stoppen Sie die Container-Instanzen und editieren die ENV-Datei:
docker compose down
nano .env
Zuunterst fügen Sie dieser Datei die Variablen für Ihren Storage hinzu:
NEKO_ROOMS_STORAGE_ENABLED=true
NEKO_ROOMS_STORAGE_INTERNAL=/data
NEKO_ROOMS_STORAGE_EXTERNAL=/opt/ neko-rooms/data
Nun ergänzen Sie in der docker-compose.yml-Datei für Neko Rooms noch ein Volume mit ebendiesem Pfad und starten die Umgebung wieder mit docker compose up -d. Anschließend sind Sie in der Lage, aus verschiedenen Images parallel mehrere Neko-Instanzen mit persistenter Konfiguration zu erzeugen (Bild 3). Das Webinterface liefert die Links zu den Instanzen, die Sie alle gleichermaßen per HTTPS erreichen.
Bild 3: Neko Rooms startet mehrere Instanzen von Neko parallel auf ein und demselben Docker-Host.
Fazit
Neko stellt einen flexiblen Ansatz dar, um virtuelle Browser, weitere Applikationen und auch Desktops online bereitzustellen. Die Kombination aus Docker und Web-RTC ermöglicht eine einfache Provisionierung und Nutzung über das Web. Administratoren profitieren von der Modu- larität und Offenheit der Software, insbesondere in Verbindung mit Neko Rooms, die die Verwaltung der Container signifikant vereinfachen und mehrere Instanzen parallel erlauben.