Kerberos Delegation in a compiled C# app?
I didn't look deep enough into the app to see if it's WCF or Windows Forms, though I don't know if that matters or not, but I'm trying to find out a way to do the following:
- Server A uses Invoke-Command to tell Server B to run an application that is in a local folder on Server B.
- The application on Server B authenticates with the Kerberos token of the calling user from Server A via Entity Framework to SQL Server C (and D).
- The application retrieves data from the SQL Servers and processes it to a file share on somewhere else, also in the security context of the calling user from Server A - from the pre-checks the application does, I'm fairly sure this will work
I've confirmed that if I log in to server B directly (a console session) as the calling user and run the executable via PowerShell on Server B, everything works.
When I try to use the remote Invoke-Command, the connection to SQL fails, and SQL logs a connection attempt from
NT AUTHORITY\ANONYMOUS LOGON, which my experience (and a healthy dose of Wireshark) tells me is happening because Server B isn't attempting Kerberos Delegation for the connection to SQL Server C or D.
My only real Google search hits seem to be for configuring an IIS server running an ASP.NET application to do the delegation... which I don't have here; the application is just a compiled executable...
Can anyone point me in the right direction?
Magus last edited by
Maybe you meant WPF? But if so, you are correct in thinking it shouldn't matter.
I don't have more help than that, other than to say that this is probably purposefully obtuse for security reasons.
Gąska last edited by
I know nothing about Kerberos or Entity Framework, but I have a gut feeling that if "running an ASP.NET application to do the delegation" is at all an option, doing such a thin wrapper around your executable will be the quickest way.
No, it doesn’t matter whether it’s WPF or WinForms; the same thing happens in PowerShell, too (try Googling for “PowerShell two hop” or “PowerShell multiple hop”).
The only “fix” I’m aware of is enabling CredSSP for those servers: https://docs.microsoft.com/en-us/powershell/module/microsoft.wsman.management/enable-wsmancredssp
That ends up sending credentials over the wire instead of the (non-transitive) Kerberos ticket, so it’s a potential security risk.
You'll have to use a more robust communication protocol than invoke-command.
We generally write a shit web service around the commands and hit it over HTTP(s), which gives us all the authentication pass through options.
But we've also stopped doing authentication pass through, because it's very fucking fragile and tough to debug.
blakeyrat last edited by blakeyrat
@izzion A Google brought up this:
Have you tried the guide in that PDF?
Apparently there's a command like Enable-ManSSD that'll help? Sorry that's the extent of my knowledge. But I also agree with Weng that if you control the source code of this product, maybe do something simpler because it sounds way too complicated as-is. (If you don't control the source code, condolences.)
Hm, yeah, I'd looked at a couple documents about CredSSP but they're generally "omg security risk" and I was hoping to avoid that, since a few of them made vague handwavy references to how Kerberos Constrained Delegation was better.
I kind of control the code for this application, but don't have scope within my project to change it, and the current application is a command line console app, not a web service. The hope was to be able to keep the command line app (and the printer drivers it requires) off of the new SQL server and have SQL call it on an application server instead, but it looks like my choices are to do that and change the application's SQL connections to SQL auth, or to not do that and have the application run locally on the calling SQL server
blakeyrat last edited by
@izzion Does the application read a connectionstring, or build its own? SQL Server connection strings are pretty damned powerful, you can probably craft one that does what you need.
It reads a string from the configuration file that I control -- the string I was trying was in the form of:
Data Source=CNAME.MYDATABASESERVER.DOMAIN.COM;Initial Catalog=MYDATABASE;Integrated Security=SSPI;
Judging by Wireshark, the application is doing NTLM auth whether I call it locally or remotely (hence why it doesn't have credentials when called remotely). The application server in question is also my SSRS reporting web server, and I know that Kerberos authentication passthrough using the SSRS service on that server (Server B ) to the same target SQL Server C is working.
sigh Aaaaaaand, even with SQL authentication to work around the Kerberos delegation problem... the damn thing won't access a network printer when Invoke-Commanded remotely.
/me throws this solution in the bit bucket.