Σήμερα το μενού έχει scripting. Πώς κάνουμε export την τιμή ενός AD Attribute με vbscript? Ξέρω, ξέρω :) προφανώς και υπάρχουν αμέτρητα άρθρα επί του θέματος, αλλά διαβάστε τα παρακάτω και δεν θα χάσετε!
Αρχίζουμε με τα απλά:
Τι γίνεται αν το Attribute name περιέχει τον χαρκτήρα “-“;
Ύστερα από αρκετό ψάξιμο βρίσκουμε το εξής post του γνωστού scripting guy:
http://blogs.technet.com/heyscriptingguy/archive/2005/06/21/how-can-i-retrieve-the-value-of-an-active-directory-attribute-that-has-a-hyphen-in-its-name.aspx
Τι γίνεται αν το Attribute name περιέχει τον χαρκτήρα “-“ ΚΑΙ είναι multivalued; Ooops πρόβλημα έτσι; Εμένα μου πήρε λίγη ωρίτσα να το βρώ, η λύση παρακάτω.
Option Explicit
Dim strMetaDataEntry, strDNSDomain, strContainer
Dim objGroup, objRootDSEDim arrMetaData
strContainer = "cn=<group name>,cn=<container>, "
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
Set objGroup = GetObject ("LDAP://"& strContainer & strDNSDomain)
objGroup.getInfoEx array("msDS-ReplValueMetaData"),0
arrMetaData = objGroup.GetEx("msDS-ReplValueMetaData")
' Loop = For Each .... Next
WScript.Echo "Metadata for members of: " & strContainer
For Each strMetaDataEntry in arrMetaData
WScript.echo strMetaDataEntry
Next
Wscript.Quit
Ελπίζω να σας φανεί χρήσιμο!
P.S Το script είναι κλινικά δοκιμασμένο :), αλλά δεν αναλαμβάνω ευθύνη!
Φιλικά
SOF
Πλησιάζοντας τον μήνα από το Release Date των Windows 2008 R2, ήδη πολλές επιχειρήσεις έχουν στο καλεντάρι τους την εγκατάσταση του πρώτου τους Windows 2008 R2 Domain Controller. Με την ευκαιρία αυτή θα δούμε σε συντομία τι πρέπει να προσέξουμε πριν την αναβάθμιση του Schema του AD σε R2 σχετικά με τα lingering objects. Προφανώς επειδή πρόκειται για σχετικά κανούργια διαδικασία, ενδέχεται να υπάρχουν σημεία τα οποία δεν τα έχω λάβει υπόψη. Σχόλια και παρατηρήσεις είναι ευπρόσδεκτα.
Ας αρχίσουμε λοιπόν.
Κατά την αναβάθμιση του Schema σε R2 είναι γνωστό ότι εισάγoνται και τα extensions για το Recycle Bin. Ακόμα και πριν ενεργοποιηθεί ο Recycle Bin, τα objects του AD προετοιμάζονται για να τον υποστηρίξουν με την εισαγωγή του isRecycled attribute. Αυτό φυσικά ισχύει και για τα deleted objects. Ύστερα από την αναβάθμιση μπορεί να προκύψουν μηνύματα λάθουs που να ισχυρίζονται ότι υπάρχουν lingering objects στο AD. Συνήθως το πρόβλημα αυτό προκύπτει σε περιβάλλοντα με πολλές καθημερινές εγγραφές/διαγραφές χρηστών, DNS records κ.α. Το αποτέλεσμα είναι να σταματά το replication μέχρι να τρέξει ο Garbage Collector στον source DC. Το "πρόβλημα" αυτό λύνεται από μόνο του, αφού δεν πρόκειται για πραγματικά lingering objects.
Μια ματιά στο υπόβαρθρο.
Το μοντέλο που ακολουθεί το Active Directory για τον συγχρονισμό των δεδομένων είναι το loose consistency with convergence
Σύμφωνα με αυτό το μοντέλο, κανείς δεν μπορεί να εγγυηθεί ότι σε ένα συγκεκριμένο χρονικό σημείο κάθε replication partner θα έχει ακριβώς τα ίδια objects, αφού επιτρέπεται να γίνονται αλλαγές σε κάθε έναν από αυτούς. Εαν όμως το σύστημα αφεθεί να φθάσει σε μια ισορροπία, μην επιτρέποντας οποιεσδήποτε αλλαγές για το χρονικό διάστημα που απαιτείται για να συγχρονιστούν οι πληροφορίες μεταξύ τους, τότε η τελική κατάσταση είναι εγγυημένα η ίδια παντού.
Στην περίπτωση μας συγκεκριμένα αυτό που συμβαίνει είναι το εξής:
α.) Γίνεται το schema update.
β.) Επηρρεάζεται ένα deleted object του οποίου το Tombstone Lifetime λήγει σήμερα, και θα το διαγράψει ο garbage collector στην επόμενη προγραμματισμένη εκτέλεσή του.
γ.) Ο garbage collector του DC προορισμού έχει τρέξει ήδη, διαγράφοντας μόνιμα το αντικείμενο αυτό.
δ.) O DC της πηγής προσπαθεί να συγχρονίσει με τον DC προορισμού.
ε.) Ο DC προορισμού δηλώνει άγνοια για το αντικείμενο αυτό, και καταχωρεί το μήνυμα NTDS Event ID: 1988
ζ.) Ο DC προορισμού μπλοκάρει το εισερχόμενο replication, λόγω του strict replication consistency.
στ.) O source DC εκτελεί τον garbage collector και το πρόβλημα λύνεται, εφόσον δεν προσπαθεί να συγχρονίσει πλέον το συγκεκριμένο object.
Τα άρθρα σχετικά με το Tombstone Lifetime και τον Garbage Collector:
The Active Directory database garbage collection process
The default tombstone lifetime (TSL) value remains at 60 days instead of increasing to 180 days in Windows Server 2003 R2
Εάν για κάποια επιχείρηση η καθυστέρηση του replication μέχρι 12 ώρες από site σε site μπορεί να σημαίνει σημαντική απώλεια κερδών, σκαρφιστίκαμε έναν τρόπο να ελλατώσουμε τις απώλειες αν όχι να τις αποφύγουμε εντελώς.
α.) Προαιρετικά: αυξάνουμε παντού την συχνότητα εκτέλεσης του garbage collector. Στο παραπάνω άρθρο περιγράφεται πώς.
β.) Συγχρονίζουμε παντού την εκτέλεση του garbage collector. Η εκτέλεση μπορεί να επιβληθεί τοπικά με την εντολή: repadmin /setattr "" "" doGarbageCollection add "1", ή ακολουθώντας τις οδηγίες εδώ. Το καλύτερο θα ήταν να προγραμματίσουμε την εκτέλεση σε κάποιο χρονικό σημείο όπου πραγματοποιούνται οι λιγότερες αλλαγές στην βάση δεδομένων του AD.
γ.) Ακριβώς μετά από την εκτέλεση του garbage collector, (τουλάχιστον μία μέρα μετά τις παραπάνω αλλαγές), αυξάνουμε την τιμή του Tombstone Lifetime στο Hub site. Αυτή η αλλαγή θα μεταφερθεί στους υπολοιπους με το replication. Το σημαντικότερο πριν την εκτέλεση αυτού του βήματος είναι να έχουμε όσο το δυνατότερο την ίδια κατάσταση σχετικά με τα διαγραφέντα αντικείμενα από την προηγούμενη εκτέλεση του garbage collector.
δ.) Εκτέλεση του Schema upgrade,
ε.) Προαιρετικά: μείωση του TBL στην αρχική τιμή. Επιβάλουμε την εκτέλεση του garbage collector ξανά. Μειώνουμε την συχνότητα εκτέλεσης στην προηγούμενη τιμή.
Προς το παρόν δεν υπάρχει κάποιο δημοσιευμένο KB επί του θέματος, αλλά απ' ότι ξέρω βρίσκεται ένα στα σκαριά.
Ελπίζω να βρήκατε τα παραπάνω χρήσιμα! Έστω και αν δεν σκοπεύετε να αναβαθμίσετε το schema σύντομα, τα περισσότερα αφορούν γενικά την λειτουργία του AD replication, οπότε αξίζει να τους ρίξετε μια ματιά!
Φιλικά
SOF
Γειά σας και πάλι μετά από καιρό. Έχω μαζέψει τόσα πολλά θέματα που θέλω να μοιραστώ μαζί σας που δεν ήξερα από που να αρχίσω. :) Διάλεξα λοιπόν να συνεχίσω από εκεί που σας άφησα την τελευταία φορά. Η ιδέα ανήκει στον GSimos.
Το μενού σήμερα έχει λίγο απ’όλα, Windows, Linux, και το αγαπημένο μου θέμα που είναι: μαντέψτε :) Kerberos. Πριν αρχίσω μια μικρή διευκρίνηση, οι γνώσεις μου σχετικά με το Linux είναι <=0, οπότε θα περιοριστώ αποκλειστικά σε αυτά που θα τεστάρω.
Το σημερινό θέμα είναι αρκετά δύσκολο, και προϋποθέτει βασικές γνώσεις σε αρκετά αντικείμενα.
Έχουμε το εξής σενάριο:
- Windows Active Directory Domain.
- Linux Intranet Web Server
- Active Directory Users
Θέλουμε:
- Οι χρήστες του Active Directory να έχουν πρόσβαση στο intranet site που τρέχει σε Linux χωρίς να χρειάζεται να δίνουν ξανά τα στοιχεία τους.
Υπάρχουν πολλές σελίδες στο Internet που παρέχουν πάρα πολλές πληροφορίες πάνω σε αυτό το θέμα, οι περισσότερες όμως είναι για Windows 2000/2003 και XP, θεωρητικά δεν θα πρέπει να διαφέρει σε τίποτα από τα 2008 και Vista/W7, έτσι δεν είναι;
Καλή η θεωρία αλλά για να δούμε στην πράξη. Ας το πάρουμε βήμα βήμα για να δούμε που θα μας βγάλει.
Ας αρχίσουμε λοιπόν.
Βήμα 1ο) Εγκατάσταση λειτουργικών σε Virtual PC.
- Linux Ubuntu-8.10 (Web Server = linuxwebserver)
- Windows Server 2008 (Domain Controller = 2008dc)
- Vista (Client = Vista1)
Βήμα 2ο) Active Directory: βασικές ρυθμίσεις
- Ρυθμίζουμε static IPs. (DC = 192.168.2.100, Vista = 192.168.2.50)
- Εγκατάσταση του DNS Server στον 2008
- dcpromo του Windows Server 2008, (FFL 2008)
- Domain join του Vista client
- Δημιουργία ενός Active Directory χρήστη για testing (intuser).
Βημα 3ο) Linux: βασικές ρυθμίσεις
Ρυθμίζουμε static IP.
Eγκατέστησα έναν DHCP με reservation στο MAC του Linux (IP= 192.168.2.200), επίσης καταχώρησα την IP του DNS Server (192.168.2.100) στο /etc/resolv.conf.
(Εχω ήδη στα VMs μου έναν Windows 2003 router που κάνει NAT, οπότε έβαλα έναν forwarder στον AD DNS να δείχνει σε έναν εξωτερικό, για να κάνω resolve τις διευθύνσεις που χρειάζονται για να εγκαθιστώ τα πακέτα)
To ping dc2008.acme.com από το Linux αργεί απελπιστικά όμως. Για να δούμε το Network Trace.
Reverse DNS queries. Φτιάχνω μια reverse lookup zone στο DNS και τρέχω ένα ipconfig /registerdns πάνω στον DC και τώρα πάει μια χαρά.
Από networking φαίνεται να είμαστε εντάξει. Πάμε στα applications και στις υπόλοιπες ρυθμίσεις.
Βήμα 4ο) Εγκατάσταση του Apache
sudo apt-get install apache2
! Τα επόμενα βήματα απαιτούν αρκετή προσοχή. Μου κόστισε μια μέρα να καταλάβω ότι τα κεφαλαία/μικρά παίζουν πολυ σημαντικό ρόλο. Case Sensitive λοιπόν.
Βήμα 5ο) Δημιουργία του Web Server account στο Active Directory
- Ανοίγω το dsa.msc –> new user –> apacheuser
- Στο command prompt τρέχω:
- setspn -a HTTP/linuxwebserver.acme.com apacheuser
- setspn -a HTTP/linuxwebserver apacheuser
- Για να δημιουργήσω το keytab file:
ktpass -princ HTTP/linuxwebserver.acme.com@ACME.COM -mapuser apacheuser -pass P@ssw0rd -ptype KRB5_NT_PRINCIPAL -out c:\apacheuser.http.keytab
Targeting domain controller: 2008DC.acme.com
Using legacy password setting method
Successfully mapped HTTP/linuxwebserver.acme.com to apacheuser.
Key created.
Output keytab to c:\apacheuser.http.keytab:
Keytab version: 0x502
keysize 72 HTTP/linuxwebserver.acme.com@ACME.COM ptype 1 (KRB5_NT_PRINCIPAL) vno 20 etype 0x17 (RC4-HMAC) keylength 16 (0xe19ccf75ee54e06b06a5907af13cef42)
- Καταχωρώ στο DNS ένα Α Record –> linuxwebserver.acme.com 192.168.2.200
Βήμα 6ο) Ρύθμιση του Kerberos στον Web Server
- sudo apt-get install
- krb5-user
- libpam-krb5 (Πιθανόν να μην χρειάζεται)
- krb5-config
- libkadm55 (Πιθανόν να μην χρειάζεται)
- libapache2-mod-auth-kerb
- Ρύθμιση του /etc/kerb.conf
[libdefaults]
default_realm = ACME.COM
# The following krb5.conf variables are only for MIT Kerberos.
kdc_timesync = 1
ccache_type = 4
forwardable = true
proxiable = true
[realms]
ACME.COM = {
kdc = 2008dc.acme.com:88
admin_server = 2008dc.acme.com
default_domain = acme.com
}
[domain_realm]
.acme.com = ACME.COM
acme.com = ACME.COM
- Αντιγραφή του keytab apacheuser.http.keytab από τον DC sto /etc/apache2/
- Ρύθμιση του /etc/apache2/apache2.conf με τις ακόλουθες επιπλέον εγγραφές
ServerName linuxwebserver.ACME.COM
<Directory "/var/www/">
AuthName "Kerberos Login"
AuthType Kerberos
Krb5Keytab /etc/apache2/apacheuser.http.keytab
KrbAuthRealm ACME.COM
KrbMethodNegotiate on
KrbMethodK5Passwd off
KrbSaveCredentials off
KrbVerifyKDC off
KrbServiceName HTTP/linuxwebserver.acme.com
Require valid-user
</Directory>
- Κάνουμε restart τον Apache: sudo service apache2 restart
Μέχρι στιγμής οι ρυθμίσεις είναι οι ίδιες με τα Windows 2003, για να δούμε αν λειτουργεί το Kerberos authentication από την μεριά του Linux.
Προσπαθούμε πρώτα χωρίς το keytab:
Όπως φαίνεται κάτι δεν πάει καλα, οπότε κοιτάμε το network trace στον DC όπου βλέπουμε το εξής: KRB Error: KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
Κάνοντάς το ένα γρήγορο search βλέπουμε ότι έχει βγεί hotfix για αυτό ακριβώς το θέμα.
An error code is returned when a Kerberos client requests a TGT against a Windows Server 2008-based domain controller: "KERB5KDC_ERR_C_PRINICPAL_UNKNOWN"
Μια μικρή διευκρίνηση: το string της μορφής <service principal name>@<domain name> σύμφωνα με τα RFCs δεν είναι αποδεκτό UPN. Τα Windows 2008 είναι πιο αυστηρά σε αυτό το θέμα, αλλά για όσους θέλουν για λόγους συμβατότητας να χρησιμοποιούν και αυτή την μορφή, μπορούν να εγκαταστήσουν το hotfix.
Ας δούμε μετά το hotfix τα αποτελέσματα:
Ολοκληρώθηκε με επιτυχία! Εδώ και το network trace:
Το τελευταίο πακέτο είναι το σημαντικό που δείχνει ότι λάβαμε το TGT, αυτό που πρέπει να προσέξουμε είναι ότι δεν χρησιμοποιούμε πλέον RC4-HMAC αλλά AES256 για την κρυπτογράφηση του TGT και του session key.
Ας προσπαθήσουμε να δηλωθούμε λοιπόν με το keytab.
“Key table entry no found while getting initial credentials” και εδώ είναι που κολλάμε και αρχίζουμε να τα ξεψαχνίζουμε όλα από την αρχή, SPNs UPNs conf files κτλ.
Ουσιαστικά αυτό που καταλαβαίνουμε από το μύνημα λάθους είναι ότι δεν βρέθηκε η συγκεκριμένη εγγραφή με το κλειδί στο keytab file. H εγγραφή από τι αποτελείται; Από το principal και από το key, εφόσον βεβαιωθούμε ότι το principal είναι σωστό τότε δεν μπορεί να φταίει παρά μόνο το κλειδί.
Βingo! To κλειδί είναι κάτι που άλλαξε από τα 2003. Δεν είναι πλέον RC4-HMAC είναι AES256.
Ας προσπαθήσουμε το εξής
ktpass -princ HTTP/linuxwebserver.acme.com@ACME.COM -mapuser apacheuser -pass P@ssw0rd -crypto AES256-SHA1 -ptype KRB5_NT_PRINCIPAL –out c:\apacheuser.http.keytab
Αντιγράφουμε το keytab file στην γνωστή τοποθεσία /etc/apache2/apacheuser.http.keytab και δοκιμάζουμε ξάνά την τύχη μας.
Δεν πέταξε λάθος οπότε είμαστε σε καλό δρόμο.
Ας τεστάρουμε λοιπόν ολόκληρο το οικοδόμημα. Ρυθμίζουμε τα security settings του Vista έτσι ώστε να χρησιμοποιούμε το Negotiate protocol και απομένει να πατήσουμε το enter στον ΙΕ!
Τζίφος!
στο error.log του apache βλέπουμε:
[client 192.168.2.50] gss_accept_sec_context() failed: Unspecified GSS failure. Minor code may provide more information (Key table entry not found)
Και πάλι δεν μπορούμε να εντοπίσουμε το keytab entry.
Οπότε το μόνο που μας έμεινε είναι να δοκιμάσουμε με άλλη κρυπτογράφηση.
Για να δούμε με Des…
ktpass -princ HTTP/linuxwebserver.acme.com@ACME.COM -mapuser apacheuser -pass P@ssw0rd +Desonly -ptype KRB5_NT_PRINCIPAL -out c:\apacheuser.http.keytab
Targeting domain controller: 2008DC.acme.com
Using legacy password setting method
Successfully mapped HTTP/linuxwebserver.acme.com to apacheuser.
Key created.
Output keytab to c:\apacheuser.http.keytab:
Keytab version: 0x502
keysize 64 HTTP/linuxwebserver.acme.com@ACME.COM ptype 1 (KRB5_NT_PRINCIPAL) vno
24 etype 0x3 (DES-CBC-MD5) keylength 8 (0x193d7f680845431f)
Account apacheuser has been set for DES-only encryption.
Επιτέλους τα καταφέραμε!
Στο access.log του apache βλέπουμε ότι ο intranet user (intuser)απέκτησε πρόσβαση:
192.168.2.50 - intuser@ACME.COM [13/Apr/2009:23:10:34 +0300] "GET / HTTP/1.1" 200 56 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618)"
Και το network trace.. όμορφο έτσι;
Προφανώς ο λόγος που δεν παίζει το AES256, είναι ότι πάει κάτι στραβά στο apache module, αφού με το kinit λειτουργεί μια χαρά.
Το ότι στην λύση μας χρησιμοποιούμε DES αντί για του πολύ ανώτερου AES256 είναι μειονέκτημα, αλλά λιγότερο επικίνδυνο από ενα χαμένο USB stick με τα keytabια μέσα. Ονόματα δεν λέμε οικογένειες δεν θίγουμε :)
Σερφάροντας για να βρώ λύσεις στα προβλήματα πολλές φορές κουράστηκα από το άναρχο documentation του Linux, δεν ήταν λίγες και οι φορές όμως που διαπίστωσα στα forums παρόμοια διάθεση από τους φίλους Linuxάδες.
Το τελικό συμπέρασμα είναι το εξής: το πάντρεμα δύο διαφορετικών τεχνολογιών είναι πάντα δύσκολο, ειδικά αν προκειται για νέα προϊόντα, αλλά όπως δείξαμε όχι ακατόρθωτο.
Eλπίζω το άρθρο να σας φανεί χρήσιμο. Θα χαρώ για σχόλια updates και διορθώσεις.
Φιλικά
SOF
Αρχικά έρχεται στο μυαλό μας ότι κάτι δεν πάει καλά με το Account Lockout Policy, ή κάποιες υπηρεσίες στις οποίες υπάρχει καταχωρημένος ένας κωδικός που έχει λήξει. Όταν όμως αυτή η συμπεριφορά όσο πάει και χειροτερεύει και δεν αφορά έναν μοναδικό λογαριασμό αλλά περισσότερους, είναι πιθανό να έχουμε μια επίθεση στο δίκτυό μας. Όταν για παράδειγμα ένα πρόγραμμα ή ένα Malware προσπαθεί να σπάσει τους κωδικούς διάφορων χρηστών με Brute Force Attack. Όταν μια τέτοια επίθεση είναι αυτοματοποιημένη , τότε κλειδώνονται πολύ γρήγορα ένας μεγάλος αριθμός από λογαριασμούς, λόγω λάθος εισαγωγής κωδικού.
Ένα παράδειγμα είναι το MalWare Win32/Conficker.B (Downandup) το οποίο είναι αυτήν την στιγμή σε έξαρση.
Περισσότερες πληροφορίες για το Malware θα βρείτε εδώ: http://www.microsoft.com/security/portal/Entry.aspx?Name=Worm%3aWin32%2fConficker.B
Το Malware επιτίθεται σε συστήματα που δεν έχουνε εγκατεστημένο το patch MS08-067, http://www.microsoft.com/technet/security/Bulletin/MS08-067.mspx
Στα μηχανήματα που έχουν προσβληθεί από τον ιό ξεκινά μια υπηρεσία με τυχαίο όνομα, και απενεργοποιεί τα services „Automatic Updates“, „Background Intelligent Transfer Service“ kai „Error Reporting Service“. Στο System Event Protocol καταγράφεται η εξής ακολουθία.
12/29/2008 16:00:04 4 0 7035 Service Control Manager NT AUTHORITY\SYSTEM CLIENTNAME RANDOΜ_NAME start
12/29/2008 16:00:05 4 0 7035 Service Control Manager NT AUTHORITY\SYSTEM CLIENTNAME Automatic Updates stop
12/29/2008 16:00:06 4 0 7036 Service Control Manager N/A CLIENTNAME Automatic Updates stopped
12/29/2008 16:00:10 4 0 7040 Service Control Manager NT AUTHORITY\SYSTEM CLIENTNAME Automatic Updates auto start disabled
12/29/2008 16:00:10 4 0 7040 Service Control Manager NT AUTHORITY\SYSTEM CLIENTNAME Background Intelligent Transfer Service demand start disabled
12/29/2008 16:00:10 4 0 7035 Service Control Manager NT AUTHORITY\SYSTEM CLIENTNAME Error Reporting Service stop
12/29/2008 16:00:10 4 0 7036 Service Control Manager N/A CLIENTNAME Error Reporting Service stopped
12/29/2008 16:00:14 4 0 7040 Service Control Manager NT AUTHORITY\SYSTEM CLIENTNAME Error Reporting Service auto start disabled
Στα Services η υπηρεσία του ιού δεν είναι ορατή, γιατί είναι hidden.
Ι ιός του οποίου το Service τρέχει κάτω από το Service Host SVCHOST
Troubleshooting steps.
1) Καταρχάς θα πρέπει να βρούμε τα μηχανήματα που έχουν είδη προσβληθεί, θα πρεπει να ενεργοποιήσουμε το Neltlogon logging σε όλους τους DCs.
http://support.microsoft.com/kb/109626
Τα Account Lockout Tools είναι σε αυτή την περίπτωση επίσης πολύ χρήσιμα.
http://www.microsoft.com/downloads/details.aspx?familyid=7AF2E69C-91F3-4E63-8629-B999ADDE0B9E&displaylang=en
2) Απενεργοποίηση του Server Service για να αποφύγουμε το re-infection.
3) Ενεργοποιούμε το Windows Update και το BITS
4) Κάνουμε reset όλους τους admin passwords με πολύπλοκους κωδικούς.
5) Κατεβάζουμε το GMER Tool για να βρούμε και να απενεργοποιήσουμε την υπηρεσία. http://www.gmer.net/gmer.zip
6) Ενεργοποιούμε το Server Service ξανά.
7) Τρέχουμε το gmer, θα βρεί τον ιο με ένα quick scan.
8) Κάνουμε ένα full scan.
9) Σημειώνουμε το dll που επιστρέφεται από το gmer.
10) Δεξί κλικ στην κόκκινη γραμμή και απενεργοποιούμε την υπηρεσία.
11) Επανεκκίνηση του συστήματος.
12) Μόλις το σύστημα ξεκινήσει, βρίσκουμε το dll που σημειώσαμε προηγουμένως στο εξής path:
c:\windows\system32 (ίσως χρειαστεί να αλλάξουμε τα view settings για να το δούμε)
13) Ανοίγουμε το gpedit στον DC και δημιουργούμε μια software restriction policy βασισμένη στο hash του dll που βρήκαμε. http://technet.microsoft.com/en-us/library/cc786154.aspx
(Μπορούμε επίσης να δημιουργήσουμε ένα local policy για το συγκεκριμένο μηχάνημα
14) Τα παραπάνω βήματα θα σταματήσουν τον ιο τώρα μπορούμε να Patchάρουμε τα μηχανήματά μας!
Καλή επιτυχία!!
Γεια σας, είμαι o Sof! Μπαίνω και εγώ στο trend των ημερών, το outsourcing. Σήμερα θα δούμε πώς μπορούμε να κρύψουμε συγκεκριμένα objects του Active Directory από επιλεγμένους χρήστες ή Groups.
Παίρνουμε για παράδειγμα το εξής σενάριο .Έχουμε ένα Active Directory Integrated Application που τρέχει στο περιβάλλον μας. Αυτό το application εξυπηρετεί δύο διαφορετικές τράπεζες. Σκοπός μας είναι να μην αφήνουμε τους χρήστες της τράπεζας Α να μπορούν να δουν τα Active Directory objects της τράπεζας Β.
Η λύση σε αυτό το πρόβλημα περιγράφεται εδώ:
Controlling Object Visibility
Καταλάβατε κάτι από το παραπάνω άρθρο; Εγώ ειλικρινά χρειάστηκε να το διαβάσω 5-6 φορές μέχρι να βρω τι παίζει.
Ας δούμε παρέα πως γίνεται.
1) Ανοίγουμε το Active Directory Users and Computers. Δημιουργούμε δύο Organizational Units (OUs), μια για κάθε τράπεζα, μέσα στο ΟU θα βρίσκονται όλα τα objects (users, computers κοκ) της τράπεζας. Δημιουργούμε δύο χρήστες, έναν για κάθε OU για τεστ.
Αν δηλωθούμε σε ένα workstation ως BankA_User και θέλουμε να δώσουμε δικαιώματα σε ένα φάκελο, θα δούμε ότι ψάχνοντας στο Active Directory για ονόματα, ο χρήστης της άλλης τράπεζας είναι μέσα στην λίστα μας.
Προφανώς αυτό δεν πρέπει να συμβαίνει. Για αυτό λοιπόν προχωρούμε με τις ρυθμίσεις μας.
2) Στο Active Directory Users and Computers κάνουμε κλίκ στο View--> Advances Features.
3) Κάνοντας δεξί κλικ επάνω στο Bank B OU --> Properties, παρατηρούμε ότι το Security tab του OU είναι πλέον διαθέσιμο. Στα security settings του Bank B OU προσθέτουμε τον χρήστη BankA_User, και κάνουμε deny στο Read.
4) Αν πάμε τώρα στο workstation που είμαστε δηλωμένοι ως BankA_User και προσπαθήσουμε να επιλέξουμε χρήστες για να τους δώσουμε δικαιώματα στα αρχεία μας, θα δούμε ότι ο χρήστης της άλλης τράπεζας BankB_User δεν είναι εκεί. Αυτό ισχύει φυσικά για οποιοδήποτε άλλο object εντός του OU.
Τα παραπάνω είναι απλά ενδεικτικά. Σε κανονικά περιβάλλοντα δεν είναι δυνατόν να κάνουμε deny σε κάθε χρήστη ξεχωριστά. Μπορούμε όμως να ακολουθήσουμε την ίδια μεθοδολογία με Groups.
Εφόσον κάνουμε τις παραπάνω ρυθμίσεις. οποιοδήποτε application τρέχει με τα credentials του χρήστη από την τράπεζα Α θα του αρνείται η πρόσβαση σε αντικείμενα της τράπεζας Β.
Θα χαρώ να απαντήσω σε ερωτήσεις! Θα τα πούμε σύντομα!
Γεια σας! Είμαι ο Sof, σήμερα θα αφιερώσω ολόκληρο το post στο troubleshooting του Kerberos Delegation.
Σε έναν ιδανικό κόσμο όπου τα event logs είναι κάτασπρα δίχως errors και warnings (τα warnings με εκνευρίζουν αφάνταστα!), κανονικά θα έπρεπε να παραλείψω αυτή την ενότητα. Δυστυχώς αυτή η εποχή αργεί ακόμα.
Ας αρχίσουμε λοιπόν. Θα προσπαθήσω να κρατήσω το post απλό, σε καταστάσεις που "καίνε" δεν υπάρχουν περιθώρια για περιττές πληροφορίες.
Εφόσον διαπιστώσουμε ότι τα πράγματα δεν λειτουργούν όπως τα είχαμε φανταστεί το πρώτο βήμα είναι να ελέγξουμε τις ρυθμίσεις.
Ο πιο εύκολος και γρήγορος τρόπος είναι να χρησιμοποιήσουμε το DelegConfig tool που το κάνει αυτόματα για μας. Στο 50% των περιπτώσεων το πρόβλημα εντοπίζεται σε αυτό ακριβώς το σημείο.
Το tool καθώς και οδηγίες εγκατάστασης θα τα βρείτε εδώ: Blog of "Brian Murphy-Booth" a.k.a. "Brian Booth"
Πριν δοκιμάσετε οτιδήποτε άλλο τρέξτε αυτό το utility!!!
Κάποιες φορές αποτυγχάνει η εκτέλεση ακόμα και του troubleshooting tool.
Εδώ είναι που πρέπει να προχωρήσουμε με υπομονή και σχολαστικά και να ελέγξουμε όλες τις παρακάτω ρυθμίσεις.
Checklists
Θα δούμε περιληπτικά τα κυριότερα σημεία που μπορεί να γίνει κάποιο λάθος, θα βρείτε αναλυτικά τις ρυθμίσεις στα δύο προηγούμενα posts.
Checklist 1. Client Side
Ο στόχος μας είναι να βεβαιωθούμε ότι ο client χρησιμοποιεί Kerberos, εκτός και αν έχουμε υλοποιήσει Kerberos Protocol Transition οπότε οι ρυθμίσεις του client δεν παίζουν κανέναν ρόλο.
1) Το application υποστηρίζει Kerberos Authentication.
2) O client να έχει ενταχθεί στο Active Directory forest.
3) ώρα δεν πρέπει να έχει μεγαλύτερη διαφορά από 5 λεπτά από τον Domain Controller.
4) To name resolution λειτουργεί. Κάνοντας ένα ping στο middle tier και στο back end διαπιστώνουμε εάν μπορούμε να κάνουμε resolve τα FQDN τους. Εάν βρισκόμαστε σε διαφορετικό domain από το middle tier βεβαιωνόμαστε ότι χρησιμοποιούμε το FQDN και όχι το NETBIOS.
5) Ο τελικός χρήστης δεν πρέπει να έχει ορισμένη την ρύθμιση: account is sensitive and cannot be delegated
6) Το Application είναι σωστά ρυθμισμένο. Οι ρυθμίσεις φυσικά διαφέρουν από app σε app. Στο πρώτο μέρος είδαμε παραδείγματος χάρη τις ρυθμίσεις που απαιτούνται για τον Internet Explorer.
Περιληπτικά:
Το site πρέπει να είναι καταχωρημένο στις local intranet zones. Και στα security settings να είναι τσεκαρισμένο το automatic logon. Για sites εντός του intranet να παρακάμπτεται ο proxy server
7) Βεβαιωνόμαστε ότι ο Client χρησιμοποιεί Kerberos για την σύνδεσή του με το middle tier.
Υπάρχουν διάφοροι τρόποι για να ελέγξουμε αν ο Client όντως χρησιμοποιεί Kerberos. Προσωπικά προτιμώ να παίρνω ένα network trace στον client χρησιμοποιώντας ένα network sniffer όπως το Wireshark ή το Netmon 3.2.
Good Trace (Kerberos Traffic)
Μπορούμε επίσης να ελέγξουμε τα security logs του web server για successful logon events.
Event Type: Success Audit
Event Source: Security
Event Category: Logon/Logoff
Event ID: 540
Date: 12/6/2008
Time: 8:50:38 AM
User: SOF\TestUser
Computer: IIS-SRV
Description:
Successful Network Logon:
User Name: TestUser
Domain: SOF
Logon ID: (0x0,0x106FB9)
Logon Type: 3
Logon Process: Kerberos
Authentication Package: Kerberos
Workstation Name:
Logon GUID: {09347f79-5bc9-86a9-bb0c-7e4b7c7d16a7}
Checklist 2. Middle Tier
Με το checklist του middle tier βεβαιωνόμαστε ότι οι ρυθμίσεις είναι τέτοιες ώστε να επιτρέπουν να γίνεται delegation.
1) Ελέγχουμε αν ο server και τα services του middle tier υποστηρίζουν Kerberos.
2) Ελέγχουμε αν τα SPN είναι σωστά καταχωρημένα (Έφαγα ένα απόγευμα γιατί αντί για http/iis-srv.sof.local είχα καταχωρίσει htttp/iis-srv.sof.local). Προσωπικά προτιμώ να χρησιμοποιώ το ldifde tool για να βλέπω τα καταχωρημένα SPNs:
ldifde -f SPN.txt -l ServicePrincipalName -r "(ServicePrincipalName=HTTP/IIS-SRV*)" -d DC=sof,dc=local
3) Ανοίγουμε το Active Directory Users and Computers για να ελέγξουμε το Delegation
Σε περίπτωση που χρησιμοποιούμε το computer account του middle tier για delegation:
Αν βρισκόμαστε σε domain level 2000 (το unconstrained delegation ήταν διαθέσιμο ήδη από τα Windows 2000), πάμε στο general tab και τσεκάρουμε το trust computer for delegation.
Αν βρισκόμαστε σε domain level 2003 τότε πάμε στο Delegation Tab και ανάλογα τι θέλουμε να υλοποιήσουμε πρέπει η ανάλογη επιλογή να είναι τσεκαρισμένη.
Unconstrained Delegation: Trust this computer for delegation to any service.
Constrained Delegation: Trust this computer for delegation to specified services (Use Kerberos only) --> Ελέγχουμε εάν έχουμε καταχωρίσει το σωστό service προς το οποίο θα προωθήσουμε τα credentials του τελικού χρήστη.
Protocol Transition: Trust this computer for delegation to specified services (Use any authentication protocol) --> Ελέγχουμε εάν έχουμε καταχωρίσει το σωστό service προς το οποίο θα προωθήσουμε τα credentials του τελικού χρήστη.
Σε περίπτωση που χρησιμοποιούμε ένα user account ως service account για delegation:
Αν βρισκόμαστε σε domain level 2000, πάμε στο account Tab του χρήστη και τσεκάρουμε το account is trusted for delegation
Αν βρισκόμαστε σε domain level 2003 τότε πάμε στο Delegation Tab και ανάλογα τι θέλουμε να υλοποιήσουμε, όπως και στην περίπτωση του computer account, πρέπει η ανάλογη επιλογή να είναι τσεκαρισμένη.
Unconstrained Delegation: Trust this computer for delegation to any service.
Constrained Delegation: Trust this computer for delegation to specified services (Use Kerberos only) --> Ελέγχουμε εάν έχουμε καταχωρίσει το σωστό service προς το οποίο θα προωθήσουμε τα credentials του τελικού χρήστη.
Protocol Transition: Trust this computer for delegation to specified services (Use any authentication protocol) --> Ελέγχουμε εάν έχουμε καταχωρίσει το σωστό service προς το οποίο θα προωθήσουμε τα credentials του τελικού χρήστη.
4) Ελέγχουμε εάν το service account έχει ένα από τα παρακάτω δικαιώματα στον web server. Μπορούμε να δώσουμε τα δικαιώματα είτε τοπικά (Local security policies), είτε με Group Policies.
- Act as part of the operating system
- Impersonate a client after authentication (IIS Worker Process Group)
5) Στην περίπτωση του Protocol Transition to account πρέπει να έχει και δικαίωμα ανάγνωσης του tokenGroupsGlobalAndUniversal Attribute του Active Directory.
6) Τέλος ελέγχουμε εάν το service account έχει αρκετά δικαιώματα πρόσβασης στα resources της εφαρμογής.
Πολλές φορές το application δεν ξεκινά καν για αυτόν ακριβώς τον λόγο.
Checklist 3 Backend
Στην περίπτωση του Backend τα βήματα είναι απλά.
Ουσιαστικά περιορίζονται στα εξής:
1) Στον έλεγχο των SPNs όπως είδαμε στο πρώτο μέρος
2) Τον έλεγχο του αν ο τελικός χρήστης έχει δικαίωμα πρόσβασης στην βάση δεδομένων.
Network trace
Ξέρεις από Βέσπα; Αν όχι αυτά που ακολουθούν είναι ότι πρέπει για να σε πάρει ο ύπνος.
Ας αναλύσουμε ένα επιτυχημένο Network trace για να δούμε τι γίνεται behind the scenes.
Το σενάριο είναι ως εξής, δηλώνομαι από έναν client στο Web Site χρησιμοποιώντας Digest και θέλω να κάνω request στον Backend SQL χρησιμοποιώντας Kerberos. Δηλαδή χρησιμοποιώ protocol transition.
Στο παρακάτω trace θα doυμε ουσιαστικά την παρακάτω διαδικασία
(1). Στα πρώτα πράσινα frames γίνεται το Authentication του χρήστη μέσω Digest, τα frames αυτά δεν παρουσιάζουν κάποιο ιδιαίτερο ενδιαφέρον γι' αυτό δεν θα τα αναλύσουμε.
(2) Στο frame 60 βλέπουμε το εξής (XP Client = 192.168.0.12 , IIS Server = 192.168.0.151, KDC = 192.168.0.101)
Το service (WebAppPollUsr) το οποίο έχει ήδη γίνει authenticated στο KDC και έχει λάβει ένα TGT, ζητά από το KDC ένα service ticket για τον εαυτό του, εκ μέρους του τελικού χρήστη χρησιμοποιώντας το καινούργιο Kerberos extension S4U2self. Ο τελικός χρήστης αναγνωρίζεται από το user name και το realm εντός του PA-S4U2self.
(3) Στο frame 61 το KDC επιστρέφει στο WebAppPool το ticket το οποίο απευθύνεται στο WebAppPool σαν να είχε ζητηθεί με το TGT του Testuser. (XP Client = 192.168.0.12 , IIS Server = 192.168.0.151, KDC = 192.168.0.101)
(6) Συνεχίζουμε με το βήμα 6 μια και το request από τον client στην περίπτωσή μας έχει ήδη γίνει. (XP Client = 192.168.0.12 , IIS Server = 192.168.0.151, KDC = 192.168.0.101)
Στο frame 66 βλέπουμε ότι το service WebAppPoolUsr ζητά ενα service ticket για το SQL service για λογαριασμό του τελικού χρήστη με Constrained Delegation.
(7). Στο frame 69 το KDC ελέγχει το privilege attribute certificate (PAC) τσεκάροντας τα signature data του PAC structure.Εάν είναι έγκυρα τότε το KDC επιστρέφει ένα service ticket για το SQL, αλλά η ταυτότητα του client που βρίσκεται στα πεδία cname και crealm του service ticket είναι αυτά του Testuser και όχι του WebAppPoolUsr.
(8). Από εκεί και πέρα το WebAppPoolUsr χρησιμοποιεί το SQL TGS για τον Testuser για να κάνει ένα AP Request στον SQL και να εκτελέσει το stored procedure. Δυστυχώς ο parser του Wireshark δεν μεταφράζει αυτά τα frames έτσι ώστε να είναι ορατό το AP Request.
(9). To SQL service επιστρέφει τα αποτελέσματα. Στην δική μου περίπτωση ο χρήστης Testuser απέτυχε να εκτελέσει το stored procedure λόγω μη επαρκών δικαιωμάτων.
\.Z:.S.q....C....N..X./.>..ekC.."....=...*.'E..@.....#....?..S........2.e4uS|..?q..)E.*..T.N....1.3...........J.C.a.n.n.o.t. .o.p.e.n. .d.a.t.a.b.a.s.e. .".K.e.r.b.S.4.u.D.B.". .r.e.q.u.e.s.t.e.d. .b.y. .t.h.e. .l.o.g.i.n... .T.h.e. .l.o.g.i.n. .f.a.i.l.e.d....S.Q.L.-.S.R.V.......f..H....%.L.o.g.i.n. .f.a.i.l.e.d. .f.o.r. .u.s.e.r. .'.S.O.F.\.T.e.s.t.U.s.e.r.'....S.Q.L.-.S.R.V...................
Αλλά το Protocol Transition me Kerberos Constrained Delegation πέτυχε!!!!
Εδώ τελειώνει και η μίνι σειρά για το Kerberos Delegation, ελπίζω να ευχαριστηθήκατε τα posts!
To επόμενο post θα είναι για ένα tool-άκι που έγραψα σε c# για να εντοπίζει loops σε group memberships, περισσότερα σύντομα!!!
Γεια σας και πάλι, Sof σπικινγκ (κλεμμένο :P) . Ύστερα απο ένα αναπάντεχο disk failure που με ανάγκασε να ξαναφτιάξω το virtual environment είμαι πάλι εδώ για να συνεχίσουμε την εξερεύνηση μας. Το θέμα μας σήμερα είναι: Protocol Transition.
Στο πρώτο μέρος είδαμε πώς μπορούμε να μεταφέρουμε τα credentials ενός χρήστη από tier σε tier χρησιμοποιώντας Kerberos Constrained Delegation.
Προφανώς προβληματιστήκατε από το γεγονός ότι αφορά μόνο περιβάλλοντα όπου ο web client, web server και SQL server βρίσκονται εντός του Active Directory.
Τι γίνεται στην περίπτωση που ο client βρίσκεται εκτός Active directory; Πριν ανοίξετε το Visual Studio για να αρχίσετε να χτίζετε την custom λύση προώθησης των credentials, ρίχτε μια ματιά στα παρακάτω, είμαι σίγουρος ότι θα τα βρείτε χρήσιμα!!!
Στα Windows Server 2003 έγιναν από την Microsoft κάποιες επεκτάσεις στο πρωτόκολλο Kerberos.
Αυτές οι επεκτάσεις δίνουν την δυνατότητα σε ένα application να αποκτήσει ένα Kerberos ticket εκ μέρους του τελικού χρήστη, έστω και αν αυτός (ο τελικός χρήστης) χρησιμοποίησε κάποιο άλλο πρωτόκολλο κατά την πιστοποίηση στο application. Και όχι μόνο αυτό αλλά και ανεξάρτητα εντελώς με το πιο πρωτόκολλο χρησιμοποιήθηκε.
Αν ακούγεται περίπλοκο δείτε το παρκάτω σχήμα.
Ο τελικός χρήστης πιστοποιείται με μία από τις παραπάνω μεθόδους στον web server αλλά ο web server με την σειρά του "μιλάει" πάντα Kerberos με τον SQL.
Το application αναλαμβάνει την ευθύνη να πιστοποιήσει τον χρήστη και να ζητήσει ένα Kerberos ticket εκ μέρους του χρήστη.
Οι δυνατότητες που έχουμε με αυτού του τύπου την υλοποίηση είναι απεριόριστες!
Πχ. μπορούμε να εκδώσουμε user certificates που θα είναι αντιστοιχισμένα (mapped) στο Active Directory Account, για να δίνουμε την δυνατότητα σε χρήστες εκτός δικτύου Active Directory να καλούν τα queries του SQL για τα οποία έχουν επαρκή rights μέσω SSL.
Ή απλά να υλοποιήσουμε ένα μηχανισμό forms authentication για να αντιστοιχίσουμε τον χρήστη σε ένα Active Directory account.
Η να πάρουμε τα NTLM credentials από ένα trusted Active Directory Domain και να τα μετατρέψουμε σε Kerberos!
Εντυπωσιαστήκατε; Ας δούμε πως υλοποιείται.
Για λόγους συντομίας θα κρατήσω τις ρυθμίσεις από το πρώτο μέρος και θα "χτίσω" πάνω σε αυτές. Οι ρυθμίσεις είναι για ένα application με forms authentication. Προφανώς δεν θα ασχοληθούμε με τις ρυθμίσεις του web client αφού αυτές δεν επηρεάζουν την υλοποίηση μας.
Μια ανασκόπηση στις ρυθμίσεις:
SQL.
1) Ρυθμίζουμε τον SQL να χρησιμοποιεί Windows Integrated Security.
2) Δίνουμε στον χρήστη (TestUser) τα απαραίτητα rights στην βάση δεδομένων.
3) Βεβαιωνόμαστε ότι έχουμε καταχωρίσει το σωστό Service Principal Name (SPN) στο Active Directory.
setspn -a MSSQLSvc/SQL-SRV:1433 SqlServerSvcAccount
setspn -a MSSQLSvc/SQL-SRV.sof.local:1433 SqlServerSvcAccount
Middle Tier
1) Δημιουργούμε τον λογαριασμό χρήστη κάτω από τον οποίο θα τρέχει το web application (WebAppPoolUsr)
2) Καταχώρηση των SPNs του λογαριασμού WebAppPoolUsr
setspn -a HTTP/iis-srv WebAppPoolUsr
setspn -a HTTP/iis-srv.sof.local WebAppPoolUsr
3) Trust this user for delegation to specified services only” --> SQL Service (Kerberos Only)
4) Δημιουργούμε Application Pool (DelegationAppPool). Στα Properties à Identity, εισάγουμε τον λογαριασμό που δημιουργήσαμε (WebAppPoolUsr).
5) Δημιουργούμε ένα Virtual Directory. Το ρυθμίζουμε να χρησιμοποιεί το Application Pool που μόλις φτιάξαμε.
6) Στο Directory Security tab à Authentication and access control à Edit, θα διαλέξουμε Integrated Windows authentication.
7) Το τελευταίο βήμα είναι να καταχωρήσουμε το λογαριασμό του WebAppPoolAccount στο Local Group IIS_WPG. Αυτό του δίνει το “Impersonate a client after authentication right.”
SQL
Οι ρυθμίσεις του SQL παραμένουν οι ίδιες.
Middle Tier
1) Θα ξεκινήσουμε με το Web application που θα το τροποποιήσουμε αναλόγως προκειμένου να υποστηρίζει Protocol Transition.
Η πιο σημαντική γραμμή κώδικα είναι η εξής
WindowsIdentity identity = new WindowsIdentity( <logon name>@<domain> );
Βλέπουμε ότι για να δημιουργήσουμε το Windows Identity που θα χρησιμοποιούμε από εδώ και πέρα δίνουμε απλά το UPN, (το οποίο το έχουμε από την διαδικασία πιστοποίησης), χωρίς να δίνουμε το password, μια και δεν χρειάζεται αφού έχουμε ήδη πιστοποιηθεί από το application.
2) Θα ρυθμίσουμε το Web App να χρησιμοποιεί πλέον Basic Authentication.
3) Θα τροποποιήσουμε τον λογαριασμό του Application Pool (WebAppPoolUser) να προωθεί τα credentials για οποιοδήποτε πρωτόκολλο
4) Θα δώσουμε στον λογαριασμό read access στο tokenGroupsGlobalAndUniversal Attribute του Active Directory.
Στο Active Directory Users and Computers, θα κάνουμε κλικ στο Builtin. θα διαλέξουμε το Windows Authorization Access Group, θα ανοίξουμε τα Properties. Θα προσθέσουμε τον λογαριασμό ως μέλος του Group.
5) Tέλος θα δώσουμε στον WebAppPoolUsr το δικαίωμα Ast As Part of the operating system στον IIS server.
Αυτές είναι και οι ρυθμίσεις που χρειάζονται. Η εφαρμογή μας είναι πλέον έτοιμη να ζητήσει από το KDC ένα Kerberos Ticket για πρόσβαση στον SQL εκ μέρους του δηλωμένου χρήστη!
Τελικά δεν ήταν τόσο περίπλοκο έτσι; Σας προκαλώ να το δοκιμάσετε και μόνοι σας. Το επόμενο μέρος θα είναι αφιερωμένο εξαιρετικά στους troubleshooters, me cool tools και network traces!
Φιλικά
Sof
PS. Η συνεχής αλλαγή γλώσσας με κουράζει αφάνταστα! Θα αρχίσω να γράφω αποκλειστικά Ελληνικά!
Tεστ:
Ή απλά να υλοποιήσουμε ένα μηχανισμό πιστοποίησης με φόρμες (και όχι με τζιν) για να αντιστοιχίσουμε τον χρήστη σε έναν λογαριασμό του Ενεργού Καταλόγου®.
Η να πάρουμε τα πιστοποιητικά ΝΤΛΜ από μία έμπιστη περιοχή Ενεργού Καταλόγου και να τα μετατρέψουμε σε Κέρβεροοο!
Γεια σας, είμαι ο Sof. Το θέμα μας σήμερα είναι: Kerberos Delegation.
Όσοι από εσάς έχουν μπει στην διαδικασία να διαχωρίσουν τα tiers ενός application σε διαφορετικά μηχανήματα εντός του εταιρικού σας δικτύου, και προσπάθησαν τα διατηρήσουν το Single Sign On, έχουν έρθει σίγουρα αντιμέτωποι με το πρόβλημα της προώθησης των credentials του χρήστη από tier σε tier.
Είναι μια διαδικασία που απαιτεί ιδιαίτερη προσοχή, προκειμένου να απαλειφτεί ο κίνδυνος του identity spoofing. Μερικά από τα σημεία που πρέπει να δοθεί ιδιαίτερο βάρος είναι η κρυπτογράφηση των credentials κατά την μεταφορά τους, η αμοιβαία πιστοποίηση των συναλλασσόμενων μερών, καθώς και η αποφυγή του replay attack.
Όλα τα παραπάνω είναι ενσωματωμένα στο Kerberos, γεγονός που μας δίνει την δυνατότητα να αποφύγουμε extra ώρες δουλειάς προκειμένου να ασφαλίσουμε την υλοποίηση μας.
Στο παρακάτω κείμενο θα δούμε ποιές επιλογές έχουμε, και πώς υλοποιούνται.
Δεν θα μπω σε λεπτομέρειες για το πώς λειτουργεί συνολικά το Kerberos και θα αποφύγω τα περιττά screenshots, μιας και εσείς που διαβάζετε το κείμενο είμαι σίγουρος ότι ξέρετε να προσθέτετε ένα user στο Active Directory!
Unconstrained Kerberos Delegation.
Ήδη από τις πρώτες μέρες του Active Directory οι administrators είχαν την δυνατότητα να εκμεταλευτούν τις δυνατότητες που προσφέρει η λύση της Microsoft.
Ένα τυπικό παράδειγμα είναι το εξής:
Θέλουμε ένα Intranet Web Application που τρέχει πάνω στον IIS να μπορεί να συνδεθεί στον Back End SQL Server με τα credentials του τελικού χρήστη, εκμεταλλευόμενο το SQL Windows Integrated Security.
Ας δούμε αναλυτικά τα μέρη που συμμετέχουν σε αυτή την διαδικασία και τις ρυθμίσεις τους.
Back-end - SQL Server:
1) Ρυθμίζουμε τον SQL να χρησιμοποιεί Windows Integrated Security.
2) Δίνουμε στον χρήστη (TestUser) τα απαραίτητα rights στην βάση δεδομένων.
3) Βεβαιωνόμαστε ότι έχουμε καταχωρίσει το σωστό Service Principal Name (SPN) στο Active Directory.
! Σε αυτό ακριβώς το βήμα γίνονται και τα περισσότερα λάθη στις ρυθμίσεις.
Λίγη θεωρία:
Το SPN είναι εγγραφή (attribute) που βρίσκεται εντός του user ή computer object στο Active Directory. Κάθε εγγραφή περιέχει τα στοιχεία μιας υπηρεσίας όπως:
· τύπος (http, ldap)
· host . (iis-srv.contoso.com)
· port (5000)
· όνομα της υπηρεσίας
Παραδείγματα:
HTTP/iis-srv.sof.local:5000
HOST/DC1.sof.local/sof.local
ldap/DC1
Ο συνδυασμός των παραπάνω ορίζει μοναδικά μια υπηρεσία. Με την καταχώριση του SPN πετυχαίνουμε να συσχετίσουμε ένα service με το account κάτω από το οποίο τρέχει αυτή η υπηρεσία.
Τα SPNs είναι δομικά στοιχεία της λειτουργίας του Kerberos.
Όπως είναι φυσικό αν το ίδιο service είναι καταχωρημένο κάτω από δύο διαφορετικά accounts τότε υπάρχει πρόβλημα. Μία υπηρεσία τρέχει πάντα στο security context ενός συγκεκριμένου account.
Αρκετά με την θεωρία ας πάμε πίσω στις ρυθμίσεις. Είχαμε μείνει στην καταχώριση του SPN.
To SQL service τρέχει κάτω από λογαριασμό SOF\SqlServerSvcAccount. (SOF είναι το NETBIOS όνομα του Domain.). Δημιουργήσαμε τον λογαριασμό ακριβώς για αυτό τον σκοπό.
Πρέπει λοιπόν να καταχωρήσουμε το SPN της υπηρεσίας SQL στα Attributes του SqlServerSvcAccount. Θα χρησιμοποιήσουμε την παρακάτω εντολή:
setspn -a MSSQLSvc/SQL-SRV:1433 SqlServerSvcAccount
setspn -a MSSQLSvc/SQL-SRV.sof.local:1433 SqlServerSvcAccount
Ας δούμε τώρα τα SPNs για τον λογαριασμό SqlServerSvcAccount:
setspn -l SQLServerSvcAccount
Όπως βλέπετε έχουμε καταχωρήσει SPN για FQDN και NETBIOS name.
Ολοκληρώνοντας τις ρυθμίσεις του SQL πρέπει να βεβαιωθούμε ότι δεν έχουμε καταχωρήσει το ίδιο SPN σε δύο διαφορετικούς λογαριασμούς. Συνήθης ύποπτος είναι το computer account του SQL.
Μπορούμε να τρέξουμε την επόμενη εντολή σε έναν Domain Controller και να ελέγξουμε το output file SPN.txt για διπλά SPNs
ldifde -f SPN.txt -l ServicePrincipalName -r "(ServicePrincipalName=MSSQLSvc/SQL-SRV*)" -d DC=sof,dc=local
Middle Tier - Web Server:
O web server έχει το ρόλο του ενδιάμεσου. Οι ρυθμίσεις μας πρέπει είναι τέτοιες έτσι ώστε ο web server να μπορεί να προωθήσει τα credentials που λαμβάνει από τον client στον SQL server.
Αλλά ας πάρουμε τα πράγματα από την αρχή.
1) Δημιουργούμε τον λογαριασμό χρήστη κάτω από τον οποίο θα τρέχει το web application.
2) Καταχώρηση των SPNs του λογαριασμού WebAppPoolUsr
setspn -a HTTP/iis-srv WebAppPoolUsr
setspn -a HTTP/iis-srv.sof.local WebAppPoolUsr
Εφόσον καταχωρήσουμε τα SPNs, εάν ανοίξουμε το Active Directory Users and Computers, θα διαπιστώσουμε ότι στα Properties του χρήστη εμφανίστηκε το Delegation Tab.
3) Θα επιλέξουμε να εμπιστευθούμε αυτόν το χρήστη για Delegation σε οποιαδήποτε υπηρεσία (Unconstrained Delegation). Ουσιαστικά αυτή είναι και η ρύθμιση που κάνει την διαφορά. Ενεργοποιώντας αυτή την επιλογή εξουσιοδοτούμε το Web Service Account να πράξει εκ μέρους του καλούντος χρήστη. Στο συγκεκριμένο σενάριο να συνδεθεί με το Backend SQL.
4) Θα δημιουργήσουμε ένα νέο Application Pool στον IIS Manager που θα το ονομάσουμε DelegationAppPool. Στα Properties --> Identity, θα έχουμε την ευκαιρία να εισάγουμε τον λογαριασμό που δημιουργήσαμε.
5) Θα δημιουργήσουμε ένα νέο Virtual Directory που θα κάνει εξυπηρετεί το Web Application.
Στα properties του Virtual Directory θα ρυθμίσουμε να χρησιμοποιεί το Application Pool που μόλις φτιάξαμε.
6) Στο Directory Security tab --> Authentication and access control --> Edit, θα διαλέξουμε Integrated Windows authentication.
7) Το τελευταίο βήμα είναι να καταχωρήσουμε το λογαριασμό του WebAppPoolAccount στο Local Group IIS_WPG. Αυτό του δίνει το “Impersonate a client after authentication right.”
Client Side – Internet Explorer
Σε αυτήν την περίπτωση ο Client είναι ο Internet Explorer.
1) Προσθέτουμε το Site στο Local Intranet Zone.
2) Βεβαιωνόμαστε ότι το Automatic Logon είναι τσεκαρισμένο για το Local Intranet Zone.
3) Ρυθμίζουμε τα Connection Settings έτσι ώστε να μην χρησιμοποιείται ο proxy για τις διευθύνσεις που βρίσκονται εντός εταιρικού δικτύου.
Οι παραπάνω ρυθμίσεις μπορούν να γίνουν φυσικά και με Group Policies, κάτι το οποίο προτείνω γιατί κρατάμε τον έλεγχο και αποφεύγουμε λάθος ρυθμίσεις από «ειδικούς».
Στην πράξη
Εφόσον ολοκληρώσουμε τις παραπάνω ρυθμίσεις είμαστε έτοιμοι να δοκιμάσουμε την υλοποίηση μας.
Εδώ ένα screenshot από το δικό μου Web Application:
Σε αυτό το Web App δεν κάναμε τίποτα άλλο από το να εκτελέσουμε ένα Stored Procedure στον SQL που μας επιστρέφει το όνομα του χρήστη.
Το πείραμα στέφθηκε με επιτυχία! To stored procedure επέστρεψε SOF\TestUser χωρίς να χρειαστεί να δώσω τα credentials παρά μόνο μία φορά, την στιγμή που δηλώθηκα στον υπολογιστή!
Χωρίς να μπω σε λεπτομέρειες, σε C# το impersonation επιτυγχάνεται ως εξής:
using System.Web.Security;
using System.Security;
using System.Security.Principal;
….
WinId = HttpContext.Current.User.Identity;
wi = (WindowsIdentity)WinId;
….
WindowsImpersonationContext wic = wi.Impersonate();
….
//Εκτέλεση κώδικα στο context του impersonated user
….
wic.Undo();
Στο πιο πάνω screenshot εκτός από το button που εκτελεί το stored procedure, υπάρχει και ένα δεύτερο. Το button Connect μας συνδέει με ένα SMB share και επιστρέφει έναν κατάλογο με τα αρχεία που περιέχει.
Εδώ ερχόμαστε αντιμέτωποι με το εξής πρόβλημα, εφόσον εμπιστευθούμε τον χρήστη WebAppPoolUsr να μας εκπροσωπεί, αυτός μπορεί να το κάνει για οποιοδήποτε Service, είτε πρόκειται για SQL είτε για SMB, CA ή ότι άλλο.
Προφανώς λοιπόν με τις παραπάνω ρυθμίσεις το Connect όπως φαίνεται παραπάνω θα λειτουργήσει.
Το πρόβλημα αυτό λύθηκε με τα Windows Server 2003. Η λύση λέγεται Kerberos Constrained Delegation
Kerberos Constrained Delegation
Το Kerberos Constrained Delegation δεν κάνει τίποτα άλλο από το να καθορίζει για ποιες ακριβώς υπηρεσίες εμπιστευόμαστε έναν χρήστη να μας εκπροσωπήσει.
Στην περίπτωσή μας θέλουμε ο WebAppPoolUsr να έχει το δικαίωμα να μας εκπροσωπεί μόνο στο SQL service.
Προφανώς η σχεδίαση αυτή δίνει μεγαλύτερη ασφάλεια στον τρόπο που διαχειριζόμαστε το Delegation. Σε περίπτωση που τα στοιχεία του χρήστη WebAppPoolUsr κλαπούν τότε περιορίζουμε την ζημιά στον SQL server.
Για να εκμεταλλευτούμε την δυνατότητα του Constrained Delegation το Active Directory domain level πρέπει να είναι 2003 ή ανώτερο. Επίσης δεν μπορούμε να το χρησιμοποιήσουμε για services που βρίσκονται σε διαφορετικά domains. Πχ. O web Server και ο SQL πρέπει να βρίσκονται στο ίδιο domain. Ο client από την μεριά του μπορεί να βρίσκεται σε οποιοδήποτε domain του Forest.
Ας δούμε τις ρυθμίσεις:
Αν ανοίξουμε το Active Directory Users and Computers και πάμε στις ιδιότητες του χρήστη WebAppPoolUsr, στο tab Delegation θα παρατηρήσουμε ότι έχουμε την επιλογή “Trust this user for delegation to specified services only”. Διαλέγοντας αυτή την επιλογή έχουμε την δυνατότητα να περιορίσουμε τα services για τα οποία ο λογαριασμός αυτός μπορεί να προωθήσει credentials. Για το δικό μας σενάριο διαλέγουμε το SQL Service.
Αυτή η ρύθμιση είναι αρκετή για να χρησιμοποιήσουμε το constrained delegation. Αν δοκιμάσω ξανά με το Connect στο web application αυτή τη φορά θα λάβουμε ένα μήνυμα λάθους.
! Tip: αν θέλετε να διαπιστώσετε αμέσως την διαφορά πρέπει να διαγράψετε τα cached Kerberos tickets του TestUser στον client. (klist.exe purge)
Αυτά όσον αφορά το Kerberos Constrained Delegation.
Ελπίζω τα παραπάνω να σας φανούν χρήσιμα! Αν σας είναι ήδη γνωστά μην απογοητεύεστε, μείνετε συντονισμένοι γιατί ακολουθεί Kerberos Protocol Transition και troubleshooting με cool tools και network traces!
Θα χαρώ να απαντήσω σε ερωτήσεις αρκεί να γνωρίζω την απάντηση!
Φιλικά!
Sof