Hello everyone.
CZ.NIC Labs just released two security patch version of Knot DNS.
Knot DNS 2.0.2
- We have recently extended our fuzzy-testing tool set by a new LibFuzzer
tool, which lead to a discovery of a bug in the packet parser. A specially
crafted packet with malformed NAPTR record can trigger an out-of-bound read,
possibly leading to the knotd daemon crash. The new version fixes this bug.
Knot DNS 1.6.6
- The 1.6 packet processing code contained the same issue in NAPTR parsing
which was present in the 2.0. However, existing code paths to its occurrence
were different. We are not aware of any possibility to remotely crash the
server daemon at the moment.
- The updated version also fixes systemd server startup notifications.
- We have included the rosedb module, which has already been distributed as
a separate tarball for a few releases. Users of rosedb should switch to the
main releases.
If you are a Knot DNS 2.0 user, we highly recommend to updated to version
2.0.2 because it is possible to cause a denial of service remotely.
If you are a Knot DNS 1.6 user, we suggest to update to the latest release
even though the fixed problems are not as critical as in the 2.0 branch.
The sources are available as usual.
Full changelogs:
https://gitlab.labs.nic.cz/labs/knot/raw/v1.6.6/NEWShttps://gitlab.labs.nic.cz/labs/knot/raw/v2.0.2/NEWS
Tarballs:
https://secure.nic.cz/files/knot-dns/knot-1.6.6.tar.xzhttps://secure.nic.cz/files/knot-dns/knot-2.0.2.tar.xz
GPG signatures:
https://secure.nic.cz/files/knot-dns/knot-1.6.6.tar.xz.aschttps://secure.nic.cz/files/knot-dns/knot-2.0.2.tar.xz.asc
Best regards! And thank you for using Knot DNS.
Jan
--
Jan Včelák, Knot DNS
CZ.NIC Labs https://www.knot-dns.cz
--------------------------------------------
Milešovská 5, 130 00 Praha 3, Czech Republic
WWW: https://labs.nic.czhttps://www.nic.cz
Hi everyone,
While working on my Knot-Resolver (kr) module, I came to think that the
current YIELD mechanism for layers will not work properly, if multiple
YIELD-enabled modules are loaded simultaneously.
My understanding of how the current YIELD system works is as follows.
A layer receives the current state through ((knot_layer_t*) ctx)->state.
The current state can be modified by previous layers returned value.
When a layer returns a YIELD state, the chain of responsability,
maintained by the lib/resolve.c:ITERATE_LAYERS macro is broken (break;)
and the resolution plan is evaluated once more to handle the tail
element of the rplan.
Once the rplan popped up all rplan_pushed queries, then the query that
yielded is once more the last element of the rplan stack. This element
is then evaluated, calling once more all layers, starting with the
first layer. This time, the state that is provided to the layers is
YIELD, except if a layer returns another value instead of returning the
state as is.
A layer could behave differently, based on whether it receives a YIELD
state or not as "input state". This is, in fact, what is provided as
example in the documentation:
>>>
consume = function (state, req, answer)
answer = kres.pkt_t(answer)
if state == kres.YIELD then
print('continuing yielded layer')
return kres.DONE
else
if answer:qtype() == kres.type.NS then
req = kres.request_t(req)
local qry = req:push(answer:qname(),
kres.type.SOA, kres.class.IN)
qry.flags = kres.query.AWAIT_CUT
print('planned SOA query, yielding')
return kres.YIELD
end
return state
end
end
<<<
The issue, I think, is that a module has no way of knowing whether it is
the one that yielded or not.
Let's say I have three module, A, B, and C. B and C can yield, and A
only returns YIELD, when it receives YIELD as input state.
On the first evaluation, A and B returns DONE. C yields. Then on the
second evaluation, A returns YIELD, because it does not handle this
state and only passes it along. B receives the YIELD from A. B, as said
above, may yield in some cases. B will therefore handle the YIELD, and
do his "YIELD" actions, ignoring the fact that the module that actually
yielded was C.
I suppose B and C could define flags to be capable of remembering
whether they yielded on this query or not. Unfortunately, there is
currently no framework to ensure uniqueness of these flags.
Sadly, this email does not come up with a proposed solution. I'm only
sharing a thought about what I think could be an issue.
What is your take on this? Have I missed something or misunderstood how
the yield state works?
Thank you.
Cheers,
Florian
Hi,
You can try setting https://www.knot-dns.cz/docs/1.6/singlehtml/index.html#ixfr-fslimit or
simply deleting the journal file corresponding to the ajetaci.cz zone.
Dan
>
> Good morning,
> where is problem with zone ?
> Error :
> journal size is too small to fit the changes.
>
> Knot is owner of this directory.
>
> After loading zone I found that record on some line in the zone file is
> invalid, I deleted it, increased serial and after reloading zone I could
> not set it UP
>
>
> Log records about the zone:
> Nov 9 08:22:14 celer knot[20407]: Semantic checks completed for
> zone=ajetaci.cz.
> Nov 9 08:22:14 celer knot[20407]: Zone 'ajetaci.cz.' loaded (serial
> 2015110901)
> Nov 9 08:22:14 celer knot[20407]: DNSSEC: Zone ajetaci.cz. - Signing
> started...
> Nov 9 08:22:14 celer knot[20407]: DNSSEC: Zone ajetaci.cz. - - Key is
> valid, tag 36256, file Kajetaci.cz.+005+36256.private, KSK, active, public
> Nov 9 08:22:14 celer knot[20407]: DNSSEC: Zone ajetaci.cz. - - Key is
> valid, tag 11937, file Kajetaci.cz.+005+11937.private, ZSK, active, public
> Nov 9 08:22:14 celer knot[20407]: DNSSEC: Zone ajetaci.cz. - - Key is
> valid, tag 5300, file Kajetaci.cz.+007+05300.private, ZSK, active, public
> Nov 9 08:22:14 celer knot[20407]: DNSSEC: Zone ajetaci.cz. - - Key is
> valid, tag 58830, file Kajetaci.cz.+007+58830.private, KSK, active, public
> Nov 9 08:22:14 celer knot[20407]: [error] Zone 'ajetaci.cz.' journal size
> is too small to fit the changes.
> Nov 9 08:22:14 celer knot[20407]: Loaded 2 out of 3 zones.
> Nov 9 08:22:14 celer knot[20407]: [warning] Not all the zones were loaded.
>
>
> Any ideas ?
> Thanks and best regards
> J.
Spam detection software, running on the system "mail.nic.cz",
has identified this incoming email as possible spam. The original
message has been attached to this so you can view it or label
similar future email. If you have any questions, see
the administrator of that system for details.
Content preview: Good morning, where is problem with zone ? Error : journal
size is too small to fit the changes. Knot is owner of this directory. After
loading zone I found that record on some line in the zone file is invalid,
I deleted it, increased serial and after reloading zone I could not set it
UP [...]
Content analysis details: (5.4 points, 5.0 required)
pts rule name description
---- ---------------------- --------------------------------------------------
0.8 DKIM_ADSP_ALL No valid author signature, domain signs all mail
-0.0 SPF_PASS SPF: sender matches SPF record
1.5 BAYES_50 BODY: Bayes spam probability is 40 to 60%
[score: 0.4973]
0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid
3.0 RDNS_NONE Delivered to internal network by a host with no rDNS
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Hi everyone,
While I was working on my Knot-Resolver (kr) module, I wondered how I
could be able to ratelimit the trafic toward specific nameservers or
influence the NS selection algorithm, in general.
Unfortunately, the current NS election algorithm that is present in the
lib/resolve.c driver and in lib/nsrep.c does not allow a module to
register a layer to influence the NS selection.
Is there any plan to add event listeners to influence NS selection, for
instance by giving layers the opportunity to "congregate" and return a
modifier, a lot like the "favour" IPv6 modifier/variable that is done in
lib/nsrep.c:eval_addr_set?
Thanks.
Cheers,
Florian
Hi everyone,
While working on a Knot-Resolver (kr) C module, I stumbled on a
limitation of the current way layers are loaded and unloaded.
My understanding is that, currently, C modules are loaded via a dlopen
call, and then a callback "moduleName_init" symbol is searched and
called.
On unloading, a symbol "moduleName_deinit" is searched and called, and
upon completion of the deinit function, a dlclose call is made to unload
the module from memory. This occurs in lib/modules.c.
As it happens, my C module provides callbacks (cb) for several layer
hooks. Some of these cb perform potentially long-lived I/O operations.
Since functions are not supposed to take a lot of CPU time, in order to
maintain kr responsiveness and with respect to the event-oriented
design, I chose to embrace libuv and use the uv_* functions to perform
these I/O operations. This means I inserted in the uv_default_loop
several cb for network or filesystem events. These cb need to be
called for some operations to be successfully completed. Think about SQL
commit statements and whatnot.
Currently when a user wants to stop the daemon, the "graceful" procedure
is to call quit() on the CLI. This procedure calls uv_stop on the
uv_default_loop, thus stopping abruptly all registered cb from
being ever called again. Then, modules are unloaded one by one. These
unloading calls to moduleName_deinit can be blocking because no service
requires responsiveness anymore.
On the other hand, if a module is shutdown during normal operations, for
instance, via a call to "modules.unload" from the CLI, the unloading
procedure cannot perform blocking actions without generating a negative
impact on the overall responsiveness. The problem is that it cannot
perform non-blocking actions either because as soon as the deinit
function returns, the code for the non-blocking actions "to wrap up"
currently registered callbacks in the uv_default_loop is removed from
memory.
To solve this problem, I would suggest creating a cleanup event, sent to
modules that should be unloaded. A module receiving a call to its
handler for this event would be expected to wrap it up ASAP. It would,
however not be expected to have completed everything at handler return
time.
The sender of the cleanup event could then register a uv_idle handler
that would call the deinit function. The deinit function would then be
in charge of ensuring the module no longer have any event handler
registered in the uv loop. If no cb are present in the loop, it would
return a status code allowing the caller to dlclose the module.
With this approach, calling the "graceful" quit procedure would then
send a cleanup event to all modules, including iterate, cache, etc.
uv_stop would not need to be called anymore because the idle handler
would be able to know that no handler are in the uv_loop except itself:
it would then unregister itself and the uv_run call would terminate
spontaneously.
What is your take on this issue? Do you think the proposed solution
would be acceptable? Would it work with all kind of modules (I'm
thinking about the lua and go modules)? I, sadly, currently have no code
to do this. I just thought it might be useful to document this on the
mailing list and share ideas about it.
Thank you.
Cheers,
Florian
Hi everyone,
I have been recently working on a Knot-Resolver (kr) module for some
research work. This led me to push new queries into the resolution plan,
wait for the answer and then resume the "standard" kr-spooled queries.
Once all queries are resolved, when my finish module callback (cb) is
invoked, I write down some statistics that were collected throughout the
various queries. Among the thing that I write down, I inspect some data
in the cache, including zonecuts.
I discovered that some information returned by
lib/zonecut.c:kr_zonecut_find_cached were different from what I
expected. I am not sure if this is because my call to
kr_zonecut_find_cached is incorrect, if I messed up some kr internal
logic or if I stumbled on a bug. Here follows a made-up domain
name tree similar to what made me stumbled on this issue, what I thought
should be returned by kr_zonecut_find_cached, and what is actually
returned.
The original query qname is example.com.. Example.com. is delegated to
a company owning example.net, a DNS reseller providing DNS hosting for
its clients.
example.com. is gluelessly delegated to ns1.example.net. and
ns2.example.net..
example.net. is gluelessly delegated from net. to
srv1.some-famous-registrar.net. and srv2.some-famous-registrar.net..
some-famous-registrar.net. is also delegated from net. to
srv1.some-famous-registrar.net. and srv2.some-famous-registrar.net. thus
using a glued delegation.
When I call kr_zonecut_find_cached in my module finish cb, with a "name"
param whose value is srv1.some-famous-registrar.net., I expected the
cut out-param to be filled with a kr_zonecut structure with a "name"
equal to some-famous-registrar.net. and a nsset equal to
srv1.some-famous-registrar.net.|srv2.some-famous-registrar.net.
Unfortunately, cut->name values net., which is of course incorrect,
since some-famous-registrar is a delegated name.
My call to kr_zonecut_find_cached is using a kr_cache_txn structure
created by the finish cb, using the cache in
((knot_layer_t*) ctx)->((kr_request*) data)->ctx->cache. It may also be
worth noting that I use "false" for the secured param of the
kr_zonecut_find_cached call.
If this is indeed a bug, my guess would be that example.com. delegation
leads kr to ask to net. nameservers for the delegation information for
example.net..
net. nameservers answer that the delegation to example.net. is through
srv1.some-famous-registrar.net.|srv2.some-famous-registrar.net.. At the
same time, net. nameservers also provide the *glues* for
srv1.some-famous-registrar.net. and srv2.some-famous-registrar.net.,
since the net. zone contains non-authoritative IP address records for
these names for the glued delegation of some-famous-registrar.net. This
could make kr to believe that net. is "authoritative" in some way for
srv1.some-famous-registrar.net. and therefore to think that the
some-famous-registrar.net is not a delegated zone. It is however
possible that I completely crashed kr zonecut logic with the additional
queries that I pushed from time to time, though.
Does that ring a bell to anyone? What would be, according to you, the
next step I should take to better understand what is going on?
Thanks for your help!
Cheers,
Florian