-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question about using NegotiateStream in linux and TokenImpersonationLevel #80846
Comments
Tagging subscribers to this area: @dotnet/ncl, @vcsjones Issue DetailsIs the check in this line still valid? I don't know about impersonation, but delegation should work, and it works for us via gssapi (linux client -> windows server scenario).
|
It may be possible. It is there probably since the initial Linux port. I'm looking at #28460 at the moment and I was planning to do more testing with Linux. The difficult part may be testing. We have some tests with Linux KDC but I'm not sure if/how we would construct test automation. If you can share some details @deryaza it would be useful. |
I just want to clarify that my "is it still valid" (or is it actually not supported) question was because some time ago, when I investigated the possibility, I used System.Net.Security code as a reference to get an idea of the native functions that could be called. After that and with some tries, I was able to get the user token and impersonate the user on the server. So that just me being curious :) Is there some concerns why NegotiateStream or the new api (that calls the same function, iirc) are limited to identification? I alse remembered seeing some flags mappings that mention delegation. Actually, after posting this, I tried to build from source and extend the check to delegation and it worked. I even got WindowsIdentity as an Identity property of NegotiateStream. So yeah, I'm just asking why validation is still like this (I could guess that it's because lack of testing?). |
I think it is lack of demand (you are really first one IMHO) and lack of testing infrastructure. I think we would be happy to take community PR. |
There's definitely a lack of testing for this but the underlying code for Unix (Linux/macOS) seems to be there. |
Just adding another voice to this ask The restriction to prevents the use of impersonation on linux systems.
This is blocking us from being able to support linux clients talking to Windows servers and using Kerberos authentication where impersonation is required. As this library is widely used, it also impacts other services like WCP's net.tcp stream. By contrast,
Another side note is that currently the error message returned by the Unix PAL incorrectly reports the following message in it's exception text
The message is incorrect, as currently only Identification is allowed. I'm certainly happy to contribute to resolving this issue, if there is a way forward here. |
yes, we would take contributions @ryannewington. As I mentioned above lack of testing and low priority is probably main reason for the gap. You can look at https://github.com/dotnet/runtime/tree/main/src/libraries/Common/tests/System/Net/EnterpriseTests/setup to see if we can somehow integrate it with current Docker tests. We would only add |
Ok! Great! So there's a few dimensions to this to consider Linux client to Windows ServerFirst, let's talk about the linux client to windows server scenario. This is going to be the most common use case. The client sets the This scenario is broken in my case, because i can't give permission for the Windows server to impersonate me with the access token I provide when coming from Linux. I think in the client scenario, there's no consequence to having the same checks as Windows, that is, allow the client to use any of the For testing, this would be as simple as pointing the linux (FWIW I've patched Windows or Linux Client to Linux server scenarioThis one has a little more nuance to it. When i set the While impersonation may not apply to a linux system, delegation technically can, and delegation (with impersonation levels being cumulative), includes the right of impersonation. If I set my Linux server-side 'minimum impersonation level' to Since the token I receive is really dependent on the client at the end of the day, perhaps it's best left to the developer to work out what they want to support? There doesn't seem to be much to gain from restricting the token types you can receive on the Linux side. And given that dotnet provides no mechanism to impersonate an identity on Linux, having an impersonation token in your possession doesn't appear to be too great of a problem. I think it's also fair to say that if a developer wanted to use the delegation token, they'd have some work to do. This is also normally handled on Windows by the That all being said, I think the likelihood of someone wanting to run a NegotiateStream server on Linux is low. Options for a way forward
Test updatesI've had a look at the existing test cases, and there doesn't appear to be any Impersonation or Delegation token level tests at all, even for Windows, but I might just not be seeing them? Would we be looking at adding additional test cases validating the expected impersonation levels to: or adding additional tests here? I guess it depends if need to validate that a) The |
To the Linux client. While I agree in principal this is server's job there may be practical limits. The functional tests you linked have only NTLM tests. To run Kerberos, you obviously need KDC. That was done as manual tests in the past and the Windows is even more complicated. AFAIK you cannot run DC in container and our automated test infrastructure does not have capability to proved test server. That really leaves only ad hoc manual tests in place. @filipnavara did great job in 7.0 to pull in Kerberos.Net so we can do more detailed tests. But that still does not have coverage in this are. |
BTW I had private conversation about this with @SteveSyfuhs and it would be great if he can chime in publicly. |
Level setting: https://syfuhs.net/understanding-identity-delegation In Windows you have an ability to authenticate a user, which translates to identifying a user, impersonating a user, or delegating a user. Each ability requires increased privileges across the resource. We all understand the authentication step. Identifying the user is nothing special; it just means you're given a username, SID, and group membership information the popped out of the authenticated ticket. This requires no special machine privileges. Impersonation means the process can act as that user on that single machine, meaning when you access local OS resources, you do so as that user. This requires explicit impersonation privileges granted by the machine and is security critical. Lastly, you have delegation of the user, which grants the process the right to act as that user on the network such as when you're querying a database or file share or whatever. This requires permission at the Active Directory level, granting the host process the right to delegate users to specific other resources. All of this comes from the NT Token for that user, where the hosting process has an implied privilege associated with that token. They that hold the [NT] token can identify or impersonate the user. It is up to the Windows system to make that decision, not the process. Whether you can impersonate that user is stamped on the token, so verifying if you can do that should really just be a matter of checking the token, nothing else. The hard part is determining if you can delegate the user. The only way you can determine that is by actually trying it, and seeing if the far side accepted it. The reason all of this works this way is because it uses Kerberos S4U (or worse, unconstrained delegation, which is like 5th or 6th on the list of technologies I'm trying to kill), and Windows hides all that machinery from you with the simple Identify|Impersonate token levels. Because this is protocol-based, the ability to impersonate or delegate on Linux or Windows is rather up to the machine and directory, not the app developer. So, in summary, I think my recommendation is don't optimistically check impersonation levels or things like that, and just handle the errors the underlying system returns instead because the OS is still the ultimate arbiter (perhaps that's obvious, and I'm missing the salient point). GSS-wise I don't know if the Linux Kerberos libraries support S4U -- it's a Microsoft-specific protocol. It's much safer than unconstrained delegation, which is basically what the OK_AS_DELEGATE flag is triggering. Kerberos.NET does support S4U and it's rather trivial to use, but that obviously leads to its own set of challenges. I think I implemented basic S4U support in the KDC too, so if you want to extend the test harness to try it out, that is probably easy enough to do too. |
@SteveSyfuhs thank you for that explanation. Always great to hear you explain things so well. Is the presence of the From my testing, it seems you can do constrained delegation with only |
I don't remember the delegation flag rule off the top of my head, but I will review the code in the morning.
Constrained delegation requires impersonation, yes. That a signal to the middlebox that you're actually allowed to act as the user in the eyes of the system itself (it would be rather awkward if you couldn't pretend to be the user locally, but could pretend to be it on the thing it's connecting to).
…________________________________
From: Ryan Newington ***@***.***>
Sent: Wednesday, February 15, 2023 7:29:46 PM
To: dotnet/runtime ***@***.***>
Cc: Steve Syfuhs ***@***.***>; Mention ***@***.***>
Subject: Re: [dotnet/runtime] Question about using NegotiateStream in linux and TokenImpersonationLevel (Issue #80846)
@SteveSyfuhs<https://github.com/SteveSyfuhs> thank you for that explanation. Always great to hear you explain things so well.
Is the presence of the Delegation flag in an access token exclusively tied to unconstrained delegation/ok-as-delegate being enabled?
From my testing, it seems you can do constrained delegation with only Impersonation flag set. Is that correct?
—
Reply to this email directly, view it on GitHub<#80846 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AAJHTYOFKOUUVXVVA3HGYGDWXWNKVANCNFSM6AAAAAAUAHGYOM>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
It so happened I was able to get my hands on setup with IIS and HttpClient on Windows calling app that needs delegation. On Linux, even if |
I'll retest this scenario in my lab, but I'm 95% sure I tested this scenario successfully. Was it linux client -> windows server? I have a very simple native negotiatestream -> negotiatestream setup, to rule out any IIS or config issues. I've had to use ModMono to overwrite the |
.NET 7 Preview 7 removed the |
@filipnavara Happy to do this! I assume you mean .NET 8 Preview 7? |
Yes, .NET 8 Preview 7, right 🤦♂️ |
sorry for silence, will try to provide some info today/tomorrow |
It works just fine, thanks! The only difference that I think could be documented somewhere is that negotiatestream now disposes remote identity on it self disposal. I will close this issue, if @ryannewington had some troubles, you can reopen it or proceed the way you want. |
Is the check in this line still valid? I don't know about impersonation, but delegation should work, and it works for us via gssapi (linux client -> windows server scenario).
https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Unix.cs#L36
The text was updated successfully, but these errors were encountered: