Skip to content

Add agent-side UDP/TCP Syslog listener support to Logcollector - #877

Open
allamiro wants to merge 1 commit into
wazuh:mainfrom
allamiro:feature/agent-side-syslog-listener-15178
Open

Add agent-side UDP/TCP Syslog listener support to Logcollector#877
allamiro wants to merge 1 commit into
wazuh:mainfrom
allamiro:feature/agent-side-syslog-listener-15178

Conversation

@allamiro

@allamiro allamiro commented Jun 25, 2026

Copy link
Copy Markdown

Summary

Adds native agent-side UDP/TCP Syslog listener support to the Wazuh Agent Logcollector.

This lets lightweight remote-site deployments forward basic Syslog directly to a local Wazuh agent over UDP or TCP, while preserving the normal agent-to-manager collection model. Received messages enter the existing Logcollector processing path, are sent through the standard encrypted/authenticated agent connection, and remain associated with the receiving agent (no manager-local 000 ingestion).

Related to wazuh/wazuh#15178.

What changed

  • New SyslogReader (implements the existing IReader interface) providing UDP and TCP listeners using the project's Boost.Asio coroutine model.
  • Logcollector::SetupSyslogReaders() parses a new logcollector.syslog configuration section and creates one listener per definition.
  • Configuration validation before any listener starts: protocol (udp/tcp), port range (1–65535), bind address (make_address), and duplicate protocol+address+port detection. Invalid/duplicate entries are logged and skipped — no listener is ever silently enabled.
  • Support for multiple independent listeners on the same agent, each with its own lifecycle, startup/shutdown and error logging.
  • Clean startup/shutdown: sockets are closed on the io_context thread, TCP client sockets are tracked and closed on stop (no fd/thread leaks).
  • Backward compatibility preserved for existing file/journald/windows/macOS collectors; manager-side remote Syslog is untouched.
  • Unit tests and documentation added.

Configuration

The new Wazuh 6.x agent uses YAML configuration (not the legacy XML <localfile>), so the issue's proposed <location type="udp"> is expressed in the existing YAML style, mirroring the journald collector:

logcollector:
  enabled: true
  syslog:
    - protocol: udp
      bind_address: 127.0.0.1   # optional, defaults to 127.0.0.1
      port: 5514
    - protocol: tcp
      bind_address: 127.0.0.1
      port: 1514
    - protocol: udp
      bind_address: 192.168.10.20
      port: 5515

Messages are pushed with the remote-syslog collector type and the listener identity (<protocol>:<address>:<port>) as the event provider.

Validation

Built and tested on Linux (RHEL 9, GCC 11.5):

  • Compiles clean under the project's strict flags (-Werror -Wconversion -Wsign-conversion -Wold-style-cast -Wshadow -Wpedantic …) — 0 warnings.
  • Syslog unit tests: 22/22 pass — 15 config-parsing/validation cases (valid UDP/TCP/multiple/optional-bind; rejects unsupported protocol, missing/zero/out-of-range/non-numeric port, malformed bind address, duplicate listener; same port + different protocol allowed) and 7 runtime cases (UDP receive, TCP receive, multi-line TCP framing, multiple concurrent listeners, empty-datagram drop, clean shutdown — exercising real loopback sockets).
  • Full Logcollector suite: 41/41 pass (no regressions).
  • Note: clang-tidy was not run locally (not installed in the build environment); the project's CI clang-tidy gate will exercise it. The code was written to satisfy those checks (const-correctness, magic-number constants, coroutine value-param suppressions, etc.).

Scope and future work

Issue #15178 proposes three ingress types for localfile: UDP/TCP syslog, UNIX sockets, and pipes. This PR implements the UDP/TCP IP-socket listeners only (the part highlighted in the recent discussion). The remaining items are intentionally deferred and tracked as future work (documented in the module README and in a reference comment in syslog_reader.hpp):

  • UNIX domain sockets (unix_stream / unix_dgram / unix_seq) — not included.
  • Named pipe / FIFO ingress (and Windows named pipes) — not included.
  • TLS Syslog for the TCP listener — not included; the TCP listener is plaintext.
  • TCP octet-counting framing (RFC 6587) — only newline-delimited ("non-transparent") framing is parsed; octet-counted messages (<len> <msg>) are not auto-detected.
  • Hostname bind_address — only numeric IPv4/IPv6 literals are accepted; DNS names are rejected by design.
  • allowed-ips source filtering — use host firewall rules until implemented.

For high-volume ingestion, TLS Syslog, disk-assisted queues, advanced filtering, transformations, routing, or complex parsing pipelines, rsyslog, syslog-ng, Logstash, or the Wazuh manager remote Syslog input remain the recommended options. This change does not modify or replace any of them.

@allamiro
allamiro force-pushed the feature/agent-side-syslog-listener-15178 branch 4 times, most recently from 49a67c8 to c21810d Compare June 25, 2026 11:11
@allamiro
allamiro force-pushed the feature/agent-side-syslog-listener-15178 branch from c21810d to 83defd8 Compare June 25, 2026 13:16
Add native agent-side Syslog listener support so the Wazuh agent can
receive basic Syslog messages directly over UDP or TCP, instead of
requiring an external service to write them to a file first. Received
messages enter the existing Logcollector processing path and are sent
through the standard agent-to-manager pipeline, remaining associated
with the receiving agent.

- New SyslogReader (IReader) implementing UDP and TCP listeners with the
  Boost.Asio coroutine model used by the other readers.
- SetupSyslogReaders parses a new logcollector.syslog configuration
  section and creates one listener per definition; multiple independent
  listeners are supported.
- Validation before any listener starts: protocol (udp/tcp), port range
  (1-65535), bind address, and duplicate protocol+address+port detection.
  Invalid or duplicate entries are logged and skipped, so no listener is
  silently enabled. bind_address defaults to 127.0.0.1.
- Clean startup/shutdown: sockets are closed on the io_context thread and
  TCP client sockets are tracked and closed on stop.
- Backward compatibility preserved for file, journald, windows and macOS
  collectors; manager-side remote Syslog is unchanged.
- Unit tests for configuration parsing/validation and runtime UDP/TCP
  receipt, plus reference documentation and sample configuration.

Related to wazuh/wazuh#15178.
@allamiro
allamiro force-pushed the feature/agent-side-syslog-listener-15178 branch from cc5938a to 75e2ba0 Compare August 6, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant