From e3a2c8dadfe2c90c773c52cec81ff44f41860994 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Sun, 20 Apr 2025 22:20:52 +0100 Subject: [PATCH] Add --log-queries=auth option. --- man/dnsmasq.8 | 3 ++- src/auth.c | 43 ++++++++++++++++++++++--------------------- src/cache.c | 4 ++++ src/dnsmasq.h | 3 ++- src/forward.c | 4 ++-- src/option.c | 2 ++ 6 files changed, 34 insertions(+), 25 deletions(-) diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index d0ccd2a..0ae46a4 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -134,7 +134,8 @@ only, to stop dnsmasq daemonising in production, use Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1. If the argument "extra" is supplied, ie .B --log-queries=extra then the log has extra information at the start of each line. -This consists of a serial number which ties together the log lines associated with an individual query, and the IP address of the requestor. If the argument "proto" is supplied, this shows everything that "extra" does and also the network protocol used to communicate the queries. +This consists of a serial number which ties together the log lines associated with an individual query, and the IP address of the requestor. If the argument "proto" is supplied, this shows everything that "extra" does and also the network protocol used to communicate the queries. Logging of only queries to the authoritative server can be configured with +.B --log-queries=auth .TP .B \-8, --log-facility= Set the facility to which dnsmasq will send syslog entries, this diff --git a/src/auth.c b/src/auth.c index 2b8d385..b2cee26 100644 --- a/src/auth.c +++ b/src/auth.c @@ -116,6 +116,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n union all_addr addr; struct cname *a, *candidate; unsigned int wclen; + unsigned int log_flags = local_query ? 0 : F_NOERR; if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY ) return 0; @@ -210,7 +211,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (local_query || in_zone(zone, intr->name, NULL)) { found = 1; - log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL, 0); + log_query(log_flags | flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL, 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_PTR, C_IN, "d", intr->name)) @@ -234,7 +235,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n strcat(name, "."); strcat(name, zone->domain); } - log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid), 0); + log_query(log_flags | flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid), 0); found = 1; if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, @@ -243,7 +244,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n } else if (crecp->flags & (F_DHCP | F_HOSTS) && (local_query || in_zone(zone, name, NULL))) { - log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid), 0); + log_query(log_flags | (crecp->flags & ~F_FORWARD), name, &addr, record_source(crecp->uid), 0); found = 1; if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, @@ -257,7 +258,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (!found && is_rev_synth(flag, &addr, name) && (local_query || in_zone(zone, name, NULL))) { - log_query(F_CONFIG | F_REVERSE | flag, name, &addr, NULL, 0); + log_query(log_flags | F_CONFIG | F_REVERSE | flag, name, &addr, NULL, 0); found = 1; if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, @@ -269,7 +270,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (found) nxdomain = 0; else - log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL, 0); + log_query(log_flags | flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL, 0); continue; } @@ -300,7 +301,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (rc == 2 && qtype == T_MX) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, "", 0); + log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "", 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_MX, C_IN, "sd", rec->weight, rec->target)) anscount++; @@ -315,7 +316,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (rc == 2 && qtype == T_SRV) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, "", 0); + log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "", 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_SRV, C_IN, "sssd", rec->priority, rec->weight, rec->srvport, rec->target)) @@ -349,7 +350,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (rc == 2 && txt->class == qtype) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, NULL, txt->class); + log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, NULL, txt->class); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, txt->class, C_IN, "t", txt->len, txt->txt)) anscount++; @@ -363,7 +364,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (rc == 2 && qtype == T_TXT) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, "", 0); + log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "", 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_TXT, C_IN, "t", txt->len, txt->txt)) anscount++; @@ -377,7 +378,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (rc == 2 && qtype == T_NAPTR) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, "", 0); + log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "", 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_NAPTR, C_IN, "sszzzd", na->order, na->pref, na->flags, na->services, na->regexp, na->replace)) @@ -407,7 +408,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n continue; found = 1; - log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL, 0); + log_query(log_flags | F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL, 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addrlist->addr)) @@ -419,7 +420,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n { nxdomain = 0; - log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL, 0); + log_query(log_flags | F_FORWARD | F_CONFIG | flag, name, &addr, NULL, 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addr)) anscount++; @@ -432,7 +433,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (qtype == T_SOA) { auth = soa = 1; /* inhibits auth section */ - log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "", 0); + log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "", 0); } else if (qtype == T_AXFR) { @@ -468,13 +469,13 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n ns = 1; /* ensure we include NS records! */ axfr = 1; axfroffset = nameoffset; - log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "", 0); + log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "", 0); } else if (qtype == T_NS) { auth = 1; ns = 1; /* inhibits auth section */ - log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "", 0); + log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "", 0); } } @@ -492,7 +493,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n (local_query || filter_zone(zone, flag, &(crecp->addr)))) { *cut = '.'; /* restore domain part */ - log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0); + log_query(log_flags | crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0); *cut = 0; /* remove domain part */ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, qtype, C_IN, @@ -513,7 +514,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n nxdomain = 0; if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr)))) { - log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr, record_source(crecp->uid), 0); + log_query(log_flags | (crecp->flags & ~F_REVERSE), name, &crecp->addr, record_source(crecp->uid), 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &crecp->addr)) @@ -560,7 +561,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (candidate) { - log_query(F_CONFIG | F_CNAME, name, NULL, NULL, 0); + log_query(log_flags | F_CONFIG | F_CNAME, name, NULL, NULL, 0); strcpy(name, candidate->target); if (!strchr(name, '.')) { @@ -578,7 +579,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n else if (cache_find_non_terminal(name, now)) nxdomain = 0; - log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL, 0); + log_query(log_flags | flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL, 0); } } @@ -873,7 +874,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (!(ansp = skip_questions(header, qlen))) return 0; /* bad packet */ anscount = authcount = 0; - log_query(F_AUTH, "reply", NULL, "truncated", 0); + log_query(log_flags | F_AUTH, "reply", NULL, "truncated", 0); } if ((auth || local_query) && nxdomain) @@ -892,7 +893,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n header->nscount = htons(0); addr.log.rcode = REFUSED; addr.log.ede = EDE_NOT_AUTH; - log_query(F_UPSTREAM | F_RCODE, "error", &addr, NULL, 0); + log_query(log_flags | F_UPSTREAM | F_RCODE, "error", &addr, NULL, 0); return resize_packet(header, ansp - (unsigned char *)header, NULL, 0); } diff --git a/src/cache.c b/src/cache.c index 94f19a5..d394112 100644 --- a/src/cache.c +++ b/src/cache.c @@ -2184,6 +2184,10 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg, if (!option_bool(OPT_LOG)) return; + /* F_NOERR is reused here to indicate logs arrising from auth queries */ + if (!(flags & F_NOERR) && option_bool(OPT_AUTH_LOG)) + return; + /* build query type string if requested */ if (!(flags & (F_SERVER | F_IPSET)) && type > 0) arg = querystr(arg, type); diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 2e6b0b7..e4af90d 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -281,7 +281,8 @@ struct event_desc { #define OPT_LOG_PROTO 73 #define OPT_NO_0x20 74 #define OPT_DO_0x20 75 -#define OPT_LAST 76 +#define OPT_AUTH_LOG 76 +#define OPT_LAST 77 #define OPTION_BITS (sizeof(unsigned int)*8) #define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) ) diff --git a/src/forward.c b/src/forward.c index 2907e6a..79830c9 100644 --- a/src/forward.c +++ b/src/forward.c @@ -1822,7 +1822,7 @@ void receive_query(struct listener *listen, time_t now) #ifdef HAVE_AUTH struct auth_zone *zone; #endif - log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff, + log_query_mysockaddr((auth_dns ? F_NOERR : 0 ) | F_QUERY | F_FORWARD, daemon->namebuff, &source_addr, auth_dns ? "auth" : "query", type); #ifdef HAVE_AUTH @@ -2488,7 +2488,7 @@ unsigned char *tcp_request(int confd, time_t now, saved_question = blockdata_alloc((char *)header, (size_t)size); saved_size = size; - log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff, + log_query_mysockaddr((auth_dns ? F_NOERR : 0) | F_QUERY | F_FORWARD, daemon->namebuff, &peer_addr, auth_dns ? "auth" : "query", qtype); #ifdef HAVE_AUTH diff --git a/src/option.c b/src/option.c index 3f7e123..7d8d726 100644 --- a/src/option.c +++ b/src/option.c @@ -3435,6 +3435,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma set_option_bool(OPT_EXTRALOG); set_option_bool(OPT_LOG_PROTO); } + else if (strcmp(arg, "auth") == 0) + set_option_bool(OPT_AUTH_LOG); } break;