Squid-Proxy auf WSL mit Kerberos

Viele Firmen schützen ihr Netzwerk mittels HTTP-Proxy und sehr oft ist ein SQUID der Kern aktiv, selbst wenn Sie glauben eine Appliance oder andere Produkt gekauft zu haben. Aber auch als Windows Admin sollten und können sie mit Squid Probleme analysieren und lösen. Seit es das "Windows Subsystem für Linux" gibt, geht das noch deutlich einfacher.

Achtung: WSL ist kein "Server", der im Hintergrund automatisch gestartet wird und durchläuft, sondern wird in einigen Fällen beendet, z.B. wenn sich der Anwender abmeldet u.a.

Warum?

"Heute braucht man keinen Proxy mehr" bekomme ich oft gesagt. Das mag sein, dass Bandbreite oft geführt genug da ist und Cloud-Dienste eh alles verschlüsseln. Aber ich habe mich mit Squid aus folgenden Gründen beschäftigt:

  • Meine Kunden haben Squid und fragen mich
    Da ist es immer gut das System zumindest etwas zu kennen und verstanden zu haben. Insbesondere wenn es um Optimierung geht.
  • Analysen
    Natürlich nutze ich auch "Fiddler" und andere Tools, um HTTP-Verbindungen zu überwachen. Aber was mache ich mit Systemen ohne Windows, z.B. NAS-Boxen, Router, WLAN AccessPoints, IoT Geräte? Über einen Proxy kann ich zumindest die CONNECT-Anfragen sehen und steuern.
  • Authentifizierung
    Ein Proxy, welche die Anwender nach Zugangsdaten fragt, ist keine gute Idee. Am besten akzeptiert der Proxy ein Kerberos-Ticket. Notfalls kann auch NTLM helfen.
  • Office 365/Microsoft 365 Freischaltungen
    Mit dem Squid kann ich auch gut zeigen und testen, wie man bestimmte URLs ohne Authentifizierung erlaubt.

Squid gibt es zwar auch für Windows (Cygwin oder native) aber müssen sie entweder selbst kompilieren oder zukaufen und sind dann doch immer versionstechnisch nicht immer aktuell. Die Installation auf Linux und insbesondere dem "Windows Subsystem für Linux" ist gar nicht mal schwer und etwas Linux-Kenntnisse schaden auch nicht.

Squid auf WSL installieren

Die Einrichtung ist denkbar einfach, wenn Sie WSL2 schon installiert haben. Ansonsten ist es bei Microsoft gut dokumentiert:

Es hindert sie natürlich niemand daran, eine vollwertigen Linux-Host (Physik/virtuell) oder als Docker-Container zu installieren.

Ich habe dazu WSL2 und die aktuelle Ubuntu Version genutzt und dann einfach folgendes eingegeben. Kommentare bitte weglassen.

# Was Windows Updates in der Microsoft Welt ist, ist "apt update" und "apt upgrade" in der Unix-Welt
$ sudo apt update
$ sudo apt upgrade

# net-tools sind erforderlich um z.B. mit IFCONFIG meine IP-Adresse zu erhalten.
$ sudo apt install net-tools
# eigene Adresse ermitteln
$ ifconfig

# Installation von squid
$ sudo apt install squid -y

# Controlle, ob sich Squid automatisch startet
$ sudo systemctl is-enabled squid

# Anzeige des aktuellen Status
$ sudo systemctl status squid

"sudo systemctl status squid" zeigt, dass Squid schon läuft.

Nun läuft Squid schon mal aber in der Standardeinstellung bedient er nur Zugriffe vom gleichen Host. Sie könnten also mit CURL oder auch einer lokal auf Linux installierten PowerShell eine HTTP-Anfrage über den Proxy auf 127:0.0.1:3128 absetzen. Allerdings ist ein Zugriff von dem WSL-Host möglich, da der Host und das Ubuntu ein gemeinsames privates Subnetz haben.

#Einfacher Test
PC C:\> Invoke-Webrequest https://www.msxfaq.net -Proxy http://172.31.61.86:3128

Ich kann den Proxy Server erreichen aber bekomme natürlich ein Access Denied.

Squid erreichbar machen

Um überhaupt von einem anderen PC mit Verbindung zum Squid einen Test machen zu können, muss ich IP-Adressen erlauben und den Service erreichbar machen.

Beschreibung Status

Squid IP-ACLs

Squid hat von Hause aus einige Subnetze schon vordefiniert, die ich einfach in ACLs nutzen kann. Dazu nutze ich den NANO-Editor.

$ sudo nano /etc/squid/squid.conf

In der Datei finden Sie z.B. folgende Definitionen, die aber nur vorbereitet sind.

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

In der Konfiguration habe ich bei "http_access" ein "http_access allow localnet" addiert:

# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed

# Diese Zeile habe ich addiert, dass die in "localnet" definierten Netzwerke zugreifen dürfen
http_access allow localnet

http_access allow localhost

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

Damit die Änderung aktiv wird muss Squid einmal neu gestartet werden. Wenn sie einen Fehler bekommen, dann können Sie sich direkt die Protokolle anschauen. Meist ist ein Tippfehler in der Konfiguration

# Neu starten
$ sudo systemctl restart squid

# Fehleranalyse 1
$ systemctl status squid.service

# Fehleranalyse 2
$ journalctl -xeu squid.service

Port Forwarding

Wenn ich den Squid unter WSL auch von anderen Systemen im LAN erreichen möchte, muss ich einen Port des Hosts auf das WSL-System weiterleiten. Das geht mit Windows Bordmitteln:

#Portforwarding von HostIP auf WSL einrichten. Zur Lesbarkeit umgebrochen
netsh interface portproxy add v4tov4 
   listenport=3128 
   listenaddress=0.0.0.0 
   connectport=3128 
   connectaddress=172.21.233.163

Windows Firewall

Zuletzt muss ich die Windows Firewall auf meinem Host mitteilen, dass er eingehende Verbindungen auf Port 3128 zulassen soll. Das geht z.B. mit:

