Maximaler Datenschutz: Windows hinter einem Proxy betreiben

Begonnen von Bit, 06.06.2024, 00:05

Vorheriges Thema - Nächstes Thema

Bit

Mit freundlicher Genehmigung des Autors, Nobody:

Häufig trifft man auf Fragen wie "Wie bekommt man Windows-Systeme datenschutzfreundlich?". Empfohlen werden dann meistens diverse Software-"Lösungen" eines Drittanbieters, Blocklisten für Pi-hole o.ä. oder irgendwelche Konfigurationen, die man wie eine Art Checkliste abarbeiten soll, empfohlen.

Dabei hängen all diese ,,Lösungen" aus Prinzip der Realität immer etwas hinterher und mit Bordmitteln lässt sich das sowieso nicht vollständig, zuverlässig und dauerhaft abstellen. Problematisch ist dabei auch, dass die Software eines Drittanbieters an einem System immer mehr ,,verstellen" kann als man möchte oder Dinge sogar ,,kaputt gemacht" werden können. Die Erfahrung hat gezeigt, dass sich nach einem Systemupdate Dinge anders verhalten können oder neue ggf. privatsphärerelevante Sachen dazu gekommen sind. ,,Klemmt" es dann mal irgendwo, dauert die Fehlersuche unter Umständen sogar länger als mit einem ,,08/15-Standard-System". Betrachtet man diese ,,Lösungen" nüchtern, ist das alles nur ein Katz-und-Maus-Spiel. Hat sich beispielsweise eine URL zum Versenden von z.B. Telemetriedaten geändert und fehlt diese neue URL auf einer Blockliste, könnten möglicherweise alle zuvor gesammelten Daten in einem Rutsch übertragen werden.

Wenn das Windows-System einen begrenzten Einsatzzweck hat, dann lässt sich das Problem viel einfacher und vor allem dauerhaft und zuverlässig lösen. In meinem Fall benötige ich die Windows-VM nur ein paar mal im Jahr für die Steuersoftware und weitere (Offline-)Anwendungen. Die notwendigen externen Endpunkte lassen sich an einer Hand abzählen und der Ansatz mit einem vorgeschalteten Proxy ist einfach perfekt. Alle Endpunkte, die nicht explizit erlaubt sind, werden vom Proxy blockiert. Updates werden von mir praktisch nicht benötigt und falls doch, lässt sich das ggf. mit ,,WSUS Offline Update" bewerkstelligen.


Für Docker-User
Diejenigen die bereits Docker verwenden, können sich auch mal dieses Projekt auf GitHub ansehen: Windows inside a Docker container. Zusammen mit einem Squid-Proxy-Container sollte sich das Windows-System ebenfalls gut einschränken/kontrollieren können. Das hab ich bisher noch nicht verwendet, da die "KVM-Variante" bei mir schon länger läuft und es bisher keinen Grund gab daran etwas zu ändern.

Ich nutze hierfür meinen Heimserver, der sowieso 24/7 läuft und sich aber auch hardwareseitig dafür bestens eignet. Der Zugriff auf die Windows-VM kann über RDP, VNC oder direkt über den Virtual Machine Manager erfolgen. Alternativ gingen natürlich auch Tools wie Guacamole von Apache, um die Windows-VM über den Browser zu bedienen - optional mit 2FA (TOTP).

Das sind die verwendenten Geräte und ihre IP-Adressen:

Router*     192.168.178.1
Linux-VM    192.168.178.70
            10.7.0.10
Windows-VM  10.7.0.2

*) Das nächste Gateway ist in der Regel der Router (z.B. FRITZ!Box), kann aber auch eine Hardware-Firewall sein, falls der Server in einer DMZ betrieben wird.

1. Übersicht

• Am Server/Host läuft Debian Stable in der Minimal-Konfiguration.
• Virtualisierung: In den folgenden Abschnitten wird QEMU/KVM genutzt, aber grundsätzlich sollte das Konzept auch mit jeder anderen Virtualisierungssoftware umsetzbar sein. War Virtualisierung bisher noch kein Thema, dann entsprechend einrichten ( -> Suchmaschine).
• Benötigt werden zwei VMs:
  ∘ 1x Linux-VM mit Squid-Proxy
    • Die VM bekommt zwei Netzwerkschnittstellen. Eine davon hängt im gemeinsamen Netz mit der Windows-VM und die andere im ,,normalen" Netzwerk.
  ∘ 1x Windows-VM
    • Die VM bekommt nur eine Netzwerkschnittstelle.

