Skip to content

out_syslog: tls feature glitches for selecting protocols - #12196

Merged
edsiper merged 3 commits into
masterfrom
cosmo0920-out_syslog-tls-feature-glitches
Aug 3, 2026
Merged

out_syslog: tls feature glitches for selecting protocols#12196
edsiper merged 3 commits into
masterfrom
cosmo0920-out_syslog-tls-feature-glitches

Conversation

@cosmo0920

@cosmo0920 cosmo0920 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Implemented the syslog TLS validation and integration coverage.

  • mode=tls automatically enables TLS over TCP.
  • mode=dtls automatically enables DTLS over UDP.
  • Plain tcp/udp remain unchanged.
  • mode=udp with tls on remains rejected.

Coverage:

  • Full syslog runtime test: passed.
  • Syslog integration suite: 4/4 passed, including real TLS and DTLS mock receivers without tls on.
  • Commit-prefix linter: passed.
  • Valgrind unavailable on this macOS host.

The review’s commit-splitting requirement is addressed:

  • f32b9e05f — implementation
  • 9b35b8365 — runtime tests
  • ee6b8058e — integration tests

No AGENTS.md change is needed.

The remote still has the previous three commits. Updating the PR requires a --force-with-lease push because the local history was rewritten; I have not pushed because force-pushing requires explicit authorization.

Closes #12193.


Enter [N/A] in the box, if an item is not applicable to your change.

Testing
Before we can approve your change; please submit the following in a comment:

  • Example configuration file for the change
  • Debug log output from testing the change
  • Attached Valgrind output that shows no leaks or memory corruption was found

If this is a change to packaging of containers or native binaries then please confirm it works for all targets.

  • Run local packaging test showing all targets (including any new ones) build.
  • Set ok-package-test label to test for all targets (requires maintainer to do).

Documentation

  • Documentation required for this feature

Backporting

  • Backport to latest stable release.

Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.

Summary by CodeRabbit

  • New Features

    • TLS and DTLS syslog modes now automatically enable secure transport.
    • Added TLS syslog integration coverage, including certificate-based connection testing.
  • Bug Fixes

    • DTLS configurations no longer require an explicit TLS setting.
    • Builds without TLS support now consistently reject both secure transport modes.
  • Tests

    • Added runtime validation for TLS and DTLS mode behavior.
    • Updated integration scenarios to verify automatic secure transport enablement.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The syslog output now enables TLS automatically for mode=tls and mode=dtls. TLS context setup is shared for stream and datagram transports. Integration and runtime tests cover both modes.

Changes

Syslog secure mode handling