New-NetFirewallRule `
   -DisplayName "WSL2 SQUID Bridge" `
   -Direction Inbound `
   -Action Allow `
   -Protocol TCP `
   -LocalPort 3128

Erreichbarkeit testen

Nun sollten Sie auch von eine anderen Client im Netzwerk den Squid erreichen können. Sie könnten das z.B. per PowerShell risikolos testen.

#Einfacher Test auf dem WSL Host zu Ubuntu
Invoke-webrequest https://www.msxfaq.net -Proxy http://172.31.61.86:3128

#Einfacher Test von einem anderen System auf den WSL Host über Firewall und Port Forwarding zu Ubuntu
Invoke-webrequest https://www.msxfaq.net -Proxy http://192.168.178.10:3128

Wireshark

Die einfache unverschlüsselte Verbindungen ist auch einfach in Wireshark zu sehen. Nach dem klassischen TCP SYN ACK RES-Handshake sehen wir den GET an den Proxy, der aber im Gegensatz zu einem Zugriff auf eine Webseite die komplette URL und nicht nur den Pfad enthält.

Der Proxy holt die Datei ohne weitere Authentifizierung (nicht sichtbar) und liefert Sie in der 5. Zeile zurück. Bei der MSXFAQ ist das nur eine "301" Umleitung und so sehen wir dann auch direkt, wie ein TLS-Handshake aufgebaut wird. Der Client sendet einen "CONNECT", damit der Proxy eine ausgehende Verbindung zum Ziel aufbaut, die dann mit einem 200 hergestellt wird.

Danach sehen wir dann den klassischen TLS Handshake, über den dann die Daten transparent übertragen werden

Squid Logging

Ehe wir die weitere Konfiguration angehen, wollte ich noch auf die beiden Protokolldateien hinweisen, die Squid standardmäßig ins Verzeichnis /var/log/squid beschreibt:

Über den Linux Logwriter werden die Logs auch rotiert bzw. komprimiert. Wir sehen hier auch schön, dass "Proxy" der Besitzer ist. Das interessante Protokoll ist das "access.log", was ich mir wie folgt einfach anzeigen lassen kann.

$ sudo tail -f /var/log/squid/access.log


Beispielausgabe Squid Logging.

Sie können das Logformat ebenfalls über die Konfigurationsdatei anpassen, z.B.

$ sudo nano /etc/squid/squid.conf
logformat squid  %tl.%03tu %6tr %>a %un %Ss/%03>Hs %<st %rm %ru %Sh/%<A %mt

Natürlich kann Squid auch Syslog und andere Ziele beschreiben. Neben Syslog etc. können Sie die Daten sogar in Azure Sentinel einspielen.

Authentifizierung: Basic

Eine Beschränkung pro IP-Adresse ist eine einfache Konfiguration und oft ausreichend, wenn Sie so den Zugriff auf interne Clients beschränken aber keine weitere Authentifizierung fordern. Ich würde aber gerne eine Anmeldung anfordern. Die Squid-Dokumentation schreibt dazu:

If Squid gets a request and the http_access rule list gets to a proxy_auth ACL or an external ACL (external_acl_type) with %LOGIN parameter, Squid looks for the Authorization: header. If the header is present, Squid decodes it and extracts a user credentials.
Quelle: How does Proxy Authentication work in Squid? https://wiki.squid-cache.org/Features/Authentication#can-i-use-different-authentication-mechanisms-together 

Um erst einmal unabhängig von Domains, DCs etc zu sei, habe ich den Wegüber eine lokale Kennwortdatei und eine Anmeldung per "Basic"-Authentication gewählt. Ohne HTTPS ist diese auch einfach mit Wireshark zu analysieren.

Wichtig: Wenn die Verbindung vom Client zum Squid nicht per HTTPS verschlüsselt ist, dann kann das Kennwort einfach mitgelesen werden. Zudem muss der Anwender das Kennwort eingeben.

Beschreibung Status

Password-Datei für Benutzerdaten

Irgendwo muss ich ja die Benutzer mit dem Kennwort hinterlegen. Da ich auf der Ubuntu-VM keine weitere Benutzer verwalte und auch keinen Apache betreibe, nutze ich hierfür eine eigene Datei. Zuerst lege ich eine "passwords"-Datei wie folgt an:

# apache2-utils für den Befehl htpasswd installieren
$ sudo apt-get install apache2-utils

# Datei anlegen und Berechtigung anpassen
$ sudo touch /etc/squid/passwords
$ sudo chown proxy: /etc/squid/passwords
$ sudo chmod 640 /etc/squid/passwords

#password-Datei anlegen mit zwei Usern
$ sudo htpasswd -cb /etc/squid/passwords user1 Password1
$ sudo htpasswd -b /etc/squid/passwords user2 Password2

In der Datei gibt es nun zwei Benutzer mit dem hier sichtbaren Kennwort.

Squid Konfiguration

Nun muss ich Squid noch anweise, diese Datei zu nutzen.

$ sudo nano /etc/squid/squid.conf

In der Konfiguration addiere aktiviere ich nun an den passenden Stellen:

# unter # OPTIONS FOR AUTHENTICATION 
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwords
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 24 hours
auth_param basic casesensitive off

acl authenticated proxy_auth REQUIRED

http_access allow authenticated

Achten sie darauf, dass z.B. das "authenticated" bei "http_access" auf den Eintrag "acl authenticated ..." referenziert und wenn Sie den Namen ändern, müssen Sie ihn bei beiden Einträgen anpassen.

Squid Neustart

Auch danach ist wieder ein Neustart des Squit zum Laden der Änderungen erforderlich.

# Squid neu starten
$ sudo systemctl restart squid

# Squid Sstatus abrufen
$ sudo systemctl status squid

Wenn Sie sich nicht vertippt haben, sollte Squid wieder laufen.

Kontrolle Anonym

Ein anonymer Zugriff per PowerShell wird nun mit einem 407-Fehler quittiert.

Invoke-Webrequest `
   -Uri http://www.msxfaq.net `
   -Proxy http://192.168.102.183:3128

Wireshark zeigt die 407-Antwort und auch die angebotenen Authentifizierungsverfahren.

Die PowerShell versucht aber keine automatische Anmeldung.

Kontrolle Basic Authentication

Natürlich will ich auch die Anmeldung prüfen. Zuerst nutze ich dazu die PowerShell und gebe die ProxyCredentials an:

PS C:> Get-Credential user1

