1

I am getting below error while trying to connect to one of the windows server from AWS cluster.

Caused by: com.jcraft.jsch.JSchException: UnknownHostKey: x.y.com. DSA key fingerprint is "ac:ew:.....

Note: I generated the RSA keys using PuTTYgen, but every time it tries to connect it gives issue with DSA fingerprint. I referred multiple SO links but unable to get the right solution.

Finally I tried below approach based on one of the posts. Get the session first time with StrictHostKeyChecking as no. Once done, save the result to known hosts file on the AWS server so that next time it tries to connect to Windows server it knows it is connecting to the right server.

session.setConfig("StrictHostKeyChecking", "no")
session.setConfig("PreferredAuthentications", "publickey,password")
session.connect(5000)
LOG.info("session connected...." + session.isConnected())
val arrayHostKey = jsch.getHostKeyRepository().getHostKey
  for (i <- 0 to arrayHostKey.size - 1) {
      println(arrayHostKey(i).getHost)
      println(arrayHostKey(i).getKey)
      println(arrayHostKey(i).getType)
      if (arrayHostKey(i).getHost.equalsIgnoreCase(host))
         session.setConfig("server_host_type", arrayHostKey(i).getType)
LOG.info("sftp session connected without using proxy..." + session.isConnected())

This works, but I think I am losing the entire reason for not setting up session.setConfig("StrictHostKeyChecking", "no") and may be it is working. What is the right way to achieve this?

Second point that I am not sure is how to force the server to ask for RSA keys only instead of DSA?

Lastly, is StrictHostKeyChecking, accept-new a more secure and recommended operation for production environments instead of no?

These are the JSch logs I am seeing.

SSH_MSG_KEXINIT sent
SSH_MSG_KEXINIT received
kex: server: diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
kex: server: ssh-dss
kex: client: diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
kex: client: ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
kex: server->client aes128-ctr hmac-md5 none
kex: client->server aes128-ctr hmac-md5 none
SSH_MSG_KEXDH_INIT sent
expecting SSH_MSG_KEXDH_REPLY
ssh_dss_verify: signature true
Disconnecting from x.y.com port 22
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Dwarrior
  • 687
  • 2
  • 10
  • 26
  • @ScaryWombat; What do you mean? The keys got added using the method I mentioned above. Without that it always threw an error. How exactly in java I should do that and what's the reasoning behind it? – Dwarrior Mar 07 '19 at 02:45
  • Note: this is a glue cluster from where I am trying to connect to windows server. Hence, once the glue environment shuts down, i dont have access to that server, its a black box. – Dwarrior Mar 07 '19 at 03:15
  • There is no `server_host_type` configuration item in Jsch. There is `server_host_key`, which corresponds to `HostKeyAlgorithms` in OpenSSH, but like all crypto config it must be set _before_ `Session.connect()` -- and setting it to the same value the server will choose anyway (here ssh-dss) is useless. – dave_thompson_085 Mar 08 '19 at 05:48
  • https://stackoverflow.com/questions/34684251/jsch-unknownhostkey-exception-when-host-key-is-in-known-hosts-and-after-adding – Jawad Jul 12 '19 at 13:19
  • @Jawad - I figured it out but thanks for posting. Someone else might find it helpful. – Dwarrior Jul 18 '19 at 11:54

1 Answers1

3

I generated the RSA keys using PuTTYgen, but every time it tries to connect it gives issue with DSA fingerprint.

It seems that you believe that the host key has something to do with key pair that you use for authentication – It does not. Those are completely unrelated. Host keys are keys of the server, they are fixed, the same for all users of the server, generated when the server is installed.

For details, see my article Understanding SSH key pairs.

I believe that once you realize this and go back to all the existing questions about UnknownHostKey, they will now make more sense to you:


Finally I tried below approach based on one of the posts. Get the session first time with StrictHostKeyChecking as no. Once done, save the result to known hosts file on the AWS server so that next time it tries to connect to Windows server it knows it is connecting to the right server.

This works, but I think I am losing the entire reason for not setting up session.setConfig("StrictHostKeyChecking", "no") and may be it is working. What is the right way to achieve this?

It's not a perfect solution, but it's acceptable.

For a perfect solution, find out the fingerprint locally on your Windows SSH server and configure your AWS Java code to expect it upfront.


Lastly, is StrictHostKeyChecking, accept-new a more secure and recommended operation for production environments instead of no?

no is not secure at all. accept-new is as good as your above solution. But JSch does not support accept-new anyway.

(it's not difficult to implement it)

Community
  • 1
  • 1
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Thank u so much for the valuable insights. Can u pls confirm on my understanding 1. When I created an openRSA key from puttygen locally, I actually created keypair for user authentication. Public key now resides in windows server where I need to connect and private key must be with me. 2. Known host public key is something which gets generated when server is installed. Hence, if server gets reinstalled we have to add a new value. Private key is with the server admin (out of scope). I think this is where my issue should be. May be the known host public key provided to me itself is incorrect. – Dwarrior Mar 07 '19 at 22:59
  • Reason: When I did strictHostKeyChecking as no and iterated over the hostkey repo, it gave me the value of key which was different from the one provided to me. Resolution: If the key I received after iterating is put in the knownhostpublicKey as string and I pass input as this, it must always work as long as the key doesn't change and this will be the most secure way of connecting: `jsch.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()))` 3. When u say it's acceptable, does it mean it's secure to connect using above method? can this be used for production? – Dwarrior Mar 07 '19 at 23:02
  • 4. It asks for DSA key fingerprint is SHA256:....That means the server itself got installed with DSA algorithm? Sorry not sure what it means. 5. What are kex: server: and kex: client values. How from the logs it will help me that which algorithm was used during handshake? For 4 and 5, I can create a new post if needed. Correct me if i am missing anything here. – Dwarrior Mar 07 '19 at 23:03
  • 2
    @Dwarrior: 1 yes. 2 when the host key is _(re)generated_ you need to get the new public key and put it in your known_hosts; you _should_ also delete the old one to reduce confusion. (Re)generation might happen at (re)installation and/or other times. I have no clue what your `knownHostPublicKey` is, but `Session.setKnownHosts` requires a file or stream that contains the format used by OpenSSH, which is never just the publickey itself, and certainly not the publickey in binary. 3 accepting whatever host key you receive is not secure if there is an active attacker on your network path(s). ... – dave_thompson_085 Mar 08 '19 at 05:59
  • 1
    ... 4 the server is using a DSA key (which for historical reasons SSH spells ssh-dss). Whether the reason for this is coding, installation, configuration, or elves we can't tell from the client. 5 kex server is the keyexchange parameters offered by the server; kex client is the keyexchange parameters offered by the client. The algorithm for choosing among them is in rfc4253, but in your log, the entry `ssh_dss_verify: true` proves that DSA=(ssh-)dss was used. – dave_thompson_085 Mar 08 '19 at 06:03
  • @dave_thompson_085: Thank you for the clarifications. I feel confident now after all the answers u have provided and the explanation that Martin provided. For 3, it comes from trusted server so we are good. 5. For one of the connections, I am getting ssh_dss_verify: false, so which values to look for further debugging? What could be the issue. I am using latest version of jsch. – Dwarrior Mar 08 '19 at 12:40
  • @Dwarrior That sounds like a new question. – Martin Prikryl Mar 08 '19 at 12:50
  • Will create a new post. Thanks – Dwarrior Mar 08 '19 at 12:57
  • Find this very helpful https://dentrassi.de/2015/07/13/programmatically-adding-a-host-key-with-jsch/ – Jawad Jul 12 '19 at 23:58