]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
doh2: log like dns v3 11536/head
authorPhilippe Antoine <pantoine@oisf.net>
Tue, 9 Jul 2024 21:33:27 +0000 (23:33 +0200)
committerVictor Julien <victor@inliniac.net>
Sat, 20 Jul 2024 08:37:58 +0000 (10:37 +0200)
rust/src/http2/logger.rs
src/output-json-dns.c
src/output-json-dns.h
src/output.c

index b424e62b8446166a85229c52e69da2328209c7d6..bf5fc9b1ea458d62dc5cc81a2075622f461e61c1 100644 (file)
@@ -17,7 +17,6 @@
 
 use super::http2::{HTTP2Frame, HTTP2FrameTypeData, HTTP2Transaction};
 use super::parser;
-use crate::dns::log::{SCDnsLogAnswerEnabled, SCDnsLogJsonAnswer, SCDnsLogJsonQuery};
 use crate::jsonbuilder::{JsonBuilder, JsonError};
 use std;
 use std::collections::{HashMap, HashSet};
@@ -282,35 +281,6 @@ fn log_http2(tx: &HTTP2Transaction, js: &mut JsonBuilder) -> Result<bool, JsonEr
     js.close()?; // http2
     js.close()?; // http
 
-    if let Some(doh) = &tx.doh {
-        js.open_object("dns")?;
-        if let Some(dtx) = &doh.dns_request_tx {
-            let mark = js.get_mark();
-            let mut has_dns_query = false;
-            js.open_array("query")?;
-            for i in 0..0xFFFF {
-                let mut jsa = JsonBuilder::try_new_object()?;
-                if !SCDnsLogJsonQuery(dtx, i, 0xFFFFFFFFFFFFFFFF, &mut jsa) {
-                    break;
-                }
-                jsa.close()?;
-                js.append_object(&jsa)?;
-                has_dns_query = true;
-            }
-            if has_dns_query {
-                js.close()?; // query
-            } else {
-                js.restore_mark(&mark)?;
-            }
-        }
-        if let Some(dtx) = &doh.dns_response_tx {
-            if SCDnsLogAnswerEnabled(dtx, 0xFFFFFFFFFFFFFFFF) {
-                // logging at root of dns object
-                SCDnsLogJsonAnswer(dtx, 0xFFFFFFFFFFFFFFFF, js);
-            }
-        }
-        js.close()?; // dns
-    }
     return Ok(has_request || has_response || has_headers);
 }
 
index 0c901e8f854f71ea927b1bb9ab12536552f8fb28..3a72cb7c586e4c232d65d985460ee214e5911c30 100644 (file)
@@ -254,6 +254,89 @@ bool AlertJsonDns(void *txptr, JsonBuilder *js)
             txptr, LOG_FORMAT_DETAILED | LOG_QUERIES | LOG_ANSWERS | LOG_ALL_RRTYPES, js);
 }
 