2. Aufbau

2.1. Virtuelles Netzwerk erstellen

Über den Virtual Machine Manager lässt sich ein virtuelles internes Netz sehr einfach erstellen. Rechtsklick auf den verbundenen Endpunkt (bspw. das lokales Gerät oder ein entfernter Server) und anschließend ,,Details" auswählen. Im nachfolgenden Fenster auf ,,Virtuelles Netzwerk" und über das ,,Plus-Zeichen" eine neue Verbindung anlegen. In dem neuen Dialog folgende Werte setzen:

Screenshot

• Modus: Isoliert
• IPv4: aktivieren
  ∘ Netzwerk: 10.7.0.0./24
  ∘ DHCPv4: deaktiviert
• IPv6: deaktiviert

2.2. Linux-VM erstellen

Ich verwende für solch minimalistischen Anwendungsfälle gerne Alpine Linux, allerdings lässt sich das Konzept auch mit nahezu allen anderen Linux Distributionen umsetzen. Alpine Linux ist noch ein ticken performanter als andere Distributionen, da es unfassbar schlank ist und für diese Anforderungen bestens geeignet.

• Meine VM ist zwar mit einem 500 MB Datenträger ,,ausgestattet", aber für die Root-Partition werden aktuell bei mir nur etwas mehr als 60 MB benötigt - inkl. Squid-Proxy, SSH-Server und ein paar anderen Tools wie htop
• Eine vCPU und 512 MB RAM sind mehr als ausreichend. Im Leerlauf benötigt Alpine Linux ca. 70 MB RAM.
• Netzwerk
  ∘ Reihenfolge beachten (Erklärung kommt unter ,,3.1.2. Netzwerkschnittstellen einrichten")
    1. Externes Netz: Die Netzwerkschnittstelle des Host-Systems (wird vermutlich eine Netzwerkbrücke wie bspw. br0 sein)
    2. Isoliertes Netz: Das virtuelle Netzwerk (z.B. vnet1) aus dem ersten Schritt übernehmen/einsetzen.

2.3. Windows-VM erstellen

• CPU, RAM, HDD -> Hier gilt ,,Klotzen statt kleckern"!
  ∘ Hier sollte man nicht sparen. Die Windows-VM wird ein vielfaches mehr an Rechenleistung brauchen, damit eine vernünftige Bedienung möglich ist. Lieber nicht einfach nur an den Mindestanforderungen orientieren, sondern am Anfang eher zu viel zur Verfügung stellen als zu wenig - insbesondere für die Installation und Einrichtung. Prozessor und Arbeitsspeicher lassen sich im Nachhinein sehr leicht reduzieren.
• Netzwerk:
  ∘ Isoliertes Netz: Das virtuelle Netzwerk (z.B. vnet1) aus dem ersten Schritt übernehmen/einsetzen.
• Optional: Man könnte an dieser Stelle auch einen zusätzlichen Datenträger einrichten, um bspw. Daten auszulagern.

3. Einrichtung

3.1. Linux-VM

3.1.1. Installation

Wer bisher noch keine Erfahrungen mit Alpine Linux gemacht hat, könnte zunächst Schwierigkeiten haben: Vieles ist etwas anders als bei anderen Distributionen. Ein Blick über den Tellerrand lohnt sich jedoch immer.

Für Alpine Linux gibt es die spezielle Variante ,,Virtual"

ZitatSimilar to standard. Slimmed down kernel. Optimized for virtual systems.

Hat man den kleinen Installationsdatenträger mit seinen etwas weniger als 50 MB heruntergeladen, erfolgt die Installation immer nach dem selben Schema:

• ISO-Datei herunterladen, mounten, ggf. Boot-Reihenfolge anpassen und von CD starten.
• Anweisungen folgen.

Der textbasierte Installer leitet einen durch die Installation. Standardmäßig wird in Alpine Linux (auch während der Installation) der Editor vi genutzt. Wer damit noch keine Erfahrung hat, sollte sich unbedingt in den wichtigsten Kommandos zur Bedienung einlesen, denn andere Editoren (z.B. nano) kann man erst installieren, wenn die Netzwerkverbindung steht ;)

