How secure Logstash keystore to keep Database Connection credentials

Hi All,

We have deployed ELK platinum and uses Logstash keystore to fetch DB logs and statistics. What are the exploit vector that some one can read the DB passwords from Keystore ? or is it safe to assume passwords are secured in the keystore ?

1 Like

Any inputs from anyone?

@Sumesh_p_s, @kelvink

The values saved in the logstash keystore are encrypted, and the keystore itself can be protected with a passphrase.

If you restrict the permissions on the keystore file and set a strong password, the attack vector is low. Even if someone gets ahold of the keystore, they will need to bruteforce the passphrase to gain access to it. As with anything involving cryptography, always keep an eye on the latest vulnerabilities which get published, just in case any are discovered which put the cryptographic strength of the keystore at risk.

Just to point out - when the keystore is password protected, an environment variable needs to be set for the logstash daemon to successful access the data in the keystore. Be sure to clear this value after logstash successfully starts up and loads all your pipelines.

https://www.elastic.co/guide/en/logstash/current/keystore.html

Hope this helps!
James

Thanks for the reply @jamesspi. As the keystore is encrypted (not the passphrase), there must be a private key somewhere within logstash that is able to decrypt the keystore. Are there any information on how secure is this private key?

Hey @kelvink, sorry for the late response.

We actually use the Java secret key factory for this - you can check out the source code here to see specific details - https://github.com/elastic/logstash/blob/master/logstash-core/src/main/java/org/logstash/secret/store/backend/JavaKeyStore.java

It uses symmetric encryption - so there is no key pair. Here is the code snippet:

if (useDefaultPass) {
        if (existing) {
            //read the pass
            SeekableByteChannel byteChannel = Files.newByteChannel(keyStorePath, StandardOpenOption.READ);
            if (byteChannel.size() > 1) {
                byteChannel.position(byteChannel.size() - 1);
                ByteBuffer byteBuffer = ByteBuffer.allocate(1);
                byteChannel.read(byteBuffer);
                int size = byteBuffer.array()[0] & 0xff;
                if (size > 0 && byteChannel.size() >= size + 1) {
                    byteBuffer = ByteBuffer.allocate(size);
                    byteChannel.position(byteChannel.size() - size - 1);
                    byteChannel.read(byteBuffer);
                    return SecretStoreUtil.deObfuscate(SecretStoreUtil.asciiBytesToChar(byteBuffer.array()));
                }
            }
        } else {
            //create the pass
            byte[] randomBytes = new byte[32];
            new Random().nextBytes(randomBytes);
            return SecretStoreUtil.base64EncodeToChars(randomBytes);
        }
    } else {
        //explicit user defined pass
        //keystore passwords require ascii encoding, only base64 encode if necessary
        return asciiEncoder.canEncode(CharBuffer.wrap(plainText)) ? plainText : SecretStoreUtil.base64Encode(plainText);
    }
    throw new SecretStoreException.AccessException(
            String.format("Could not determine keystore password. Please ensure the file at %s is a valid Logstash keystore", keyStorePath.toAbsolutePath()));
}

Hope this helps!
James

1 Like

That is what we needed to understand. Thanks @jamesspi !

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.