PowerShell credential request
Enter your credentials.
Password for user user1: *********

PS C:\> Invoke-Webrequest  http://www.msxfaq.net -Proxy http://192.168.102.183:3128 -ProxyCredential $cred

StatusCode        : 200
StatusDescription : OK
Content           : <!doctype html>
                    <html lang="de">
                    <!-- #BeginTemplate "msxfaq2023.dwt" -->
.....

Ein Versuch mit "-ProxyUseDefaultCredentials" funktioniert aber nicht, da der Proxy nur Basic anbietet und die Powershell keinen Zugriff auf mein Kennwort hat. Der Proxy müsste daher Negotiate/Kerberos/NTLM unterstützen.

Der Firefox-Browser erlaubt unabhängig von Windows eine Konfiguration des Browsers. Hier sehe ich dann auch direkt den 407 als Dialogbox:

Wenn ich hier nun Benutzername und Kennwort eingebe und die Verbindung zum Proxy nicht TLS-verschlüsselt ist, können Sie diese Daten in Wireshark einfach mitlesen:

Für eine grundlegende Funktion des Proxy mit einer Authentifizierung gegen eine lokale Credential-Datei ist dies legitim aber sicher keine Konfiguration für den produktiven Einsatz. Gefährlich wird es, wenn Squid dann diese erhaltenen Daten an einen anderen Authentifizierungsdienst weiterreicht. (Siehe Domainanmeldung).

Authentifizierung: Kerberos

Die Anmeldung per Basic Authentication mit Benutzername und Kennwort aus einer lokalen Datei skaliert natürlich nicht, ist unsicher und für den Anwender durch die Kennworteingaben keine Lösung. Mein Ziel ist daher die integrierte Authentifizierung per NTLM oder Kerberos oder vielleicht sogar OAUTH. NTLM gibt es mittels Winbind schon länger und auch Kerberos sollte möglich sein, während OAUTH/Bearer schon fast fertig ist.

Der Host selbst muss nicht Mitglied des Active Directory sein.

In diesem Abschnitt geht es darum, eine Anmeldung am Squid mittels "negotiate" (enthält Kerberos) zu ermöglichen. Dazu muss mein Squid aber mehrere Dinge erfüllen:

  • Er braucht einen Namen, z.B. squidproxy.msxfaq.net
    Ein KDC stellt Kerberos-Tickets anhand eines SPN aus und dort sind IP-Adresse nicht erlaubt. Also muss ich zumindest einen HOSTS oder DNS-Eintrag (A-Record, kein CNAME) anlegen
  • Active Directory mit Computerkonto
    In meinem Fall ist Squid zwar auf WSL aber ist gefühlt dennoch ein eigener Server mit eigener IP-Adresse. Er kommt also sicher nicht an die Secrets des Host-Systeme heran. Daher ist ein eigenes Konto im AD erforderlich und auch sinnvoll
  • Windows KTPass.EXE oder Linux MSKTUTIL
    Mit dem Tool wird aus dem AD-Computerobjekt eine Keytab-Datei erstellt, die dann Squid zur Authentifizierung nutzen kann
  • Uhrzeit
    Kerberos-Tickets haben einen Zeitstempel. Daher sollte die Zeit des Proxy-Servers nicht allzu stark abweichen.
  • Squid-Konfiguration
    Zuletzt muss ich dem Squid noch sagen, dass er Kerberos anbieten und verstehen soll.

Zur Konfiguration habe ich mir wieder eine Checkliste gebaut.

Beschreibung Status

Vorarbeiten

Die bisher beschriebenen Vorarbeiten bleiben unverändert erhalten, d.h.

  • WSL installieren
  • Squid installieren
  • Port-Weiterleitung von 3128 auf die WSL-IP
  • Firewall für eingehende Pakete auf 3128

AD-User

Damit der KDC ein Ticket für Squid ausstellen kann, muss es ein passendes Objekt im Active Directory geben, damit dort ein SPN aber auch ein Credentials hinterlegt werden. Das ausgestellte Ticket wird nicht nur vom KDC signiert sondern auch mit den Daten für das Zielsystem geschützt. Das Objekt kann ein AD-Benutzer oder Computer sein.

Ich ziehe Computerkonten vor, da diese sich weder "interaktiv" anmelden können noch "Domain User" sind. Sie sind daher erst einmal sicherer. Group Managed Service Accounts gehen meines Wissens hier nicht und Sie sollten auch wissen, dass der Squid damit nicht "Domainmitglied" ist. Er bekommt also keine Gruppenrichtlinien o.ä.

Sie müssen das Computerkonto nicht anlegen. Das erfolgt gleich über die WSL.

Linux und Kerberos

Einen Windows Desktop können Sie ja in die Domain aufnehmen und damit vertraut der dem Active Directory. Ein Linux-System ist erst einmal ein Einzelsystem, aber kann mit zentralen Verzeichnisdiensten (z.B. NIS/YellowPages) oder auch Windows Domains verbunden werden. Ich muss dem Linux beibringen, wo es die Kerberos-Dienste findet, denn eine DNS-Abfrage über den "_msdcs"-Baum findet nicht statt. Die Vertrauensstellung zum AD muss ich herstellen, in dem ich die Datei "/etc/krb5.conf" anlege oder editiere.

$ sudo nano /etc/krb5.conf

Hier definiere ich die REALMs, also die AD-Domain und die dazu hinterlegten Server. Hier ein Beispiel mit TCP Enforcement:

[libdefaults]
   default_realm = MSXFAQ.NET
   dns_lookup_kdc = no
   dns_lookup_realm = no
   default_tgs_enctypes = aes256-cts-hmac-sha1-96
   default_tkt_enctypes = aes256-cts-hmac-sha1-96
   permitted_enctypes = aes256-cts-hmac-sha1-96

[realms]
   MSXFAQ.NET = {
      kdc = 192.168.100.11:88
      admin_server = 192.168.100.11:464
}

[domain_realm]
   .MSXFAQ.NET = MSXFAQ.NET
   MSXFAQ.NET = MSXFAQ.NET

[logging]
   kdc = FILE:/var/log/kdc.log
   admin_server = FILE:/var/log/kadmin.log
   default = FILE:/var/log/krb5lib.log

Eine Variante mit DNS-Namen statt IP-Adressen schwächeren Cryptoverfahren und zwei DCs wäre:

[libdefaults]
    default_realm = MSXFAQ.NET
    default_keytab_name = /etc/squid/squiduser.keytab
    default_tgs_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
    default_tkt_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
    permitted_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5

[realms]
    MSXFAQ.NET = {
        kdc = dc01.msxfaq.net
        kdc = dc02.msxfaq.net
        admin_server = dc01.msxfaq.net
        admin_server = dc02.msxfaq.net
        default_domain = msxfaq.net
    }

[domain_realm]
    .msxfaq.net = MSXFAQ.NET
    msxfaq.net = MSXFAQ.NET

Es müssen aber immer die Server oder Domains angegeben werden. Die erweiterten DNS-Einträge von Windows mit "_msdcs" werden nicht genutzt.

Sie können aber auch die DNS-Anfrage für KDC und REALMs aktivieren:

[libdefaults]
   dns_lookup_kdc = no
   dns_lookup_realm = no

Dann sucht das Linux wird auch Windows Clients nach den SRV-Records "_kerberos._udp.<domain>", "_kerberos._tcp.<domain>" und "_kpasswd._udp.<domain>", "_kpasswd._udp.<domain>". Diese Einträge können Sie recht schnell mit "nslookup -q=SRV _kpasswd._tcp.msxfaq.de" auf der Konsole abprüfen.

Diese Vorarbeiten sind zwingend, damit Linux überhaupt weiß, wie es mit wem eine Kerberos-Kommunikation aufbauen kann.

KTPASS und KEYTAB-Datei

Squid muss sich am AD natürlich legitimieren. Dazu nutzt er wie alle anderen "Memberserver" ein Computer/User-Konto und braucht die Zugangsdaten dazu. Diese werden auf Linux in einer KEYTAB-Datei hinterlegt. Es gibt zwei Optionen, die Keytab-Datei zu erzeugen:

  • KTPASS auf Windows
    Der Windows Domain Admin legt im Active Directory ein User oder ComputerObjekt an und erstellt auf dem Domain Controller eine KEYTAB-Datei, die er zum Squid-Server bringt
  • msktutil auf Linux
    Sie können aber auch direkt auf dem Linux-Host sich als "Domain Admin" an Windows anmelden und mit msktutil eine KEYTAB-Datei erzeugen.

KEYTAB mit Linux und Computerkonto

Der Weg über Linux erscheint mir für viele Anwender einfacher und beschreibe ich daher zuerst. Es sind im Prinzip nur einige Befehle, die Sie auf der WSL Kommandozeile passende angeben müssen. Zuerst installieren wir die Kerberos User Parts und MSKTUTIL.

#Installieren der Pakete. Kann je nach Distribution abweichen.
$ sudo apt install msktutil krb5-user

Dann melden wir uns mit KINIT einmal am DC an. Damit haben wir dann ein Ticket für den nächsten Schritt. zudem sehen wir hier gleich, dass dier kerb5.conf-Datei korrekt ist und lassen uns das Ticket anzeigen.

$ sudo kinit administrator@msxfaq.net
$ sudo klist

Wenn Sie hier schon Fehler bekommen, dann sollte Sie noch einmal ihre KRB5.CONF prüfen. Tippfehler, Gross/Kleinschrift, falsche IP-Adressen oder Verschlüsselungsverfahren sind die häufigsten Fehler. Im Extremfall müssten sie mit Wireshark die Anmeldung mit dem Filter "port 88" mitschneiden um den Fehler zu sehen. Hier ein Beispiel:

Zuerst versucht es der Client per UDP aber mit "KRB5KRB_ERR_RESPONSE_TOO_BIG schaltet er auf TCP. Der Client sendet dann ein AS-REQ über TCP und bekommt acuh ein AS-REP zurück. In den Details können Sie dann die verwendeten Cipher-Verfahren einsehen. Die erfolgreiche KDC-Verbindung bedeutet, dass die meisten Einstellungen in der krb5.conf schon mal korrekt sind.

Dennoch kann z.B. ein "kinit: KDC reply did not match expectations while getting initial credentials" zurückgegeben werden.

$ sudo msktutil -c -b "CN=COMPUTERS"  \
   -s HTTP/squidproxy.msxfaq.net  \
   -k /etc/squid/squidproxy.keytab  \
   --computer-name SQUIDPROXY  \
   --upn HTTP/squidproxy.msxfaq.net  \
   --server dc01.msxfaq.net  \
   --enctypes 24  \
   --verbose


-- init_password: Wiping the computer password structure
-- generate_new_password: Generating a new, random password for the computer account
-- generate_new_password: Characters read from /dev/urandom = 75
-- create_fake_krb5_conf: Created a fake krb5.conf file: /tmp/.msktkrb5.conf-vfWOVY
-- destroy_g_context: Destroying Kerberos Context
-- initialize_g_context: Creating Kerberos Context
-- finalize_exec: SAM Account Name is: SQUIDPROXY$
-- try_machine_password: Trying to authenticate for SQUIDPROXY$ with password
-- create_default_machine_password: Default machine password for SQUIDPROXY$ is squidproxy
-- try_machine_password: Error: krb5_get_init_creds_keytab failed (Preauthentication failed)
-- try_machine_password: Authentication with password failed
-- try_user_creds: Checking if default ticket cache has tickets
-- finalize_exec: Authenticated using method 5
-- LDAPConnection: Connecting to LDAP server: nawdc01.msxfaq.net
SASL/GSSAPI authentication started
SASL username: Admin@msxfaq.net
SASL SSF: 256
SASL data security layer installed.
-- ldap_get_base_dn: Determining default LDAP base: dc=MSXFAQ,dc=DE
-- ldap_check_account: Checking that a computer account for SQUIDPROXY$ exists
-- ldap_check_account: Checking computer account - found
-- ldap_check_account: Found userAccountControl = 0x1000
-- ldap_check_account: Found supportedEncryptionTypes = 28
-- ldap_check_account: Found dNSHostName = fc-desktop.msxfaq.net
-- ldap_check_account: Found Principal: HTTP/squidproxy.msxfaq.net
-- ldap_check_account: userPrincipal specified on command line
-- ldap_check_account_strings: Inspecting (and updating) computer account attributes
-- ldap_check_account_strings: Found userPrincipalName = HTTP/squidproxy.msxfaq.net@msxfaq.net
-- ldap_check_account_strings: userPrincipalName should be HTTP/squidproxy.msxfaq.net@msxfaq.net
-- ldap_check_account_strings: Nothing to do
-- ldap_set_supportedEncryptionTypes: No need to change msDs-supportedEncryptionTypes they are 28
-- ldap_set_userAccountControl_flag: Setting userAccountControl bit at 0x200000 to 0x0
-- ldap_set_userAccountControl_flag: userAccountControl not changed 0x1000
-- ldap_get_kvno: KVNO is 1
-- set_password: Attempting to reset computer's password
-- set_password: Try change password using user's ticket cache
-- ldap_get_pwdLastSet: pwdLastSet is 133469330611457545
-- set_password: Successfully set password
-- ldap_add_principal: Checking that adding principal host/fc-desktop.msxfaq.net to SQUIDPROXY$ won't cause a conflict
Error: Another computer account (CN=FC-DESKTOP,OU=Clients,DC=msxfaq,DC=de) has the principal host/fc-desktop.msxfaq.net



