diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:24:08 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:24:08 +0000 |
commit | f449f278dd3c70e479a035f50a9bb817a9b433ba (patch) | |
tree | 8ca2bfb785dda9bb4d573acdf9b42aea9cd51383 /src/knot/modules/queryacl | |
parent | Initial commit. (diff) | |
download | knot-upstream.tar.xz knot-upstream.zip |
Adding upstream version 3.2.6.upstream/3.2.6upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/knot/modules/queryacl')
-rw-r--r-- | src/knot/modules/queryacl/Makefile.inc | 12 | ||||
-rw-r--r-- | src/knot/modules/queryacl/queryacl.c | 93 | ||||
-rw-r--r-- | src/knot/modules/queryacl/queryacl.rst | 70 |
3 files changed, 175 insertions, 0 deletions
diff --git a/src/knot/modules/queryacl/Makefile.inc b/src/knot/modules/queryacl/Makefile.inc new file mode 100644 index 0000000..25dcc38 --- /dev/null +++ b/src/knot/modules/queryacl/Makefile.inc @@ -0,0 +1,12 @@ +knot_modules_queryacl_la_SOURCES = knot/modules/queryacl/queryacl.c +EXTRA_DIST += knot/modules/queryacl/queryacl.rst + +if STATIC_MODULE_queryacl +libknotd_la_SOURCES += $(knot_modules_queryacl_la_SOURCES) +endif + +if SHARED_MODULE_queryacl +knot_modules_queryacl_la_LDFLAGS = $(KNOTD_MOD_LDFLAGS) +knot_modules_queryacl_la_CPPFLAGS = $(KNOTD_MOD_CPPFLAGS) +pkglib_LTLIBRARIES += knot/modules/queryacl.la +endif diff --git a/src/knot/modules/queryacl/queryacl.c b/src/knot/modules/queryacl/queryacl.c new file mode 100644 index 0000000..e787083 --- /dev/null +++ b/src/knot/modules/queryacl/queryacl.c @@ -0,0 +1,93 @@ +/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "knot/include/module.h" +#include "contrib/sockaddr.h" + +#define MOD_ADDRESS "\x07""address" +#define MOD_INTERFACE "\x09""interface" + +const yp_item_t queryacl_conf[] = { + { MOD_ADDRESS, YP_TNET, YP_VNONE, YP_FMULTI }, + { MOD_INTERFACE, YP_TNET, YP_VNONE, YP_FMULTI }, + { NULL } +}; + +typedef struct { + knotd_conf_t allow_addr; + knotd_conf_t allow_iface; +} queryacl_ctx_t; + +static knotd_state_t queryacl_process(knotd_state_t state, knot_pkt_t *pkt, + knotd_qdata_t *qdata, knotd_mod_t *mod) +{ + assert(pkt && qdata && mod); + + queryacl_ctx_t *ctx = knotd_mod_ctx(mod); + + // Continue only for regular queries. + if (qdata->type != KNOTD_QUERY_TYPE_NORMAL) { + return state; + } + + if (ctx->allow_addr.count > 0) { + const struct sockaddr_storage *addr = knotd_qdata_remote_addr(qdata); + if (!knotd_conf_addr_range_match(&ctx->allow_addr, addr)) { + qdata->rcode = KNOT_RCODE_NOTAUTH; + return KNOTD_STATE_FAIL; + } + } + + if (ctx->allow_iface.count > 0) { + struct sockaddr_storage buff; + const struct sockaddr_storage *addr = knotd_qdata_local_addr(qdata, &buff); + if (!knotd_conf_addr_range_match(&ctx->allow_iface, addr)) { + qdata->rcode = KNOT_RCODE_NOTAUTH; + return KNOTD_STATE_FAIL; + } + } + + return state; +} + +int queryacl_load(knotd_mod_t *mod) +{ + // Create module context. + queryacl_ctx_t *ctx = calloc(1, sizeof(queryacl_ctx_t)); + if (ctx == NULL) { + return KNOT_ENOMEM; + } + + ctx->allow_addr = knotd_conf_mod(mod, MOD_ADDRESS); + ctx->allow_iface = knotd_conf_mod(mod, MOD_INTERFACE); + + knotd_mod_ctx_set(mod, ctx); + + return knotd_mod_hook(mod, KNOTD_STAGE_BEGIN, queryacl_process); +} + +void queryacl_unload(knotd_mod_t *mod) +{ + queryacl_ctx_t *ctx = knotd_mod_ctx(mod); + if (ctx != NULL) { + knotd_conf_free(&ctx->allow_addr); + knotd_conf_free(&ctx->allow_iface); + } + free(ctx); +} + +KNOTD_MOD_API(queryacl, KNOTD_MOD_FLAG_SCOPE_ANY, + queryacl_load, queryacl_unload, queryacl_conf, NULL); diff --git a/src/knot/modules/queryacl/queryacl.rst b/src/knot/modules/queryacl/queryacl.rst new file mode 100644 index 0000000..1a402f6 --- /dev/null +++ b/src/knot/modules/queryacl/queryacl.rst @@ -0,0 +1,70 @@ +.. _mod-queryacl: + +``queryacl`` — Limit queries by remote address or target interface +================================================================== + +This module provides a simple way to whitelist incoming queries +according to the query's source address or target interface. +It can be used e.g. to create a restricted-access subzone with delegations from the corresponding public zone. +The module may be enabled both globally and per-zone. + +.. NOTE:: + The module limits only regular queries. Notify, transfer and update are handled by :ref:`ACL<ACL>`. + +Example +------- + +:: + + mod-queryacl: + - id: default + address: [192.0.2.73-192.0.2.90, 203.0.113.0/24] + interface: 198.51.100 + + zone: + - domain: example.com + module: mod-queryacl/default + +Module reference +---------------- + +:: + + mod-queryacl: + - id: STR + address: ADDR[/INT] | ADDR-ADDR ... + interface: ADDR[/INT] | ADDR-ADDR ... + +.. _mod-queryacl_id: + +id +.. + +A module identifier. + +.. _mod-queryacl_address: + +address +....... + +An optional list of allowed ranges and/or subnets for query's source address. +If the query's address does not fall into any +of the configured ranges, NOTAUTH rcode is returned. + +*Default:* not set + +.. _mod-queryacl_interface: + +interface +......... + +An optional list of allowed ranges and/or subnets for query's target interface. +If the interface does not fall into any +of the configured ranges, NOTAUTH rcode is returned. Note that every interface +used has to be configured in :ref:`listen<server_listen>`. + +.. NOTE:: + Don't use values *0.0.0.0* and *::0*. These values are redundant and don't + work as expected. + +*Default:* not set |