From 15273a57db03a4e03cc023edbf5b3318316ad474 Mon Sep 17 00:00:00 2001
From: Tomas Krizek <tomas.krizek@nic.cz>
Date: Tue, 23 Nov 2021 15:23:07 +0100
Subject: [PATCH] renumber: warn when using unsupported network mask

---
 daemon/lua/kres-gen-29.lua    | 2 +-
 daemon/lua/kres-gen-31.lua    | 2 +-
 lib/log.c                     | 1 +
 lib/log.h                     | 2 ++
 modules/policy/policy.lua     | 8 +++++++-
 modules/renumber/README.rst   | 8 +++++++-
 modules/renumber/renumber.lua | 7 ++++++-
 7 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/daemon/lua/kres-gen-29.lua b/daemon/lua/kres-gen-29.lua
index ded494651..b1a09f9aa 100644
--- a/daemon/lua/kres-gen-29.lua
+++ b/daemon/lua/kres-gen-29.lua
@@ -308,7 +308,7 @@ struct kr_server_selection {
 	struct local_state *local_state;
 };
 typedef int kr_log_level_t;
-enum kr_log_group {LOG_GRP_UNKNOWN = -1, LOG_GRP_SYSTEM = 1, LOG_GRP_CACHE, LOG_GRP_IO, LOG_GRP_NETWORK, LOG_GRP_TA, LOG_GRP_TLS, LOG_GRP_GNUTLS, LOG_GRP_TLSCLIENT, LOG_GRP_XDP, LOG_GRP_ZIMPORT, LOG_GRP_ZSCANNER, LOG_GRP_DOH, LOG_GRP_DNSSEC, LOG_GRP_HINT, LOG_GRP_PLAN, LOG_GRP_ITERATOR, LOG_GRP_VALIDATOR, LOG_GRP_RESOLVER, LOG_GRP_SELECTION, LOG_GRP_ZCUT, LOG_GRP_COOKIES, LOG_GRP_STATISTICS, LOG_GRP_REBIND, LOG_GRP_WORKER, LOG_GRP_POLICY, LOG_GRP_TASENTINEL, LOG_GRP_TASIGNALING, LOG_GRP_TAUPDATE, LOG_GRP_DAF, LOG_GRP_DETECTTIMEJUMP, LOG_GRP_DETECTTIMESKEW, LOG_GRP_GRAPHITE, LOG_GRP_PREFILL, LOG_GRP_PRIMING, LOG_GRP_SRVSTALE, LOG_GRP_WATCHDOG, LOG_GRP_NSID, LOG_GRP_DNSTAP, LOG_GRP_TESTS, LOG_GRP_DOTAUTH, LOG_GRP_HTTP, LOG_GRP_CONTROL, LOG_GRP_MODULE, LOG_GRP_DEVEL, LOG_GRP_REQDBG};
+enum kr_log_group {LOG_GRP_UNKNOWN = -1, LOG_GRP_SYSTEM = 1, LOG_GRP_CACHE, LOG_GRP_IO, LOG_GRP_NETWORK, LOG_GRP_TA, LOG_GRP_TLS, LOG_GRP_GNUTLS, LOG_GRP_TLSCLIENT, LOG_GRP_XDP, LOG_GRP_ZIMPORT, LOG_GRP_ZSCANNER, LOG_GRP_DOH, LOG_GRP_DNSSEC, LOG_GRP_HINT, LOG_GRP_PLAN, LOG_GRP_ITERATOR, LOG_GRP_VALIDATOR, LOG_GRP_RESOLVER, LOG_GRP_SELECTION, LOG_GRP_ZCUT, LOG_GRP_COOKIES, LOG_GRP_STATISTICS, LOG_GRP_REBIND, LOG_GRP_WORKER, LOG_GRP_POLICY, LOG_GRP_TASENTINEL, LOG_GRP_TASIGNALING, LOG_GRP_TAUPDATE, LOG_GRP_DAF, LOG_GRP_DETECTTIMEJUMP, LOG_GRP_DETECTTIMESKEW, LOG_GRP_GRAPHITE, LOG_GRP_PREFILL, LOG_GRP_PRIMING, LOG_GRP_SRVSTALE, LOG_GRP_WATCHDOG, LOG_GRP_NSID, LOG_GRP_DNSTAP, LOG_GRP_TESTS, LOG_GRP_DOTAUTH, LOG_GRP_HTTP, LOG_GRP_CONTROL, LOG_GRP_MODULE, LOG_GRP_DEVEL, LOG_GRP_RENUMBER, LOG_GRP_REQDBG};
 
 kr_layer_t kr_layer_t_static;
 _Bool kr_dbg_assertion_abort;
