Sunday, November 4. 2018
MS-SFU kerberos extensions and cross-realm support
The last month I have been working in a enhancement to make SFU kerberos extensions in Java to work in multi-realm environments. The MS-SFU (Microsoft Service for User) are two kerberos extensions created by Microsoft to provide delegation and impersonation features to the kerberos standard. Delegation is managed by the S4U2proxy extension, a server can request a kerberos ticket on behalf of a user to access a subsequent server. For that with the server's own ticket and the user's ticket the server requests to the KDC (Kerberos Domain Controller) another ticket to connect to a backend server. The ticket is issued and the access to the backend server is performed as it was done by the initial user that connected to the intermediate server. The impersonation moves delegation one step forward, performed by the S4U2self extension, the frontend server in this case is a legacy server (as Microsoft calls it) which does not support kerberos, therefore there is no ticket for the user (the final user logged in using another method, for example common username and password), and this intermediate server performs a full impersonation with its own ticket to access the final backend on behalf of the user. Obviously this features should be configured, the frontend server should be granted with rights to do both operations, and Microsoft currently gives several ways of granting those privileges.
In general the SFU extensions are old and supported by Java since Java 8 but with windows 2012R2 Microsoft added support to cross-realm access. Previously the three roles (final user, frontend server and backend server) should be in the same realm/domain but a new concept, called resource-based constrained delegation, was incorporated to expanse SFU for multi-realm. The JDK never supported the new feature as stated in this JDK bug.
In theory the documentation for MS-SFU is available in the first link at the beginning of this entry but, in my humble opinion, the explanation of how to call both extensions leaves much to be desired. To my surprise, after a lot of tests and tries, when my two demos (delegation and impersonation) started to work, the procedure was not so difficult as it seems to be. Therefore I decided to write how cross-realm for SFU works for me in windows, in an easier way than official documentation.
S4U2self:
In the self (impersonation) extension the idea is simple, there are two roles, the user to impersonate and the server that impersonates. First the server should know in which realm the user is located (that part is out of the scope of this explanation). Once you know the realm where the user resides, you get a TGT (ticket) to that realm and perform a S4U2self against the KDC of the user's realm. The KDC returns a proper ticket with the information for that user (PAC extensions with roles and everything is included in the credentials) because, in the end, this is the KDC for the user, the one that knows the account information. After that, the ticket received is updated back to the server realm and a final S4U2self is executed against the local realm. This time the user information is there and the impersonation in the local realm can be completed. So, in summary, two S4U2self calls are needed, first in the user's realm (this one obtains the user information) and then another one in the server's realm. Moving from one realm to another requires to obtain TGTs and jumping from realm to realm following authentication paths (capaths).
S4U2proxy:
In the proxy call (delegation) the idea is similar, but not the same, because now we have a third role, the backend service we are delegating the user to, and two tickets, the user's ticket and our own server's ticket. In this case I finally made it work doing the following steps. First a S4U2proxy is executed against the local server realm, this way we obtain the user's service ticket we can move to the backend's realm. Then both credentials can be moved realm by realm until we reach where the backend server is located. We have to move both tickets (user's and server's service ticket). There a new S4U2proxy is executed that finally returns all the proper grants to call the backend server.
For a complete view, the needed configuration to the involved accounts should be described. In this case we need to setup the resource-based constraints delegation using power-shell commands. For the delegation/S4U2proxy the frontend account should be obtained from the domain and assigned as a valid user to be delegated to the backend server (in this example the accounts are called frontend and backend respectively):
$frontend = Get-ADUser -Identity frontend -server FRONTEND.DOMAIN.COM
Set-ADUser -Identity backend -server BACKEND.DOMAIN.COM -PrincipalsAllowedToDelegateToAccount $frontend
Get-ADUser -Identity backend -server BACKEND.DOMAIN.COM -Properties PrincipalsAllowedToDelegateToAccount
The commands use the server option to read the accounts from the needed realm, this way the accounts can be in different AD domains.
In order to perform impersonation the frontend user should be allowed to do so:
Set-ADAccountControl $frontend -TrustedToAuthForDelegation $true
This sets up the delegation for any authenticated protocol in the frontend user, the associated user in AD presents the following configuration.
It seems that S4U2proxy uses the PrincipalsAllowedToDelegateToAccount, users from different domains can be configured as allowed to delegate to the backend account. But in the case of S4U2self the user should have the account control that allows the account to impersonate, TrustedToAuthForDelegation (which is shown as use any authenticated protocol in the user delegation tab).
And that is all. Today's entry is just the explanation of how I think SFU extensions work when different realms are involved. We are trying to add cross-realm to SFU and support for resource-based constraint delegations inside the JDK implementation, my demos are working now but I suppose the process is going to be long so I prefer to, for the moment, not anticipate any event in the blog. I will add more details if I see something moves forward.
Best regards!
Comments