JSch can't connect via Kerberos keytab file
Asked Answered
K

1

6

I built a Java application, which runs a command via ssh. In the first attempt I authenticated via username and password, and everything worked fine.

Now I want to use a Kerberos keytab file to make the authentication, but this makes problems!

Here a few words to my configuration:

  • KDC server: my-server.de
  • Realm name: MYREALM.DE
  • Keytab username: keytabuser
  • KDC = server: runs on CentOS 7
  • my client: Windows 8.1 (x64) with all default configurations, Kerberos for Windows installed
  • my username on client: Daniel
  • kinit -kt ... seems to work fine, so the keytab file should also be ok

What I have so far is this code snippet:

public static void main(String[] args) {
        String host = "my-server.de";
        String user = "keytabuser";
        String  command = "ls -l";

        JSch jsch = new JSch();
        jsch.setLogger(new MyLogger());

        System.setProperty("java.security.krb5.conf", "C:\\ProgramData\\MIT\\Kerberos5\\krb5.ini");
        System.setProperty("java.security.auth.login.config", "C:\\ProgramData\\MIT\\Kerberos5\\jaas.conf");
        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");

        //to enable kerberos debugging mode
        System.setProperty("sun.security.krb5.debug", "true");

        try {
            Session session = jsch.getSession(user, host, 22);
            Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            config.put("PreferredAuthentications", "gssapi-with-mic");

            session.setConfig(config);
            session.connect(20000);

            Channel channel = session.openChannel("exec");
            ... // Do the commands

            channel.disconnect();
            session.disconnect();
            System.out.println("DONE");

        } catch (JSchException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
}

This is my jaas.conf file:

com.sun.security.jgss.krb5.initiate {
  com.sun.security.auth.module.Krb5LoginModule required
  doNotPrompt=true
  principal="[email protected]"
  useKeyTab=true
  keyTab="C:\ProgramData\MIT\Kerberos5\keytabuser.keytab"
  storeKey=true;
};

And here my krb5.ini file:

[libdefaults]
  default_realm = MYREALM.DE

[realms]
  MYREALM.DE = {
    admin_server = my-server.de
    kdc = my-server.de
  }

When I run this application I get the following output:

UPDATED: New console output after new jsch dependency 0.1.54

INFO: Connecting to my-server.de port 22
INFO: Connection established
INFO: Remote version string: SSH-2.0-OpenSSH_6.6.1
INFO: Local version string: SSH-2.0-JSCH-0.1.54
INFO: CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
INFO: aes256-ctr is not available.
INFO: aes192-ctr is not available.
INFO: aes256-cbc is not available.
INFO: aes192-cbc is not available.
INFO: CheckKexes: diffie-hellman-group14-sha1,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
INFO: CheckSignatures: ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
INFO: SSH_MSG_KEXINIT sent
INFO: SSH_MSG_KEXINIT received
INFO: kex: server: [email protected],ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
INFO: kex: server: ssh-rsa,ecdsa-sha2-nistp256,ssh-ed25519
INFO: kex: server: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,[email protected],[email protected],[email protected],aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,[email protected]
INFO: kex: server: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,[email protected],[email protected],[email protected],aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,[email protected]
INFO: kex: server: [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],hmac-md5,hmac-sha1,[email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96
INFO: kex: server: [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],hmac-md5,hmac-sha1,[email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96
INFO: kex: server: none,[email protected]
INFO: kex: server: none,[email protected]
INFO: kex: server: 
INFO: kex: server: 
INFO: kex: client: ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
INFO: kex: client: ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
INFO: kex: client: aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc
INFO: kex: client: aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc
INFO: kex: client: hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96
INFO: kex: client: hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96
INFO: kex: client: none
INFO: kex: client: none
INFO: kex: client: 
INFO: kex: client: 
INFO: kex: server->client aes128-ctr hmac-md5 none
INFO: kex: client->server aes128-ctr hmac-md5 none
INFO: SSH_MSG_KEX_ECDH_INIT sent
INFO: expecting SSH_MSG_KEX_ECDH_REPLY
INFO: ssh_rsa_verify: signature true
WARN: Permanently added 'my-server.de' (RSA) to the list of known hosts.
INFO: SSH_MSG_NEWKEYS sent
INFO: SSH_MSG_NEWKEYS received
INFO: SSH_MSG_SERVICE_REQUEST sent
INFO: SSH_MSG_SERVICE_ACCEPT received
INFO: Authentications that can continue: gssapi-with-mic
INFO: Next authentication method: gssapi-with-mic
INFO: Disconnecting from my-server.de port 22
com.jcraft.jsch.JSchException: Auth fail
    at com.jcraft.jsch.Session.connect(Session.java:519)
    at kerberos.JschKerberos.main(JschKerberos.java:49)

Is there something incorrect with my configuration? Are there some conditions between the local (user, domain, etc.) and the remote one?

Koah answered 20/1, 2017 at 12:18 Comment(8)
My 2 cents: to get all debug traces, add -Dsun.security.krb5.debug=true -Djava.security.debug=gssloginconfig,configfile,configparser‌​,logincontext on the command line, to be sure that you don't miss any initialization setpMemorialist
Also set useTicketCache=false and storeKey=false to make sure that you don't suffer from side effects from the cache. Since you provide the keytab to JAAS, you can keep your ticket private to your Java process.Memorialist
Ok, I'll try later, thank you for the help so far. The jaas.conf and krb5.ini are ok or did I miss something?Algerian
The java.security.debug flags will show you exactly what Java thinks about your config...Memorialist
I added also the second flag to my java code by "System.setProperty("java.security.debug", "gssloginconfig,configfile,configparser‌​‌​,logincontext");" (the first one I already had in the code). Still the same console output like above...Algerian
Setting that property via System.setProperty() might be to late. Try passing that as a parameter to the java binary (using -D....)Philosophism
Ok, added the flags to the "java" command, still exact the same output.Algerian
changed the jsch version to the newest (0.1.54), now getting a longer console output, see in the question section above.Algerian
K
5

I finally found the solution! It was a missing service keytab for the sshd service! Some service principals aren't generated automatically by the Kerberos server. So this has to been done manually by the kadmin, as the sshd service also has to authenticate against Kerberos! This is done by the host/fqdn@REALM principal.

Important here: The "host" is a fixed String(!), I always replaced it by the hostname of my OpenSSH server machine... So, only "fqdn" and "REALM.COM" must be replaced by your data!

So these were the necessary steps for me to get the application work:

  1. Set GSSAPIAuthentication yes in the /etc/ssh/sshd_conf config file of the OpenSSH server
  2. Set Host * [...] GSSAPIAuthentication yes in the /etc/ssh/ssh_conf config file of the ssh client
  3. Check the jaas.conf and krb5.conf (or .ini) files on the client for correct settings (see the code blocks in the question section above)
  4. On the Kerberos server, open kadmin.local and type ktadd host/my-server.de
  5. optional: Add a user principal (if not exists yet): ktadd keytabuser
  6. Make a kinit keytabuser (with password) or kinit -kt /path/to/file.keytab keytabuser (normal Kerberos command)
  7. Check if the user is authenticated via klist
  8. Run the application or ssh directly via console ssh [email protected]
  9. You should be logged in by the cached ticket!

Of course, the user keytabuser must be a user on the ssh-server machine!

Koah answered 24/1, 2017 at 14:44 Comment(1)
Duh. So you tried Kerberos auth in SSH, without first binding globally your Linux server auth to Kerberos (via sssd and the default /etc/krb5.keytab). And you did not know about Kerberos SPN (Service Principal Name) syntax. Looks like you got to a result against all odds, congratulations...Memorialist

© 2022 - 2024 — McMap. All rights reserved.