diff --git a/daemon/lua/kres-gen-31.lua b/daemon/lua/kres-gen-31.lua
index dc7334728..8fe3ac8c3 100644
--- a/daemon/lua/kres-gen-31.lua
+++ b/daemon/lua/kres-gen-31.lua
@@ -308,7 +308,7 @@ struct kr_server_selection {
 	struct local_state *local_state;
 };
 typedef int kr_log_level_t;
-enum kr_log_group {LOG_GRP_UNKNOWN = -1, LOG_GRP_SYSTEM = 1, LOG_GRP_CACHE, LOG_GRP_IO, LOG_GRP_NETWORK, LOG_GRP_TA, LOG_GRP_TLS, LOG_GRP_GNUTLS, LOG_GRP_TLSCLIENT, LOG_GRP_XDP, LOG_GRP_ZIMPORT, LOG_GRP_ZSCANNER, LOG_GRP_DOH, LOG_GRP_DNSSEC, LOG_GRP_HINT, LOG_GRP_PLAN, LOG_GRP_ITERATOR, LOG_GRP_VALIDATOR, LOG_GRP_RESOLVER, LOG_GRP_SELECTION, LOG_GRP_ZCUT, LOG_GRP_COOKIES, LOG_GRP_STATISTICS, LOG_GRP_REBIND, LOG_GRP_WORKER, LOG_GRP_POLICY, LOG_GRP_TASENTINEL, LOG_GRP_TASIGNALING, LOG_GRP_TAUPDATE, LOG_GRP_DAF, LOG_GRP_DETECTTIMEJUMP, LOG_GRP_DETECTTIMESKEW, LOG_GRP_GRAPHITE, LOG_GRP_PREFILL, LOG_GRP_PRIMING, LOG_GRP_SRVSTALE, LOG_GRP_WATCHDOG, LOG_GRP_NSID, LOG_GRP_DNSTAP, LOG_GRP_TESTS, LOG_GRP_DOTAUTH, LOG_GRP_HTTP, LOG_GRP_CONTROL, LOG_GRP_MODULE, LOG_GRP_DEVEL, LOG_GRP_REQDBG};
+enum kr_log_group {LOG_GRP_UNKNOWN = -1, LOG_GRP_SYSTEM = 1, LOG_GRP_CACHE, LOG_GRP_IO, LOG_GRP_NETWORK, LOG_GRP_TA, LOG_GRP_TLS, LOG_GRP_GNUTLS, LOG_GRP_TLSCLIENT, LOG_GRP_XDP, LOG_GRP_ZIMPORT, LOG_GRP_ZSCANNER, LOG_GRP_DOH, LOG_GRP_DNSSEC, LOG_GRP_HINT, LOG_GRP_PLAN, LOG_GRP_ITERATOR, LOG_GRP_VALIDATOR, LOG_GRP_RESOLVER, LOG_GRP_SELECTION, LOG_GRP_ZCUT, LOG_GRP_COOKIES, LOG_GRP_STATISTICS, LOG_GRP_REBIND, LOG_GRP_WORKER, LOG_GRP_POLICY, LOG_GRP_TASENTINEL, LOG_GRP_TASIGNALING, LOG_GRP_TAUPDATE, LOG_GRP_DAF, LOG_GRP_DETECTTIMEJUMP, LOG_GRP_DETECTTIMESKEW, LOG_GRP_GRAPHITE, LOG_GRP_PREFILL, LOG_GRP_PRIMING, LOG_GRP_SRVSTALE, LOG_GRP_WATCHDOG, LOG_GRP_NSID, LOG_GRP_DNSTAP, LOG_GRP_TESTS, LOG_GRP_DOTAUTH, LOG_GRP_HTTP, LOG_GRP_CONTROL, LOG_GRP_MODULE, LOG_GRP_DEVEL, LOG_GRP_RENUMBER, LOG_GRP_REQDBG};
 
 kr_layer_t kr_layer_t_static;
 _Bool kr_dbg_assertion_abort;
