Partager via


Kerberos domain routing

So the scenarios is pretty simple.

Forest trust like so:

 

image

Basic problem. User tried to access sharepoint and fails to use Kerberos.

So we can review the end to end process ( still at a high level )

1. User logs on

2. User gets TGT for kz.com domain

3. User requests a TGS for http/AMSH

4. DC doesn't find the SPN

5. DC queries the GC for all servers in the forest for the SPN

6. SPN not found

7. DC (GC ) checks its forest trust info for trusts that are established with its forest, and, if found, it compares the name suffixes listed in the forest trust trusted domain object (TDO) to the suffix of the target SPN to find a match

a. let's examine that bit of info for a minute.

Here is the data from the AD, grabbed from both sides of the trust.

dn: CN=kz.com,CN=System,DC=spat,DC=com

changetype: add

objectClass: top

objectClass: leaf

objectClass: trustedDomain

cn: kz.com

distinguishedName: CN=kz.com,CN=System,DC=spat,DC=com

instanceType: 4

whenCreated: 20080815081653.0Z

whenChanged: 20080815081700.0Z

uSNCreated: 28889

uSNChanged: 28891

showInAdvancedViewOnly: TRUE

name: kz.com

objectGUID:: 9V8zcH6/i0Wbt//1qEmeAw==

securityIdentifier:: AQQAAAAAAAUVAAAAucwqv/m5b+9l/yCu

trustDirection: 2 #define TRUST_DIRECTION_OUTBOUND 0x00000002

trustPartner: kz.com

trustPosixOffset: -2147483648

trustType: 2 #define TRUST_TYPE_UPLEVEL 0x00000002

trustAttributes: 8 #define TRUST_ATTRIBUTE_FOREST_TRANSITIVE 0x00000008

flatName: KZ

objectCategory: CN=Trusted-Domain,CN=Schema,CN=Configuration,DC=spat,DC=com

isCriticalSystemObject: TRUE

msDS-TrustForestTrustInfo::

 AQAAAAIAAAAXAAAAAAAAAK/+yAFpQFxKAAYAAABhdS5uZXQ5AAAAAAAAAK/+yAFpQFxKAhgAAAABBA

 AAAAAABRUAAAC5zCq/+blv72X/IK4GAAAAYXUubmV0AgAAAEFV

dn: CN=spat.com,CN=System,DC=kz,DC=com

changetype: add

objectClass: top

objectClass: leaf

objectClass: trustedDomain

cn: spat.com

distinguishedName: CN=spat.com,CN=System,DC=kz,DC=com

instanceType: 4

whenCreated: 20080815081613.0Z

whenChanged: 20080815081619.0Z

uSNCreated: 24663

uSNChanged: 24670

showInAdvancedViewOnly: TRUE

name: spat.com

objectGUID:: Xr8tbptbSkyuGg7XD2o9Gg==

securityIdentifier:: AQQAAAAAAAUVAAAAk07wgTv3rlETk9Dd

trustDirection: 1 #define TRUST_DIRECTION_INBOUND 0x00000001

trustPartner: spat.com

trustPosixOffset: 0

trustType: 2 #define TRUST_TYPE_UPLEVEL 0x00000002

trustAttributes: 8 #define TRUST_ATTRIBUTE_FOREST_TRANSITIVE 0x00000008

flatName: SPAT

objectCategory: CN=Trusted-Domain,CN=Schema,CN=Configuration,DC=kz,DC=com

isCriticalSystemObject: TRUE

msDS-TrustForestTrustInfo::

 AQAAAAIAAAAXAAAAAAAAAK/+yAF99yAyAAYAAABhbS5uZXQ5AAAAAAAAAK/+yAF99yAyAhgAAAABBA

 AAAAAABRUAAACTTvCBO/euUROT0N0GAAAAYW0ubmV0AgAAAEFN

 

 

 

Here is the relevant data type to interpret some of the info hilighted above.

 

typedef struct _TRUSTED_DOMAIN_INFORMATION_EX {
LSA_UNICODE_STRING Name;
LSA_UNICODE_STRING FlatName;

PSID Sid;
  ULONG TrustDirection;
ULONG TrustType;
ULONG TrustAttributes;

} TRUSTED_DOMAIN_INFORMATION_EX,
*PTRUSTED_DOMAIN_INFORMATION_EX;

 

