Add --log-queries=auth option.

This commit is contained in:
Simon Kelley
2025-04-20 22:20:52 +01:00
parent 95b74a7acf
commit e3a2c8dadf
6 changed files with 34 additions and 25 deletions

View File

@@ -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 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 .B --log-queries=extra
then the log has extra information at the start of each line. 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 .TP
.B \-8, --log-facility=<facility> .B \-8, --log-facility=<facility>
Set the facility to which dnsmasq will send syslog entries, this Set the facility to which dnsmasq will send syslog entries, this

View File

@@ -116,6 +116,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
union all_addr addr; union all_addr addr;
struct cname *a, *candidate; struct cname *a, *candidate;
unsigned int wclen; unsigned int wclen;
unsigned int log_flags = local_query ? 0 : F_NOERR;
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY ) if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
return 0; 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)) if (local_query || in_zone(zone, intr->name, NULL))
{ {
found = 1; 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, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, daemon->auth_ttl, NULL,
T_PTR, C_IN, "d", intr->name)) 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, ".");
strcat(name, zone->domain); 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; found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, 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))) 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; found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, 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))) 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; found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 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) if (found)
nxdomain = 0; nxdomain = 0;
else 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; 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) if (rc == 2 && qtype == T_MX)
{ {
found = 1; found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>", 0); log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<MX>", 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_MX, C_IN, "sd", rec->weight, rec->target)) NULL, T_MX, C_IN, "sd", rec->weight, rec->target))
anscount++; 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) if (rc == 2 && qtype == T_SRV)
{ {
found = 1; found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>", 0); log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<SRV>", 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_SRV, C_IN, "sssd", NULL, T_SRV, C_IN, "sssd",
rec->priority, rec->weight, rec->srvport, rec->target)) 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) if (rc == 2 && txt->class == qtype)
{ {
found = 1; 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, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, txt->class, C_IN, "t", txt->len, txt->txt)) NULL, txt->class, C_IN, "t", txt->len, txt->txt))
anscount++; 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) if (rc == 2 && qtype == T_TXT)
{ {
found = 1; found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>", 0); log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<TXT>", 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_TXT, C_IN, "t", txt->len, txt->txt)) NULL, T_TXT, C_IN, "t", txt->len, txt->txt))
anscount++; 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) if (rc == 2 && qtype == T_NAPTR)
{ {
found = 1; found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>", 0); log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>", 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_NAPTR, C_IN, "sszzzd", NULL, T_NAPTR, C_IN, "sszzzd",
na->order, na->pref, na->flags, na->services, na->regexp, na->replace)) 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; continue;
found = 1; 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, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN, daemon->auth_ttl, NULL, qtype, C_IN,
qtype == T_A ? "4" : "6", &addrlist->addr)) 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; 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, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addr)) daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addr))
anscount++; 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) if (qtype == T_SOA)
{ {
auth = soa = 1; /* inhibits auth section */ auth = soa = 1; /* inhibits auth section */
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>", 0); log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>", 0);
} }
else if (qtype == T_AXFR) 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! */ ns = 1; /* ensure we include NS records! */
axfr = 1; axfr = 1;
axfroffset = nameoffset; axfroffset = nameoffset;
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>", 0); log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>", 0);
} }
else if (qtype == T_NS) else if (qtype == T_NS)
{ {
auth = 1; auth = 1;
ns = 1; /* inhibits auth section */ ns = 1; /* inhibits auth section */
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>", 0); log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>", 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)))) (local_query || filter_zone(zone, flag, &(crecp->addr))))
{ {
*cut = '.'; /* restore domain part */ *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 */ *cut = 0; /* remove domain part */
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN, 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; nxdomain = 0;
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr)))) 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, if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN, daemon->auth_ttl, NULL, qtype, C_IN,
qtype == T_A ? "4" : "6", &crecp->addr)) 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) 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); strcpy(name, candidate->target);
if (!strchr(name, '.')) 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)) else if (cache_find_non_terminal(name, now))
nxdomain = 0; 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))) if (!(ansp = skip_questions(header, qlen)))
return 0; /* bad packet */ return 0; /* bad packet */
anscount = authcount = 0; 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) 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); header->nscount = htons(0);
addr.log.rcode = REFUSED; addr.log.rcode = REFUSED;
addr.log.ede = EDE_NOT_AUTH; 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); return resize_packet(header, ansp - (unsigned char *)header, NULL, 0);
} }

View File

@@ -2184,6 +2184,10 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
if (!option_bool(OPT_LOG)) if (!option_bool(OPT_LOG))
return; 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 */ /* build query type string if requested */
if (!(flags & (F_SERVER | F_IPSET)) && type > 0) if (!(flags & (F_SERVER | F_IPSET)) && type > 0)
arg = querystr(arg, type); arg = querystr(arg, type);

View File

@@ -281,7 +281,8 @@ struct event_desc {
#define OPT_LOG_PROTO 73 #define OPT_LOG_PROTO 73
#define OPT_NO_0x20 74 #define OPT_NO_0x20 74
#define OPT_DO_0x20 75 #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_BITS (sizeof(unsigned int)*8)
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) ) #define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )

View File

@@ -1822,7 +1822,7 @@ void receive_query(struct listener *listen, time_t now)
#ifdef HAVE_AUTH #ifdef HAVE_AUTH
struct auth_zone *zone; struct auth_zone *zone;
#endif #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); &source_addr, auth_dns ? "auth" : "query", type);
#ifdef HAVE_AUTH #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_question = blockdata_alloc((char *)header, (size_t)size);
saved_size = 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); &peer_addr, auth_dns ? "auth" : "query", qtype);
#ifdef HAVE_AUTH #ifdef HAVE_AUTH

View File

@@ -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_EXTRALOG);
set_option_bool(OPT_LOG_PROTO); set_option_bool(OPT_LOG_PROTO);
} }
else if (strcmp(arg, "auth") == 0)
set_option_bool(OPT_AUTH_LOG);
} }
break; break;