Layer / File(s) Summary
Secure mode setup and validation
plugins/out_syslog/syslog.c, plugins/out_syslog/syslog_conf.c
TLS and DTLS modes now enable TLS and use shared context setup. Unsupported builds reject both modes. Configuration descriptions reflect automatic TLS enablement.
Integration TLS coverage
tests/integration/scenarios/out_syslog/config/*, tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py
The integration scenario adds a certificate-backed TLS receiver and verifies TLS payload delivery. The DTLS test name reflects automatic TLS enablement.
Runtime secure mode coverage
tests/runtime/out_syslog.c
Runtime tests verify TLS activation, context creation, and the expected stream or datagram client mode.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SyslogConfig
  participant SyslogOutput
  participant TLSContext
  participant TLSReceiver
  SyslogConfig->>SyslogOutput: configures mode=tls
  SyslogOutput->>TLSContext: creates client TLS context
  SyslogOutput->>TLSReceiver: sends TLS syslog payload
  TLSReceiver-->>SyslogOutput: accepts and reads payload
Loading

Possibly related PRs

Suggested reviewers: edsiper

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR fixes plaintext transmission by auto-enabling TLS, but issue #12193 requests rejecting mode=tls without tls=on. Reject mode=tls when tls=off, while preserving mode=tls with tls=on; update tests and documentation to match this behavior.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The source changes and TLS/DTLS tests address syslog protocol selection and the linked TLS handling issue.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title identifies out_syslog TLS protocol-selection issues, which matches the main change to automatic TLS handling and validation.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cosmo0920-out_syslog-tls-feature-glitches

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cosmo0920 cosmo0920 changed the title out_syslog" tls feature glitches for selecting protocols out_syslog: tls feature glitches for selecting protocols Aug 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py (2)

309-336: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Wrap service.start() in the try/finally block for cleanup safety.

In test_out_syslog_tls, service.start() runs before the try block. If service.start() raises an unexpected error, service.stop() never runs, and the mock TLS receiver thread or a partially started Fluent Bit process is not cleaned up. test_out_syslog_tls_mode_requires_tls above already wraps its service.start() call in try/finally.

Move service.start() inside the try block for symmetry and safer cleanup on unexpected failures.

🧹 Proposed fix
 def test_out_syslog_tls():
     service = Service("out_syslog_tls.yaml", "tls")
-    service.start()
 
     try:
+        service.start()
         payload = service.receiver.wait_message(timeout=20)
     finally:
         service.stop()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py` around
lines 309 - 336, Move service.start() inside the existing try/finally block in
test_out_syslog_tls, keeping service.stop() guaranteed to run if startup or
message reception fails.

114-152: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Set a timeout on the raw socket before the TLS handshake.

TlsReceiver._run accepts a connection and wraps it with tls_context.wrap_socket(conn, server_side=True) without first calling conn.settimeout(...). The parent class TcpReceiver._run sets conn.settimeout(20) right after accept(), but TlsReceiver only sets a timeout on tls_conn after the handshake completes. In blocking mode, the TLS handshake performed inside wrap_socket can hang indefinitely if the client never completes it.

Set the timeout on conn before calling wrap_socket, so the handshake itself is bounded.

🔒️ Proposed fix
                 self._ready.set()
                 conn, _ = server.accept()

+                conn.settimeout(20)
                 with tls_context.wrap_socket(conn, server_side=True) as tls_conn:
                     tls_conn.settimeout(20)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py` around
lines 114 - 152, Update TlsReceiver._run to set the accepted raw conn socket
timeout before calling tls_context.wrap_socket, using the existing 20-second
timeout. Keep the existing tls_conn timeout and message-reading behavior
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py`:
- Around line 309-336: Move service.start() inside the existing try/finally
block in test_out_syslog_tls, keeping service.stop() guaranteed to run if
startup or message reception fails.
- Around line 114-152: Update TlsReceiver._run to set the accepted raw conn
socket timeout before calling tls_context.wrap_socket, using the existing
20-second timeout. Keep the existing tls_conn timeout and message-reading
behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 72cc858f-953e-48e8-bcb4-2e13ceb393d8

📥 Commits

Reviewing files that changed from the base of the PR and between f724311 and 6c0d0f5.

📒 Files selected for processing (6)
  • plugins/out_syslog/syslog.c
  • plugins/out_syslog/syslog_conf.c
  • tests/integration/scenarios/out_syslog/config/out_syslog_tls.yaml
  • tests/integration/scenarios/out_syslog/config/out_syslog_tls_without_tls.yaml
  • tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py
  • tests/runtime/out_syslog.c

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6c0d0f54fd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py Outdated
@edsiper

edsiper commented Aug 3, 2026

Copy link
Copy Markdown
Member

Would be possible to make it auto enable? If the user needs mode tls , tls gets on automatically?

Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
@cosmo0920
cosmo0920 force-pushed the cosmo0920-out_syslog-tls-feature-glitches branch from 6c0d0f5 to ee6b805 Compare August 3, 2026 14:17
@cosmo0920

Copy link
Copy Markdown
Contributor Author

Got it. I changed to enable TLS/DTLS automatically.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py (1)

113-151: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared read loop instead of duplicating it in TlsReceiver.

TlsReceiver._run repeats the accept-and-chunk-read loop from TcpReceiver._run almost verbatim, differing only in the TLS wrapping step. Extract the chunk-reading logic (lines 79-89 in TcpReceiver._run, lines 134-144 here) into a shared helper that both classes call with the connected socket object.

♻️ Proposed refactor to share the read loop
 class TcpReceiver:
     ...
+    def _read_message(self, conn, timeout=20):
+        conn.settimeout(timeout)
+        chunks = []
+        while True:
+            chunk = conn.recv(4096)
+            if not chunk:
+                break
+            chunks.append(chunk)
+            if b"\n" in chunk:
+                break
+        return b"".join(chunks)
+
     def _run(self):
         try:
             with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
                 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                 server.bind((self.host, self.port))
                 server.listen(1)
                 server.settimeout(120)
                 self._ready.set()
                 conn, _ = server.accept()

                 with conn:
-                    conn.settimeout(20)
-                    chunks = []
-
-                    while True:
-                        chunk = conn.recv(4096)
-                        if not chunk:
-                            break
-                        chunks.append(chunk)
-                        if b"\n" in chunk:
-                            break
-
-                    self.message = b"".join(chunks)
+                    self.message = self._read_message(conn)
                     self._done.set()
         except Exception as exc:
             self.error = exc
             self._ready.set()
             self._done.set()


 class TlsReceiver(TcpReceiver):
     ...
     def _run(self):
         try:
             tls_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
             tls_context.load_cert_chain(certfile=self.cert_file, keyfile=self.key_file)

             with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
                 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                 server.bind((self.host, self.port))
                 server.listen(1)
                 server.settimeout(120)
                 self._ready.set()
                 conn, _ = server.accept()

                 with tls_context.wrap_socket(conn, server_side=True) as tls_conn:
-                    tls_conn.settimeout(20)
-                    chunks = []
-
-                    while True:
-                        chunk = tls_conn.recv(4096)
-                        if not chunk:
-                            break
-                        chunks.append(chunk)
-                        if b"\n" in chunk:
-                            break
-
-                    self.message = b"".join(chunks)
+                    self.message = self._read_message(tls_conn)
                     self._done.set()
         except Exception as exc:
             self.error = exc
             self._ready.set()
             self._done.set()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py` around
lines 113 - 151, Extract the repeated chunk-reading and message assembly logic
from TcpReceiver._run and TlsReceiver._run into a shared helper that accepts a
connected socket, then have both _run methods call it after establishing their
respective connections. Preserve the existing newline-terminated read behavior,
message assignment, and completion signaling while keeping TLS wrapping specific
to TlsReceiver.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py`:
- Around line 113-151: Extract the repeated chunk-reading and message assembly
logic from TcpReceiver._run and TlsReceiver._run into a shared helper that
accepts a connected socket, then have both _run methods call it after
establishing their respective connections. Preserve the existing
newline-terminated read behavior, message assignment, and completion signaling
while keeping TLS wrapping specific to TlsReceiver.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: db47608e-d135-4285-a724-c07ffa3ac878

📥 Commits

Reviewing files that changed from the base of the PR and between 6c0d0f5 and ee6b805.

📒 Files selected for processing (6)
  • plugins/out_syslog/syslog.c
  • plugins/out_syslog/syslog_conf.c
  • tests/integration/scenarios/out_syslog/config/out_syslog_dtls.yaml
  • tests/integration/scenarios/out_syslog/config/out_syslog_tls.yaml
  • tests/integration/scenarios/out_syslog/tests/test_out_syslog_001.py
  • tests/runtime/out_syslog.c
💤 Files with no reviewable changes (2)
  • plugins/out_syslog/syslog_conf.c
  • tests/integration/scenarios/out_syslog/config/out_syslog_dtls.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/integration/scenarios/out_syslog/config/out_syslog_tls.yaml

@edsiper
edsiper merged commit b9d2782 into master Aug 3, 2026
66 checks passed
@edsiper
edsiper deleted the cosmo0920-out_syslog-tls-feature-glitches branch August 3, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

out: syslog: mode:tls without tls:on sends plaintext over TCP.

2 participants