Fix logging of DNSSEC queries in TCP mode. Destination server address was misleading.

This commit is contained in:
Simon Kelley
2018-10-06 23:23:23 +01:00
parent 0fdf3c1f61
commit e1791f36ea
3 changed files with 52 additions and 39 deletions

View File

@@ -1227,7 +1227,7 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
#endif #endif
/* dnssec.c */ /* dnssec.c */
size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, union mysockaddr *addr, int edns_pktsz); size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, int edns_pktsz);
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class); int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class); int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class, int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class,

View File

@@ -2026,19 +2026,11 @@ int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen)
} }
size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class,
int type, union mysockaddr *addr, int edns_pktsz) int type, int edns_pktsz)
{ {
unsigned char *p; unsigned char *p;
char *types = querystr("dnssec-query", type);
size_t ret; size_t ret;
if (addr->sa.sa_family == AF_INET)
log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, name, (struct all_addr *)&addr->in.sin_addr, types);
#ifdef HAVE_IPV6
else
log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, name, (struct all_addr *)&addr->in6.sin6_addr, types);
#endif
header->qdcount = htons(1); header->qdcount = htons(1);
header->ancount = htons(0); header->ancount = htons(0);
header->nscount = htons(0); header->nscount = htons(0);

View File

@@ -1058,7 +1058,7 @@ void reply_query(int fd, int family, time_t now)
status = STAT_ABANDONED; status = STAT_ABANDONED;
else else
{ {
int fd, type = SERV_DO_DNSSEC; int querytype, fd, type = SERV_DO_DNSSEC;
struct frec *next = new->next; struct frec *next = new->next;
char *domain; char *domain;
@@ -1111,15 +1111,26 @@ void reply_query(int fd, int family, time_t now)
if (status == STAT_NEED_KEY) if (status == STAT_NEED_KEY)
{ {
new->flags |= FREC_DNSKEY_QUERY; new->flags |= FREC_DNSKEY_QUERY;
nn = dnssec_generate_query(header, ((unsigned char *) header) + server->edns_pktsz, querytype = T_DNSKEY;
daemon->keyname, forward->class, T_DNSKEY, &server->addr, server->edns_pktsz);
} }
else else
{ {
new->flags |= FREC_DS_QUERY; new->flags |= FREC_DS_QUERY;
nn = dnssec_generate_query(header,((unsigned char *) header) + server->edns_pktsz, querytype = T_DS;
daemon->keyname, forward->class, T_DS, &server->addr, server->edns_pktsz);
} }
nn = dnssec_generate_query(header,((unsigned char *) header) + server->edns_pktsz,
daemon->keyname, forward->class, querytype, server->edns_pktsz);
if (server->addr.sa.sa_family == AF_INET)
log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, daemon->keyname, (struct all_addr *)&(server->addr.in.sin_addr),
querystr("dnssec-query", querytype));
#ifdef HAVE_IPV6
else
log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, daemon->keyname, (struct all_addr *)&(server->addr.in6.sin6_addr),
querystr("dnssec-query", querytype));
#endif
if ((hash = hash_questions(header, nn, daemon->namebuff))) if ((hash = hash_questions(header, nn, daemon->namebuff)))
memcpy(new->hash, hash, HASH_SIZE); memcpy(new->hash, hash, HASH_SIZE);
new->new_id = get_id(); new->new_id = get_id();
@@ -1653,9 +1664,9 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
new_status = STAT_ABANDONED; new_status = STAT_ABANDONED;
break; break;
} }
m = dnssec_generate_query(new_header, ((unsigned char *) new_header) + 65536, keyname, class, m = dnssec_generate_query(new_header, ((unsigned char *) new_header) + 65536, keyname, class,
new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, &server->addr, server->edns_pktsz); new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, server->edns_pktsz);
*length = htons(m); *length = htons(m);
@@ -1688,30 +1699,30 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
(type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) || (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) ||
(server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP))) (server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
continue; continue;
retry: retry:
/* may need to make new connection. */ /* may need to make new connection. */
if (server->tcpfd == -1) if (server->tcpfd == -1)
{ {
if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1) if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
continue; /* No good, next server */ continue; /* No good, next server */
#ifdef HAVE_CONNTRACK #ifdef HAVE_CONNTRACK
/* Copy connection mark of incoming query to outgoing connection. */ /* Copy connection mark of incoming query to outgoing connection. */
if (have_mark) if (have_mark)
setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int)); setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
#endif #endif
if (!local_bind(server->tcpfd, &server->source_addr, server->interface, 0, 1) || if (!local_bind(server->tcpfd, &server->source_addr, server->interface, 0, 1) ||
connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1) connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
{ {
close(server->tcpfd); close(server->tcpfd);
server->tcpfd = -1; server->tcpfd = -1;
continue; /* No good, next server */ continue; /* No good, next server */
} }
server->flags &= ~SERV_GOT_TCP; server->flags &= ~SERV_GOT_TCP;
} }
if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) || if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) ||
!read_write(server->tcpfd, &c1, 1, 1) || !read_write(server->tcpfd, &c1, 1, 1) ||
@@ -1728,6 +1739,16 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
else else
continue; continue;
} }
if (server->addr.sa.sa_family == AF_INET)
log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, keyname, (struct all_addr *)&(server->addr.in.sin_addr),
querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS));
#ifdef HAVE_IPV6
else
log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, keyname, (struct all_addr *)&(server->addr.in6.sin6_addr),
querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS));
#endif
server->flags |= SERV_GOT_TCP; server->flags |= SERV_GOT_TCP;