# Rechte auf Keytab-Darei anpassen, damit Squid diese lesen darf
$ sudo chgrp proxy /etc/squid/squidproxy.keytab
$ sudo chmod g+r /etc/squid/squidproxy.keytab

# Danach kann ich meine Tickets des Administrator im Cache wieder löschen
$ kdestroy

Über Active Directory User und  Computer sollten Sie dann das Computerobjekt sehen:

Alternativ geht auch einfach eine CMD-Shell mit SETSPN:

setspn -T * -F -Q */squidproxy.msxfaq.net
Die Gesamtstruktur "DC=msxfaq,DC=net" wird überprüft.
CN=SQUIDPROXY,CN=Computers,DC=msxfaq,DC=net
        HTTP/squidproxy.msxfaq.net

Bestehender SPN wurde gefunden.

Der SPN ist entsprechend gepflegt aber der UPN ist ungewöhnlich.

Wenn Sie Squid auf WSL nutzen, dann versucht MSKTUTIL auch den Windows Hostnamen als SPN zu addieren. Das klappt dann nicht, da der SPN ja nur einem Objekt vergeben werden kann.

KEYTAB mit Windows

Alternativ können Sie mit KTPASS.EXE, welches auf dem Domain Controller standardmäßig vorhanden ist, eine KEYTAB-Datei erstellen. (Zur Lesbarkeit umgebrochen)

# Anlegen der Datei mit dem ersten Namen
ktpass.exe 
   /princ HTTP/squidproxy.msxfaq.net@msxfaq.net 
   /mapuser squiduser@msxfaq.net
   /pass *
   -crypto AES256-SHA1
   +dumpsalt
   -setupn
   -setpass
   -ptype KRB5_NT_PRINCIPAL
   /out squiduser.keytab

# Erweitern der Datei mit einem zweiten SPN
ktpass.exe 
   /princ HTTP/squid@msxfaq.net
   /mapuser squiduser@msxfaq.net
   /pass *
   -crypto AES256-SHA1
   +dumpsalt
   -setupn
   -setpass
   -ptype KRB5_NT_PRINCIPAL
   /out squiduser.keytab
   /in squiduser.keytab

Durch den Eintrag "/pass *" werde ich bei der Generierung nach dem Kennwort gefragt.

Kontrollieren Sie beim Benutzerobjekt, dass der SPN addiert wurde:

Die so erzeugte KEYTAB Datei müssen Sie nun natürlich noch auf das Linux-System kopieren, z.B. indem Sie die Datei zuerst auf den Windows Host des WSL übertragen und dann mittels Mountpoint importieren:

# Paket fuer KLIST installieren
$ sudo apt install krb5-user

# keytab-Datei aus Mountpoint kopieren
$ sudo cp /mnt/c/users/fc/squiduser.keytab /etc/squid/squiduser.keytab

$ sudo chown root:proxy /etc/squid/squiduser.keytab
$ sudo chmod 640 squid /etc/squid/squiduser.keytab

Ich nutze im weiteren Prozess das Computerkonto mit /etc/squid/squidproxy.keytab, welches ich über msmkutil auf dem Linux Subsystem direkt erstellt habe.

Keytab in Squid einbinden

Zuerst schaue ich mal in die KEYTAB-Datei und sie zeigt mehrere Schlüssel für die UPNs und den Computer aber auch welche für den Host selbst, die aber nicht funktionieren werden.

# Anzeige der Konfiguration
$ sudo klist -e -k /etc/squid/squidproxy.keytab

$ sudo klist -e -k /etc/squid/squidproxy.keytab
[sudo] password for fcarius:
Keytab name: FILE:/etc/squid/squidproxy.keytab
KVNO Principal
---- --------------------------------------------------------------------------
1 SQUIDPROXY$@MSXFAQ.NET (aes128-cts-hmac-sha1-96)
1 SQUIDPROXY$@MSXFAQ.NET (aes256-cts-hmac-sha1-96)
1 HTTP/squidproxy.msxfaq.net@MSXFAQ.NET (aes128-cts-hmac-sha1-96)
1 HTTP/squidproxy.msxfaq.net@MSXFAQ.NET (aes256-cts-hmac-sha1-96)
1 host/fc-desktop@MSXFAQ.NET (aes128-cts-hmac-sha1-96)
1 host/fc-desktop@MSXFAQ.NET (aes256-cts-hmac-sha1-96)

Eine zweite Prüfung ist die Überprüfung der Authentifizierung.

$ sudo kinit -V -k -t /etc/squid/squidproxy.keytab HTTP/squidproxy.msxfaq.net@MSXFAQ.NET
Using default cache: /tmp/krb5cc_0
Using principal: HTTP/squidproxy.msxfaq.net@MSXFAQ.NET
Using keytab: /etc/squid/squidproxy.keytab
Authenticated to Kerberos v5

Hier sollte kein Fehler zu sehen sein.

Während meiner Konfiguration und Tests habe nicht natürlich einige Fehler durchlaufen. Hier ein paar Beispiele:

Verschiedene Fehler sind denkbar:

  • kinit: Client 'HTTP/squidproxy.msxfaq.net@msxfaq.net' not found in Kerberos database while getting initial credentials
    Hier sollten Sie mit Wireshark sehen, dass Linux auf den KDC zugreift.

    Der Fehler "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" ist ein Hinweis, dass der SPN im AD nicht gefunden wird.

Es gibt sicher noch viele andere Fehlerquellen, auf die ich noch nicht gestoßen bin

Squid für Kerberos einrichten

Der nächste Schritt ist wieder die Konfiguration der Authentifizierung in Squid. Wir brauchen wieder den Editor.

$ sudo nano /etc/squid/squid.conf

Hier muss ich drei Abschnitte addieren.

# Konfiguration von Kerberos mit de Helper und der Datei
auth_param negotiate program /usr/lib/squid/negotiate_kerberos_auth -k /etc/squid/squidproxy.keytab -s HTTP/squidproxy@msxfaq.net -s GSS_C_NO_NAME
auth_param negotiate children 10
auth_param negotiate keep_alive on

# Konfiguration einer ACL, damit ProxyAuth erforderlich ist. 
# Der Eintrag ist eventuell durch die BasicAuth schon da
acl authenticated proxy_auth REQUIRED

# Anlegen eienes Allow HTTP_Access-Eintrags vor einem DENY
http_access allow authenticated

Die erste Zeile definiert Negotiate und verweist auf den helper "negotiate_kerberos_auth", der Zugriff auf die Keytab-Datei braucht und welcher SPN genutzt wird. Eventuell müssen Sie je nach Linux-Distribution prüfen, mit welchem Benutzer der SQUID-Prozess läuft und ggfls. die Rechte auf die Datei mit CHOWN und CHMOD anpassen.

Ich habe am Anfang auch einfach mal den User "Proxy" als Besitzer angeben und mit CHMOD 777 alle die Leserechte gegeben. Wenn dann die Anmeldung geklappt hat, sollten Sie die Rechte aber wieder zurückbauen, denn die keytab ist schützenswert!

Natürlich ist auch nach dieser Änderung ein Neustart von Squid erforderlich.

sudo systemctl restart squid
systemctl status squid.service

DNS-Eintrag oder Host

Kerberos funktioniert nur mit einen DNS-Namen und nicht über die Angabe einer IP-Adresse als Proxy. Ich kann daher auf den Clients einen lokale Hosts-Datei pflegen aber bequemer ist natürlich ein DNS Eintrag:

squidproxy.mxsfaq.de   A  192.168.102.183

Achten Sie darauf, dass es sich um einen A-Record und nicht um einen CNAME handelt, denn beim CNAME wird der Name des WSL-Hosts aufgelöst und der hat ein anderes Kennwort, so dass die dafür ausgestellten Kerberos-Tickets nicht von Squid decodiert werden können.

Testen

Auch hier nutze ich erst mal wieder die PowerShell, bei der ich nun die integrierte ProxyAuthentifizierung aktiviere. Diesmal muss ich aber den den Namen und nicht die IP-Adresse des Proxy-Servers nutzen.

Invoke-Webrequest `
   -Uri http://www.msxfaq.net `
   -Proxy http://squidproxy.msxfaq.net:3128 `
   -ProxyUseDefaultCredentials 

Diese kurze Zeile prüft direkt und indirekt gleich mehrere Dinge:

  • Erreichbarkeit des Proxy
    Der Weg von meinem Client zum ProxyServer kann aufgrund Namensauflösung, IP-Routing, Firewall oder einem falschen Port schon verhindert sein. Ein Fehlerbild sieht dann z.B.: so aus
  • Fehler Bei Kerberos-Ticket
    Wenn die Anfrage vom Proxy beantwortet wird und ein 407-Fehler kommt dann würde ich zuerst einmal mit KLIST schauen, ob der Client sich überhaupt ein Kerberos-Ticket geholt hat

    Wenn hier kein Ticket zu sehen ist, dann liefert der Proxy entweder nicht mit, dass er Kerberos unterstützt oder der SPN ist doch nicht korrekt gesetzt worden. Was der Squid-Server zu ihnen sendet, können Sie mit Wireshark bei Verzicht auf HTTPS gut sehen. Leider liefert Invoke-WebRequest den Header des 407-Fehler nicht. Das geht aber dann mit dem folgenden Skript:
$url = "http://www.msxfaq.de"
$proxyUrl = "http://squid.msxfaq.de:3128"
 
$request = [System.Net.HttpWebRequest]::Create($url)
$request.Proxy = New-Object System.Net.WebProxy($proxyUrl, $false)
$request.Proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
 
try {
    $response = $request.GetResponse()
}
catch [System.Net.WebException] {
    $errorResponse = $_.Exception.Response
    $errorResponse.Headers.GetValues("Proxy-authenticate") 
}

Die Ausgabe liefert die Authentication-Header. Sollte hier kein "Negotiate" mit erscheinen, dann prüfen Sie die Konfiguration in der squid.config unter "auth_param negotiate ". Sollte hier aber "Negotiate" kommen und der Client entsprechend ein Ticket an den Squid senden, dann hat Squid wohl ein Problem bei der Auswertung des übermittelten Kerberos-Tickets

  • Squid Logs
    Dann müssen wir auf Squid in die Logs schauen. Interessant ist hier dann die Datei /var/log/squid/cache.log. Die folgende Fehlermeldungen weist auf Berechtigungen oder Tippfehler bei der Keytab-Datei hin.

    Auch Rechte auf die Keytab können hinderlich sein, speziell bei Nutzung der Computer Keytab "ERROR: keytab file /etc/krb5.keytab is not accessible "
  • Ansonsten können Sie in der squid.conf bei "auth_param negotiate program /usr/lib/squid/negotiate_kerberos_auth -k" noch den Wert "-d" für Debug addieren. Dann sehen sie noch mehr Einträge. Bei mir erscheinen dann alle RIDs im Ticket

    So sieht dann natürlich eine erfolgreiche Kerberos-Abfrage aus.

Weitere Fehlermeldungen reiche ich nach, wenn Sie auftreten.

Authentifizierung über Gruppen und User