Editor - VIM (wiki.ubuntuusers.de)
Vi Editor Tipps und Tricks (www.thomas-krenn.com).

3.1.2. Netzwerkschnittstellen einrichten

Welche Schnittstelle als eth0 und welche als eth1 erkannt wird, hängt im Grunde von der Reihenfolge ab, in der sie in KVM hinzugefügt wurden bzw. an der dadurch automatischen Nummerierung bei bus="0x08" (XML-Ansicht im virt-manager). Alternativ kann man sich auch an der MAC-Adresse orientieren (ip a).

Screenshot

In der Datei /etc/network/interfaces lassen sich beide Netzwerkschnittstellen definieren:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
        address 192.168.178.70
        netmask 255.255.255.0
        gateway 192.168.178.1
        pre-up sysctl -w net.ipv6.conf.eth0.disable_ipv6=1

# isoliertes netz
auto eth1
iface eth1 inet static
      address 10.7.0.10
      netmask 255.255.255.0
      pre-up sysctl -w net.ipv6.conf.eth1.disable_ipv6=1
      post-up route add default gw 192.168.178.1

Hat man die Netzwerkkonfiguration im Installer übersprungen, fehlt noch ein DNS Server in /etc/resolv.conf

nameserver 192.168.178.1
Nachdem das Netzwerk manuell eingerichtet wurde, müssen die beiden Netzwerkschnittstellen neu gestartet werden:

/etc/init.d/networking restart
3.1.3. squid installieren, konfigurieren und aktivieren

Die Installation des Squid-Proxy erfolgt einfach über den Paketmanager:

apk add squid
# ggf. weiteren Editor wie z.B. nano installieren

In /etc/squid/squid.conf befindet sich anschließend eine Squid Standard-Konfiguration. Dort fügt man direkt nach

# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
nun die Domains ein, die erlaubt sein sollen (eine vollständige Konfiguration befindet sich am Ende). Die Domains werden zuerst einer ACL (Access Control List) hinzugefügt und anschließenden eine Regel für diese ACL angelegt.

Hier ein Beispiel mit einer kurzen Erklärung:

acl erlaubte_domains dstdomain mycloud.example.com
# Alternativ:
# acl erlaubte_domains dstdomain .example.com

acl = Anweisung zur Definition einer Access Control List
erlaubte_domains = Name der ACL
dstdomain = ACL-Typ (Destination Domain)
mycloud.example.com = Domain. Ein vorangestellter Punkt bedeutet, dass sowohl die Domain selbst als auch alle Subdomains erlaubt sind. Der Eintrag .example.com erlaubt also Zugriffe zu

  ∘ example.com
  ∘ www.example.com
  ∘ mail.example.com
  ∘ ...

http_access allow erlaubte_domains
http_access = Anweisung um den Zugriff basierend auf ACLs zu kontrollieren.
allow = Zugriff erlauben, wenn nachfolgende Bedingungen erfüllt sind.
erlaubte_domains = Name der ACL

Vollständiges Beispiel für eine squid.conf
In dieser Konfiguration sind bereits ein paar Domains hinterlegt:

• Eigene Nextcloud:
  ∘ mycloud.example.com
• Steuersoftware/Finanzamt (inkl. aller Subdomains):
  ∘ .buhl.de
  ∘ .buhl-data.com
  ∘ .elster.de
• Firefox interner Updater (inkl. aller Subdomains)
  ∘ .download-installer.cdn.mozilla.net

Diese Liste lässt sich natürlich beliebig erweitern.

# Recommended minimum configuration:
#

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 0.0.0.1-0.255.255.255  # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8    # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10      # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16    # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12      # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16    # RFC 1918 local private network (LAN)
acl localnet src fc00::/7          # RFC 4193 local private network range
acl localnet src fe80::/10          # RFC 4291 link-local (directly plugged) machines

