]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
time_skew: Detect time skew during kresd start.
authorVítězslav Kříž <vitezslav.kriz@nic.cz>
Wed, 6 Dec 2017 13:00:16 +0000 (14:00 +0100)
committerPetr Špaček <petr.spacek@nic.cz>
Thu, 7 Dec 2017 21:31:49 +0000 (22:31 +0100)
This module is enabled by default, but disabled in Deckard tests.

daemon/bindings.c
daemon/lua/kres-gen.lua
daemon/lua/kres-gen.sh
daemon/lua/sandbox.lua
doc/modules.rst
lib/rplan.h
modules/detect_time_skew/README.rst [new file with mode: 0644]
modules/detect_time_skew/detect_time_skew.lua [new file with mode: 0644]
modules/detect_time_skew/detect_time_skew.mk [new file with mode: 0644]
modules/modules.mk
tests/deckard

index bde8d7a319afeb6035a26644f277fb28c92add3e..742510b16c75ad2ecbfe6e33c9af5b9c2aa4aecd 100644 (file)
@@ -1226,6 +1226,10 @@ static int wrk_resolve(lua_State *L)
        if (options->DNSSEC_WANT) {
                knot_edns_set_do(pkt->opt_rr);
        }
+       if (options->DNSSEC_CD) {
+               knot_wire_set_cd(pkt->wire);
+       }
+
        if (lua_isfunction(L, 5)) {
                /* Store callback in registry */
                lua_pushvalue(L, 5);
index 8410f21bff306f12efd6133f4a08fff7413621a4..4dc309d5b436f6656a2e052a7bf9250f8751825e 100644 (file)
@@ -77,6 +77,7 @@ struct kr_qflags {
        _Bool DNSSEC_WANT : 1;
        _Bool DNSSEC_BOGUS : 1;
        _Bool DNSSEC_INSECURE : 1;
+       _Bool DNSSEC_CD : 1;
        _Bool STUB : 1;
        _Bool ALWAYS_CUT : 1;
        _Bool DNSSEC_WEXPAND : 1;
@@ -217,6 +218,8 @@ void knot_rrset_init_empty(knot_rrset_t *);
 uint32_t knot_rrset_ttl(const knot_rrset_t *);
 int knot_rrset_txt_dump(const knot_rrset_t *, char **, size_t *, const knot_dump_style_t *);
 int knot_rrset_txt_dump_data(const knot_rrset_t *, const size_t, char *, const size_t, const knot_dump_style_t *);
+uint32_t knot_rrsig_sig_expiration(const knot_rdataset_t *, size_t);
+uint32_t knot_rrsig_sig_inception(const knot_rdataset_t *, size_t);
 const knot_dname_t *knot_pkt_qname(const knot_pkt_t *);
 uint16_t knot_pkt_qtype(const knot_pkt_t *);
 uint16_t knot_pkt_qclass(const knot_pkt_t *);
index 865cd1ce6c706c6804db2b9e570659387e07f2d9..f6625c52b9a9a1114b9b25bc28428c58a640b04c 100755 (executable)
@@ -96,6 +96,8 @@ printf "\tchar _stub[];\n};\n"
        knot_rrset_ttl
        knot_rrset_txt_dump
        knot_rrset_txt_dump_data
+       knot_rrsig_sig_expiration
+       knot_rrsig_sig_inception
 # Packet
        knot_pkt_qname
        knot_pkt_qtype
index 08be5101750cd66cac66ceb67e61e42e97446035..f90473ffb1c2d6ac6602929aeb9831eefb30348b 100644 (file)
@@ -205,6 +205,7 @@ end
 -- Load embedded modules
 modules.load('ta_signal_query')
 modules.load('priming')
+modules.load('detect_time_skew')
 
 -- Interactive command evaluation
 function eval_cmd(line, raw)
index 709fee8ed0b3edec4d3999c46c7953e95ca0cb93..f8e69edc1963c9bc0c0dc7043f3a78deb0551832 100644 (file)
@@ -27,3 +27,4 @@ Knot DNS Resolver modules
 .. include:: ../modules/dnstap/README.rst
 .. include:: ../modules/ta_signal_query/README.rst
 .. include:: ../modules/priming/README.rst
+.. include:: ../modules/detect_time_skew/README.rst
index 9a0998474aa6b55e5207cbcf9bc7a147fc91adbf..f87d7f2535368e25595c7302f45f3ed074d80870 100644 (file)
@@ -44,6 +44,7 @@ struct kr_qflags {
                                  * i.e. knot_wire_set_cd(request->answer->wire). */
        bool DNSSEC_BOGUS : 1;   /**< Query response is DNSSEC bogus. */
        bool DNSSEC_INSECURE : 1;/**< Query response is DNSSEC insecure. */
+       bool DNSSEC_CD : 1;      /**< CD bit in query */
        bool STUB : 1;           /**< Stub resolution, accept received answer as solved. */
        bool ALWAYS_CUT : 1;     /**< Always recover zone cut (even if cached). */
        bool DNSSEC_WEXPAND : 1; /**< Query response has wildcard expansion. */
diff --git a/modules/detect_time_skew/README.rst b/modules/detect_time_skew/README.rst
new file mode 100644 (file)
index 0000000..87e45fe
--- /dev/null
@@ -0,0 +1,21 @@
+.. _mod-detect_time_skew:
+
+System time skew detector
+-------------------------
+
+This module compares local system time with inception and expiration time
+bounds in DNSSEC signatures for `. NS` records. If the local system time is
+outside of these bounds, it is likely a misconfiguration which will cause
+all DNSSEC validation (and resolution) to fail.
+
+In case of mismatch, a warning message will be logged to help with
+further diagnostics.
+
+.. warning:: Information printed by this module can be forged by a network attacker!
+  System administrator MUST verify values printed by this module and
+  fix local system time using a trusted source.
+
+This module is useful for debugging purposes. It runs only once during resolver
+start does not anything after that. It is enabled by default.
+You may disable the module by appending
+`modules.unload('detect_time_skew')` to your configuration.
diff --git a/modules/detect_time_skew/detect_time_skew.lua b/modules/detect_time_skew/detect_time_skew.lua
new file mode 100644 (file)
index 0000000..ec84e59
--- /dev/null
@@ -0,0 +1,77 @@
+-- Module interface
+local ffi = require('ffi')
+local knot = ffi.load(libknot_SONAME)
+
+local mod = {}
+local event_id = nil
+
+-- Resolve callback
+-- Check time validity of RRSIGs in priming query
+-- luacheck: no unused args
+local function check_time_callback(pkt, req)
+       pkt = kres.pkt_t(pkt)
+       if pkt:rcode() ~= kres.rcode.NOERROR then
+               warn("[detect_time_skew] cannot resolve '.' NS")
+               return nil
+       end
+       local valid_rrsigs = 0
+       local section = pkt:rrsets(kres.section.ANSWER)
+       local now = os.time()
+       local time_diff = 0
+       local inception = 0
+       local expiration = 0
+       for i = 1, #section do
+               local rr = section[i]
+               if rr.type == kres.type.RRSIG then
+                       for k = 0, rr.rrs.rr_count - 1 do
+                               inception = knot.knot_rrsig_sig_inception(rr.rrs, k)
+                               expiration = knot.knot_rrsig_sig_expiration(rr.rrs, k)
+                               if now > expiration then
+                                       -- possitive value = in the future
+                                       time_diff = now - expiration
+                               elseif now < inception then
+                                       -- negative value = in the past
+                                       time_diff = now - inception
+                               else
+                                       valid_rrsigs = valid_rrsigs + 1
+                               end
+                       end
+               end
+       end
+       if valid_rrsigs == 0 then
+               warn("[detect_time_skew] Local system time %q seems to be at "..
+                    "least %u seconds in the %s. DNSSEC signatures for '.' NS "..
+                    "are not valid %s. Please check your system clock!",
+                    os.date("%c", now),
+                    math.abs(time_diff),
+                    time_diff > 0 and "future" or "past",
+                    time_diff > 0 and "yet" or "anymore")
+       elseif verbose() then
+               log("[detect_time_skew] Local system time %q is within "..
+                   "RRSIG validity interval <%q,%q>.", os.date("%c", now),
+                   os.date("%c", inception), os.date("%c", expiration))
+       end
+end
+
+-- Make priming query and check time validty of RRSIGs.
+local function check_time()
+       resolve(".", kres.type.NS, kres.class.IN, {"DNSSEC_WANT", "DNSSEC_CD"},
+                check_time_callback)
+end
+
+function mod.init()
+       if event_id then
+               error("Module is already loaded.")
+       else
+               event_id = event.after(0 , check_time)
+       end
+end
+
+function mod.deinit()
+       if event_id then
+               event.cancel(event_id)
+               event_id = nil
+       end
+end
+
+return mod
diff --git a/modules/detect_time_skew/detect_time_skew.mk b/modules/detect_time_skew/detect_time_skew.mk
new file mode 100644 (file)
index 0000000..bc29deb
--- /dev/null
@@ -0,0 +1,2 @@
+detect_time_skew_SOURCES := detect_time_skew.lua
+$(call make_lua_module,detect_time_skew)
index 23d597d116d4cdb3757a85f330a17684116fdd93..3df953c0a623bf8eb50d9b83f05b18c677ee0325 100644 (file)
@@ -34,7 +34,8 @@ modules_TARGETS += etcd \
                    workarounds \
                    version \
                    ta_signal_query \
-                   priming
+                   priming \
+                   detect_time_skew
 endif
 
 # Make C module
index fcfade5d1805b7c1151523991e4d5ea68db03f03..a5cd67c98836690e00ab76b7bd220023f7993ee9 160000 (submodule)
@@ -1 +1 @@
-Subproject commit fcfade5d1805b7c1151523991e4d5ea68db03f03
+Subproject commit a5cd67c98836690e00ab76b7bd220023f7993ee9