Die aktuelle Konfiguration stellt sicher, dass ein Benutzer sich mit Kerberos authentifizieren kann und dann Zugriff erhält. Squid bedient sich dabei verschiedener Helper, um die Mitgliedschaften eines OBjekts in Gruppen zu prüfen. Da wir schon eine Anmeldung per Kerberos haben und das Ticket auch die Gruppen enthält. Allerdings sind dies nur die Gruppen-SIDs. Wenn ich nun in der Konfigration einen Gruppennamen angeben will, dann muss Squid die SIDs aus dem Ticket gegen die Gruppe auflösen.


Auszug aus Squid helpers http://www.squid-cache.org/Doc/man/

Die Nutzung von "Kerberos SID" gibt es seit Squid 5.x

Ein Mapping der Zugriff auf Benutzer und eine Steuerung über AD-Gruppen habe ich auf meiner Test-Umgebung nicht konfiguriert. Mir reicht erst einmal, dass überhaupt alle Anfragen authentifiziert sein müssen.

Dazu dienen folgende beiden Einträge:

# Authentication anfordern aktivieren
acl authenticated proxy_auth REQUIRED

# authentifizierte Benutzer zulassen
http_access allow authenticated

# alle anderen Zugriffe unterbinden
http_access deny all

Es gibt natürlich vor dem letzten "http_access deny all" noch ein paar Allows für Manager und ausgewählte IP-Adressen

Microsoft 365 Bypass

Sie können die Belastung des Proxy-Servers reduzieren, wenn Sie ausgewählte URLs vielleicht ohne Authentifizierung erlauben. Das können die CRLs zu bekannten Zertifizierungsstellen sein, wodurch die Sicherheit sogar noch verbessert wird und z.B. die Installation von Exchange Updates meist schneller erfolgt. Auch die Installation von anderen Programmen oder Skripten mit "Code Signing" sind sicherer und schneller, wenn die Frage nach dem Status des verwendeten Zertifikats schnell möglich ist. Aber dann gibt es noch all die viele Cloud-Dienste, von denen sie ja wissen, dass der Zugriff darauf schon auf der anderen Seite eine Authentifizierung erfordert.

Die meisten Firmen hatten in der Vergangenheit ja auch keinen Proxy Server zwischen Client und Server. Die Cloud ist zwar nicht mehr ihr persönlicher Server sondern wird auch von anderen Firmen genutzt, aber einen gewissen Vertrauensvorschuss sollte eine Cloud schon haben, wenn Sie ihre Daten dort hin ablegen. Insofern bietet es sich an, im Proxy-Server z.B. die Domains und IP-Adressen von Office 365 über eine Allow-Liste zu steuern.

Auf Office 365 Netzwerkziele habe ich einige Beispiele, wie Sie die Microsoft JSON-Quellen anzapfen können. Mach meiner Erfahrung reichen aber auch die wenigen Adressen, die viel Last produzieren oder keine Anmeldung können.

Dazu zählen:

outlook.office.com              Alles mit Exchange Online
teams.microsoft.com             (Fast) alles zu Microsoft Teams
<tenantname>.sharepoint.com     Zugriffe auf das SharePoint ihres tenant
<tenantname>-my.sharepoint.com  Zugriff auf die persänlichen OneDrive-Daten

Natürlich können Sie noch weitere Adressen übernehmen. Alternativ können Sie den Proxy aber auch komplett aus der Kommunikation nehmen, indem Sie die gewünchten Ziele auf der Firewall per NAT und DNS erreichbar machen und in der PROXY.PAC entsprechende Ausnahmen definieren

Technisch können die Namen über die "ACL-Directive" eingebunden werden. Wobei es vermutlich sinnvoller ist, diese in einer eigenen Datei abzulegen und mittels Include einzubinden.

acl youtube_domains dstdomain .youtube.com .googlevideo.com .ytimg.com
acl m365teams dstdomain  teams.microsoft.com
acl m365exo   dstdomain  outlook.office.com

http_access allowed_domains ad_grp-proxyallow01

Ein fertiges Script, welches mittels CRON-Job die JSON-Datei zyklisch lädt, umbaut, im Squid hinterlegt und die neue Konfiguration aktiviert, habe ich noch nicht gefunden.

Wobei diese Optimierung nur zweite Wahl ist. Besser ist die Ausnahme in der Proxy.PAC und den Bypass auf der Firewall. Viele Firewalls haben dazu schon passende Listen. Siehe auch Office 365 Firewalls

IP Rotation

Wir sollten alle das 65535 Port-Limit kennen: Ein Computer kann mit der Standardkonfiguration maximal so viele ausgehende Verbindungen gleichzeitig pro IP-Adresse aufbauen. In der Praxis sind es sogar noch weniger, da die niedrigsten und höchsten Ports meist vom Betriebssystem für die eigene Verwendung geblockt sind, so dass real nur ca. 50.000 verfügbar sind. Wenn sich dann 1000 Anwender an einem Standort einen Proxy teilen und jeder 50 Connections in die Cloud hält, dann kann das eng werden. Sie meinen, dass 50 zu viel ist? Dann schauen Sie doch einfach mal nach mit:

PS C:\>Get-NetTCPConnection | group state -NoElement

Sie können aber dem Squid-Server problemlos mehrere IP-Adressen geben und in der Konfiguration diese dann als gültige ausgehende Adressen hinterlegen.

acl ip1 myip 192.168.178.11
tcp_outgoing_address 192.168.178.11 ip1
acl ip2 myip 192.168.178.12
tcp_outgoing_address 192.168.178.12 ip2

Websocket erlauben

Nachdem ich einen eigenen Squid mit Kerberos im Betrieb habe, konnte ich natürlich auch die erweiterten Funktionen testen. Ein für mich interessantes Protokoll sind die Websockets, da Sie in modernen Webseiten und Webanwendungen immer intensiver als bidirektionaler Kommunikationskanal genutzt werden. Auch Copilot und Teams Townhall Meetings/LiveEvents nutzen Websockets zum Streaming von Audio/Video zu den Clients statt RTP over UDP. Weitere Details dazu finden Sie auf Live Event Netzwerk.

