Wednesday, May 27, 2020

SSH improvements in Apache Karaf

Last year I contributed a number of SSH improvements to Apache Karaf, which I never found the time to blog about. In this post I'll cover how to use SSH with Apache Karaf, and also what the improvements were.

1) Using SSH with Apache Karaf

Download and extract Apache Karaf (4.2.8 was used for the purposes of this post). Start it by running "bin/karaf". By default, Karaf starts an SSH service which is configured in 'etc/org.apache.karaf.shell.cfg'. Here you can see that the default port is 8101. Karaf uses JAAS to authenticate SSH credentials - the default realm is "karaf". Associated with this realm is a PropertiesLoginModule, which authenticates users against the credentials stored in 'etc/users.properties'. Also note that the user must have a group defined that matches the value for "sshRole" in 'etc/org.apache.karaf.shell.cfg'. So let's try to SSH into Karaf using the default admin credentials, and it should work:
  • ssh karaf@localhost -p 8101

2) SSH algorithm update

The first improvement, which was merged for the 4.2.7 release, was to remove support by default for a number of outdated algorithms:
  • SHA-1 algorithms were removed
  • CBC ciphers were removed
  • Old ciphers such as 3-DES, Blowfish, Arcfour were removed
These can all be configured in 'etc/org.apache.karaf.shell.cfg' if necessary. The configuration values + defaults are now as follows:
  • ciphers = aes256-ctr,aes192-ctr,aes128-ctr
  • macs = hmac-sha2-512,hmac-sha2-256
  • kexAlgorithms = ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
So for example, the following now fails with Karaf 4.2.8 using the default configuration:
  • ssh karaf@localhost -p 8101 -c 3des-cbc

3) Elliptic curve support for SSH server keys 

The second improvement, which was also merged for 4.2.7, was to add support to configure Karaf with an elliptic curve SSH key. Previously only RSA keys were supported. When you start Karaf, it will generate an SSH key if one does not already exist, according to the "algorithm" (RSA) and "keySize" (2048) defined in 'etc/org.apache.karaf.shell.cfg', and store it in the "hostKey" (etc/host.key) file. As part of the improvement, the public key is also written out to a new configuration property "hostKeyPub" (etc/host.key.pub).

To see this in action, delete 'etc/host.key.*' and edit 'etc/org.apache.karaf.shell.cfg' and change:
  • keySize = 256
  • algorithm = EC
Now restart Karaf + try to ssh in using the "-v" parameter. You will see something like: "debug1: Server host key: ecdsa-sha2-nistp256 SHA256:sDa1k...".

4) Support for elliptic keys in the PublicKeyLoginModule

As well as supporting authentication using a password via the PropertiesLoginModule, Karaf also supports authentication using a public key via the PublickeyLoginModule. The PublickeyLoginModule authenticates a public key for SSH by comparing it to keys stored in 'etc/keys.properties'. I added support for Karaf 4.2.7 to be able to authenticate using elliptic keys stored in 'etc/key.properties', before only RSA public keys were supported.

To see how this works, generate a new elliptic curve key with an empty password:
  • ssh-keygen -t ecdsa -f karaf.id_ec
Now edit 'etc/keys.properties' and copy the public key that was written in "karaf.id_ec.pub". For example:
  • colm=AAAAE2VjZHNhLXNoY...0=,_g_:sshgroup
  • _g_\:sshgroup = group,ssh
 Now we can SSH into Karaf without a password prompt via:
  • ssh colm@localhost -p 8101 -i karaf.id_ec

5) Support for encrypted key password for SSH

Finally, I added support for encrypted key passwords for SSH. This change necessitated moving from using not-yet-commons-ssl to BouncyCastle for parsing SSH keys, as the former does not support encrypted keys or newer security algorithms in general. As a result, encrypted key passwords for SSH are not available in Karaf 4.2.x, but will be in the next major release (4.3.0). Note as well that encrypted key passwords only work for when Karaf is reading an externally generated encrypted private key.

To test this out, grab Karaf 4.3.x and generate a new RSA encrypted private key as follows (specifying a password of "security"):
  • openssl genpkey -out rsa.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -aes256
Edit 'etc/org.apache.karaf.shell.cfg' and change it as follows:
  • hostKey = ${karaf.etc}/rsa.pem
  • hostKeyPassword = security
Before starting Karaf, it's also necessary to register BouncyCastle as a security provider. Edit 'etc/config.properties' and add:
  • org.apache.karaf.security.providers = org.bouncycastle.jce.provider.BouncyCastleProvider
Now copy the BouncyCastle provider jar (e.g. bcprov-jdk15on-1.65.jar) to lib/ext and restart Karaf. It should be possible then to SSH into Karaf.

No comments:

Post a Comment