syslog-ng is a high-performance, feature-rich syslog daemon that far exceeds the capabilities of the standard rsyslog — it supports complex log routing with conditional filters, structured parsing, TLS-encrypted transport, and native output plugins for Elasticsearch, Kafka, and cloud logging services. On RHEL 8 the package is available from EPEL, making installation straightforward without manual source compilation. This tutorial covers installing syslog-ng, configuring it as both a local collector and a centralised log server, enabling TLS-encrypted forwarding between a client and server node, and finally shipping logs to Elasticsearch.
Prerequisites
- One or two RHEL 8 servers (or AlmaLinux 8 / Rocky Linux 8) — one acting as the log client, one as the centralised log server
- EPEL 8 repository enabled on both hosts:
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm - Port 514 TCP/UDP (plain syslog) or 6514 TCP (TLS syslog) open between client and server in firewalld
- OpenSSL installed for TLS certificate generation
- Root or sudo access on both hosts
Step 1 — Install syslog-ng from EPEL
Stop and disable rsyslog first to avoid both daemons competing for the same log sockets, then install syslog-ng from EPEL on both the client and server nodes.
sudo systemctl stop rsyslog
sudo systemctl disable rsyslog
sudo dnf install -y epel-release
sudo dnf install -y syslog-ng
syslog-ng --version | head -3
sudo systemctl enable --now syslog-ng
sudo systemctl status syslog-ng
Step 2 — Configure a Local Log Source and Remote Destination
Edit /etc/syslog-ng/syslog-ng.conf on the client host to define a local source from the systemd journal and kernel, a network destination pointing at the central server, and a log path wiring them together. Back up the original file first.
sudo cp /etc/syslog-ng/syslog-ng.conf /etc/syslog-ng/syslog-ng.conf.bak
sudo tee /etc/syslog-ng/syslog-ng.conf > /dev/null <<'EOF'
@version: 4.7
@include "scl.conf"
options {
flush_lines(0);
time_reopen(10);
log_fifo_size(1000);
long_hostnames(off);
use_dns(no);
use_fqdn(no);
create_dirs(yes);
keep_hostname(yes);
};
source s_local {
system();
internal();
};
destination d_local {
file("/var/log/messages"
template("${ISODATE} ${HOST} ${PROGRAM}[${PID}]: ${MSG}n")
);
};
destination d_remote {
network(
"LOG_SERVER_IP"
port(514)
transport("tcp")
);
};
log {
source(s_local);
destination(d_local);
destination(d_remote);
};
EOF
Replace LOG_SERVER_IP with the IP address of your central syslog-ng server. Reload the daemon after saving.
sudo syslog-ng --syntax-only
sudo systemctl reload syslog-ng
Step 3 — Configure syslog-ng as a Central Collector
On the server host, configure syslog-ng to listen on TCP port 514 and write incoming messages to per-host log files under /var/log/hosts/.
sudo tee /etc/syslog-ng/syslog-ng.conf > /dev/null <<'EOF'
@version: 4.7
@include "scl.conf"
options {
flush_lines(0);
time_reopen(10);
create_dirs(yes);
keep_hostname(yes);
use_dns(no);
};
source s_local { system(); internal(); };
source s_network {
network(
ip("0.0.0.0")
port(514)
transport("tcp")
);
};
destination d_hosts {
file("/var/log/hosts/${HOST}/${YEAR}-${MONTH}-${DAY}.log"
create_dirs(yes)
template("${ISODATE} ${HOST} ${PROGRAM}[${PID}]: ${MSG}n")
);
};
log { source(s_local); destination(d_hosts); };
log { source(s_network); destination(d_hosts); };
EOF
sudo firewall-cmd --permanent --add-port=514/tcp
sudo firewall-cmd --reload
sudo systemctl reload syslog-ng
Step 4 — Enable TLS-Encrypted Transport
Plain TCP syslog transmits log data unencrypted. Generate a self-signed CA and server certificate, then update both the client and server configurations to use TLS on port 6514.
# On the SERVER — generate CA and server certificate
sudo mkdir -p /etc/syslog-ng/tls/{ca,server}
# CA key and certificate
openssl genrsa -out /etc/syslog-ng/tls/ca/ca-key.pem 4096
openssl req -new -x509 -days 3650
-key /etc/syslog-ng/tls/ca/ca-key.pem
-out /etc/syslog-ng/tls/ca/ca-cert.pem
-subj "/CN=syslog-ng CA"
# Server key and certificate signed by the CA
openssl genrsa -out /etc/syslog-ng/tls/server/server-key.pem 4096
openssl req -new
-key /etc/syslog-ng/tls/server/server-key.pem
-out /tmp/server.csr
-subj "/CN=log-server"
openssl x509 -req -days 3650
-in /tmp/server.csr
-CA /etc/syslog-ng/tls/ca/ca-cert.pem
-CAkey /etc/syslog-ng/tls/ca/ca-key.pem
-CAcreateserial
-out /etc/syslog-ng/tls/server/server-cert.pem
# Copy ca-cert.pem to the CLIENT at /etc/syslog-ng/tls/ca/ca-cert.pem
Update the server network source to add a tls() block, and update the client destination similarly. Example server source snippet:
# Server — replace the s_network source with the TLS version
source s_network {
network(
ip("0.0.0.0")
port(6514)
transport("tls")
tls(
key-file("/etc/syslog-ng/tls/server/server-key.pem")
cert-file("/etc/syslog-ng/tls/server/server-cert.pem")
ca-dir("/etc/syslog-ng/tls/ca")
peer-verify(optional-untrusted)
)
);
};
# Client — replace the d_remote destination with the TLS version
destination d_remote {
network(
"LOG_SERVER_IP"
port(6514)
transport("tls")
tls(
ca-dir("/etc/syslog-ng/tls/ca")
)
);
};
# Reload both nodes
sudo systemctl reload syslog-ng
Step 5 — Forward Logs to Elasticsearch
syslog-ng ships with a native Elasticsearch destination in its syslog-ng-mod-elasticsearch-http package (available from EPEL or the syslog-ng premium repo). Add it to the server’s configuration to index every received log line into Elasticsearch.
sudo dnf install -y syslog-ng-devel syslog-ng-http
# Add this destination block to /etc/syslog-ng/syslog-ng.conf on the server
destination d_elasticsearch {
elasticsearch-http(
url("http://localhost:9200/_bulk")
index("syslog-ng-${YEAR}.${MONTH}.${DAY}")
type("")
template("$(format-json --pair ISODATE=${ISODATE} --pair HOST=${HOST}
--pair PROGRAM=${PROGRAM} --pair PID=${PID} --pair MSG=${MSG})")
flush-lines(100)
flush-timeout(10)
);
};
# Add d_elasticsearch to both log paths
# log { source(s_network); destination(d_hosts); destination(d_elasticsearch); };
sudo syslog-ng --syntax-only
sudo systemctl reload syslog-ng
# Verify logs are arriving in Elasticsearch
curl -s "http://localhost:9200/syslog-ng-*/_count" | python3 -m json.tool
Conclusion
You have installed syslog-ng from EPEL on RHEL 8, configured it as a local log collector and a centralised TCP server writing per-host log files, secured the transport with TLS certificates, and added an Elasticsearch output destination for log analytics. syslog-ng’s flexible configuration language lets you add filters, rewrite rules, and branching log paths without restarting the daemon — making it well suited to environments where log routing requirements evolve frequently. For high-throughput deployments, consider enabling the multi-line-mode() option for multi-line application logs and tuning the log_fifo_size and flush_lines options to balance latency against throughput.
Next steps: Parsing Structured Application Logs with syslog-ng PatternDB, Setting Up a Redundant syslog-ng Relay Network, and Shipping syslog-ng Output to an OpenSearch Cluster.