Jump to content
  • entries
    16
  • comments
    22
  • views
    6450

Kerberos Delegetion (Μέρος 1ο, Implementation)


SOF

1027 views

 Share

 

Γεια σας, είμαι ο 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.

Ένα τυπικό παράδειγμα είναι το εξής:

 

ev_007

 

Θέλουμε ένα 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.). Δημιουργήσαμε τον λογαριασμό ακριβώς για αυτό τον σκοπό.

KerbDel2

Πρέπει λοιπόν να καταχωρήσουμε το 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

KerbDel3

Όπως βλέπετε έχουμε καταχωρήσει 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.

KerbDel4

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.

KerbDel5

4)     Θα δημιουργήσουμε ένα νέο Application Pool στον IIS Manager που θα το ονομάσουμε DelegationAppPool. Στα Properties --> Identity, θα έχουμε την ευκαιρία να εισάγουμε τον λογαριασμό  που δημιουργήσαμε.

KerbDel6

5)     Θα δημιουργήσουμε ένα νέο Virtual Directory που θα κάνει εξυπηρετεί το Web Application.

Στα properties του Virtual Directory θα ρυθμίσουμε να χρησιμοποιεί το Application Pool που μόλις φτιάξαμε.

KerbDel7

6)     Στο Directory Security tab --> Authentication and access control --> Edit, θα διαλέξουμε Integrated Windows authentication.

KerbDel8

7)     Το τελευταίο βήμα είναι να καταχωρήσουμε το λογαριασμό του WebAppPoolAccount στο Local Group IIS_WPG. Αυτό του δίνει το “Impersonate a client after authentication right.”

KerbDel9

Client Side – Internet Explorer

Σε αυτήν την περίπτωση ο Client είναι ο Internet Explorer.

1)     Προσθέτουμε το Site στο Local Intranet Zone.

KerbDel10

2)     Βεβαιωνόμαστε ότι το Automatic Logon είναι τσεκαρισμένο για το Local Intranet Zone.

KerbDel11

3)     Ρυθμίζουμε τα Connection Settings έτσι ώστε να μην χρησιμοποιείται ο proxy για τις διευθύνσεις που βρίσκονται εντός εταιρικού δικτύου.

KerbDel12

Οι παραπάνω ρυθμίσεις μπορούν να γίνουν φυσικά και με Group Policies, κάτι το οποίο προτείνω γιατί κρατάμε τον έλεγχο και αποφεύγουμε λάθος ρυθμίσεις από «ειδικούς».

Στην πράξη

Εφόσον ολοκληρώσουμε τις παραπάνω ρυθμίσεις είμαστε έτοιμοι να δοκιμάσουμε την υλοποίηση μας.

Εδώ ένα screenshot από το δικό μου Web Application:

KerbDel13

Σε αυτό το 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 και επιστρέφει έναν κατάλογο με τα αρχεία που περιέχει.

KerbDel14

Εδώ ερχόμαστε αντιμέτωποι με το εξής πρόβλημα, εφόσον εμπιστευθούμε τον χρήστη WebAppPoolUsr να μας εκπροσωπεί, αυτός μπορεί να το κάνει για οποιοδήποτε Service, είτε πρόκειται για SQL είτε για SMB, CA ή ότι άλλο.

Προφανώς λοιπόν με τις παραπάνω ρυθμίσεις το Connect όπως φαίνεται παραπάνω θα λειτουργήσει.

Το πρόβλημα αυτό λύθηκε με τα Windows Server 2003. Η λύση λέγεται Kerberos Constrained Delegation

 

Kerberos Constrained Delegation

Το Kerberos Constrained Delegation δεν κάνει τίποτα άλλο από το να καθορίζει για ποιες ακριβώς υπηρεσίες εμπιστευόμαστε έναν χρήστη να μας εκπροσωπήσει.

Στην περίπτωσή μας θέλουμε ο WebAppPoolUsr να έχει το δικαίωμα να μας εκπροσωπεί μόνο στο SQL service.

ev_011

Προφανώς η σχεδίαση αυτή δίνει μεγαλύτερη ασφάλεια στον τρόπο που διαχειριζόμαστε το 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.

KerbDel16

Αυτή η ρύθμιση είναι αρκετή για να χρησιμοποιήσουμε το constrained delegation. Αν δοκιμάσω ξανά με το Connect στο web application αυτή τη φορά θα λάβουμε ένα μήνυμα λάθους.

KerbDel17

! Tip: αν θέλετε να διαπιστώσετε αμέσως την διαφορά πρέπει να διαγράψετε τα cached Kerberos tickets του TestUser στον client. (klist.exe purge)

 

Αυτά όσον αφορά το Kerberos Constrained Delegation.

Ελπίζω τα παραπάνω να σας φανούν χρήσιμα! Αν σας είναι ήδη γνωστά μην απογοητεύεστε, μείνετε συντονισμένοι γιατί ακολουθεί Kerberos Protocol Transition και troubleshooting με cool tools και network traces!

Θα χαρώ να απαντήσω σε ερωτήσεις αρκεί να γνωρίζω την απάντηση!

 

Φιλικά!

Sof

 

 Share

5 Comments


Recommended Comments

"Αν σας είναι ήδη γνωστά μην απογοητεύεστε"

Χαχα! Ωραία αστεία λες συναγωνιστή Sof! Τόσα χρόνια στο κουρμπέτι είναι η πρώτη φορά που βλέπω άρθρο στη μητρική μου γλώσσα για τέτοιο θέμα. Περιμένουμε εναγωνίως και τα υπόλοιπα του "σετ"!

Link to comment

Αν έρθουν και άλλα τέτοια άρθρα (γιατί δεν είναι απλά posts) τότε μάλλον να το κλείσουμε το portal και να φτιάξουμε έναν εκδοτικό οίκο...

 

ΜΠΡΑΒΟ!

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...