pondělí 25. dubna 2016

Ignore the boring SSH error message - Host identification has changed!

The problem

If you work with virtual machines in clouds, or you run an SSH server in Docker containers, then you've probably met the following error message during making ssh connection:
(I'm connecting through SSH to a docker container)
~$ ssh -p 8822 root@localhost
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
Please contact your system administrator.
Add correct host key in /home/jcacek/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/jcacek/.ssh/known_hosts:107
  remove with:
  ssh-keygen -f "/home/jcacek/.ssh/known_hosts" -R [localhost]:8822
ECDSA host key for [localhost]:8822 has changed and you have requested strict checking.
Host key verification failed.
And as a result the ssh refused to connect to requested server.

The problem is, you are reusing the host/port combination which was already registered in your system and the SSH client tries to keep you on a safe side. It doesn't connect to a server whose public key doesn't match the one registered in your system.

The obvious solution

Yes, I know. You say, the message suggest me a solution. Just to run
ssh-keygen -f "/home/jcacek/.ssh/known_hosts" -R [localhost]:8822
... and everything works correctly. Or doesn't it? Let's try.
~$ ssh -p 8822 root@localhost
The authenticity of host '[localhost]:8822 ([]:8822)' can't be established.
ECDSA key fingerprint is SHA256:smYv5yA0n9/YrBgJMUCk5dYPWGj7bTpU40M9aFBQ72Y.
Are you sure you want to continue connecting (yes/no)?
Oh My Java! I have to write "yes". And No! the "y", "Y", "yep" etc. don't work.
Are you sure you want to continue connecting (yes/no)? y
Please type 'yes' or 'no': Y
Please type 'yes' or 'no': yep
Please type 'yes' or 'no': I give up!
Please type 'yes' or 'no': 
So it's really irritating and it takes time to handle it.

The real solution

So what can we do with it? Just add some more arguments to our ssh command
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 8822 root@localhost
By using the UserKnownHostsFile option we said we don't want to use ~/.ssh/known_host file, but rather the one provided as a value of this option. And the /dev/null is always empty (i.e. it can't cause a conflict with the checked server key).

The "no" value in StrictHostKeyChecking option disables the question if the new key can be stored into the provided known hosts file.

To make it simpler, just add an alias into your system. E.g. this is a line in my ~/.bash_aliases file:
alias sshx='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'


Use this only if you are aware of risks coming from the relaxing SSH security mechanisms.

pondělí 15. února 2016

Playing live demos on Linux

I like live demos during presentations. When they work and don't take too much time.

And I don't like when the presenter types too much.

So I've created the demo-step script.


I've tried to find a way how to "play" live demos (on Linux) in a natural way. First I've found solution by putting keyboard shortcuts into the ~/.inputrc configuration file (example here). The disadvantage is, you have to remember, what's the next shortcut.

I'm not so good in remembering shortcuts, so I've created simpler solution by utilizing xdotool Linux application (xdotool home).

Sample usage

You can find sample presentation with uses the demo-step on my GitHub.

You just need to put the live demo commands into the ~/demo.commands text file and then play them by running demo-step after pressing a keyboard shortcut.

Sample content of the ~/demo.commands:

#\n# search images in Docker public registry (Docker hub)\ndocker search wildfly
#\n# run container from an image\ndocker run -it jboss/wildfly

And the output in the console window after the first demo-step script execution:

$ #
$ # search images in Docker public registry (Docker hub)
$ docker search wildfly

pátek 25. září 2015

Solution to failing Configuration.getConfiguration() in Java

Sometimes the calling javax.security.auth.login.Configuration.getConfiguration() fails with SecurityException in our tests (both Oracle and IBM).

A quick solution (without touching JDK installation or configuring java.security.auth.login.config system property) is simple. Just create an empty file .java.login.config in your user home directory (more info in ConfigFile JavaDoc). Thats it!

touch ~/.java.login.config

Just to make the picture complete, here is the stack trace we see on IBM JDK:

Exception in thread "main" java.lang.SecurityException: Unable to locate a login configuration
 at com.ibm.security.auth.login.ConfigFile.<init>(ConfigFile.java:125)
 at java.lang.J9VMInternals.newInstanceImpl(Native Method)
 at java.lang.Class.newInstance(Class.java:1681)
 at javax.security.auth.login.Configuration$2.run(Configuration.java:263)
 at javax.security.auth.login.Configuration$2.run(Configuration.java:255)
 at java.security.AccessController.doPrivileged(AccessController.java:338)
 at javax.security.auth.login.Configuration.getConfiguration(Configuration.java:254)
 at org.jboss.test.App.main(App.java:15)
Caused by: java.io.IOException: Unable to locate a login configuration
 at com.ibm.security.auth.login.ConfigFile.init(ConfigFile.java:282)
 at com.ibm.security.auth.login.ConfigFile.<init>(ConfigFile.java:123)
 ... 7 more