Im ersten Teil dieser Serie haben wir uns angeschaut, wie man einfache Abfragen gegen das Active Directory machen kann. In diesem Teil wollen wir nun herausfinden, was wir für Aktionen mit den User-Abfragen machen können.
Nachdem wir nun wissen, wie wir Benutzer mithilfe des “Get-ADUser” Befehls finden können, können wir uns auch überlegen viele Benutzer beispielsweise in Gruppen zu stecken.
Viele User in eine Gruppe aufnehmen
Nehmen wir an, ich möchte gerne alle Mitarbeiter der Abteilung “IT” in eine Gruppe namens “IT-Mitarbeiter” stecken. Als erstes würde ich mir in diesem Fall gerne mal anschauen, wer momentan in der Gruppe “IT-Mitarbeiter” ist:
Get-ADGroupMember "IT-Mitarbeiter"
Wie kann ich jetzt alle Benutzer der Abteilung in die Gruppe stecken? Dazu muss ich erst herausfinden, was alle User der IT-Abteilung gemeinsam haben. Schauen wir uns doch nochmal an, welche Attribute es innerhalb eines Benutzers gibt:
Get-ADUser "LLange" -Properties *
#Zur Wiederholung: mit -Properties * zeige ich mir alle Attribute des Users an
Hier findet sich ein Attribut namens “Department”! Department ist die englische Übersetzung für Abteilung, hier steht bereits “IT” bei allen Benutzern drin.
Was gilt es also nun zu tun? Richtig, alle User anzeigen lassen, bei denen “IT” in Department eingetragen ist. Dazu benutzen wir die Vergleichsoperatoren aus dem ersten Teil:
Get-ADUser -Filter {Department -eq "IT"}
#Zeige Alle User, deren Attribut Department IT entspricht
Nun haben wir eine Liste mit Usern, die wir gerne in die Gruppe aufnehmen wollen. Da wir bereits den Befehl “Get-ADGroupmember” kennen, suchen wir doch einfach mal nach weiteren ähnlichen Befehlen. Dazu gibt es in der Powershell den Befehl “Get-Command”, um alle verfügbaren Befehle anzuzeigen
Get-Command
#Um direkt spezifischer zu suchen, kann ich auch einen gewünschten Befehl anzeigen lassen:
#Der Befehl wird vermutlich irgendetwas mit "ADGroup" heißen, deshalb suche ich mit Sternchen nach dem Befehl:
Get-Command *ADGroup*
Hier gibt es einen Befehl “Add-ADGroupMember”, das klingt doch perfekt! Wir können also alle User abfragen und anschließend mit der Pipe an den zweiten Befehl weiterreichen. Schauen wir uns mal die Hilfe zu dem Befehl an:
Get-Help Add-ADGroupMember
<#
SYNTAX
Add-ADGroupMember [-Identity] <ADGroup> [-Members] <ADPrincipal[]> [-AuthType {Negotiate | Basic}] [-Credential <PSCredential>] [-Partition <String>] [-PassThru] [-Server <String>] [-Confirm] [-WhatIf] [<CommonParameters>]
BESCHREIBUNG
The Add-ADGroupMember cmdlet adds one or more users, groups, service accounts, or computers as new members of an Active Directory group.
The Identity parameter specifies the Active Directory group that receives the new members. You can identify a group by its distinguished name (DN), GUID, security identifier (SID) or Security Accounts Manager (SAM) account name.
You can also specify group object variable, such as $<localGroupObject>, or pass a group object through the pipeline to the Identity parameter. For example, you can use the Get-ADGroup cmdlet to get a group object and then pass the
object through the pipeline to the Add-ADGroupMember cmdlet.
The Members parameter specifies the new members to add to a group. You can identify a new member by its distinguished name (DN), GUID, security identifier (SID) or SAM account name. You can also specify user, computer, and group
object variables, such as $<localUserObject>. If you are specifying more than one new member, use a comma-separated list. You cannot pass user, computer, or group objects through the pipeline to this cmdlet. To add user, computer,
or group objects to a group by using the pipeline, use the Add-ADPrincipalGroupMembership cmdlet.
#>
Der vorletzte Satz macht uns leider Probleme. “You cannot pass user, computer, or group objects through the pipeline to this cmdlet.” Das bedeutet, wir müssen uns einen anderen Befehl suchen. Aber zum Glück wird uns der Befehl auch direkt im letzten Satz verraten. “To add user, computer, or group objects to a group by using the pipeline, use the Add-ADPrincipalGroupMembership cmdlet.”
Super! Also schauen wir uns davon mal die Hilfe an:
Und schwupps, sind alle IT-Mitarbeiter Mitglied der Gruppe 🙂 Kontrollieren können wir das natürlich nochmal mit der Abfrage vom Anfang. Hier sollten jetzt alle User zu sehen sein.
Alle Gruppenmitglieder in eine weitere Gruppe aufnehmen
Nehmen wir an, Mitglieder von GruppeA müssen alle auch Mitglied von GruppeB werden. Auch das können wir ganz bequem mit den uns bekannten Befehlen machen:
Get-ADGroupmember "GruppeA" | Add-ADPrincipalGroupMembership "GruppeB"
#Die Ausgebe von allen Mitgliedern von GruppeA wird an den Befehl "Add-ADPrincipalGroupMembership GruppeB" übergeben
Das ging sehr schnell! Was aber wenn wir Mitglieder von einer Gruppe in mehrere Gruppen aufnehmen wollen? Muss ich den Befehl jetzt viele Male ausführen? Schauen wir uns dazu nochmal die Hilfe des Befehls an:
Get-Help Add-ADPrincipalGroupMembership
<#
BESCHREIBUNG
The Add-ADPrincipalGroupMembership cmdlet adds a user, group, service account, or computer as a new member to one or more Active Directory groups.
#>
Super, also kann ich meinen Befehl einfach mit mehreren Gruppen angeben! So kann ich mit einem Befehl alle Mitglieder einer Gruppe in beliebig viele andere Gruppen aufnehmen.
Get-ADGroupmember "GruppeA" | Add-ADPrincipalGroupMembership "GruppeB","GruppeC","GruppeD"
# Die Mitglieder von GruppeA werden Mitglied in GruppeB, GruppeC und GruppeD
Viele AD-Objekte auf einmal bearbeiten
Im nächsten Schritt fällt uns auf, dass bei keinem User das Attribut “City” gesetzt ist. In diesem Attribut sollte aber eigentlich die Stadt des Benutzers eingetragen sein. Deshalb entscheiden wir uns dazu, das Attribut bei allen Usern zu setzen. Über den Get-Command Befehl habe ich nach *ADUser* gesucht und den Befehl “Set-ADUser” gefunden:
Get-ADUser -Filter * | Set-ADUser -City "Bitburg"
#Durch -Filter * werden alle User abgerufen und werden per Pipe an den Befehl "Set-ADUser" weitergegeben
Seit der Powershell in Windows 10/Server 2016 gibt es auch die Möglichkeit die Schalter des Befehls anzuzeigen. Dazu schreibst du den Befehl den du benutzen möchtest und ein “-” und drückst anschließend STRG+LEERTASTE. Daraufhin werden dir alle möglichen Schalter angezeigt. Durch die verschiedenen Möglichkeiten kannst du dann einfach mit der TAB-Taste scrollen:
Auf diesem Weg musst du dir oft nicht erst die komplette Hilfe eines Befehls anzeigen lassen um die nötige Einstellung zu finden.
SPF, DKIM und DMARC einrichten: Spätestens seit Emotet und den fast täglich ankommenden Rechnungen die angeblich von Amazon stammen, ist es sinnvoll sich dem Thema Email Authentifizierung zu widmen. In diesem Artikel versuche ich etwas Licht in die Zusammenhänge zu bringen.
Wie können Absender/ Empfänger überhaupt gefälscht werden?
Dazu müssen wir kurz einen Schritt zurück gehen und eine theoretische Situation betrachten:
Stell dir vor du schreibst eine Postkarte. Dort schreibst du als Absender “Angela Merkel” drauf, als Empfänger “Max Mustermann“.
Diese Postkarte legst du nun in einen Briefumschlag und klebst ihn zu. Was musst du nun auf diesen Briefumschlag schreiben, damit du ihn verschicken kannst? Richtig: Einen Absender und einen Empfänger.
In meinem Beispiel adressieren wir den Brief an Bob in der Musterstraße 17. Damit der Briefumschlag nun auch bei Bob ankommt, musst du logischerweise auch die richtige Adresse angeben. Wie soll die Post ihn sonst richtig abgeben? Den Absender dagegen, kontrolliert beim Absenden niemand. Selbst wenn du dort als Absender Luke Skywalker in der Sternenstraße 42 drauf schreibst, ist die Wahrscheinlichkeit groß, dass der Brief an Bob zugestellt wird.
Der Brief kommt nun bei Bobs Briefkasten an. Sein Sekretär packt den Brief für ihn aus und schmeißt den Briefumschlag weg. Bob erhält also nur die Postkarte, schaut sie sich an und wundert sich:
Auf der Postkarte stehen seltsame Empfänger und Absender. Der Empfänger der auf dieser Postkarte zu sehen ist, ist doch überhaupt nicht Bob. Warum ist diese Postkarte nun bei Bob angekommen? Und warum schickt Angela Merkel diese Postkarte ab?
Jetzt hast du einen Überblick darüber, wie E-Mails aufgebaut sind und wo das Problem liegt.
Die verschiedenen Absender- und Empfänger-Felder
Bei E-Mails haben wir das gleiche Prinzip. Eine E-Mail hat einen Envelope (Briefumschlag) mit Empfänger und Absender. Der Envelope wird zum Zustellen von den Mailservern genutzt (in unserem Beispiel die Post). Dein E-Mail Programm (Sekretär) blendet diesen Teil dann für dich aus. Die Empfänger und Absender die du nun in deinem Mail-Programm siehst, sind diejenigen des Mail-Headers (Postkarte).
Hier findest du nun die Namen der Felder, wie du sie oft vorfinden wirst:
Name aus Beispiel
SMTP-Name
Envelope Absender
MAIL FROM: (Envelope-From, Return-Path, …)
Envelope Empfänger
RCPT TO:
Header Empfänger
To
Header Absender
From
Du siehst also, es gibt nur eine einzige Adresse, die man nicht fälschen kann: die Envelope Empfänger Adresse (Die Empfänger-Adresse des Briefumschlag). Denn wenn man diese falsch angeben würde, kommt die Mail nicht beim gewünschten Empfänger an. Alle anderen Adressen könnte man theoretisch beliebig fälschen!
Um nun sicher zu stellen, dass beide Absender-Adressen (Envelope und Header) meiner Domain nicht gefälscht werden können, brauche ich zwei verschiedene Werkzeuge.
SPF (Sender Policy Framework)
SPF schützt die Envelope (Briefumschlag) Absender Adresse. Das ist also die Adresse, die der Mailserver betrachtet. Die Idee hinter SPF ist relativ einfach: Ich nenne bestimmte Server denen ich erlaube unter meiner Domain Mails zu versenden. Das mache ich, indem ich einen DNS-Eintrag für meine Domain veröffentliche. Ich erzeuge einen sogenannten TXT-Record und gebe dort beispielhaft folgendes an:
IPv4 Adresse (bzw. Bereich, wenn ein Bereich nach dem / folgt)
include:
Ich inkludiere einen weiteren SPF-Eintrag In diesem Beispiel dürfen also alle Outlook-Server ebenfalls Mails für diese Domain versenden
-all
Was soll passieren wenn die Mail nicht von einem erlaubten Server kam -all = Ablehnen ~all = Softfail ?all = Nichts unternehmen
Gerade Include: Einträge machen es leicht SPF einzurichten, da ich so einem E-Mail Dienstleister die Verwaltung meines SPF-Eintrags übertragen kann. So kann ich z.B. sagen “Outlook Online verwaltetet meinen SPF-Eintrag, schaut dort nach”. In einem SPF-Eintrag dürfen allerdings maximal 10 DNS-Anfragen vorkommen. In meinem Eintrag oben ist nur eine DNS-Anfrage enthalten, nämlich auf spf.protection.outlook.com. Würden aber hinter diesem Outlook-DNS-Eintrag nochmal 2 include Einträge stecken, wäre mein SPF-Eintrag schon bei insgesamt 3 DNS-Anfragen.
Eine super Seite um sich das im Detail anzeigen zu lassen, ist emailstuff.org. Dort kann man unter Authentication/SPF den eigenen Domainnamen eingeben. Anschließend überprüft die Seite, ob der Record gültig ist.
Du kannst aber natürlich auch jederzeit selbst eine DNS-Anfrage machen. Eine sehr einfache Seite dazu ist http://kloth.net/ . Dort musst du oben auf TXT umstellen und findest anschließend den SPF-Eintrag:
DKIM (Domain Key Identified Mail)
DKIM schützt ebenfalls die Envelope (Briefumschlag) Absender Adresse. Dazu wird ein kleines Programm auf deinem Mail Server installiert, welches ausgehende Mails signiert. Das kannst du dir so vorstellen:
Als erstes wird die Mail generiert. In dem Header der Mail stehen jetzt schon viele verschiedene Dinge, wie die beiden Absender-Adressen, welches E-Mail Programm du nutzt, wie groß die Mail ist, … viele Informationen halt 🙂
All diese Informationen werden jetzt mit einem privaten Schlüssel eines Zertifikats signiert. Diese Signatur wird ebenfalls in den Header der Mail eingefügt. Der öffentliche Schlüssel dieses Zertifikats wird nun ebenfalls als DNS-Eintrag in deiner Domain veröffentlicht. Wenn du also jetzt eine Mail versendest, wird diese im Header automatisch mit deinem eigenen privaten Schlüssel signiert.
Der Empfänger sieht jetzt diese Mail und bemerkt den signierten Header-Teil. Er schaut in deinem DNS nach, ob er dort den öffentlichen Schlüssel dazu finden kann. Wenn er den signierten Teil mit dem öffentlichen Schlüssel entschlüsseln kann, weiß er, dass diese Mail wirklich von deinem Mailserver kam.
DKIM baut dabei auf sogenannte “Selectors”. So kannst du beispielsweise auf deinem Mailserver im DKIM-Programm mehrere Selectors anlegen, die unterschiedliche Namen haben und unterschiedliche Zertifikate benutzen.
Falls du dich fragst warum: Wir benutzen hierbei Zertifikate, die natürlich irgendwann mal ablaufen. Wenn das Zertifikat von Selector1 getauscht werden soll, kann ich in der Zeit einfach auf Selector2 umstellen. Ab dann werden alle Mails mit dem Selector2 signiert und ich kann in der Zwischenzeit in aller Ruhe Selector1 austauschen. Würde ich diesen Schwenk auf Selector2 nicht vorher machen, würde in der Zeit, in der ich das Zertifikat von Selector1 tausche, die Mails nicht signiert werden. Somit würde die Mail für meine Empfänger gefälscht aussehen!
In dem Mail-Header siehst du aber sofort, welcher Selector zum Signieren genutzt wurde. Deshalb brauchst du auch den Selector und den Domain-Namen, um einen DKIM-Record zu kontrollieren. Im Header sieht das dann wie folgt aus:
Hinter dem s= siehst du den Namen des DKIM Selectors. Hinter d= siehst du diejenige Domain, die im Header-FROM (Postkarte, die sichtbare E-Mailadresse) Teil angegeben wurde. Somit kannst du selbst diesen Record überprüfen, indem du z.B. bei Emailstuff.org unter Authentication DKIM auswählst und dann dort nach dem Selector strato-dkim-0002 und der Domain lukaslange.de suchst. Präsentiert wird dir der öffentliche Schlüssel, den Strato veröffentlicht hat und mit dem diese Mail signiert wurde 🙂 Genau das macht dein E-Mail Server dann automatisch für dich und schreibt es anschließend in den Authentication-Results Teil des Headers.
Ein DKIM Record im DNS ist wie folgt aufgebaut:
SELECTORNAME._domainkey.domainname.de
In meinem Beispiel von oben findest du den Record also unter:
strato-dkim-0002._domainkey.lukaslange.de
Der DKIM Selector für lukaslange.de
Super! Nun könnte man meinen, dass alles sicher ist! Aber was soll ein Empfänger machen, wenn SPF nicht stimmt, aber DKIM? Oder was soll er machen, wenn DKIM stimmt, aber SPF nicht?
DMARC (Domain-based Message Authentication, Reporting and Conformance)
Mit DMARC kommt nun das letzte wichtige Konzept ins Spiel: Das sogenannte “Domain Alignment”. DMARC erfordert eine Domain-Übereinstimmung über SPF oder DKIM.
Damit SPF übereinstimmt, muss die versteckte Envelope-From (Briefumschlag) und die sichtbare Header-From (Postkarte) Domain übereinstimmen.
Damit DKIM übereinstimmt, muss die sichtbare Header-From (Postkarte) und die DKIM d= Domain übereinstimmen.
Wie SPF und DKIM baut auch DMARC auf einem DNS-Eintrag auf. Ein DMARC Record sieht dabei wie folgt aus:
Policy – Was soll passieren? none = Nichts unternehmen reject = Ablehnen quarantine = In die Quarantäne verschieben
pct=100
Auf wie viel Prozent der Emails soll das angewandt werden?
rua
Eine Adresse an die aggregierte Berichte gesendet werden sollen
ruf
Eine Adresse an die forensische Berichte gesendet werden sollen
fo=1
Failure reporting 1 = Generiere einen Fehler-Report wenn irgendeine Authentifizierungs-Methode fehlschlägt
sp=none
Subdomain Policy Ist relevant wenn auch von Subdomains gesendet wird (z.B. blog.lukaslange.de oder shop.lukaslange.de). Hier kann angegeben werden ob die Policy für die Subdomains gleich gilt
aspf=r
SPF Regelwerk r= relaxed
Über die DMARC Regeln kannst du also ganz genau sagen, was dein Empfänger machen soll, wenn etwas fehlschlägt.
Praktisch ist dabei, wenn man p=none für den Anfang aktiviert. Dadurch nimmt der Empfänger trotzdem jede E-Mail von dir an, selbst wenn SPF oder DKIM nicht stimmt. Durch die Adressen die bei rua und ruf angegeben sind, wird jedesmal eine Email mit einem kleinen Report an diese Adressen gesendet. Auf diesem Weg kannst du also kontrollieren, ob es vielleicht noch andere Adressen oder Anbieter gibt, die unter deiner Domain E-Mails verschicken. Je nachdem kann es sich dabei um Fälscher handeln, oder natürlich auch echten Dienst-Anbietern (Z.B. Ein Newsletter-Anbieter der in deinem Namen Mails versendet!)
Bei den Forensichen Reports solltest du aber unbedingt auf die Vereinbarkeit mit der DSGVO achten. Hierbei werden teilweise die Mails als Anhang an die Adresse gesendet. Da momentan sowieso viele Report-Sender nur die zusammengefassten Reports (Aggregate Reports) versenden, empfehle ich deshalb gerne, die ruf-Adresse nicht zu setzen.
DMARC DNS-Records sind immer wie folgt aufgebaut:
_dmarc.domainname.de
In meinem Beispiel also:
_dmarc.lukaslange.de
Der DMARC Eintrag für lukaslange.de
Die Reports, die an diese Adressen gesendet werden, enthalten dabei immer XML-Dokumente. In diesen XML-Dokumenten findest du dann die Authentication-Stati einzelner Mails.
Lesbarkeit der DMARC XML-Reports
Die XML-Dateien werden teilweise doppelt gezippt und so an die Empfänger-Adresse gesendet. Somit ist die Lesbarkeit und Analyse dieser Sender wirklich sehr schwierig. Glücklicherweise gibt es aber diverse Anbieter, die dir die Reports automatisch aufbereiten. In meinem DMARC-Record siehst du oben schon angedeutet, dass ich dmarc.postmarkapp.com nutze. Der Dienst ist völlig kostenlos und kann einfach auf der Seite angefordert werden.
Dazu musst du deinen Domainnamen dort angeben und anschließend die angezeigte E-Mail Adresse mit in deine rua Adressen aufnehmen. Anschließend werden dir wöchentlich leicht lesbare Reports zugesandt, die dir auf einen Blick alles verraten.
Für Office 365 Kunden gibt es sogar ein kostenloses Angebot mit einem eigenen Dashboard, von der Firma Valimail. Das Prinzip ist das gleiche, man muss ebenfalls Domains einrichten und dann im eigenen Record die rua Adresse von Valimail hinzufügen.
Empfangen von Reports anderer Domains
Gerade wenn du mehrere Domains hast, kann es gut sein, dass du gerne eine zentrale Mailadresse verwenden möchtest, um alle Reports zu erhalten. Damit das aber möglich ist, musst du von der empfangenden Domain aus dein Okay dazu geben.
Nehmen wir als Beispiel den Dienst-Anbieter postmarkapp.com. Wenn ich in meinem DMARC-Record angebe, dass die Mails an die Adresse in dieser Domain gesendet werden sollen, würde das nicht ohne weiteres funktionieren. Damit das aber doch möglich ist, muss dmarc.postmarkapp.com nochmal einen DNS-Record für meine Domain veröffentlichen. Der ist dabei wie folgt aufgebaut:
meinedomain.de._report._dmarc.reportdomain.de
In diesem Beispiel also:
lukaslange.de._report._dmarc.postmarkapp.com
Diejenige Domain, die Reports von meiner Domain erhalten soll, erlaubt das also durch einen DNS-Eintrag in der meine Domain angegeben ist.
SPF, DKIM und DMARC zusammen
Wir haben nun erfolgreich alle Authentisierungs-Verfahren eingerichtet. Was passiert nun, wenn jemand meine Domain als Absender fälscht?
Fälscht der Angreifer den Absender im Envelope-Absender (der Briefumschlag, also die Adresse die hauptsächlich vom Server genutzt wird) mit meiner Domain, überprüft der Empfänger im SPF Record, ob dieser Server überhaupt unter dieser Domain senden darf. Da der Angreifer das natürlich nicht darf und sein Email Server nicht in meinem SPF Record steht, wird SPF=Fail registriert. Ist kein Record vorhanden, wird SPF=none registriert.
Fälscht er den Absender in der Header-Absender (die Postkarte, also die Adresse die der User im Programm direkt sieht), gibt es drei Möglichkeiten. DKIM=pass, DKIM=fail und DKIM=none
Der Empfänger prüft, ob eine DKIM Signatur vorhanden ist. Wenn ja, wird geprüft ob der passende Record auch vorhanden ist. Ist er vorhanden und die Signatur passt, wird DKIM=pass angegeben. Ist er vorhanden, aber die Signatur stimmt nicht überein, wird es DKIM=fail. Wird aber überhaupt keine DKIM Signatur mitgesendet, wird es DKIM=none.
Jetzt wird der DMARC Record wichtig. Wie du dir sicher schon denken kannst, gäbe es ohne DMARC ein Problem. Denn dann könnte der Angreifer die Mail einfach wie folgt aufbauen:
Absender-Adresse
Wert
Envelope-From
Angreifer@AngreiferDomainMitSPF.de
Header-From
Chef@meinedomain.de
Was passiert nun? Der Empfänger schaut im Envelope-From (Briefumschlag) und findet dort die Domain AngreiferDomainMitSPF.de. Er schaut also bei AngreiferDomainMitSPF.de nach, ob es einen SPF-Record dafür gibt. In diesem Fall gibt es den und unter dieser Domain darf der Angreifer auch von diesem Server aus senden. Somit wird SPF=Pass!
Der Header-From ist hierbei also die gefälschte Adresse. Dort steht jetzt meine Domain drin, aber es wird keine DKIM Signatur gemacht. Somit wird DKIM=None
Der Angreifer hat also SPF=PASS und DKIM=NONE. Ohne DMARC weiß der Empfänger aber nicht, dass das ein Problem ist!
Nur wenn mein DMARC-Record jetzt vorhanden ist, gilt die Mail als richtig wenn SPF ODER DKIM auf Pass stehen, damit DMARC=Pass wird.
Ich hoffe der Beitrag hat dir geholfen die Thematik besser zu verstehen. Schreibe mir gerne einen Kommentar wenn du Fragen oder Anregungen hast!
Der OneDrive Sync Client unter Windows hat eine Fehlermeldung mit dem Code 0x800701AA ausgegeben. Dabei war Files On Demand aktiv und die Dokumente als “Cloud Only” Dokumente vorhanden. Nach mehreren Recherchen und Lösungs-Ansätzen hat es schließlich nur geholfen den OneDrive Client einmal komplett zu deinstallieren und neu zu installieren.
Dazu kann man wie folgt vorgehen:
Die Synchronisation aller Teamsites und OneDrive im Client beenden
Wenn wir versuchten die Windows 10 Spotify App zu starten, erschien immer der folgende Fehler:
Anfangs etwas ratlos, wussten wir nicht woran es liegen könnte. Es schien, als wäre der Fehler bei allen Windows 10 Apps vorhanden, die auf das Internet zugreifen. Reine offline-Apps funktionierten.
Mithilfe von Procmon.exe haben wir festgestellt, dass ein Dienst (svchost.exe) auf die Datei C:\Program Files\WindowsApps\SpotifyAB.SpotifyMusic_1.84.344.0_x86__zpdnekdrzrea0\SpotifyMigrator.exe zugreift. Es wurde anschließend ein Zugriffsfehler beim Lesen des Ordners C:\Users\USERNAME\AppData\Local\Microsoft\Windows\Temporary Internet Files gemeldet.
In einer Testumgebung wurde dieser Pfad allerdings überhaupt nicht angefragt, weshalb die Vermutung nahe lag, dass es sich um eine alte Gruppenrichtlinie handelte. Der Ordner “Temporary Internet Files” wurde bis Windows 8 als Standard genommen, seit dem ist er aber unter:
Wir haben den Fehler also gefunden! Nach einer kurzen Google-Recherche stellte sich heraus, dass die Cache Ordner in der Registry an folgenden Stellen angegeben werden:
Bei den Problem-Rechnern (bzw. Usern) war hier der Ordner “Temporary Internet Files” angegeben, der eigentlich von modernen Browsern nicht mehr genutzt werden sollte.
Wie finde ich nun heraus, welche GPO diese Einstellung setzt?
Öffne eine Kommandozeile (CMD.EXE) und generiere darüber einen Bericht der angewendeten Gruppenrichtlinien mit folgendem Befehl:
gpresult /H c:\gpresult.html
Es wird eine HTML-Datei unter c:\gpresult.html angelegt. Hier gibt es jetzt relativ weit oben irgendwo die Möglichkeit auf “Alle Einblenden” zu klicken. Du solltest also nun alle Einstellungen sehen, die gesetzt werden. Am besten nutzt du nun die Suchfunktion deines Browsers, indem du STRG+F drückst. Wenn du jetzt nach dem fehlerhaften Pfad suchst, solltest du direkt an die Stelle springen, wo die Einstellung gesetzt ist. Darüber findest du dann den Namen der GPO und kannst es entsprechend anpassen.
Viele der täglichen Arbeiten eines Administrators im Active Directory lassen sich mit der Powershell schneller erledigen als über viele Klick-Wege in der GUI. Allerdings besteht oftmals eine gewisse Angst davor Massen-Aktionen auszuführen. In diesem Artikel möchte ich allen interessierten schildern, wie man sich Schritt für Schritt der Verwaltung mit der Powershell nähern kann (bzw. aufzeigen wie ich mich selbst rangetastet habe). Etwas beruhigendes vorweg: Wir arbeiten im ersten Part nur mit “Get-” Befehlen. Allgemein kannst du dir merken dass ein Get-Befehl keine Auswirkungen haben kann, solange nirgends in dem Befehl ein “Set-” oder “Update-” steht.
Hinweis: Dieser Text ist als Fließtext geschrieben, du kannst aber natürlich auch einfach zwischen den Code-Snippets und den Überschriften hin und her springen.
Anzeigen eines AD-Users
Nehmen wir als erstes Beispiel die Abfrage eines AD-Users. Üblicherweise auf einem Domaincontroller oder einem Computer auf dem die RSAT-Tools installiert sind, gibt es die Konsole “Active Directory Users & Computers”. In dieser GUI würde mich der Weg jetzt über mehrere Klicks und Suchen führen; und das obwohl ich sogar weiß dass der User den ich suche LLange heißt. Ich öffne also das Startmenü, suche nach “Active Directory Users & Computers”, klicke dort oben auf das Suchen Symbol und geben anschließend den Usernamen ein.
Sind die RSAT-Tools auf dem Computer installiert, oder handelt es sich um einen Domaincontroller, sind aber auch die Powershell-Module für die Active Directory Verwaltung installiert. In der Powershell kann ich also ebenfalls Infos zu einem User anzeigen. Das erledige ich mit dem einfachen Befehl “Get-ADUser”:
Get-ADUser -Identity "LLange"
Diesen Befehl kann ich sogar noch weiter kürzen:
Get-ADUser -Identity "LLange"
# den Schalter -Identity kann man weglassen, da es der Standard Input ist
Get-ADUser "LLange"
# Drückt man die TAB-Taste, kann man Befehle automatisch vervollständigen lassen. So tippe ich nur noch folgendes:
Get-ADU<#TAB-Taste#> "LLange"
Was wird mir nun angezeigt? Nur wenige Attribute des AD-Users (DistinguishedName, SAMAccountName, UserPrincipalName etc). In Wirklichkeit gibt es aber natürlich noch viel mehr Attribute eines Users, die ich natürlich ebenfalls explizit mit anzeigen kann. Dazu gebe ich den Parameter -Properties gefolgt von dem gewünschten Attribut mit. In diesem Beispiel lasse ich zusätzlich die Mailadresse und das Erstellerdatum des Users anzeigen:
Get-ADUser "LLange" -Properties mail, whencreated
Was aber tun, wenn man nicht weiß wie das gewünschte Feld heißt? In traditioneller Trial & Error Methode, lassen wir uns einfach alle Attribute des Users anzeigen:
# Das Stern-Symbol ist eine sogenannte Wildcard. Gibt man nichts außer dem Stern an, ist es gleichzusetzen mit "Alles"
Get-ADUser "LLange" -Properties *
Jetzt sieht man natürlich einiges 🙂 Wir können aber einfach schauen welche Attribute für uns interessant sind und anschließend nur die für uns wichtigen Attribute anzeigen. Dazu nutzen wir die sogenannte Pipe | (Falls du das Symbol noch nicht genutzt hast, auf der deutschen Tastatur findest du es auf der Taste der spitzen Klammern < > ). Pipe heißt übersetzt Rohr und soll symbolisieren was dieses Symbol macht.
Pipe zum Weiterleiten von Befehls-Outputs
Im Normalfall geben wir etwas in eine Konsole ein und die Konsole gibt uns anschließend wieder etwas aus. Was aber wenn mich aber der Output dieses ersten Befehls nicht interessiert, sondern ich nur das was ich dort herausgefunden habe weiterverarbeiten möchten? In diesem Fall kann ich den Output eines Befehls mit der Pipe (dem Rohr) an einen weiteren Befehl weiterleiten. Ein sehr einfaches Beispiel ist hierbei der select Befehl:
Get-ADUser "LLange" -Properties * | select name, samaccountname, mail
Der Output des ersten Befehls war uns viel zu viel. Deshalb haben wir diesen Output nun weitergeleitet an den Befehl select und haben dort nur die 3 Attribute name, samaccountname und mail angegeben. Wir haben also alles angezeigt und anschließend davon nur 3 Dinge ausgewählt (“selected” auf englisch).
Schnelles Abrufen von versteckten Attributen
Du hast es vielleicht noch nicht gemerkt, aber du kannst bereits jetzt schon etwas viel schneller als vorher: Stell dir beispielsweise vor, du möchtest die PersonalNummer eines Users auslesen. Im Active Directory ist das Standard Feld dazu “employeeID“. In der GUI (Active Directory Users & Computers) findest du diese Information aber nicht ohne weiteres. Damit du sie anzeigen kannst, musst du als erstes unter View die Erweiterte Ansicht aktivieren
Anschließend reicht es nicht nach dem User zu suchen. Denn was wir brauchen ist der Attribut Editor. Diesen findest du aber nur, wenn du einen User direkt anklickst. Du musst dich also zuerst durch alle OUs hangeln, anschließend Rechtsklick/Eigenschaften machen, den Attribut-Editor auswählen und dort nach dem Feld “employeeID” suchen.
Wie würdest du das jetzt in der Powershell erledigen? Du weißt bereits alles was du dazu benötigst:
Das war auf jeden Fall erheblich leichter und schneller als über die GUI, oder? Du zeigst dir einfach alle Attribute des Users an und selektierst anschließend nur das interessante, die employeeID.
Hilfe eines Befehls aufrufen um die Funktion zu verstehen
Was ist wenn ich beispielsweise nicht genau weiß wie der Username eines Benutzers ist? Der Befehl nimmt für den -Identity Parameter nur vorhandene Benutzernamen. In diesem Fall lohnt sich der Blick in die Hilfe des Befehls:
Get-Help "Get-ADUser"
Der Output verrät uns einiges über den Befehl, unter anderem die Syntax:
Es gibt also die Möglichkeit den Parameter -Filter zu nutzen. Um einen Filter zu nutzen, müssen wir allerdings zuerst einen kleinen Ausflug zu den Operatoren machen.
Vergleichsoperatoren
Ein Operator wird genutzt um zu beschreiben wie etwas verglichen werden soll. Stell dir beispielsweise vor du möchtest einen User finden, dessen SAMAccountName “LLange” ist. In diesem Fall nutzt du in Powershell den Operator “-eq“was für “equals” steht:
Get-ADUser -Filter {SamAccountName -eq "LLange"}
Möchtest du etwas finden, das alles außer “LLange” heißt, kannst du das Gegenteil benutzen (du ahnst es vielleicht schon) “-ne” für “not equals“:
Get-ADUser -Filter {SamAccountName -ne "LLange"}
Je nachdem wie viele User es in deinem Active Directory gibt, ist jetzt eine ganz schön lange Liste vor dir abgelaufen 🙂 Du hast dir alle User angezeigt, die NICHT den SAMAccountName LLange haben.
Was machst du aber wie in unserem Beispiel, wenn du dir nicht sicher bist wie der SamAccountName ist? “Equals” wäre in diesem Fall falsch, da es ganz genau stimmen muss. Für diese “ungenauen” Abfragen gibt es in Powershell den Operator “-like“. Like muss zusammen mit Platzhaltern genutzt werden. Einen Platzhalter kennst du bereits, die Wildcard “*“:
Mir werden nun alle User angezeigt, die einen SAMAccountNamen haben, der mit lange endet. Möchte ich alle User haben die mit Lange beginnen, kann ich die Wildcard hinter den Suchbegriff setzen (“Lange*”).
Es gibt viele weitere Operatoren auf die ich nun nicht genauer eingehen möchte, hier findet ihr aber trotzdem mal eine kurze Liste:
-eq
equals
-ne
not equals
-lt
lower than
-gt
greater than
-le
lower or equals
-ge
greater or equals
-like
ungefähre Übereinstimmung mit Platzhaltern
-match
eine Anzahl von Zeichen muss genau so vorkommen
-contains
In einer Liste muss ein Objekt übereinstimmen
Filtern mit mehreren Bedingungen
Möchten wir nun mehrere Bedingungen in unsere Abfrage einbauen, können wir das wie oben mit logischen UND und OR machen:
Jetzt werden mir nur diejenigen User angezeigt deren Nachname (SurName) Lange ist und gleichzeitig der Vorname (GivenName) Lukas ist. Gibt es also nur einen Lukas Lange im Active Directory, finde ich nur diesen einen User. Ist dagegen nur eins der beiden Dinge wichtig, kann ich ein OR verwenden:
Hier werden mir jetzt alle diejenigen User angezeigt die mit Nachnamen Lange heißen oder mit Vornamen Lukas. Gibt es also 3 User die mit Vornamen Lukas heißen und 2 User die mit Nachnamen Lange heißen, werden mir diese 5 User angezeigt.
Ich hoffe diese Informationen helfen dir etwas weiter und du traust dir nun zu einige Funktionen der Powershell zu nutzen.
Im nächsten Teil schauen wir uns dann an, was man mit den Usern sonst so anstellen kann.
Viele Fotografen speichern Ihre Bilder als RAW und JPG Dateien gleichzeitig. Das ist natürlich sehr praktisch, da man auf diesem Weg direkt beide Formate zur Verfügung hat und sich entscheiden kann welche man nutzt. In meinem Workflow hat sich dann aber immer folgendes Problem ergeben:
Ich schaue mir die JPG Version der Bilder an und lösche diejenigen, die nichts geworden sind, oder mir nicht gefallen. Wie werde ich jetzt auf schnelle Art und Weise diejenigen RAW-Dateien los, deren JPG ich bereits gelöscht habe?
Dazu habe ich ein kurzes Powershell-Script geschrieben, was genau das erledigt. Meine Kamera erstellt RAW-Dateien im .cr2 Format. Ich durchlaufe also alle .cr2 Dateien im aktuellen Ordner und teste ob es eine zugehörige JPG Datei gibt. Gibt es diese nicht, wird die RAW-Datei gelöscht.
foreach ($raw in (Get-Item *.cr2))
{# Durchlaufen aller .cr2 Dateien
if (!(Test-Path "$(($raw.Name).split(".")[0]).jpg"))
{<#
Wenn kein passendes .jpg zum aktuellen Raw vorhanden ist, lösche das Raw
Hier wird er Dateiname der RAW (z.B. img01.cr2) am . gesplittet und stattdessen ein .jpg angehängt
#> Remove-Item $raw
}
}
Am schnellsten kannst du das Script nutzen indem du im Datei-Explorer den Ordner öffnest in dem sich die Bilder befinden. Tippe anschließend oben “powershell.exe” im Datei-Pfad ein. Es öffnet sich ein Powershell-Fenster genau in diesem Ordner. Kopierst du nun das Script in das Fenster und drückst die Enter-Taste, werden die .cr2 Dateien ohne zugehörige JPG Datei gelöscht.
Der Azure Application Proxy ermöglicht es auf sehr einfache Art und Weise interne Webseiten bzw. Web-Applikationen auch nach extern zu veröffentlichen. Die Möglichkeit “Azure Pre Authentication” zu nutzen, macht den Zugriff von extern zusätzlich auch noch sicher. Dazu werden in Azure Applikationen angelegt, die eine externe Adresse haben und auf eine interne Webseite verweisen. Auf diese Art und Weise kann man SAP Fiori Applikationen relativ einfach von extern erreichbar machen.
Der Aufbau ist dabei wie folgt:
Intern steht ein Server der den “Azure Application Proxy Connector” installiert hat. Dieser Server baut eine ausgehende Verbindung zu Azure auf und wartet auf einen Zugriff. Wenn ich nun in Azure auf die Applikation zugreife, muss ich als erstes meinen Azure-User samt Passwort angeben. Wenn ich mich erfolgreich authentifiziert habe (und die nötigen Rechte für die Applikation in Azure zugewiesen habe), wird die Anfrage an den internen Azure Application Proxy Connector weitergeleitet. Dieser baut einen ausgehenden Tunnel auf und fungiert als “Jump-Server”. Der Traffic läuft also von Azure zum Application Proxy Connector Server und dann von dort aus zur internen Webseite.
Da ich mich bereits in Azure Authentifiziert habe, kann ich dem Azure Application Proxy Connector diese Anmelde-Daten auch mitgeben. Von diesem Server aus kann ich dann die Anmelde-Daten an den Webserver weitergeben. Dieses Verfahren nennt sich “Kerberos Constrained Delegation”.
ServicePrincipalName und Kerberos Constrained Delegation
Ich nutze dazu den ServicePricipalName der als “Empfänger” für das Kerberos-Ticket genommen wird. Es sollte bereits ein SPN auf dem Ziel-Server vorhanden sein, mit dem Aufbau:
http/NETBIOSNAMESERVERSAP
Hier sei nochmal der Hinweis darauf gegeben, dass das http/ keine URL ist und tatsächlich nur mit einem / notiert wird. Rufe ich nun die “Active Directory Users and Computers” Konsole auf, kann ich dort nach dem Azure Application Connector Server suchen. In den Eigenschaften des Computers gibt es einen Tab “Delegation”, in diesem stelle ich nun auf “Trust this computer for delegation to specified services only”.
Anschließend suche ich nach dem SAP Fiori Server und wähle dort den entsprechenden SPN.
SPNego
Nutzt du SPNego für das Single Sign On, hast du wahrscheinlich “User Service Principal Names” im Einsatz. Da SPNego hier auf den Service-User baut, reicht es deshalb nicht aus nur dem Server auf dem der SAP-Service läuft die Delegierung der Kerberos-Tickets zu erlauben. In diesem Fall muss dem Azure Application Proxy Server erlaubt werden, Kerberos Tickets an diesen Service-Account zu delegieren. Der Application Proxy Server leitet das Kerberos Ticket also an den Service User weiter.
Da es dazu keine GUI gibt, musst du es auf Powershell-Ebene machen. Das ist aber relativ einfach und gut nachvollziehbar:
#Der AzureAppProxyServer wird in die Variable gespeichert und angezeigt
$AzureAppProxyServer = Get-ADComputer -identity SERVERNAME
$AzureAppProxyServer
#Der SAP SSO User wird in die Variable gespeichert und angezeigt
$SSOServiceUser = Get-ADUser -Identity SAPSSOSERVICEUSERNAME
$SSOServiceUser
#Dem AzureAppProxyServer wird erlaubt Kerberos Tickets an den SAP SSO User zu delegieren
Set-ADUser $SSOServiceUser -PrincipalsAllowedToDelegateToAccount $AzureAppProxyServer
So haben wir jetzt das gleiche Ergebnis wie oben: Der Azure App Proxy Server darf Kerberos-Tickets an die Empfänger-Stelle delegieren.
Usermapping für SAP
Bei einigen SAP-Systemen wird der SNC-Name zum SSO genutzt. Dieser setzt sich wie folgt zusammen:
SAMAccountName@internerDomainAufbau
In Azure melde ich mich aber mit meinem UserPrincipalName an. Was kommt nun am Backend-System an und wie kann ich das Mapping gestalten? Das kann ganz granular in der Azure Application festgelegt werden:
Hier wird also der On-premises SAMAccountName an das Backend weitergeleitet. So können Name-Mapping Probleme komplett gelöst werden.
Im Azure melde ich mich mit meinem UserPrincipalName (lukas.lange@lukaslange.de) an und komme im Backend mit meinem SAMAccountName (langead\lukas.lange) an. Wenn SAP nun das Mapping macht und ein anderes Format braucht, stellt dies kein Problem mehr dar.
In der Vergangenheit ist es immer mal wieder erforderlich gewesen bestimmte Registry-Keys von Office365 zu löschen. Zuletzt als bei einigen Usern die angehefteten Dokumente in den verschiedenen Office-Anwendungen nicht mehr angeheftet blieben.
Um das Löschen für den Benutzer etwas einfacher zu machen, oder sogar per Logon-Script einzubinden, habe ich ein kurzes Script dazu geschrieben.
Die betroffenen Registry-Keys finden sich (Stand 2019.10.10) unter Hkey Current User:\Software\Microsoft\Office\16.0\. Da der User in HKCU keine Administratoren-Rechte benötigt, kann das Script im Kontext des Benutzers ausgeführt werden.
# Erstellen von Array worin die einzelnen RegKeys gesammelt werden
$regkeys = @()
# Hinzufügen der einzelnen RegKeys ins Array
$regkeys += Get-Item -Path "HKCU:\Software\Microsoft\Office\16.0\Excel" -ErrorAction SilentlyContinue
$regkeys += Get-Item -Path "HKCU:\Software\Microsoft\Office\16.0\PowerPoint" -ErrorAction SilentlyContinue
$regkeys += Get-Item -Path "HKCU:\Software\Microsoft\Office\16.0\Word" -ErrorAction SilentlyContinue
$regkeys += Get-Item -Path "HKCU:\Software\Microsoft\Office\16.0\Common\Internet\WebServiceCache" -ErrorAction SilentlyContinue
$regkeys += Get-Item -Path "HKCU:\Software\Microsoft\Office\16.0\Common\Internet\Server Cache" -ErrorAction SilentlyContinue
$regkeys += Get-Item -Path "HKCU:\Software\Microsoft\Office\16.0\Common\Identity" -ErrorAction SilentlyContinue
# Übergeben des Arrays an den Befehl Remove-Item. -Recurse sorgt dafür dass auch alle RegKeys gelöscht werden die unterhalb der Hives sind.
$regkeys | Remove-Item -Recurse -Confirm:$true
Möchte man auslesen welcher User Daten in Azure hinterlegt hat, so kann man dies pro User im Azure-Portal tun. Möchte man aber alle Daten zentriert in eine CSV exportieren, so kann man dies mit einem relativ kurzen Powershell-Script tun.
Dies kann unter anderem nützlich sein, wenn man in der Umstellung zu Azure MFA ist. Hier ist es oft interessant, wie viele Benutzer der Aufforderung zur Hinterlegung von Sicherheitsinformationen nachkommen.
<#
Herstellen der Verbindung zu Azure. Es muss das Powershell-Modul "MSOLSERVICE installiert sein.
Informationen zum Installieren findet man unter https://docs.microsoft.com/de-de/office365/enterprise/powershell/connect-to-office-365-powershell
#>Connect-MsolService
# Mit Get-MsolUser wird eine Liste aller Azure User abgefragt. durch die Pipe werden dann nur diejenigen User angezeigt, die auch eine Lizenz haben
$allAzureUsers = Get-MsolUser -Synchronized -All |?{$_.islicensed}
Clear-Host
Write-Output "Bitte warten, lese die Sicherheitsinformationen der Azure-User aus"
# Anlegen einer Liste als Array. Darin werden die User samt ihrer Sicherheitsinformationen gesammelt
$liste =@()
# Usercounter - Nur für die Anzeige während des Scripts notwendig
$counter = 1
foreach ($azureuser in $allAzureUsers)
{# Durchlaufen aller lizensierter Azure User
# Anzeigen des Fortschritts in %. Realisiert durch die Powershell-Funktion Write-Progress
Write-Progress -Activity "Rufe Sicherheitsinformationen der User ab." `
-PercentComplete $(($counter / ($allAzureUsers|measure).count * 100)) `
-Status "User $counter von $(($allAzureUsers|measure).count)"
<#Es wird ein ein eigenes Objekt namens User angelegt. Dieses Objekt dient nur der besseren Formatierung.
In das Objekt werden die Informationen des aktuell betrachteten User geschrieben
#> $user = [pscustomobject]@{
"Name" = $azureuser.Displayname
"UserPrincipalName" = $azureuser.Userprincipalname
"Department" = $azureuser.Department
"MobilePhone" = $azureuser.MobilePhone
"MFA_AnzahlMethoden" = 0
"MFA_PhoneNumber" = ($azureuser |select strongauthenticationuserdetails).strongauthenticationuserdetails.phonenumber
"MFA_AuthenticatorApps" = ($azureuser.StrongAuthenticationPhoneAppDetails |measure).count
"MFA_AlternativePhoneNumber" = ($azureuser |select strongauthenticationuserdetails).strongauthenticationuserdetails.alternativephonenumber
"MFA_EMail" = ($azureuser |select strongauthenticationuserdetails).strongauthenticationuserdetails.email
}
if($user.MFA_PhoneNumber)
{# Wenn Telefonnummer hinterlegt, zähle Anzahl Methoden 1 hoch
$user.MFA_Anzahlmethoden ++
}
if($user.MFA_AuthenticatorApps)
{# Wenn Authenticator hinterlegt, addiere die Anzahl der Methoden um die Anzahl von Authenticatorn hoch
$user.MFA_Anzahlmethoden += $user.MFA_AuthenticatorApps
}
if($user.MFA_AlternativePhoneNumber)
{# Wenn Alternative Telefonnummer vorhanden, zähle Anzahl Methoden 1 hoch
$user.MFA_Anzahlmethoden ++
}
# Der Liste den aktuellen User hinzufügen und den Counter hochzählen
$liste += $user
$counter ++
}
# Export der Liste als CSV nach C:\Temp\mfa-methoden_hinterlegt.csv
Write-Host "Die Liste wird exportiert nach `"C:\Temp\mfa-methoden_hinterlegt.csv`""
$liste | sort -Property name| Export-Csv -Path "C:\Temp\mfa-methoden_hinterlegt.csv" -Delimiter ";" -NoTypeInformation -Encoding utf8
There, now he’s trapped in a book I wrote: a crummy world of plot holes and spelling errors! It must be wonderful. Oh right. I forgot about the battle. I am the man with no name, Zapp Brannigan! That’s not soon enough!
Whoa a real live robot; or is that some kind of cheesy New Year’s costume? Now Fry, it’s been a few years since medical school, so remind me. Disemboweling in your species: fatal or non-fatal? I don’t know what you did, Fry, but once again, you screwed up! Now all the planets are gonna start cracking wise about our mamas.
I’ll tell them you went down prying the wedding ring off his cold, dead finger. Come, Comrade Bender! We must take to the streets! And until then, I can never die? Tell them I hate them. It’s just like the story of the grasshopper and the octopus. All year long, the grasshopper kept burying acorns for winter, while the octopus mooched off his girlfriend and watched TV. But then the winter came, and the grasshopper died, and the octopus ate all his acorns. Also he got a race car. Is any of this getting through to you?
No! I want to live! There are still too many things I don’t own! Is the Space Pope reptilian!? Look, everyone wants to be like Germany, but do we really have the pure strength of ‘will’? Is the Space Pope reptilian!?
Well, then good news! It’s a suppository. Tell her she looks thin. OK, if everyone’s finished being stupid. You can crush me but you can’t crush my spirit! Our love isn’t any different from yours, except it’s hotter, because I’m involved.
Um dir ein optimales Erlebnis zu bieten, verwenden wir Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wenn du diesen Technologien zustimmst, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn du deine Zustimmung nicht erteilst oder zurückziehst, können bestimmte Merkmale und Funktionen beeinträchtigt werden.
FunktionalImmer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt.Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.