acl SSL_ports port 443
acl Safe_ports port 80      # http
acl Safe_ports port 21      # ftp
acl Safe_ports port 443    # https
acl Safe_ports port 70      # gopher
acl Safe_ports port 210    # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280    # http-mgmt
acl Safe_ports port 488    # gss-http
acl Safe_ports port 591    # filemaker
acl Safe_ports port 777    # multiling http

#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports

# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports

# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager

# This default configuration only allows localhost requests because a more
# permissive Squid installation could introduce new attack vectors into the
# network by proxying external TCP connections to unprotected services.
http_access allow localhost

# The two deny rules below are unnecessary in this default configuration
# because they are followed by a "deny all" rule. However, they may become
# critically important when you start allowing external requests below them.

# Protect web applications running on the same server as Squid. They often
# assume that only local users can access them at "localhost" ports.
http_access deny to_localhost

# Protect cloud servers that provide local users with sensitive info about
# their server via certain well-known link-local (a.k.a. APIPA) addresses.
http_access deny to_linklocal

#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#

acl erlaubte_domains dstdomain mycloud.example.com
acl erlaubte_domains dstdomain .buhl.de
acl erlaubte_domains dstdomain .elster.de
acl erlaubte_domains dstdomain .buhl-data.com
acl erlaubte_domains dstdomain .download-installer.cdn.mozilla.net

http_access allow erlaubte_domains

# For example, to allow access from your local networks, you may uncomment the
# following rule (and/or add rules that match your definition of "local"):
# http_access allow localnet

# And finally deny all other access to this proxy
http_access deny all

# Squid normally listens to port 3128
http_port 3128

# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /var/cache/squid 100 16 256

# Leave coredumps in the first cache dir
coredump_dir /var/cache/squid

#
# Add any of your own refresh_pattern entries above these.
#
refresh_pattern ^ftp:      1440    20% 10080
refresh_pattern ^gopher:    1440    0%  1440
refresh_pattern -i (/cgi-bin/|?) 0 0%  0
refresh_pattern .      0  20% 4320

Damit ist die Squid Konfiguration auch schon abgeschlossen. Wir müssen nun nur noch den Dienst aktivieren, damit dieser mit jedem Systemstart automatisch gestartet wird und ihn einmalig manuell starten:

rc-update add squid default
service squid start

3.1.4. Zusatzsoftware

An der Stelle könnte man noch weitere Dienste installieren. Vorstellbar wäre z.B. ein SMB-Share, welches sich die Linux-VM (oder der Host) und die Windows-VM teilen, damit ein unkomplizierter Datenaustausch möglich ist. In meinem Fall ist das nicht eingerichtet, da ich der Windows-VM einen separaten Zugang zu meiner Nextcloud spendiert habe und den offiziellen Nextcloud-Client für die Synchronisation verwende.

3.2. Windows-VM

3.2.1 Installationsdatenträger

Die Installation erfolgt mit der offiziellen ISO (z.B. Windows 10)

3.2.2. Netzwerk einrichten

Screenshot

• Einstellungen -> Netzwerk und Internet
• Ethernet -> Netzwerkadapter auswählen
• IP-Einstellungen -> Bearbeiten
• Manuell
  ∘ IPv4: aktiviert
  ∘ IP-Adresse: 10.7.0.2
  ∘ Gateway: 10.7.0.10
  ∘ DNS: 10.7.0.10
  ∘ IPv6: deaktiviert

3.2.3. Proxy im System hinterlegen

Screenshot

• Einstellungen -> Netzwerk und Internet
• Ethernet -> Proxy -> Manuelle Proxyeinrichtung
• Proxyserver verwenden: aktiviert
• Adresse: 10.7.0.10
• Port: 3128

3.2.4. ggf. Zusatzsoftware installieren

Normalerweise erkennt eine Zusatzsoftware den im System hinterlegten Proxy automatisch. Falls nicht, lässt sich das recht einfach innerhalb der Anwendung festlegen.

Beispiel Firefox:
• Einstellungen -> Verbindungs-Einstellungen -> Einstellungen
• Proxy-Einstellungen des Systems verwenden: ausgewählt

