Skip to content

Commit

Permalink
doh2: log like dns v3
Browse files Browse the repository at this point in the history
  • Loading branch information
catenacyber authored and victorjulien committed Jul 20, 2024
1 parent 8aa2964 commit 7f6c963
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 34 deletions.
30 changes: 0 additions & 30 deletions rust/src/http2/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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);
}

Expand Down
90 changes: 90 additions & 0 deletions src/output-json-dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}
2 changes: 2 additions & 0 deletions src/output-json-dns.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
6 changes: 2 additions & 4 deletions src/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 },
Expand Down

0 comments on commit 7f6c963

Please sign in to comment.