syslog-ng Relay Architecture for Network Logs - 夜莺博客

syslog-ng Relay Architecture for Network Logs

Send a thousand network devices straight at a single collector and the first firewall rule you write will not be the problem — the collector's connection table will be. A relay tier between the devices and the central store absorbs that fan-in, survives a collector outage without losing logs, and gives you one place to enforce TLS and to tag traffic by site. This article covers the relay configuration model, the buffering that makes it durable, and the verification that proves logs are arriving rather than silently queuing.

The relay model

A relay receives logs over the network from clients and forwards them to a central server, optionally filtering, rewriting and tagging on the way. Because it speaks the same protocols on both sides, adding a relay does not change what the devices send. What it changes is scale: each relay handles a bounded number of connections, and the collector sees a handful of relay connections instead of thousands of device connections.

Deploy one relay per site or per network zone. That also gives you a natural place to attach the source site as a tag, which is the single most useful piece of metadata when you are searching across tens of thousands of messages.

Configuration structure

syslog-ng configuration is built from four statement types — source, filter, destination, log — assembled into a log path.

@version: 4.8
@include "scl.conf"

# 1. Accept RFC5424 and legacy BSD syslog from devices
source s_network {
    network(
        ip("0.0.0.0")
        port(514)
        transport("udp")
        flags(no-parse)
    );
    network(
        ip("0.0.0.0")
        port(601)
        transport("tcp")
        keep-alive(yes)
        max-connections(500)
    );
};

# 2. Tag everything with the site so searches can be scoped
source s_network {
    network(ip("0.0.0.0") port(601) transport("tcp")
        flags(no-parse)
        default-facility(network)
        tags("site_dc1")
    );
};

# 3. Drop the noise you never read
filter f_noise {
    not match("last message repeated" value("MESSAGE"));
};

# 4. Forward to the central collector with a disk buffer
destination d_central {
    syslog("10.10.50.20" transport("tls")
        port(6514)
        tls(peer-verify(required-trusted) ca-dir("/etc/syslog-ng/ca.d"))
        disk-buffer(
            mem-buf-size(64M)
            disk-buf-size(2048M)
            reliable(yes)
            dir("/var/spool/syslog-ng")
        )
        frac-digits(6)
    );
};

# 5. Local file as a short-term fallback
destination d_local {
    file("/var/log/relay/${HOST}.log" template("${ISODATE} ${HOST} ${MSGHDR}${MSG}\n"));
};

log { source(s_network); filter(f_noise); destination(d_central); destination(d_local); };

Three parts of that configuration deserve attention. The UDP source carries flags(no-parse) because legacy devices send formats that strict parsing will reject, and rejecting them silently is worse than forwarding them verbatim. The disk buffer with reliable(yes) is what makes the relay useful during a collector outage: memory buffering alone loses everything on a process restart. And frac-digits(6) preserves sub-second timestamps, which matters when you are correlating a routing event across three devices.

Rewriting before forwarding

rewrite r_hostname {
    set("${HOST}", value("HOST_FROM"));
    subst("^([^.]+)\..*", "$1", value("HOST"));
};

destination d_central {
    syslog("10.10.50.20" transport("tls") port(6514)
        template("$ISODATE $HOST $PROGRAM $MSGID $MSG\n")
    );
};

Normalising hostnames and timestamps at the relay means the central store receives consistent data regardless of which vendor's device sent it. Doing this at the destination instead means every downstream consumer has to cope with the variants.

Verify, do not assume

syslog-ng -s -f /etc/syslog-ng/syslog-ng.conf      # syntax check
systemctl reload syslog-ng
syslog-ng-ctl stats | grep -E "s_network|d_central"
syslog-ng-ctl query get "*.*" | head
tail -f /var/log/relay/switch-01.example.com.log
ls -lh /var/spool/syslog-ng/                       # buffer growth during an outage

The stats output is the important one: it shows messages received, messages queued and messages dropped per destination. A relay that is up, has a healthy connection, and shows a growing queue depth is working exactly as designed during a collector outage — and that queue depth is the number to alert on, because a full disk buffer is where the data loss finally happens.

Operational notes

  • Size the buffer for your worst outage — a busy site can generate gigabytes per day; a 2 GB disk buffer buys hours, not days.
  • TLS on the relay-to-collector hop — device-to-relay traffic is often plain syslog because the devices cannot do better, so the relay is where you enforce encryption. Verify the peer certificate; do not disable verification to make a connection work.
  • Time synchronisation — a relay with a drifting clock corrupts every timestamp downstream. Use authenticated time sources as described in our Chrony NTP server configuration on Linux.
  • Rate limiting — a looping or malfunctioning device can flood the relay. Per-source limits protect the collector.

syslog-ng and rsyslog make different trade-offs, and the rsyslog approach in rsyslog central log server forwarding is worth reading before standardising on one. Whichever you choose, the design principle is the same: keep the device-to-relay hop simple and tolerant, and put your durability, filtering and encryption where you can manage them in one place.

原文链接:https://syslog-ng.github.io/admin-guide/070_Destinations/310_syslog-ng/000_syslog-ng_destination_options.html