Introduction
In this article, I will describe how to configure IBM App Connect Enterprise and a Logstash server (that is part of an ELK stack) so that log messages can be sent securely using Basic Auth and TLS mutual-authentication over HTTP.
In order to achieve this, configuration is needed in both ACE and Logstash. Communication is achieved over HTTPS by creating keystore and truststore files that are used by both ACE and the Logstash server. In my setup, my Logstash server was running natively on Red Hat Linux and ACE was running on Mac.
Create a self-signed SSL certificate
On my Linux machine where my Logstash server will run, I start by creating a self-signed SSL certificate. In order to do this, openssl must be installed. It is usually available on most linux systems. These are the steps to carry out:
- cd to a directory where you will keep your keystore and trustore artefacts which will be referenced by logstash
cd ssl_files
- Make a copy of the openssl master configuration file:
cp /etc/pki/tls/openssl.cnf my_openssl.cnf
- Edit the openssl configuration file which you just copied.
• Edit my_openssl.cnf
• In v3_ca topic, replace
[ v3_ca ]
subjectAltName = IP: YOUR_LOGSTASH_SERVER_IP
with
[ v3_ca ]
subjectAltName = IP: 10.256.35.21
- Generate the SSL certificate and key
openssl req -x509 -batch -nodes -days 3650 -newkey rsa:2048 -keyout logstash.key -out logstash.crt -config my_openssl.cnf
- Confirm you have these files:
If you type ls,
you should see these files listed:
[sanjayn@sachin ssl_files]$ ls
logstash.crt logstash.key my_openssl.cnf
Import the generated certificate into a keystore and truststore
Now that you have generated the self-signed certificate, you need to import the certificate into the truststore and keystore.
- The certificate needs to be in PEM format before it can be imported. The certificate can be converted to PEM format using the openssl tool by running this command:
openssl x509 -in logstash.crt -out logstashkey.pem -outform PEM
You should now have the following files in the directory:
[sanjayn@sachin ssl_files]$ ls
logstash.crt logstash.key logstashkey.pem my_openssl.cnf
- Now import the signed PEM certificate into a keystore. Run this command:
keytool -import -file logstashkey.pem -keystore keystore.jks -keypass keypassw0rd -storepass keystorepassw0rd
This will have created a keystore.jks file.
You should now have the following files in the directory:
[sanjayn@sachin ssl_files]$ ls
keystore.jks logstash.crt logstash.key logstashkey.pem my_openssl.cnf
- Now the signed certificate needs to be exported from the keystore so that it can be added to the truststore. Run this command:
keytool -export -file client.cer -keystore keystore.jks
Enter keystore password:
Certificate stored in file <client.cer>
When you are prompted to enter the keystore password, enter ‘keystorepassw0rd’.
This will have created a client.cer file.
You should now have the following files in the directory:
[sanjayn@sachin ssl_files]$ ls
client.cer keystore.jks logstash.crt logstash.key logstashkey.pem my_openssl.cnf
- The exported certificate now needs to be imported into the truststore. Run this command:
keytool -import -file client.cer -trustcacerts -keystore truststore.jks -storepass truststorepassw0rd
You should now have the following files in the directory:
[sanjayn@sachin ssl_files]$ ls
client.cer keystore.jks logstash.crt logstash.key logstashkey.pem my_openssl.cnf truststore.jks
Configure the logstash configuration file
Now you need to configure a logstash configuration file. In the directory where logstash is installed, change to the config directory and create a file called logstash.conf. In the file, use this content:
input {
http {
port => 5888
codec => json
user => "sanjay"
password => "secretpassword"
ssl => true
ssl_certificate => "/home/sanjayn/ssl_files/logstash.crt"
ssl_key => "/home/sanjayn/ssl_files/logstash.key"
}
}
output {
csv {
id => "csvTraceLogstashOutput"
path => "/tmp/logstashOutput.csv"
flush_interval => 0
fields => ["type", "ibm_product", "ibm_recordtype", "ibm_serverName", "ibm_processName", "ibm_messageId" ]
}
}
Change the location of the ssl certificate and ssl key to use the directory where you created the certificate in the previous steps. Also change the value of user and password to values of your choice. These values are used for BasicAuth so that the authentication check is done when the log messages are sent over https. This logstash configuration file is using an output plugin to create a CSV file. You could equally send the data to elasticsearch and visualize the data in a Kibana dashboard if you wish.
Configure ACE to use ELK with https
You now need to configure ACE so that log messages can be sent to Logstash using https and BasicAuth.
- Copy the keystore and trustore files from the logstash server to your ACE machine and place them in a location eg:
mkdir elk_ssl_files
cd elk_ssl_files
scp sanjayn@sachin.hursley.ibm.com:/home/sanjayn/ssl_files/keystore.jks .
scp sanjayn@sachin.hursley.ibm.com:/home/sanjayn/ssl_files/truststore.jks .
- Create a work directory for an ACE Integration Server:
sanjays-mbp:~ sanjayn$ mqsicreateworkdir work_elk_ssl_demo
mqsicreateworkdir: Copying sample server.config.yaml to work directory
1 file(s) copied.
Successful command completion.
- Configure the server.conf.yaml file
cd work_elk_ssl_demo
cd overrides
Create a file named ‘server.conf.yaml’ and paste the following into the file. Change the location of where you copied the keystore and truststore files to on your ACE machine.
Log:
elkLog: true # Control the publication of BIP messages to an ELK (Elasticsearch, Logstash, Kibana) stack. Set to true or false, default is false.
elkConnections: 'elkConnection1' # Name of the ELK connection to use, for example 'elkConnection1'
ServerCredentials:
elk: # CredentialType
elk_id: # CredentialName
username: 'sanjay'
password: 'secretpassword'
ELKConnections:
elkConnection1:
elkProtocol: 'https' # Logstash input protocol. Valid values are: 'beats', 'beatsTls', 'http', or 'https'.
hostname: 'sachin.hursley.ibm.com' # Hostname for the elkProtocol endpoint.
port: 5888 # Port for the elkProtocol endpoint.
uploadIntervalMilliSecs: 1000 # Interval between uploading cached data, set in milliseconds.
elkCredential: 'elk_id' # Set an 'elk' credential alias name to enable basic authentication, if it is required by the Logstash input protocol.
keystoreFile: '/Users/sanjayn/elk_ssl_files/keystore.jks' # Set the path to the keystore to be used, if it is required by the Logstash input protocol.
keystorePass: 'keystorepassw0rd' # Set the password, or 'keystore' credential alias to the password, of the keystore.
keyAlias: 'mykey' # Set the alias name of the private key, if mutual authentication is required by the Logstash input protocol.
keyPass: 'keypassw0rd' # Set the password, or 'keystorekey' credential alias to the password, for accessing the private mutual authentication key.
truststoreFile: '/Users/sanjayn/elk_ssl_files/truststore.jks' # Set the path to the truststore to be used, if it is required by the Logstash input protocol.
truststorePass: 'truststorepassw0rd' # Set the password, or 'truststore' credential alias to the password, for accessing the truststore.
Test your setup
Start your logstash server using:
bin/logstash -f config/logstash.conf
Logstash will have started after you see this line in stdout:
[2020-03-31T19:09:23,228][INFO ][logstash.agent ] Successfully started Logstash API endpoint {:port=>9600}
Start your Integration Server using:
IntegrationServer --name ELK_DEMO --work-dir work_elk_ssl_demo
You will know that ACE has successfully sent messages to Logstash when you see:
The integration server successfully sent data to ELK connection 'elkConnection1' using elkProtocol 'https', hostname 'sachin.hursley.ibm.com' and port '5888'.
Connect to the Integration Server and deploy a bar file containing an application. Try stopping and starting the application.
On the logstash server, you will see a file called /tmp/logstashOutput.csv
is created. It will contain entries like this:
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,2155I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,2866I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,3132I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,1991I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,2155I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,2269I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,1996I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,3132I
Configure ACE to use the Credentials Vault
The passwords can be stored in the ACE credentials vault instead of showing them in plain text in the server.conf.yaml. You can do this by running these ACE commands.
- Create a credential vault for the Integration Server
mqsivault --work-dir work_elk_ssl_demo --create --vault-key myvaultkey
- Store the credential required for basic auth using the ‘elk’ credential type
mqsicredentials --work-dir work_elk_ssl_demo --vault-key myvaultkey --create --credential-type elk --credential-name elk_id --username sanjay --password secretpassword
- Store the credential required to access the keystore using the ‘keystore’ credential type
mqsicredentials --work-dir work_elk_ssl_demo --vault-key myvaultkey --create --credential-type keystore --credential-name keystore_id --password keystorepassw0rd
- Store the credential required to access the key in the keystore using the ‘keystorekey’ credential type
mqsicredentials --work-dir work_elk_ssl_demo --vault-key myvaultkey --create --credential-type keystorekey --credential-name keystorekey_id --password keypassw0rd
- Store the credential required to access the truststore using the ‘truststore’ credential type
mqsicredentials --work-dir work_elk_ssl_demo --vault-key myvaultkey --create --credential-type truststore --credential-name truststore_id --password truststorepassw0rd
- Check that you have the following credentials defined:
mqsicredentials --work-dir work_elk_ssl_demo --vault-key myvaultkey --report
BIP15118I: The Integration Server/Integration Node is not running. Only credentials from the 'vault' provider will be shown.
BIP15110I: The credential name 'elk_id' of type 'elk' contains user name 'sanjay' from provider 'vault' and has the following properties defined: 'password'
BIP15121I: The credential name 'keystore_id' of type 'keystore' from provider 'vault' has the following properties defined: 'password'
BIP15121I: The credential name 'keystorekey_id' of type 'keystorekey' from provider 'vault' has the following properties defined: 'password'
BIP15121I: The credential name 'truststore_id' of type 'truststore' from provider 'vault' has the following properties defined: 'password'
BIP8071I: Successful command completion.
- Edit work_elk_ssl_demo/overrides/server.conf.yaml
- Add these lines to the end of the ELKConnections stanza.
elkConnection2:
hostname: 'sachin.hursley.ibm.com' # Hostname of the elkProtocol endpoint
port: 5888 # Port for the elkProtocol endpoint
elkProtocol: 'https' # Set one of 'beats', 'beatsTls', 'http' or 'https'
uploadIntervalMilliSecs: 1000 # Upload interval in milliseconds
elkCredential: 'elk_id' # Set a credentials alias name to enable basic auth
keystoreFile: '/Users/sanjayn/elk_ssl_files/keystore.jks' # Set the path to the truststore
keystorePass: 'keystore_id' # Set the password or alias to the password of the keystore
keyAlias: 'mykey' # Set the optional alias name of the private key to use for mutual auth SSL
keyPass: 'keystorekey_id' # Set the optional passwored of the credential alias to the private key to use for mutual auth SSL
truststoreFile: '/Users/sanjayn/elk_ssl_files/truststore.jks' # Set the path to the truststore
truststorePass: 'truststore_id' # Set the password or alias to the password of the truststore
- Change the value of elkConnections to ‘elkConnection2’
Change
elkConnections: 'elkConnection1'
to
elkConnections: 'elkConnection2'
- Comment out the ServerCredentials stanza
#ServerCredentials:
# elk: # CredentialType
# elk_id: # CredentialName
# username: 'sanjay'
# password: 'secretpassword'
- The work_elk_ssl_demo/overrides/server.conf.yaml should look like the screenshot below.
The values in elkConnection1 have the credential values in plain text. The values in elkConnection2 reference credentials that are stored in the credential vault used by the Integration Server.
- Start the Integration Server. The credential vault key must be specified when it is started:
IntegrationServer --name ELK_DEMO --work-dir work_elk_ssl_demo --vault-key myvaultkey
Check that the Integration Server is now using
'elkConnection2'.
Previously, it used
'elkConnection1'.
The integration server successfully sent data to ELK connection 'elkConnection2' using elkProtocol 'https', hostname 'sachin.hursley.ibm.com' and port '5888'.
- Check that values are written to
/tmp/logstashOutput.csv
after the Integration Server was re-started.
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,2155I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,2866I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,3132I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,1991I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,6503I
ace_message,IBM App Connect Enterprise,log,ELK_DEMO,IntegrationServer,1989I
Summary
In this article, I have shown how to configure an ACE Integration Server to send log messages to a Logstash server in an ELK stack using Basic Auth and TLS mutual authentication over HTTP.
You may also be interested in reading my previous article, Sending ACE log messages to an ELK stack.