Denis Machard

My technical gists

Infrastructure architect by profession but always consider himself as a developer and an open source enthusiast.
@github @mastodon @rss

Enable TLS encryption and mutual authentication with syslog-ng

By following this guide, you can enhance the security of your log management system by enabling TLS encryption and mutual authentication with syslog-ng. This ensures that your log data remains confidential and trustworthy, even in a potentially insecure environment.

Prepare working directory

Before we begin, make sure you have the following prerequisites in place:

  • You’ll need Docker installed on your system to run syslog-ng in a container.

    This guide test is based on the docker https://hub.docker.com/r/linuxserver/syslog-ng image version 4.1

  • Create a directory for your syslog-ng configuration and logs. You can do this with the following commands:

    mkdir syslogng_tls
    mkdir syslogng_tls/config
    mkdir syslogng_tls/log
    

Configuration

  1. Create self-signed certificates

In this guide, you’ll need to create self-signed certificates and place them in the conf folder. For a detailed guide on how to create self-signed certificates using OpenSSL, you can refer to this tutorial.

To avoid the error following error in syslog-ng: Invalid certificate found in chain, basicConstraints.ca is unset in non-leaf certificate

Generate your Certificate Authority with:

[ req ]
x509_extensions          = v3_ca

[ v3_ca ]
basicConstraints         = CA:TRUE
  1. Create syslog-ng configuration

Now, let’s create the syslog-ng.conf configuration file. Below is a sample configuration that sets up syslog-ng to use TLS encryption and listens on port 6514:

@version: 4.1

options {
  keep_hostname(yes);
};

source s_network_tls {
  syslog(
        transport(tls)
        port(6514)
        tls (
           cert-file("/config/server.crt")
           key-file("/config/server.key")
           peer-verify(optional-untrusted)
        )
  );
};

destination d_local {
  file("/var/log/messages-kv.log" template("$ISODATE $HOST $(format-welf --scope all-nv-pairs)\n") frac-digits(3));
};

log {
  source(s_network_tls);
  destination(d_local);
};
  1. Create Docker Compose

Next, create a Docker Compose file, docker-compose.yml, to deploy the syslog-ng container:

version: "3.8"

services:
  syslog-ng:
    image: lscr.io/linuxserver/syslog-ng:4.1.1
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - ./config:/config
      - ./log:/var/log
    ports:
      - 6514:6514/tcp
    restart: unless-stopped

Docker file is on github https://github.com/linuxserver/docker-syslog-ng

All config are available in the following github github.com/dmachard/docker-stack-syslog-ng

Deploy syslog-ng with Docker Compose

Deploy syslog-ng with Docker Compose

$ sudo docker compose up -d
[+] Running 1/1
 ✔ Container syslogng-compose-syslog-ng-1  Started

You can check the status of your Docker containers with:

$ sudo docker compose ls
NAME                STATUS              CONFIG FILES
syslogng-compose    running(1)          syslogng-compose/docker-compose.yml

Sending encrypted logs

To send encrypted logs to your syslog server, you can use the socat command. Here’s an example:

$ printf "107 <30>1 2023-10-17T21:25:15+02:00 hostname /usr/bin/binary 78175 tag - This is a sample log message over TLS." | socat - openssl:127.0.0.1:6514,verify=0

You can monitor the incoming logs in the messages-kv.log file.

$ tail -f messages-kv.log
2023-10-17T21:25:15.000+02:00 denis-laptop HOST=denis-laptop HOST_FROM=denis-laptop MESSAGE="This is a sample log message over TLS." MSGID=tag PID=78175 PROGRAM=/usr/bin/binary SOURCE=s_network_tls

Mutual TLS authentication

For enhanced security, you can enable mutual TLS authentication mTLS and restrict TLS to version 1.3. Update your syslog-ng configuration as follows:

source s_network_tls {
  syslog(
        transport(tls)
        port(6514)
        tls (
           cert-file("/config/server.crt")
           key-file("/config/server.key")
           ca-file("/config/ca.crt")
           peer-verify(required-trusted)
           ssl-options(no-tlsv12)
        )
  );
};

After making this change, restart your syslog-ng container.

Use nmap command to check the TLS version

$ nmap --script ssl-enum-ciphers -p 6514 127.0.0.1
Starting Nmap 7.93 ( https://nmap.org ) at 2023-10-22 16:17 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00011s latency).

PORT     STATE SERVICE
6514/tcp open  syslog-tls
| ssl-enum-ciphers: 
|   TLSv1.3: 
|     ciphers: 
|       TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|       TLS_AKE_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
|     cipher preference: server
|_  least strength: A

Nmap done: 1 IP address (1 host up) scanned in 0.25 seconds

To test mutual TLS authentication, try sending a log message without providing the client certificate and key.

$ printf "107 <30>1 2023-10-17T21:25:15+02:00 hostname /usr/bin/binary 78175 tag - This is a sample log message over TLS." | socat - openssl:127.0.0.1:6514,verify=0

You should receive an error message peer did not return a certificate indicating that the peer did not return a certificate.

$ tail -f config/log/current
2023-10-22 17:08:42.165093663  [2023-10-22T17:08:42.165054] Syslog connection accepted; fd='13', client='AF_INET(172.21.0.1:46488)', local='AF_INET(0.0.0.0:6514)'
2023-10-22 17:08:42.170333871  [2023-10-22T17:08:42.170290] SSL error while reading stream; tls_error='error:0A0000C7:SSL routines::peer did not return a certificate', location='/config/syslog-ng.conf:7:4'
2023-10-22 17:08:42.170373178  [2023-10-22T17:08:42.170322] Error reading RFC6587 style framed data; fd='13', error='Connection reset by peer (104)'
2023-10-22 17:08:42.170387705  [2023-10-22T17:08:42.170369] Syslog connection closed; fd='13', client='AF_INET(172.21.0.1:46488)', local='AF_INET(0.0.0.0:6514)'

Retry to send a log message with mutual authentication, provide the client certificate and key, like this:

printf "107 <30>1 2023-10-17T21:25:15+02:00 hostname /usr/bin/binary 78175 tag - This is a sample log message over TLS." | socat - openssl:127.0.0.1:6514,cert=config/client.crt,key=config/client.key,verify=0

Your log should now be successfully received and logged by syslog-ng.

$ tail -f messages-kv.log
2023-10-17T21:25:15.000+02:00 denis-laptop .tls.x509_cn=client.home.lab .tls.x509_o=Home .tls.x509_ou=Lab HOST=denis-laptop HOST_FROM=denis-laptop MESSAGE="This is a sample log message over TLS." MSGID=tag PID=78175 PROGRAM=/usr/bin/binary SOURCE=s_network_tls
propulsed by hugo and hugo-theme-gists