Open fvollmer opened 5 months ago
Constrained delegation definitely works it just doesn't work like the normal GSSAPIDelegateCredentials
option. This means the client doesn't explicitly opt into it, the service just needs to be configured. The S4UProxy call happens implicitly on the server side if you attempt to access a service that the constrained delegation allows for. For example the server2025$
principal is allowed to delegate to cifs/dc01.domain.test
and klist.exe
shows the retrieved ticket
jborean:~/dev$ ssh server2025.domain.test pwsh -Command 'gci \\dc01.domain.test\c$; klist'
Directory: \\dc01.domain.test\c$
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 8/06/2024 8:39 PM PerfLogs
d-r-- 16/06/2024 8:37 AM Program Files
d-r-- 15/06/2024 11:03 AM Program Files (x86)
d---- 16/06/2024 5:59 AM temp
d-r-- 16/06/2024 5:58 AM Users
d---- 20/06/2024 5:32 AM Windows
Current LogonId is 0:0x356d42
Cached Tickets: (2)
#0> Client: vagrant-domain @ DOMAIN.TEST
Server: cifs/dc01.domain.test @ DOMAIN.TEST
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x40a50000 -> forwardable renewable pre_authent ok_as_delegate name_canonicalize
Start Time: 6/22/2024 23:45:16 (local)
End Time: 6/23/2024 0:00:16 (local)
Renew Time: 6/29/2024 23:45:15 (local)
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0
Kdc Called: DC01.domain.test
#1> Client: vagrant-domain @ DOMAIN.TEST
Server: host/server2025.domain.test @ DOMAIN.TEST
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x40210000 -> forwardable pre_authent name_canonicalize
Start Time: 6/22/2024 23:42:44 (local)
End Time: 6/23/2024 9:42:42 (local)
Renew Time: 0
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0x8 -> ASC
Kdc Called:
One thing to note is that the client must request a TGT that is forwardable. It doesn't have to be explicitly forwarded (unconstrained delegation) but if on Linux/macOS it means using the -f
flag with kinit
or setting forwardable = true
in the krb5.conf
. For Windows clients this works like normal.
Great to know that this should be working.
I'm trying to ssh from a windows client to a linux server (ubuntu 24.04, OpenSSH_9.6p1 Ubuntu-3ubuntu13, OpenSSL 3.0.13 30 Jan 2024
). Is there some special config setting that I need to enable? Or is constrained delegation not supported in this use case?
Unconstrained delegation works fine, but with constrained delegation I get no tickets:
ssh -K -v my.server.com
[...]
debug1: Next authentication method: gssapi-with-mic
debug1: Delegating credentials
debug1: sspi delegation was requested but not fulfilled
debug1: Delegating credentials
debug1: sspi delegation was requested but not fulfilled
debug1: Authentication succeeded (gssapi-with-mic).
[...]
klist
klist: No credentials cache found (filename: /tmp/krb5cc_<myuserid>)
Ah ok sorry I thought your target was a Windows host.
Unconstrained delegation works fine, but with constrained delegation I get no tickets:
This is the problem unfortunately, you have no ticket because you don't actually have a proper TGT that can be used to request a normal service ticket like unconstrained delegation does. With constrained delegation (S4UProxy) you use the service principals context to request the additional ticket based on the limited data provided by the client in the initial exchange.
Based on the great docs for MIT krb5 constrained delegation on GSSAPI looks like https://web.mit.edu/kerberos/krb5-devel/doc/appdev/gssapi.html#constrained-delegation-s4u
gss_accept_sec_context
GSS_C_BOTH
GSS_C_ACCEPT
https://github.com/openssh/openssh-portable/blob/603193e32aef5db7d60c58066d5de89806e79312/gss-serv.c#L118-L120delegated_cred_handle
contains a "proxied credential"
gss_krb5_copy_ccache
KRB5CCNAME
env var for the user https://github.com/openssh/openssh-portable/blob/603193e32aef5db7d60c58066d5de89806e79312/gss-serv-krb5.c#L176-L187gss_init_sec_context
with the proxy credential from delegated_cred_handle
So while OpenSSH does seem to store the proxied credential it won't have this proxied credential because it's using GSS_C_ACCEPT
rather than GSS_C_BOTH
on the acceptor credential. The bigger issue though is doing the S4UProxy dance as the service principal SSH is running as. This means you need to either have access to the service's keytab (security risk) or have some sort of privileged broker that perform S4UProxy using the service principal's Kerberos context but with the provided proxy credential. Window's opted for the latter solution as the SMB request is done automatically for you but I'm not aware of a way to do this with SSH on Linux. Granted there may be a solution to this that I don't know off but unfortunately I just don't think it is possible right now outside of Windows as the target environment.
Summary of the new feature / enhancement
Currently, we use unconstrained Kerberos delegation for logging in and accessing network drives, which poses security concerns.
When attempting to switch to constrained Kerberos delegation, the error
sspi delegation was requested but not fulfilled
occurs, and no tickets are available on the host. It would be beneficial to utilize constrained Kerberos delegation.This issue is related to #2214
Proposed technical implementation details (optional)
I think we want S4U2proxy. According to https://web.mit.edu/kerberos/krb5-1.20/doc/appdev/gssapi.html
gss_acquire_cred_impersonate_name
has to be used, which is similar togss_acquire_cred
, which is currently used.