In order to read the msDS-TrustForestTrustInfo attribute we can see the following documentation:

 

From the MCPP docs..

 

Information about trust relationships with other forests is stored in objects of class trustedomain in the domain NC replica of the forest root domain. Specifically, the msDS-TrustForestTrustInfo attribute on such objects contains information about the trusted forest or realm. The structure of the information contained in this attribute is represented in the following manner.

 

 

Version (4 bytes): Version of the data structure. The only supported version of the data structure is 1.

RecordCount (4 bytes): Number of records present in the data structure.

Records (variable): Variable-length records each containing a specific type of data about the forest trust relationship.

 

 

And it goes on and on about how it stores the data..

 

In the end, for reading it, you can simply use the following command:

netdom trust kz.com /domain:spat.com /namesuffixes:spat.com

Name, Type, Status, Notes

1. *.spat.com, Name Suffix, Enabled

2. spat.com, Domain DNS name, Enabled

3. SPAT, Domain NetBIOS name, Enabled, For spat.com

4. s-1-5-21--2114957677-1370421051--573533421, Domain SID, Enabled, For spat.com

So it makes sense that it can look at the msDS-TrustForestTrustInfo and determine if the SPN matches a specific suffix and route accordingly.

However .. if we look at a few pieces of data we can see where and why it was failing.

A quick network trace shows the error:

KERBEROS: Error code (error-code[6]) = Server not found in Kerberos database

KERBEROS: Principal name value (name-string[1]) =HTTP/amsh

If we can't guess the problem from that - some additional info from the KDCSVC logging shows:

408.924> KDC-Warning: KdcFindReferralTarget KLIN(40b02ae) Failed to find referral target amsh

Guess the problem?

How can we know where to route this SPN request? The server looks at it - finds the hostname of the machine and the servicetype but has no idea on how to route it to spat.com

KdcFindReferralTarget is a very descriptive name , and if you are so inclined , hook a debugger to your DC and explore it a bit. But you will see that the name says it all --- go find a referral target - oh ummm.. couldn't find one since there is not enough info to route this .. sorry.

Answer: Connect via IE to the FQDN .... https://amsh.spat.com , now we match the SPN to a known suffix and can route the data properly. The SPN is http/amsh.spat.com and from the msDS-TrustForestTrustInfo attribute data we can see this is a routable suffix so it will send it to the proper forest.

OK next problem.

The MOSS server will really be addressed via a CNAME -- like https://www.contoso.com

Hrmm .. even if we used the FQDN - we can see from the data above that there is no way to find contoso.com - since it is not a real forest trust we hold. And in this case.. we will end up in the same boat. No routing info.

Turns out there are these magical things called Routing Name suffixes. From https://technet.microsoft.com/en-us/library/cc784334.aspx

( BTW , if you wonder why I always paste in relevant info from a site - is because I never know when it will change or just up and disappear )

Routing name suffixes across forests

Name suffix routing is a mechanism used to manage how authentication requests are routed across Windows Server 2003 forests that are joined together by forest trusts. To simplify administration of authentication requests, when a forest trust is initially created, all unique name suffixes are routed by default. A unique name suffix is a name suffix within a forest, such as a user principal name (UPN) suffix, service principal name (SPN) suffix, or DNS forest or domain tree name, that is not subordinate to any other name suffix. For example, the DNS forest name microsoft.com is a unique name suffix within the microsoft.com forest.

Forests can contain multiple unique name suffixes, and all children of unique name suffixes are routed implicitly. In Active Directory Domains and Trusts, name suffixes appear with an asterisk (*) at the beginning because of this. For example, if your forest uses *.microsoft.com as a unique name suffix, then authentication requests for all children of microsoft.com (*.child.microsoft.com) will be routed because the child domains are part of the microsoft.com name suffix.

If a forest trust exists between two forests, then name suffixes that do not exist in one forest can be used to route authentication requests to a second forest. When a new child name suffix (*.child.widgets.com) is added to a unique name suffix (*.widgets.com), the child name suffix will inherit the routing configuration of the unique name suffix to which it belongs. Any new unique name suffixes that are created after a forest trust has been established will be visible in the forest trust Properties dialog box after you verify the trust. However, routing for those new unique name suffixes will be disabled by default. For more information about how to verify a trust, see Verify a trust.

When a duplicate name suffix is detected, the routing for the newest name suffix will be disabled by default. For more information about how to route name suffixes, see Enable or disable an existing name suffix from routing. Administrators can use the forest trust Properties dialog box to manually prevent authentication requests for specific name suffixes from being routed to a forest.

So we need to add a new suffix.

On the TRUSTING domain ( in this case SPAT.COM ) go to AD domains and trust and add a new UPN suffix to the forest.

 

image

 

image

Contoso.com for example.

Then - on the TRUSTED domain ( KZ.COM ) go to the trust information for SPAT.COM and click on the properties.

 

image

 

There is a name suffix routing tab and it should show the new suffix as disabled - enable it and now we can verify the routing via the netdom parsing of msDS-TrustForestTrustInfo

 

image

netdom trust kz.com /domain:spat.com /namesuffixes:spat.com

Name, Type, Status, Notes

1. *.spat.com, Name Suffix, Enabled

2. *.contoso.com, Name Suffix, Enabled

3. spat.com, Domain DNS name, Enabled

4. SPAT, Domain NetBIOS name, Enabled, For spat.com

5. s-1-5-21--2114957677-1370421051--573533421, Domain SID, Enabled, For spat.com

Now when the user goes to access www.contoso.com - it will get sent through the SPAT.COM trust info.

In your kerb ticket list - you end up seeing the following:

HTTP/www.contoso.com@SPAT.COM

Other note - for ms-DS-SPN-Suffixes - check it out.

Maybe I'll talk about this some other time.

spatdsg

PS : where's waldo, from the data in this post - tell me what the real names of the domains were... not that they were really real, they were fake real ( lab like ) but it's a fun game to play.

Comments

  • Anonymous
    August 21, 2008
    So is it just "Spat" in person, or perhaps Mr. Spat?  What do people call you when you post something not-quite-right, perhaps SpatUlar.  Anyway, feel free to ignore this drivel ... it's here 'cause I can't tell if my comments on MSDN are actually getting there (could simply be they're all being screened of course but that's a lot of screening.)

  • Anonymous
    August 21, 2008
    ... and after all that drivel, I forget your question :0/ -

  • au.net / AU

  • am.net / AM ... no moderation here huh?  Trusting fellow aren't we. :0)

  • Anonymous
    August 24, 2008
    Ya no moderating.. i am a bit trusting maybe --- should I turn it off? I see ill make my next puzzle more interesting :)

  • Anonymous
    August 27, 2008
    If you've no reason to moderate based on past comments ... for me, I wouldn't bother until something changes. As for your puzzle - yeah, it was interesting enough to motivate me to decode those blobs.

  • Anonymous
    September 01, 2008
    Wow thats impressive. On a hunch I tried certutil to decode. Is that how you did it Dean?

  • Anonymous
    September 02, 2008
    The comment has been removed

  • Anonymous
    September 08, 2008
    Also exists a utility called base64 which you can still get from here: http://www.fourmilab.ch/webtools/base64/ Copy the msDS-TrustForestTrustInfo blob to a text file and remove all the spaces and returns and use it as your input file. The output file is the converted data and reveals the real names of the domains. V.interesting read! Thanks!

  • Anonymous
    March 01, 2009
    Hi Spat, Nice article. Hey what if the service accounts for MOSS are from kz.com? This should work right? The SPN lookup is just done within the the user's domain and it should just work? I've set up the exact scenario above with just a plain IIS server instead of MOSS, I'm running the IIS AppPool under a kz.com service account added; the SPN for webtest and webser.kz.com but I always just get an IIS error 500. I'm heading towards a split back-to-back MOSS project where the web servers will be in the perimeter and everything else including SQl will be in the corp network with a one way forest trust from corp to perimeter. Any tips or direction would be much appreciated. Cheers, Rhys

  • Anonymous
    September 23, 2017
    The comment has been removed