Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSch can't connect via Kerberos keytab file

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?

like image 622
D. Müller Avatar asked Jan 20 '17 12:01

D. Müller


1 Answers

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!

  • See this for more information (in German): http://www.pks.mpg.de/~mueller/docs/suse10.3/opensuse-manual_de/manual/sec.kerbadmin.hostprinc.html
  • This also shows the steps (English): http://www.microhowto.info/howto/create_a_host_principal_using_mit_kerberos.html

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!

like image 200
D. Müller Avatar answered Nov 08 '22 22:11

D. Müller