Interessanterweise konnte mein Squid 5.7 schon ohne weitere Freischaltung auch Websockets. Ich habe daher die Defaults gelassen und erst einmal nicht explizit verboten oder erlaubt. Ein Blick in die Konfiguration sagt aber:

#  TAG: http_upgrade_request_protocols
#       Controls client-initiated and server-confirmed switching from HTTP to
#       another protocol (or to several protocols) using HTTP Upgrade mechanism
#       defined in RFC 7230 Section 6.7. Squid itself does not understand the
#       protocols being upgraded to and participates in the upgraded
#       communication only as a dumb TCP proxy. Admins should not allow
#       upgrading to protocols that require a more meaningful proxy
#       participation.
#
#       Usage: http_upgrade_request_protocols <protocol> allow|deny [!]acl ...
#....
#Default:
# Upgrade header dropped, effectively blocking an upgrade attempt.

Wenn Sie aber die Funktion eines Proxy-Servers nun besser kennen, dann wissen Sie, dass ein Proxy ohne SSL-Inspection nur bei einer Verbindung per "Klartext" auch den "Upgrade"-Wunsch und die "101 SWITCHING"-Antwort sehen kann. Wenn die Websocket-Verbindung aber per HTTPS erfolgt und der Client zu erst einen "CONNECT" über den Proxy startet, dann ist der Upgrade der HTTP-Verbindung zu Websockets für den Proxy gar nicht mehr sichtbar. Er könnte nur anhand der vermutlich bidirektionalen Kommunikation mit vielleicht symmetrischen Daten vermuten, dass dies hier kein HTTP-Surfen ist.

Ich gehe davon aus, dass die meisten Server bei Kunden hier auch die Standardwerte nutzen. Ansonsten gibt es ja entsprechende Testseiten.

WSL im Hintergrund

Der Squid-Task startet auf meiner WSL-Umgebung automatisch, sobald ich WSL gestartet habe. Aber in der Standardeinstellung startet WSL selbst ja nicht alleine, sondern erst, wenn ich WSL selbst nutze. Solange niemand am Computer angemeldet ist oder ich mich nur anmelde aber keine WSL-Funktionen benötige, liegt die WSL inaktiv im Hintergrund.

Achtung: "wsl.exe -v -l" zeigt die Version der WSL an während "wsl.exe -l -v" die Distributionen mit den Details anzeigt. Die Reihenfolge ist wichtig

Damit ist Squid natürlich nicht erreichbar. Natürlich könnte ich nun einen "geplanten Task" einstellen, der nach meiner Anmeldung die WSL startet. Aber hier sollten Sie schon zwischen Test/Labor und Produktion unterscheiden. Wenn Sie Squid für mehrere Clients im Netzwerk bereitstellen wollen, dann sollte dies nicht auf einem Desktop mit WSL erfolgen. Dafür ist dann eine Linux-VM auf einem HyperV-Server o.ä. der bessere Ansatz. Daher gehe ich auf die Nutzung von Squid und anderen Diensten als Hintergrundprozess auf WSL nicht weiter ein.

Irrungen

Zwei Vorfälle haben mich kurz verwirrt und möchte ich nicht vorenthalten. Zuerst ist mit ein suspektes Verhalten mit PowerShell 7.40 in Verbindung mit BasicAuth und "-ProxyUseDefaultCredentials" aufgefallen.

Invoke-Webrequest `
   -Uri http://www.msxfaq.net `
   -Proxy http://192.168.102.183:3128 `
   -ProxyUseDefaultCredentials

Die PowerShell hat ja gar keine Credentials und dennoch reagiert sie auf den ersten 407 mit einem neuen Request mit leeren Anmeldedaten.

Also nicht wundern, wenn sie zwei 407-Einträge im Log sehen aber die Anmeldung nicht gelingt.

Die zweite Unstimmigkeit betrifft Wireshark bzw. der Capture-Mode. Auf einem Client hat Wireshark mir zwei 407-meldungen hintereinander angezeigt. Auf den erstne GET kommt der 407 aber dr zweite GET war bei mir nicht zu sehen. Wenn ich den Mitschnitt Aber auf der Gegenseite gemacht habe, waren zwei GET und zwei 407 z ufinden

Ich schiebe das einmal auf WSL oder die Docking-Unit, die dem Client einen Ethernet-Port per USB bereitgestellt hat. Beim Zugriff per WLAN wurde alles korrekt decodiert.

Automatische Updates mit WSL

Wie für Windows werden auf auf Linux immer wieder Fehlerkorrekturen und Updates bereit gestellt. Auch WSL ist im Grund in Linux Subsystem um dessen Aktualisierung sie sich selbst kümmern müssen. Natürlick können Sie immer mal wieder daran denken, die folgenden Befehle auszuführen:

sudo apt upgrade && sudo apt update

Aber auch das können Sie wie bei Windows Updates mit folgenden Schritten automatisieren.

# Modul fuer automatische Updates installieren und aktivieren
apt install unattended-upgrades && systemctl enable --now unattended-upgrades

# Kopie der Konfiguration anlegen
cp /etc/apt/apt.conf.d/50unattended-upgrades /etc/apt/apt.conf.d/50unattended-upgrades.BACKUP

Kondiguration anpassen
nano /etc/apt/apt.conf.d/50unattended-upgrades

Mit NANO können Sie in der Datei bestimmen, welche Pakete von welchen Quellen aktualisiert werden. Ich belasse es bei der Standardeinstellung:

Um allerdings automatisch die Updates mit Reboot zu aktivieren, müssen sie die Zeile "Unattende-Upgrade::Automatic-Reboot "true" auf true setzen. Bei einem Linux ohne GUI gibt es ansonsten keinen Hinweis, dass Updates ausstehen und ein Neustart erforderlich ist.

Das Modul kann seine Aktivitäten auch per SYSLOG oder Mail senden. Im ersten Moment wollte ich SMTP aktivieren, aber die Voraussetzungen bringen ca 80MB und den vollwertigen Mailserver EXIM auf mein System. Das war mir dann doch etwas viel, um einfach eine Mail per SMTP loszusenden.

Vergessen nicht nicht auch das WSL selbst mit "wsl --update" ggfls. zu aktualisieren.

REM Aktualisierung von WSL

wsl --update

Weitere Links