Security
Invariant Discovery pipeline uses Kafka for messaging. There are several approaches to configure Apache Kafka, including user/password combinations, server authentication or mutual SSL authentication using CA certificate. Security has three primary components:
Encryption of data in-flight using SSL/TLS - Data is encrypted between producers and Kafka and between consumers and Kafka.
Authentication using SSL or SASL - Allows producers and consumers to authenticate to your Kafka cluster and verify their identity.
Authorization using ACLs - Once clients are authenticated, Kafka brokers can use access control lists (ACL) to determine whether or not a particular client is authorized to read/write from a topic.
SSL Authentication
SSL Auth leverages 2-way authentication. The idea is to also issue certificates to your clients, signed by a certificate authority, which will allow your Kafka brokers to verify the identity of the clients.
SASL Authentication
SASL (Simple Authorization Service Layer) is another authentication mechanism, and the following are supported by Kafka.
SASL PLAINTEXT
This is a classic username/password combination. These usernames and passwords have to be stored on the Kafka brokers in advance and each change needs to trigger a rolling restart. When using SASL/PLAINTEXT, make sure to enable SSL encryption so that credentials aren’t sent as PLAINTEXT on the network
SASL SCRAM
This is a username/password combination alongside a challenge (salt), which makes it more secure. When using SASL/SCRAM, make sure to enable SSL encryption so that credentials aren’t sent as PLAINTEXT on the network
As described earlier, Kafka authentication can be done using certificates and trust store. It supports both server-only authentication (certificate presented by server) and mutual authentication (both client and server certificates validated).
Generating Certificates
For using TLS with Kafka, you have to provide the following certificates.
Certificate Authority (CA) certificate
Kafka Server certificate
Kafka Client certificate
OpenSSL and Keytool commands can be used to generate certificates and trust store. You may need root access to carry out some of these tasks.
Configuration for Test Setup
Follow these Steps for testing
Create folder on the server /opt/invariant/security. Create key and trust store
Create a topic for testing
[invapp@myserver bin]$ kafka-topics.sh --create --zookeeper localhost:2183 \
--replication-factor 1 --partitions 1 --topic sectest
Describe the topic
[invapp@myserver bin]$ kafka-topics.sh --zookeeper localhost:2183 \
--describe --topic sectest
Test setup prior to enabling SSL
[invapp@myserver bin]$ kafka-console-producer.sh --broker-list \
myserver.invariant.io:9094 --topic sectest
Read the messages
[invapp@myserver bin]$ kafka-console-consumer.sh --bootstrap-server localhost:9094 \
--whitelist 'sectest' --from-beginning
From /opt/invariant/security, create the trust store , import the root cert , intermediary cert
[invapp@myserver bin]$ keytool -keystore kafka.truststore.jks -alias CARoot \
-import -file INV-0.cer
[invapp@myserver bin]$ keytool -keystore kafka.truststore.jks -alias intermediary \
-import -file INV-2.cer
Setup Server keystore
Create a PKCS#12 file using OpenSSL
Change the following as necessary CN=myserver.invariant.io, OU=TECH, O=INVARIANT, L=SACRAMENTO, ST=CALIFORNIA, C=US
[invapp@ myserver bin]$ openssl pkcs12 -export -name myserver.invariant.io \
-in inv101.cer -inkey myserver_cert_key.pem -out keystore.p12
Convert it to JKS using
[invapp@myserver bin]$ keytool -importkeystore -destkeystore myserver.keystore.jks \
-srckeystore keystore.p12 -srcstoretype pkcs12 -alias myserver.invariant.io
Import the root and intermediary certs
[invapp@myserver bin]$ keytool -keystore myserver.keystore.jks \
-alias CARoot -import -file INV-0.cer
[invapp@myserver bin]$ keytool -keystore myserver.keystore.jks \
-alias intermediary -import -file INV-2.cer
Check the contents of the Keystore
[invapp@myserver bin]$ keytool -list -v -keystore myserver.keystore.jks
To set up the server edit the server.properties and add the following
advertised.listeners=PLAINTEXT://myserver.invariant.io:9094, SSL://myserver.invariant.io:9095
ssl.keystore.location=/opt/invariant/security/myserver.keystore.jks
ssl.keystore.password=password01
ssl.key.password=password01
ssl.truststore.location=/opt/invariant/security/kafka.truststore.jks
ssl.truststore.password=password123
ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1
ssl.keystore.type=JKS
ssl.truststore.type=JKS
ssl.client.auth=none
ssl.secure.random.implementation=SHA1PRNG
Startup the server and test the setup
openssl s_client -debug -connect myserver.invariant.io:9095 -tls1
Setup the client store
Create the client keystore , CN=myserver.invariant.io, OU=TECH, O=INVARIANT, L=SACRAMENTO, ST=CALIFORNIA, C=US
[invapp@myserver security]$ keytool -genkey -alias localhost \
-keyalg RSA -keypass password01 -storepass password01 \
-keystore client.keystore.jks
Import root cert into keystore
[invapp@myserver security]$ keytool -keystore client.keystore.jks \
-alias CARoot -import -file INV-0.cer
[invapp@myserver security]$ keytool -keystore client.keystore.jks \
-alias intermediary -import -file INV-2.cer
Import the server cert into keystore
[invapp@myserver security]$ keytool -keystore client.keystore.jks \
-alias localhost -import -file myserver.cer
Add SSL for the client in a new file called ssl.properties
[invapp@myserver security]$ vi ./config/ssl.properties
Add the following entries
security.protocol=SSL
ssl.truststore.location=/opt/invariant/security/kafka.truststore.jks
ssl.truststore.password=[replace password]
ssl.keystore.location=/opt/invariant/security/client.keystore.jks
ssl.keystore.password=[replace password]
ssl.key.password=[replace password]
ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1
ssl.client.auth=none
Test messages both producer and consumer
/opt/invariant/kafka/bin/kafka-console-producer.sh \
--broker-list myserver.invariant.io:9095 --topic sectest \
--producer.config /opt/invariant/kafka/config/ssl.properties
/opt/invariant/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server myserver.invariant.io:9095 \
--whitelist 'sectest' --from-beginning \
--consumer.config /opt/invariant/kafka/config/ssl.properties
/opt/invariant/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server myserver.invariant.io:9094 \
--whitelist 'sectest' --from-beginning
Pipeline Configuration
The data pipelines, which processes the message from Kafka and write out to HDFS stream can use secured Kafka. The administrator can provide the Kafka security settings in the config file security.brkadapter.properties
security.protocol=SASL_SSL
ssl.truststore.location=/opt/server-sec/kafka.truststore.jks
ssl.truststore.password=password
ssl.keystore.location=/opt/client-sec/client.keystore.jks
ssl.keystore.password=password
ssl.key.password=password
ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule
Additional Resources
For more details, refer to
Kafka docs: https://kafka.apache.org/documentation/#security
OpenSSL docs: https://www.openssl.org/docs/man1.0.2/apps/openssl.html
Last updated