My org is running Active Directory which uses Kerberos for authentication. I have a group of linux computers that are not permitted to be joined to AD. For user authentication, I setup kerberos and pam to point to the AD server. After adding the user to the system, I can login using my AD username and password. After logging in, I have a ticket. This is a great convenience as I don't need to maintain a separate set of credentials for users.
Now I'd like to setup ticket forwarding between my group of computers so I don't have to retype my password every time. This doesnt work.
Example scenario: AD client ssh to server1 in my group of computers not in AD. I can use my username and password to login. After login I have a ticket. I now want to login to server1 in my group of computers not in AD. This prompts me for a password again. Ideally, since I already have a ticket on the AD client, I shouldn't need to enter my password for either login.
Based on my rudimentary understanding of kerberos, I think this is failing on the "TGS-REQ" step where the client tries to get a host (server) service ticket from kdc. Since my host isn't registered/added/joined, I assume the KDC/AD can't provide one and that step fails.
My questions?
- Am I correct, is this the cause of my issues?
- Is there any way around this to achieve my single sign-on using AD creds goal?
- What if I setup my own local KDC/AD/IDM. Is there a way to point that to the main AD?
Yes, specifically for the server (SSH target) not having a Kerberos principal.
It's not just about a DB entry, though – the important part is that a 'domain join' sets up a shared key between the server and the KDC (the /etc/krb5.keytab), which is associated with the server's host principal. Kerberos cannot function without that, as it's the only way for a service to verify the authenticity of a ticket.
It's not "one or both"; there are three distinct procedures that make a TGS-REQ and each expects only one specific principal:
During your initial local login to the system (i.e. password-based login through PAM), Windows or pam_krb5 makes a TGS-REQ for its own local system's host principal as part of "KDC spoofing" mitigation, i.e. making sure PAM can't be tricked into accepting a fake password. (If you've set up pam_krb5 on an unjoined system, it is vulnerable to KDC spoofing.)
Note that this is not actually part of TGT acquisition, as such – you can perfectly well obtain tickets and use Kerberos without the local host having its own principal (though preferably using
kinit
instead of the PAM integration).During authentication to remote services (e.g. SSH), the client makes a TGS-REQ for the server system's host principal (or some other service principal). For example, if you run
ssh mailsrv
it will make a TGS-REQ for thehost/mailsrv
service.Note that this is not called "ticket forwarding" – that term specifically refers to unconstrained delegation (which forwards tickets together with their session keys), whereas authentication only presents a ticket in much the same way as a TLS server presents its certificate, i.e. without ever sending the private key.
After authentication, if both the client and server have the option enabled, Kerberos can copy your whole TGT to the server for "second hop" authentication. This is what Unix Kerberos calls "ticket forwarding" (compare to SSH agent forwarding), and is also known as "unconstrained delegation" in Active Directory. For historical reasons, forwarding doesn't just copy your TGT as-is but instead makes a TGS-REQ for
krbtgt
to get a duplicate TGT.So in brief, if you have a TGT and you're looking for plain Kerberos authentication to other systems, then it is specifically the server that must be joined to the Kerberos realm – the client's principal never comes into play, so it cannot be described as "one or both".
But the server you're SSH'ing to must be joined to the Kerberos realm – that is a hard requirement, as it's the fundamental basis for Kerberos as a protocol: it relies on the service and the KDC having a shared encryption key (the keytab or the machine account password), which the service would use to verify the ticket it receives.
(The server doesn't necessarily need a "full" AD join configuration, with PAM and Samba and Winbindd and everything; but it needs to have a computer account in AD.)
If you're not allowed to create computer accounts for the Linux systems, then you cannot set up Kerberos SSO for SSHing into them.
Setting up your own KDC is possible, but it would contradict your goal of not having two sets of credentials, as the new KDC would have a separate set of accounts. You cannot have a "proxy" KDC.
While technically it is possible to have two Kerberos realms trust each other (e.g. so that a user in realm A could obtain tickets for services in both realms A & B without needing separate credentials from realm B), this would require more privileges than joining the individual machines – it would require an AD-wide "realm trust".
(It might be that the AD admins accept creating an outbound-only trust from AD to your realm, as it doesn't really have any security risks – it only lets AD users access the servers on your realm, not the other way around – but if they refuse something as basic as joining non-Windows hosts to Ad, most likely they'll be reluctant to even touch the trusts section.)
So without privileges you could only set up a manual password resync system where someone can log in with their AD details and the system automatically issues them a Linux Kerberos account. (I've actually seen multiple universities document this kind of setup, e.g. when they have a historical MIT Kerberos realm for the CS dept. and a brand new Windows AD realm for everyone else.)
It is possible to have more than one TGT at a time, so you could run your own KDC for your Linux machines while still getting AD tickets for AD machines, but this can sometimes become a bit of a headache. I do this on my work laptop, with entirely separate TGTs from my own Kerberos realm and the work AD realm.
In the end it might be easiest to use SSH public-key authentication (or even SSH host-based authentication, where your group of hosts implicitly trust each other for SSH login).
Keep in mind that if the system doesn't have a host keytab and only does an AS-REQ, then this is vulnerable against KDC spoofing – if an attacker gets control over the network first, then they could redirect all Kerberos traffic to their own KDC and have it answer with "successful" AS-REPs and 'krbtgt's for whatever username and password the attacker wants.
The standard mitigation is to have the client system immediately use the received TGT to request a service ticket to itself, so that it could validate that ticket against its own key that was established previously (i.e. during domain join – machine account password on Windows or keytab on Linux) and which only a legitimate KDC would know.
(The post you mentioned says: "S1 attempts to decrypt the TGT using a key generated from your password. If the decryption succeeds, the password is accepted as correct." This is the vulnerable part, and that's where S1 would additionally do a TGS-REQ for its own "host/S1" principal.)