# mod-reqin-log `mod_reqin_log` is an Apache HTTPD module (C shared object) that captures HTTP request metadata and sends it as JSON to a UNIX datagram socket. It serves as the HTTP-layer ingestion point for the ja4-platform pipeline, feeding request data to the [correlator](correlator.md) for joining with TLS fingerprint data from [sentinel](sentinel.md). ## Purpose Apache processes HTTP requests after TLS termination, so it has access to the decoded HTTP method, path, headers, and client IP/port. mod-reqin-log hooks into the `post_read_request` phase to serialize this data immediately, before any rewrite or auth module modifies the request. ## Apache Directives Reference All directives are server-level (`RSRC_CONF`): | Directive | Type | Default | Description | |-----------|------|---------|-------------| | `JsonSockLogEnabled` | Flag (On/Off) | Off | Enable or disable the module | | `JsonSockLogSocket` | String | — | UNIX domain socket path for JSON output | | `JsonSockLogHeaders` | String list | — | HTTP header names to log (repeatable) | | `JsonSockLogMaxHeaders` | Integer | `25` | Maximum number of headers to log | | `JsonSockLogMaxHeaderValueLen` | Integer | `256` | Maximum length of each header value (truncated beyond) | | `JsonSockLogReconnectInterval` | Integer (seconds) | `10` | Minimum seconds between reconnection attempts | | `JsonSockLogErrorReportInterval` | Integer (seconds) | `10` | Minimum seconds between error log entries (throttling) | | `JsonSockLogLevel` | String | `WARNING` | Module log level: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `EMERG` | ### Example httpd.conf ```apache LoadModule reqin_log_module modules/mod_reqin_log.so JsonSockLogEnabled On JsonSockLogSocket /var/run/logcorrelator/http.socket JsonSockLogHeaders User-Agent Accept Accept-Encoding Accept-Language JsonSockLogHeaders Content-Type X-Request-Id X-Trace-Id X-Forwarded-For JsonSockLogHeaders Sec-CH-UA Sec-CH-UA-Mobile Sec-CH-UA-Platform JsonSockLogHeaders Sec-Fetch-Dest Sec-Fetch-Mode Sec-Fetch-Site JsonSockLogMaxHeaders 25 JsonSockLogMaxHeaderValueLen 256 JsonSockLogReconnectInterval 10 JsonSockLogErrorReportInterval 10 JsonSockLogLevel WARNING ``` ## Output JSON Schema Each HTTP request is serialized as a flat JSON object and sent as a single UNIX datagram: ```json { "time": "2026-03-09T14:30:00Z", "src_ip": "203.0.113.42", "src_port": 52341, "dst_ip": "192.168.1.10", "dst_port": 443, "method": "GET", "scheme": "https", "host": "example.com", "path": "/api/v1/users", "query": "page=1&limit=20", "http_version": "HTTP/2.0", "client_headers": "User-Agent,Accept,Accept-Encoding,Accept-Language", "header_User-Agent": "Mozilla/5.0 ...", "header_Accept": "text/html,application/xhtml+xml", "header_Accept-Encoding": "gzip, deflate, br", "header_Accept-Language": "en-US,en;q=0.9", "header_Sec-Fetch-Dest": "document", "header_Sec-Fetch-Mode": "navigate", "header_Sec-Fetch-Site": "none" } ``` ### Field Reference | Field | Type | Description | |-------|------|-------------| | `time` | string (ISO 8601) | Request timestamp (UTC) | | `src_ip` | string | Client IP address | | `src_port` | int | Client source port | | `dst_ip` | string | Server IP address | | `dst_port` | int | Server port | | `method` | string | HTTP method (`GET`, `POST`, etc.) | | `scheme` | string | URL scheme (`http` or `https`) | | `host` | string | HTTP Host header value | | `path` | string | Request URI path | | `query` | string | Query string (without `?`) | | `http_version` | string | HTTP version (`HTTP/1.1`, `HTTP/2.0`) | | `client_headers` | string | Comma-separated list of header names sent by client (order preserved) | | `header_` | string | Value of each configured header (one field per header) | ### Sensitive Headers The following headers are **always excluded** from output regardless of `JsonSockLogHeaders`: - `Authorization` - `Cookie` - `Set-Cookie` - `X-Api-Key` - `X-Auth-Token` - `Proxy-Authorization` - `WWW-Authenticate` ### Size Limits - Maximum JSON size: **64 KB** (prevents memory exhaustion DoS) - Header values are truncated to `JsonSockLogMaxHeaderValueLen` bytes ## Thread Safety mod-reqin-log is designed for Apache's `worker` and `event` MPMs (multi-threaded): - **Socket FD** is protected by an `apr_thread_mutex_t` (`fd_mutex`) - **Per-child process state** includes the socket file descriptor, mutex, and error tracking - **Error reporting** uses `LOG_THROTTLED` macro with timestamp-based deduplication - All JSON serialization uses per-request pool allocation — no shared buffers ### Architecture ``` Apache HTTPD process ├── child process 1 │ ├── fd_mutex (apr_thread_mutex_t) │ ├── socket_fd (shared across threads) │ ├── thread 1 → post_read_request → serialize JSON → mutex lock → sendto() → unlock │ ├── thread 2 → post_read_request → serialize JSON → mutex lock → sendto() → unlock │ └── ... ├── child process 2 │ ├── fd_mutex │ ├── socket_fd (independent) │ └── ... ``` ## Reconnection Behavior - Socket is opened during `child_init` (per-child process startup) - If the socket is unavailable at startup, connection is deferred - On send failure, reconnection is attempted respecting `JsonSockLogReconnectInterval` - Failed sends are silently dropped (HTTP request processing is not blocked) - Error log entries are throttled by `JsonSockLogErrorReportInterval` - Socket type: `SOCK_DGRAM` (connectionless UNIX datagram) - Non-blocking sends with `MSG_NOSIGNAL` ## Deployment ### Installation via RPM ```bash rpm -ivh mod_reqin_log-1.0.19-1.el10.x86_64.rpm ``` ### LoadModule Directive ```apache LoadModule reqin_log_module modules/mod_reqin_log.so ``` ### Verifying Installation ```bash httpd -M | grep reqin_log # Expected: reqin_log_module (shared) ``` ## Build All builds run inside Docker: ```bash # Run unit tests make test-mod-reqin-log # Build RPM packages (el8, el9, el10) make rpm-mod-reqin-log # RPMs in services/mod-reqin-log/dist/rpm/el{8,9,10}/ ``` ### Local Build (requires Apache development headers) ```bash cd services/mod-reqin-log make build # Compiles mod_reqin_log.so via apxs make test # Runs unit tests ``` ### Test Coverage Unit tests cover: - JSON serialization (escaping, size limits, field output) - Config parsing (all directives, edge cases) - Header handling (sensitive header exclusion, max headers, truncation) - Module integration (real Apache module hooks) ## Source Files | File | Description | |------|-------------| | `src/mod_reqin_log.c` | Main module source | | `src/mod_reqin_log.h` | Header with types, constants, defaults | | `conf/mod_reqin_log.conf` | Example Apache configuration | | `tests/unit/test_json_serialization.c` | JSON output tests | | `tests/unit/test_config_parsing.c` | Directive parsing tests | | `tests/unit/test_header_handling.c` | Header filtering tests | | `tests/unit/test_module_real.c` | Integration tests |