mirror of
https://github.com/openbsd/src.git
synced 2024-12-21 23:18:00 -08:00
unwind: support wildcard in blacklist
Any domain in the blacklist that starts with '.', which is not a legal name due to an empty label, is treated as any subdomain on that zone. This means that .example.com blocks all requests to any subdomain of example.com, but allows example.com. No objections: florian@ OK: kn@
This commit is contained in:
parent
4e55220c92
commit
a95f0396ca
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: frontend.c,v 1.89 2024/11/21 13:35:20 claudio Exp $ */
|
||||
/* $OpenBSD: frontend.c,v 1.90 2024/11/24 11:33:34 kirill Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
|
||||
@ -118,6 +118,8 @@ TAILQ_HEAD(, pending_query) pending_queries;
|
||||
struct bl_node {
|
||||
RB_ENTRY(bl_node) entry;
|
||||
char *domain;
|
||||
int len;
|
||||
int wildcard;
|
||||
};
|
||||
|
||||
__dead void frontend_shutdown(void);
|
||||
@ -153,6 +155,7 @@ int bl_cmp(struct bl_node *, struct bl_node *);
|
||||
void free_bl(void);
|
||||
int pending_query_cnt(void);
|
||||
void check_available_af(void);
|
||||
void reverse(char *, char *);
|
||||
|
||||
struct uw_conf *frontend_conf;
|
||||
static struct imsgev *iev_main;
|
||||
@ -741,7 +744,7 @@ handle_query(struct pending_query *pq)
|
||||
{
|
||||
struct query_imsg query_imsg;
|
||||
struct bl_node find;
|
||||
int rcode;
|
||||
int rcode, matched;
|
||||
char *str;
|
||||
char dname[LDNS_MAX_DOMAINLEN + 1];
|
||||
char qclass_buf[16];
|
||||
@ -798,12 +801,19 @@ handle_query(struct pending_query *pq)
|
||||
log_debug("%s: %s %s %s ?", ip_port((struct sockaddr *)&pq->from),
|
||||
dname, qclass_buf, qtype_buf);
|
||||
|
||||
find.domain = dname;
|
||||
if (RB_FIND(bl_tree, &bl_head, &find) != NULL) {
|
||||
if (frontend_conf->blocklist_log)
|
||||
log_info("blocking %s", dname);
|
||||
error_answer(pq, LDNS_RCODE_REFUSED);
|
||||
goto send_answer;
|
||||
if (!RB_EMPTY(&bl_head)) {
|
||||
find.len = strlen(dname);
|
||||
find.wildcard = 0;
|
||||
reverse(dname, dname + find.len);
|
||||
find.domain = dname;
|
||||
matched = (RB_FIND(bl_tree, &bl_head, &find) != NULL);
|
||||
reverse(dname, dname + find.len);
|
||||
if (matched) {
|
||||
if (frontend_conf->blocklist_log)
|
||||
log_info("blocking %s", dname);
|
||||
error_answer(pq, LDNS_RCODE_REFUSED);
|
||||
goto send_answer;
|
||||
}
|
||||
}
|
||||
|
||||
if (pq->qinfo.qtype == LDNS_RR_TYPE_AXFR || pq->qinfo.qtype ==
|
||||
@ -1549,14 +1559,20 @@ parse_blocklist(int fd)
|
||||
if (linelen >= 2 && line[linelen - 2] != '.')
|
||||
line[linelen - 1] = '.';
|
||||
else
|
||||
line[linelen - 1] = '\0';
|
||||
line[linelen-- - 1] = '\0';
|
||||
}
|
||||
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
bl_node = malloc(sizeof *bl_node);
|
||||
if (bl_node == NULL)
|
||||
fatal("%s: malloc", __func__);
|
||||
if ((bl_node->domain = strdup(line)) == NULL)
|
||||
fatal("%s: strdup", __func__);
|
||||
reverse(bl_node->domain, bl_node->domain + linelen);
|
||||
bl_node->len = linelen;
|
||||
bl_node->wildcard = line[0] == '.';
|
||||
if (RB_INSERT(bl_tree, &bl_head, bl_node) != NULL) {
|
||||
log_warnx("duplicate blocked domain \"%s\"", line);
|
||||
free(bl_node->domain);
|
||||
@ -1571,7 +1587,12 @@ parse_blocklist(int fd)
|
||||
|
||||
int
|
||||
bl_cmp(struct bl_node *e1, struct bl_node *e2) {
|
||||
return (strcasecmp(e1->domain, e2->domain));
|
||||
if (e1->wildcard == e2->wildcard)
|
||||
return (strcasecmp(e1->domain, e2->domain));
|
||||
else if (e1->wildcard)
|
||||
return (strncasecmp(e1->domain, e2->domain, e1->len));
|
||||
else /* e2->wildcard */
|
||||
return (strncasecmp(e1->domain, e2->domain, e2->len));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1830,3 +1851,16 @@ check_available_af(void)
|
||||
&available_af, sizeof(available_af));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
reverse(char *begin, char *end)
|
||||
{
|
||||
char t;
|
||||
|
||||
while (begin < --end) {
|
||||
t = *begin;
|
||||
*begin = *end;
|
||||
*end = t;
|
||||
++begin;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: unwind.conf.5,v 1.34 2024/06/30 16:10:26 florian Exp $
|
||||
.\" $OpenBSD: unwind.conf.5,v 1.35 2024/11/24 11:33:34 kirill Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2018 Florian Obser <florian@openbsd.org>
|
||||
.\" Copyright (c) 2005 Esben Norby <norby@openbsd.org>
|
||||
@ -18,7 +18,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: June 30 2024 $
|
||||
.Dd $Mdocdate: November 24 2024 $
|
||||
.Dt UNWIND.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -72,6 +72,8 @@ answers with a return code of
|
||||
With
|
||||
.Cm log
|
||||
blocked queries are logged.
|
||||
The list supports limited wildcard syntax: domains starting with . (dot)
|
||||
are treated as any subdomains on that zone.
|
||||
.It Ic forwarder Brq Ar address Oo Ic port Ar number Oc Oo Oo Ic authentication name Ar name Oc Ic DoT Oc ...
|
||||
A list of addresses of DNS name servers to forward queries to.
|
||||
.Ic port
|
||||
|
Loading…
Reference in New Issue
Block a user