rekowski.info David Rekowski's random stuff

Use the log4j2 SocketAppender to log to logstash/kibana via SSL/TLS

2018-10-08

Abstract

This article describes how to setup the log4j2 SocketAppender in an SSL/TLS context. If you know how it works, it's simple, but maybe someone else can benefit from the hours I spent looking into this.

Keywords

java, log4j2, logging, logstash, kibana, tcp, socket, ssl, tls

Creating the keystore with the server certificate

  1. Retrieve the server certificate, one way to do so is using openssl:
echo -n | openssl s_client -connect log-server.tld:5010 -servername log-server.tld \
| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | tee "server.crt"
  1. Create the keystore to hold the server certificate.
keytool -import -alias log-server-certificate-alias -keystore log-server-cert.jks -file server.crt

A prompt for a password should show up. It's best to provide one (>=6 chars), but it doesn't contain secrets like a private key, so in this case it's not of much concern. It should be possible to not use a password, but that may cause more problems in the end.

  1. Put the keystore (log-server-cert.jks) on the classpath, e.g. besides the log4j2.xml configuration

Configuration

  1. Speaking of which, I ended up with the following log4j2.xml (excerpt):
  ...
  <Appenders>
    <Socket name="socket" host="log-server.tld" port="5010">
      <JsonLayout compact="true" eventEol="true" properties="true" />
      <SSL>
        <TrustStore location="log-server-cert.jks" password="the-keystore-pwd"/>
      </SSL>
    </Socket>
    ...
    <Loggers>
    <AsyncRoot level="info">
      ...
      <AppenderRef ref="socket"/>
    </AsyncRoot>

Explanation

  • log-server.tld - the hostname of the log server
  • 5010 - the port of the e.g. logstash instance accepting logging requests
  • log-server-cert.jks - the keystore with the certificate on your classpath
  • the-keystore-pwd - password used in 2) to create the keystore
  • Add the AppenderRef to either AsyncRoot or Root (whatever you use), where @ref (here: socket) must correspond to the value used in Socket/@name

JsonLayout

A PatternLayout can also be used, but kibana will probably not recognize any fields in that case. Importent if you're using MDC: The properties flag ensures the log will contain the ThreadContext content, e.g. the values set for MDC.

Additional information

You can add a SSL/KeyStore setup in your log4j2.xml to provide a client certificate and key.

References