3.3. Routing

Abhängig davon wie das Netzwerk aufgebaut ist und wie man auf die Windows-VM zugreifen möchte, sind ggf. statische Routen notwendig.

Verwendet man ausschließlich den ,,Virtual Machine Manager", um auf die Windows-VM zugreifen zu wollen, dann benötigt man keine statische Route.

Möchte man bspw. auf die Windows-VM über RDP oder VNC zugreifen, müssen die Clients wissen, dass sie das Netz 10.7.0.0/24 über 192.168.178.70 (Linux-VM) erreichen. Dazu muss am nächsten Gateway (Router/Hardware-Firewall) oder am Client selbst eine statische Route angelegt werden. Als Beispiel hier die Schritte an einer FRITZ!Box:

• Heimnetz -> Netzwerk -> Netzwerkeinstellungen
• ,,Weitere Einstellungen"
• Punkt ,,Tabelle für statische Routen" -> Button ,,IPv4-Routen"

Dort müssen folgende Daten eingetragen werden:
• IPv4-Netzwerk: 10.7.0.0
• Subnetzmaske: 255.255.255.0
• Gateway: 192.168.178.70
• IPv4-Route aktiv: aktiviert

Wird eine statische Route im Router angelegt, gilt sie für alle daran angeschlossenen Geräte. Alternativ kann man eine statische Route nur für einen einzelnen Client anlegen - dann weiß nur dieser Client, dass das Netz 10.7.0.0/24 über 192.168.178.70 (Linux-VM) erreichbar ist.

4. Abschluss

Geschafft 🥳 Die Windows-VM befindet sich nun in einem vollständig isolierten und kontrollierten Netz. Die externe Kommunikation ist nur über die im Squid-Proxy hinterlegten Endpunkte möglich. Am System selbst wurde (abgesehen von der Netzwerkkonfiguration) nichts verändert und befindet sich somit im Auslieferungszustand. Beste Voraussetzungen für alle weiteren Anwendungen.

Sollten im Laufe der Zeit weitere Endpunkte notwendig werden, lassen sich diese einfach in der Squid-Proxy-Konfiguration hinzufügen. Nach einem Neustart mit service squid restart ist dann auch der neue Endpunkt erreichbar.

Benötigt eine bestimmte Anwendung weitere Endpunkte, hilft meist ein kurzer Blick in das Logfile. Die Logdateien von Squid befindet sich hier:

/var/log/squid/access.log
Falls dort zu viele Einträge vorhanden sind oder eine zweifelsfreie Zuordnung nicht möglich ist, hilft ggf. die Suchmaschine weiter. Viele Hersteller dokumentieren die notwendigen Endpunkte.

Hinweis: Auch wenn Windows keinen Endpunkt erreichen kann, wird es die Squid-Proxy Logs permanten mit Einträgen füllen. Hilfreich ist in diesem Fall das Tool logrotate.

Fazit

Es ist gar nicht so schwer ein Windows-System bezüglich Privatsphäre sicher einzurichten und zu betreiben. Um maximalen Datenschutz zu erreichen ist man nun unabhängig von Drittanbietersoftware, Blocklisten oder den Systemeinstellungen und kann sich absolut sicher sein, dass nur die Endpunkte kontaktiert werden können, die vorher explizit definiert wurden. Anstatt sich regelmäßig mit diesem Thema zu beschäftigen, betreibt man den Aufwand nur einmalig und muss sich zukünftig keine Sorgen machen. Mit ,,WSUS Offline Update" lässt sich das System bei Bedarf aktualisieren. Ob Systemupdates überhaupt notwendig sind, hängt im wesentlichen vom konkreten Anwendungsfall bzw. den genutzten Anwendungen ab. Grundsätzlich lassen sich damit auch alle anderen Systeme (7, Vista, XP, ...) isolieren.

Wird die Windows-VM nur selten benutzt, kann man diese nach der Nutzung einfach herunterfahren oder den Zustand sichern, um bspw. Ressourcen für andere Anwendungen freizugeben. Die Linux-VM kann man bei dem geringen Ressourcenverbrauch problemlos permanent laufen lassen.