+bool AlertJsonDoh2(void *txptr, JsonBuilder *js)
+{
+    JsonBuilderMark mark = { 0, 0, 0 };
+
+    jb_get_mark(js, &mark);
+    // first log HTTP2 part
+    bool r = rs_http2_log_json(txptr, js);
+    if (!r) {
+        jb_restore_mark(js, &mark);
+    }
+    // then log one DNS tx if any, preferring the answer
+    void *tx_dns = DetectGetInnerTx(txptr, ALPROTO_DOH2, ALPROTO_DNS, STREAM_TOCLIENT);
+    if (tx_dns == NULL) {
+        tx_dns = DetectGetInnerTx(txptr, ALPROTO_DOH2, ALPROTO_DNS, STREAM_TOSERVER);
+    }
+    bool r2 = false;
+    if (tx_dns) {
+        jb_get_mark(js, &mark);
+        r2 = AlertJsonDns(tx_dns, js);
+        if (!r2) {
+            jb_restore_mark(js, &mark);
+        }
+    }
+    return r || r2;
+}
+
+static int JsonDoh2Logger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f,
+        void *alstate, void *txptr, uint64_t tx_id)
+{
+    LogDnsLogThread *td = (LogDnsLogThread *)thread_data;
+    LogDnsFileCtx *dnslog_ctx = td->dnslog_ctx;
+
+    JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_FLOW, "dns", NULL, dnslog_ctx->eve_ctx);
+
+    if (unlikely(jb == NULL)) {
+        return TM_ECODE_OK;
+    }
+
+    JsonBuilderMark mark = { 0, 0, 0 };
+
+    jb_get_mark(jb, &mark);
+    // first log HTTP2 part
+    bool r = rs_http2_log_json(txptr, jb);
+    if (!r) {
+        jb_restore_mark(jb, &mark);
+    }
+
+    void *tx_dns = DetectGetInnerTx(txptr, ALPROTO_DOH2, ALPROTO_DNS, STREAM_TOCLIENT);
+    if (tx_dns == NULL) {
+        tx_dns = DetectGetInnerTx(txptr, ALPROTO_DOH2, ALPROTO_DNS, STREAM_TOSERVER);
+    }
+    bool r2 = false;
+    if (tx_dns) {
+        // mix of JsonDnsLogger
+        if (SCDnsTxIsRequest(tx_dns)) {
+            if (unlikely(dnslog_ctx->flags & LOG_QUERIES) == 0) {
+                goto out;
+            }
+        } else if (SCDnsTxIsResponse(tx_dns)) {
+            if (unlikely(dnslog_ctx->flags & LOG_ANSWERS) == 0) {
+                goto out;
+            }
+        }
+
+        if (!SCDnsLogEnabled(tx_dns, td->dnslog_ctx->flags)) {
+            goto out;
+        }
+
+        jb_get_mark(jb, &mark);
+        // log DOH2 with DNS config
+        r2 = SCDnsLogJson(tx_dns, td->dnslog_ctx->flags, jb);
+        if (!r2) {
+            jb_restore_mark(jb, &mark);
+        }
+    }
+out:
+    if (r || r2) {
+        OutputJsonBuilderBuffer(jb, td->ctx);
+    }
+    jb_free(jb);
+    return TM_ECODE_OK;
+}
+
 static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data,
     const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id)
 {
@@ -591,3 +674,10 @@ void JsonDnsLogRegister (void)
             JsonDnsLogInitCtxSub, ALPROTO_DNS, JsonDnsLogger, LogDnsLogThreadInit,
             LogDnsLogThreadDeinit, NULL);
 }
+
+void JsonDoh2LogRegister(void)
+{
+    OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonDoH2Log", "eve-log.doh2",
+            JsonDnsLogInitCtxSub, ALPROTO_DOH2, JsonDoh2Logger, LogDnsLogThreadInit,
+            LogDnsLogThreadDeinit, NULL);
+}
index 1fe11427b3046b5ac37ca04f7fcec55a43206629..e5f07bcea97f948f45c6361e70925d700300093d 100644 (file)
@@ -25,7 +25,9 @@
 #define SURICATA_OUTPUT_JSON_DNS_H
 
 void JsonDnsLogRegister(void);
+void JsonDoh2LogRegister(void);
 
 bool AlertJsonDns(void *vtx, JsonBuilder *js);
+bool AlertJsonDoh2(void *vtx, JsonBuilder *js);
 
 #endif /* SURICATA_OUTPUT_JSON_DNS_H */
index f621964146544afd05c00528c2604593eb2b58c1..f5bd70f66ec871d9d2ac22f16371e4d2cadd9894 100644 (file)
@@ -1097,9 +1097,7 @@ void OutputRegisterLoggers(void)
             OutputJsonLogInitSub, ALPROTO_LDAP, JsonGenericDirPacketLogger, JsonLogThreadInit,
             JsonLogThreadDeinit, NULL);
     /* DoH2 JSON logger. */
-    OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonDoH2Log", "eve-log.doh2",
-            OutputJsonLogInitSub, ALPROTO_DOH2, JsonGenericDirFlowLogger, JsonLogThreadInit,
-            JsonLogThreadDeinit, NULL);
+    JsonDoh2LogRegister();
     /* Template JSON logger. */
     OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonTemplateLog", "eve-log.template",
             OutputJsonLogInitSub, ALPROTO_TEMPLATE, JsonGenericDirPacketLogger, JsonLogThreadInit,
@@ -1156,7 +1154,7 @@ static EveJsonSimpleAppLayerLogger simple_json_applayer_loggers[ALPROTO_MAX] = {
     { ALPROTO_TELNET, NULL }, // no logging
     { ALPROTO_WEBSOCKET, rs_websocket_logger_log },
     { ALPROTO_LDAP, rs_ldap_logger_log },
-    { ALPROTO_DOH2, rs_http2_log_json }, // http2 logger knows how to log dns
+    { ALPROTO_DOH2, AlertJsonDoh2 },
     { ALPROTO_TEMPLATE, rs_template_logger_log },
     { ALPROTO_RDP, (EveJsonSimpleTxLogFunc)rs_rdp_to_json },
     { ALPROTO_HTTP2, rs_http2_log_json },