Skip to content

Commit

Permalink
Merge pull request #524 from MrAnno/webhook-proxy-and-headers
Browse files Browse the repository at this point in the history
`webhook()`: proxy and headers support
  • Loading branch information
OverOrion authored Mar 3, 2025
2 parents 983b87d + 1b2911c commit c79f209
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ block source webhook(
tls_use_system_cert_store(no)
tls_ca_file("")
tls_ca_dir("")
proxy_header("")
include_request_headers(no)
...
)
{
Expand All @@ -48,6 +50,8 @@ block source webhook(
"tls_use_system_cert_store" => `tls_use_system_cert_store`
"tls_ca_file" => "`tls_ca_file`"
"tls_ca_dir" => "`tls_ca_dir`"
"proxy_header" => "`proxy_header`"
"include_request_headers" => `include_request_headers`
)
`__VARARGS__`
);
Expand Down
41 changes: 39 additions & 2 deletions modules/python-modules/syslogng/modules/webhook/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,22 @@
#############################################################################

from syslogng import LogSource, LogMessage
from collections import defaultdict

import logging
import asyncio
import threading
import tornado
import ssl
import signal
import json
from typing import Any

signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGTERM, signal.SIG_IGN)
WEBHOOK_QUERY_NV_PREFIX = "webhook.query."
WEBHOOK_NV_PREFIX = "webhook."
WEBHOOK_QUERY_NV_PREFIX = WEBHOOK_NV_PREFIX + "query."
WEBHOOK_HEADERS_KEY = WEBHOOK_NV_PREFIX + "headers"


class Handler(tornado.web.RequestHandler):
Expand All @@ -52,6 +56,26 @@ async def post(self, **path_arguments) -> None:

await self.finish({"status": "received"})

def _set_proxied_ip(self, msg: LogMessage) -> None:
proxy_headers = self.request.headers.get_list(self.source.proxy_header)

if proxy_headers and len(proxy_headers) > 0:
# the closest/last IP (the proxy_header flag implies that the last one can be trusted)
msg.set_source_ipaddress(proxy_headers[-1])
msg["PEERIP"] = self.request.remote_ip
return

msg.set_source_ipaddress(self.request.remote_ip)

def _set_request_headers(self, msg: LogMessage) -> None:
headers = defaultdict(list)
for h in self.request.headers.get_all():
name = h[0]
if name:
headers[name].append(h[1])

msg[WEBHOOK_HEADERS_KEY] = json.dumps(headers)

def _construct_msg(self, request, path_arguments) -> LogMessage:
msg = LogMessage(self.request.body)
msg.set_recvd_rawmsg_size(len(self.request.body))
Expand All @@ -63,7 +87,13 @@ def _construct_msg(self, request, path_arguments) -> LogMessage:
for key, value in path_arguments.items():
msg[key] = value

msg.set_source_ipaddress(self.request.remote_ip)
if self.source.include_request_headers:
self._set_request_headers(msg)

if self.source.proxy_header:
self._set_proxied_ip(msg)
else:
msg.set_source_ipaddress(self.request.remote_ip)

return msg

Expand Down Expand Up @@ -184,6 +214,13 @@ def init_options(self, options: dict[str, Any]) -> bool:
self.tls_use_system_cert_store = bool(options.get("tls_use_system_cert_store", False))
self.tls_ca_file = options.get("tls_ca_file")
self.tls_ca_dir = options.get("tls_ca_dir")

self.proxy_header = options.get("proxy_header")
if self.proxy_header == "yes":
self.proxy_header = "x-forwarded-for"

self.include_request_headers = bool(options.get("include_request_headers", False))

return True
except KeyError as e:
self.logger.error(f"Missing option '{e.args[0]}'")
Expand Down
14 changes: 14 additions & 0 deletions news/feature-524.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
`webhook()`: headers support

`include-request-headers(yes)` stores request headers under the `${webhook.headers}` key,
allowing further processing, for example, in FilterX:

```
filterx {
headers = json(${webhook.headers});
$type = headers["Content-Type"][-1];
};
```

`proxy-header("x-forwarded-for")` helps retain the sender's original IP and the proxy's IP address
(`$SOURCEIP`, `$PEERIP`).

0 comments on commit c79f209

Please sign in to comment.