diff --git a/lib/log.c b/lib/log.c
index 175b54b8e..1f44637fe 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -78,6 +78,7 @@ const log_group_names_t log_group_names[] = {
 	GRP_NAME_ITEM(LOG_GRP_CONTROL),
 	GRP_NAME_ITEM(LOG_GRP_MODULE),
 	GRP_NAME_ITEM(LOG_GRP_DEVEL),
+	GRP_NAME_ITEM(LOG_GRP_RENUMBER),
 	GRP_NAME_ITEM(LOG_GRP_REQDBG),
 	{ NULL, LOG_GRP_UNKNOWN },
 };
diff --git a/lib/log.h b/lib/log.h
index 8b7d11cc2..a2879469b 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -78,6 +78,7 @@ enum kr_log_group {
 	LOG_GRP_CONTROL,
 	LOG_GRP_MODULE,
 	LOG_GRP_DEVEL,
+	LOG_GRP_RENUMBER,
 	/* ^^ Add new log groups above ^^. */
 	LOG_GRP_REQDBG, /* Must be first non-displayed entry in enum! */
 };
@@ -130,6 +131,7 @@ enum kr_log_group {
 #define LOG_GRP_CONTROL_TAG		"contrl"	/**< ``contrl``: TTY control sockets*/
 #define LOG_GRP_MODULE_TAG		"module"	/**< ``module``: suitable for user-defined modules */
 #define LOG_GRP_DEVEL_TAG		"devel"		/**< ``devel``: for development purposes */
+#define LOG_GRP_RENUMBER_TAG		"renum"		/**< ``renum``: operation related to renumber */
 #define LOG_GRP_REQDBG_TAG		"reqdbg"	/**< ``reqdbg``: debug logs enabled by policy actions */
 ///@}
 
diff --git a/modules/policy/policy.lua b/modules/policy/policy.lua
index 7cd8ff926..e8d7e9b96 100644
--- a/modules/policy/policy.lua
+++ b/modules/policy/policy.lua
@@ -187,7 +187,13 @@ function policy.REROUTE(tbl, names)
 	local ren = require('kres_modules.renumber')
 	local prefixes = {}
 	for from, to in pairs(tbl) do
-		table.insert(prefixes, names and ren.name(from, to) or ren.prefix(from, to))
+		local prefix = names and ren.name(from, to) or ren.prefix(from, to)
+		local bitlen = prefix[2]
+		if bitlen ~= nil and bitlen % 8 ~= 0 then
+			log_warn(ffi.C.LOG_GRP_POLICY,
+				'REROUTE: network mask - only /8, /16, /24 etc. are supported (entire octets are rewritten)')
+		end
+		table.insert(prefixes, prefix)
 	end
 	-- Return rule closure
 	return ren.rule(prefixes)
diff --git a/modules/renumber/README.rst b/modules/renumber/README.rst
index ea26eafcb..b3cfc23e7 100644
--- a/modules/renumber/README.rst
+++ b/modules/renumber/README.rst
@@ -10,7 +10,13 @@ e.g. you can redirect malicious addresses to a blackhole, or use private address
 in local zones, that will be remapped to real addresses by the resolver.
 
 
-.. warning:: While requests are still validated using DNSSEC, the signatures are stripped from final answer. The reason is that the address synthesis breaks signatures. You can see whether an answer was valid or not based on the AD flag.
+.. warning:: While requests are still validated using DNSSEC, the signatures
+   are stripped from final answer. The reason is that the address synthesis
+   breaks signatures. You can see whether an answer was valid or not based on
+   the AD flag.
+
+.. warning:: The module is currently limited to rewriting complete octets of
+   the IP addresses, i.e. only /8, /16, /24 etc. network masks are supported.
 
 Example configuration
 ---------------------
diff --git a/modules/renumber/renumber.lua b/modules/renumber/renumber.lua
index 425bc0546..ccd320f63 100644
--- a/modules/renumber/renumber.lua
+++ b/modules/renumber/renumber.lua
@@ -25,7 +25,12 @@ end
 
 -- Add subnet prefix rewrite rule
 local function add_prefix(subnet, addr)
-	table.insert(prefixes_global, matchprefix(subnet, addr))
+	local prefix = matchprefix(subnet, addr)
+	local bitlen = prefix[2]
+	if bitlen ~= nil and bitlen % 8 ~= 0 then
+		log_warn(ffi.C.LOG_GRP_RENUMBER, 'network mask: only /8, /16, /24 etc. are supported (entire octets are rewritten)')
+	end
+	table.insert(prefixes_global, prefix)
 end
 
 -- Match IP against given subnet or record owner
-- 
GitLab