Message Image  

Sending IBM App Connect Enterprise log messages to an ELK stack using Basic Auth and TLS mutual authentication

 View Only
Wed July 29, 2020 09:46 AM

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:

  1. cd to a directory where you will keep your keystore and trustore artefacts which will be referenced by logstash
    cd ssl_files
  2. Make a copy of the openssl master configuration file:
    cp /etc/pki/tls/openssl.cnf my_openssl.cnf
  3. 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
  4. 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
  5. 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.

  1. 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
  2. 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
  3. 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
  4. 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.

  1. 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 .
  2. 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.
  3. 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.

  1. Create a credential vault for the Integration Server
    mqsivault --work-dir work_elk_ssl_demo --create --vault-key myvaultkey
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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.
  7. 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'
  8. 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.

  9. 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'.
  10. 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.

2 comments on"Sending IBM App Connect Enterprise log messages to an ELK stack using Basic Auth and TLS mutual authentication"

  1. Atul April 22, 2020

    Hi Sanjay, thanks for sharing the steps to configure the ELK with ACE for capturing logs from standard output.
    Can we send any other log file from ACE to ELK ?

    Reply (Edit)
    • SanjayNagchowdhury April 23, 2020

      Hi. Not yet. We plan to extend this in the future.

      Thanks

      Sanjay

      Reply (Edit)