]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/rules: WIP adding tagset for auditing
authorVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 4 Sep 2025 06:52:57 +0000 (08:52 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 9 Oct 2025 09:04:32 +0000 (11:04 +0200)
daemon/lua/kres-gen-33.lua
lib/resolve.h
lib/rules/api.c
modules/policy/policy.lua

index 62d93e66993f7885969ae28131617502f084f15b..cf45a2d996a9220e13d4c0e4990fab037f0226cf 100644 (file)
@@ -235,6 +235,7 @@ struct kr_extended_error {
 };
 struct kr_request_rule {
        int8_t action;
+       kr_rule_tags_t tags;
 };
 struct kr_request {
        struct kr_context *ctx;
@@ -285,7 +286,8 @@ struct kr_request {
        unsigned int count_no_nsaddr;
        unsigned int count_fail_row;
        alloc_wire_f alloc_wire_cb;
-       kr_rule_tags_t rule_tags;
+       kr_rule_tags_t rule_tags_apply;
+       kr_rule_tags_t rule_tags_audit;
        struct kr_extended_error extended_error;
 };
 enum kr_rank {KR_RANK_INITIAL, KR_RANK_OMIT, KR_RANK_TRY, KR_RANK_INDET = 4, KR_RANK_BOGUS, KR_RANK_MISMATCH, KR_RANK_MISSING, KR_RANK_INSECURE, KR_RANK_AUTH = 16, KR_RANK_SECURE = 32};
index 749a548dc6f1b8b6fe77167b163fa5b6a971d9e5..2cddaa16564c55cae7647d3792828f00e5cff409 100644 (file)
@@ -211,9 +211,11 @@ typedef array_t(union kr_sockaddr) kr_sockaddr_array_t;
 /** Information about rules/policies applied to a kr_request.
  *
  * Let's keep this compatible with dnstap, including the number values.
- * Though the meaning can't "match exactly". */
+ * Though the meaning can't "match exactly".
+ * TODO: when multiple actions happen during one kr_request... */
 struct kr_request_rule {
        int8_t action;
+       kr_rule_tags_t tags; /// TagSet that caused the action
 };
 enum kr_request_rule_action {
        // zero == unset
@@ -318,7 +320,8 @@ struct kr_request {
        unsigned int count_no_nsaddr;
        unsigned int count_fail_row;
        alloc_wire_f alloc_wire_cb; /**< CB to allocate answer wire (can be NULL). */
-       kr_rule_tags_t rule_tags; /**< TagSet applying to this request. */
+       kr_rule_tags_t rule_tags_apply; /**< TagSet applying to this request. */
+       kr_rule_tags_t rule_tags_audit; /**< TagSet audited by this request. */
        struct kr_extended_error extended_error;  /**< EDE info; don't modify directly, use kr_request_set_extended_error() */
 };
 
index abdbf38e686d031c966e21764729d4dbf9854e2a..0054e621cd727b31207a3876e670e9ea6ed5fc01 100644 (file)
@@ -241,7 +241,12 @@ int kr_rules_reset(void)
        return ruledb_op(commit, false, true);
 }
 
-static bool kr_rule_consume_tags(knot_db_val_t *val, const struct kr_request *req)
+/** Eat and process tags from *val.
+ *
+ * Returning true means that the rule should apply,
+ * and it requires the caller to fill req->rule.action later.
+ */
+static bool kr_rule_consume_tags(knot_db_val_t *val, struct kr_request *req, bool allow_audit)
 {
        kr_rule_tags_t tags;
        if (deserialize_fails_assert(val, &tags)) {
@@ -250,7 +255,19 @@ static bool kr_rule_consume_tags(knot_db_val_t *val, const struct kr_request *re
                 * will fail anyway due to zero remaining length. */
                return false;
        }
-       return tags == KR_RULE_TAGS_ALL || (tags & req->rule_tags);
+       // _apply tags take precendence, and we store the last one
+       kr_rule_tags_t const tags_apply = tags & req->rule_tags_apply;
+       if (tags == KR_RULE_TAGS_ALL || tags_apply) {
+               req->rule.tags = tags_apply;
+               return true;
+       }
+       // _audit: we fill everything iff we're the very first action
+       kr_rule_tags_t const tags_audit = tags & req->rule_tags_audit;
+       if (allow_audit && tags_audit && !req->rule.action) {
+               req->rule.tags = tags_audit;
+               req->rule.action = KREQ_ACTION_AUDIT;
+       }
+       return false;
 }
 
 
@@ -407,8 +424,10 @@ static int subtree_search(const size_t lf_start_i, const knot_db_val_t key,
                if (kr_request_unblocked(req))
                        goto shorten;
 
+               // Let's never audit _UNBLOCK actions.
+               const bool allow_audit = ztype != VAL_ZLAT_UNBLOCK;
                // The other ztype possibilities are similar; check the tags now.
-               if (!kr_rule_consume_tags(&val, req)) {
+               if (!kr_rule_consume_tags(&val, req, allow_audit)) {
                        kr_assert(key_leq.len >= lf_start_i);
                shorten:
                        // Shorten key_leq by one label and retry.
@@ -538,7 +557,7 @@ int rule_local_data_answer(struct kr_query *qry, knot_pkt_t *pkt)
                        for (ret = ruledb_op(it_first, &key, &val);
                                        ret == 0;
                                        ret = ruledb_op(it_next, &val)) {
-                               if (!kr_rule_consume_tags(&val, qry->request))
+                               if (!kr_rule_consume_tags(&val, qry->request, true))
                                        continue;
 
                                // We found a rule that applies to the dname+rrtype+req.
@@ -938,7 +957,8 @@ static int answer_zla_redirect(struct kr_query *qry, knot_pkt_t *pkt, const char
        knot_db_val_t val;
        // Multiple variants are possible, with different tags.
        for (ret = ruledb_op(it_first, &key, &val); ret == 0; ret = ruledb_op(it_next, &val)) {
-               if (kr_rule_consume_tags(&val, qry->request)) {
+               const bool allow_audit = false; // we just audited at _REDIRECT root
+               if (kr_rule_consume_tags(&val, qry->request, allow_audit)) {
                        int ret2 = answer_exact_match(qry, pkt, qry->stype, &val);
                        if (ret2 != RET_CONTINUE)
                                return ret2;
index 41eff2daa689ac41427fe97c99450244f480ea53..19d589dfd93181b72ed0637882f46be7ff9e5065 100644 (file)
@@ -855,7 +855,7 @@ function policy.get_tagset(names)
 end
 function policy.tags_assign_bitmap(bitmap)
        return function (_, req)
-               req.rule_tags = bitmap
+               req.rule_tags_apply = bitmap
        end
 end
 function policy.TAGS_ASSIGN(names)