#include "validate.hh"
#include "validate-recursor.hh"
#include "root-dnssec.hh"
+#include "dnssecinfra.hh"
+#include "dnsseckeeper.hh"
+#include "zoneparser-tng.hh"
GlobalStateHolder<LuaConfigItems> g_luaconfs;
lci.negAnchors.clear();
});
+ Lua.writeFunction("readTrustAnchorsFromFile", [&lci](const std::string& fname) {
+ warnIfDNSSECDisabled("Warning: reading Trust Anchors from file (readTrustAnchorsFromFile), but dnssec is set to 'off'!");
+ auto zp = ZoneParserTNG(fname);
+ DNSResourceRecord rr;
+ DNSRecord dr;
+ try {
+ while(zp.get(rr)) {
+ dr = DNSRecord(rr);
+ if (rr.qtype == QType::DS) {
+ auto dsr = getRR<DSRecordContent>(dr);
+ if (dsr == nullptr) {
+ throw PDNSException("Unable to parse DS record '" + rr.qname.toString() + " " + rr.getZoneRepresentation() + "'");
+ }
+ lci.dsAnchors[rr.qname].insert(*dsr);
+ }
+ if (rr.qtype == QType::DNSKEY) {
+ auto dnskeyr = getRR<DNSKEYRecordContent>(dr);
+ if (dnskeyr == nullptr) {
+ throw PDNSException("Unable to parse DNSKEY record '" + rr.qname.toString() + " " + rr.getZoneRepresentation() +"'");
+ }
+ auto dsr = makeDSFromDNSKey(rr.qname, *dnskeyr, DNSSECKeeper::SHA256);
+ lci.dsAnchors[rr.qname].insert(dsr);
+ }
+ }
+ }
+ catch (const std::exception &e) {
+ throw PDNSException("Error while reading Trust Anchors from file (readTrustAnchorsFromFile) '" + fname + "': " + e.what());
+ }
+ catch (...) {
+ throw PDNSException("Error while reading Trust Anchors from file (readTrustAnchorsFromFile) '" + fname + "'");
+ }
+ });
+
#if HAVE_PROTOBUF
Lua.writeFunction("setProtobufMasks", [&lci](const uint8_t maskV4, uint8_t maskV6) {
lci.protobufMaskV4 = maskV4;
Now (re)start the recursor to load these trust anchors.
+Reading trust anchors from files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since version 4.2.0 of the PowerDNS Recursor, it is also possible to read the Trust Anchors from a BIND-style zonefile.
+Only the DS and DNSKEY records from this file are read.
+Debian and its derivatives ship the ``dns-root-data`` package that contains the DNSSEC root trust anchors in ``/usr/share/dns/root.key``.
+
+To only use the distribution-provided Trust Anchors, add the following to the :ref:`setting-lua-config-file`:
+
+.. sourcecode:: lua
+
+ clearTA() -- Remove built-in trust-anchors
+ readTrustAnchorsFromFile("/usr/share/dns/root.key") -- Use these keys
+
Runtime Configuration of Trust Anchors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To change or add trust anchors at runtime, use the :doc:`manpages/rec_control.1` tool.
not given, remove *all* negative trust anchors instead.
:param str name: The name in the DNS tree from where this NTA should be removed
+
+.. function:: readTrustAnchorsFromFile(fname)
+
+ .. versionadded:: 4.2.0
+
+ Reads all DS and DNSKEY records from ``fname`` (a BIND zone file) and adds these to the Trust Anchors.
+ This function can be used to read distribution provided trust anchors, as for instance ``/usr/share/dns/root.key`` from Debian's ``dns-root-data`` package.
+
+ :param str fname: Path to a zone file with Trust Anchors
luaconfpath = os.path.join(confdir, 'conffile.lua')
with open(luaconfpath, 'w') as luaconf:
if cls._root_DS:
- luaconf.write("addDS('.', '%s')\n" % cls._root_DS)
+ luaconf.write("addTA('.', '%s')\n" % cls._root_DS)
if cls._lua_config_file:
luaconf.write(cls._lua_config_file)
conf.write("lua-config-file=%s\n" % luaconfpath)
--- /dev/null
+. 300 IN DNSKEY 257 3 13 aPHAAOTdxA8XxiUo8YTOXPG7uRXPA4XFhcnJ/I13+f/0I/B0TobNDG0t aRjsp/rezR1o0DXh0fb4vvC+STbPog== ; Should be converted to DS
+. 3600 IN DS 36914 13 2 C94ED457FF79AFE03804C26CE4FA832687DB92BC231AFF98617791FC 71A65870 ; Will be used as-is
+. 1200 IN A 192.0.2.1 ; Should be ignored
_config_template = """dnssec=validate"""
_lua_config_file = """addNTA("bogus.example")
addNTA('secure.optout.example', 'Should be Insecure, even with DS configured')
-addDS('secure.optout.example', '64215 13 1 b88284d7a8d8605c398e8942262f97b9a5a31787')"""
+addTA('secure.optout.example', '64215 13 1 b88284d7a8d8605c398e8942262f97b9a5a31787')"""
def testDirectNTA(self):
"""Ensure a direct query to a bogus name with an NTA is Insecure"""
--- /dev/null
+import os
+import subprocess
+from recursortests import RecursorTest
+
+
+class testReadTrustAnchorsFronFile(RecursorTest):
+ _confdir = 'ReadTAsFromFile'
+
+ _config_template = """dnssec=validate"""
+ _lua_config_file = """clearTA()
+readTrustAnchorsFromFile('root.keys')"""
+
+ def testCorrectFile(self):
+ """Ensure the file is read correctly"""
+ rec_controlCmd = [os.environ['RECCONTROL'],
+ '--config-dir=%s' % 'configs/' + self._confdir,
+ 'get-tas']
+ expected = """Configured Trust Anchors:
+.
+\t\t36914 13 2 c94ed457ff79afe03804c26ce4fa832687db92bc231aff98617791fc71a65870
+\t\t42924 13 2 b49e0aafd6e147742afb9eab0e76af0546357dc6c61bf67d7c745cf6f43f460e
+"""
+ try:
+ ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
+ self.assertEqual(ret, expected)
+
+ except subprocess.CalledProcessError as e:
+ print e.output
+ raise
+