Kerberos
With a Kerberos ticket, an SSH server can let you in without a password or key: gssapi-with-mic authentication (RFC 4462), what
ssh does with GSSAPIAuthentication yes. The ticket comes from the platform: the Windows logon session in an Active Directory
domain (SSPI), or elsewhere the credential cache that kinit fills (MIT or Heimdal GSS-API).
When to use
- Servers are joined to Active Directory or an MIT Kerberos realm, and users already have tickets.
- A service account should log in with its domain identity instead of a stored key.
Log in with the current ticket
if (!SshGssapiOptions.IsSupported)
{
throw new PlatformNotSupportedException("Kerberos authentication needs .NET 10.");
}
await using var client = await SshClient.ConnectAsync("build.corp.example.com", 22, new SshClientOptions
{
UserName = "deploy",
HostKeyVerifier = verifier,
Gssapi = new SshGssapiOptions(), // the current ticket (Windows logon, or kinit); host/build.corp.example.com@REALM
}, cancellationToken);
Connect by address
Kerberos names the server's service principal after its DNS name (host/<name>@REALM), so connecting by IP address or over a
stream needs the name given explicitly:
await using var client = await SshClient.ConnectAsync("192.0.2.10", 22, new SshClientOptions
{
UserName = "deploy",
HostKeyVerifier = verifier,
// Kerberos names services by DNS name: say which one when connecting by address or over a stream.
Gssapi = new SshGssapiOptions { TargetHost = "build.corp.example.com" },
}, cancellationToken);
From ssh_config
Host build
HostName build.corp.example.com
GSSAPIAuthentication yes
GSSAPIDelegateCredentials no
HostName is the target, and PreferredAuthentications can place gssapi-with-mic anywhere in the order.
Notes and pitfalls
- .NET 10 only. It relies on
NegotiateAuthentication.ComputeIntegrityCheck, which .NET 8 lacks. CheckSshGssapiOptions.IsSupported; on .NET 8 the method is not offered and the others are tried. - Order. When on, Kerberos is tried first (as in
ssh's default order), and only if the server offers it. If it fails (no ticket, an unknown service principal), the other methods follow. - Delegation.
DelegateCredentials = trueforwards your ticket to the server so programs there can authenticate onward as you. Leave it off unless you trust the server. - Explicit credentials.
SshGssapiOptions.Credentialtakes a user, password and realm instead of the current ticket; read the password from a secret store. - Host keys still matter. The host key is verified as always:
gssapi-keyex(Kerberos instead of host keys) is not supported.
See also
- Authentication: Kerberos
- SshGssapiOptions in the API reference