Bug #8377
openOPNsense Suricata divert-to mode causes aborted HTTPS response streams (Axios / Node.js) – works with responseType: stream
Description
Describe the bug¶
When using Suricata with the new divert-to mode in OPNsense, some HTTPS requests made with Node.js (Axios) fail with response stream aborted.
The same request works normally when:
- `divert-to` is disabled (`none`)
- Axios is configured with `responseType: "stream"`
- requesting a static file (e.g. `/robots.txt`) instead of an HTML page
Issue in OPNsense: https://github.com/opnsense/core/issues/9956
Network Setup
Cloud VM (uptime-kuma)
│
Internet
│
OPNsense (Suricata IPS enabled, divert-to mode)
│
Reverse Proxy
│
Backend Application
To Reproduce¶
The request is sent from an external cloud VM to a public service behind OPNsense.
- Deploy a service behind OPNsense that is reachable via HTTPS through a reverse proxy.
- Enable Suricata IPS on the WAN interface using divert-to mode.
- From an external system (e.g. cloud VM), run the following Node.js request:
node -e ' const axios = require("axios"); const https = require("https"); const http = require("http"); const httpsAgent = new https.Agent({ rejectUnauthorized: true, maxCachedSessions: 0 }); const httpAgent = new http.Agent({ maxCachedSessions: 0 }); axios({ url: "https://example.com", method: "get", timeout: 10000, maxRedirects: 10, httpAgent, httpsAgent, headers: { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" } }) .then(res => { console.log("STATUS", res.status); }) .catch(err => { console.error("ERROR", err.message); }); '
Output: ERROR response stream aborted
Suricata disabled¶
When i set divert-to to None it works as expected:
node -e ' const axios = require("axios"); const https = require("https"); const http = require("http"); const httpsAgent = new https.Agent({ rejectUnauthorized: true, maxCachedSessions: 0 }); const httpAgent = new http.Agent({ maxCachedSessions: 0 }); axios({ url: "https://example.com", method: "get", timeout: 10000, maxRedirects: 10, httpAgent, httpsAgent, headers: { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" } }) .then(res => { console.log("STATUS", res.status); }) .catch(err => { console.error("ERROR", err.message); }); '
Output: STATUS 200
Response Type: stream¶
If set 'responseType: "stream",' the request works as expected even with suricata divert-to enabled:
node -e ' const axios = require("axios"); const https = require("https"); const http = require("http"); const httpsAgent = new https.Agent({ rejectUnauthorized: true, maxCachedSessions: 0 }); const httpAgent = new http.Agent({ maxCachedSessions: 0 }); axios({ url: "https://example.com", method: "get", responseType: "stream", timeout: 10000, maxRedirects: 10, httpAgent, httpsAgent, headers: { "A
ccept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" } }) .then(res => { console.log("STATUS", res.status); }) .catch(err => { console.error("ERROR", err.message); }); '
Output: STATUS 200
Expected behavior¶
I would expect STATUS 200 with suricata divert-to enabled.
Relevant log files¶
There are no relevant logs and no alerts.
Environment¶
- OPNsense version: 26.1.4
- Suricata version: 8.0.3
- Client: Node.js + Axios
- Test system: containerized uptime-kuma