If the configure fails, it may be due to missing or old
dependencies.
</para>
-
+
<note>
<para>For notes on configuring and building DHCPv6 with MySQL see <xref linkend="dhcp6-install">.</xref></para>
</note>
<para>
The key ring lives in the configuration in "tsig_keys/keys". Most of
the system uses the keys from there — ACLs, authoritative server to
- sign responses to signed queries, and <command>b10-xfrout</command>
- to sign transfers. The <command>b10-xfrin</command> uses its own
- configuration for keys, but that will be fixed in Trac ticket
- <ulink url="http://bind10.isc.org/ticket/1351">#1351</ulink>.
+ sign responses to signed queries, and <command>b10-xfrin</command>
+ and <command>b10-xfrout</command> to sign transfers.
</para>
<para>
</para>
</section>
+ <section>
+ <title>TSIG</title>
+ If you want to use TSIG for incoming transfers, a system wide TSIG
+ key ring must be configured (see <xref linkend="tsig-key-ring"/>).
+ To specify a key to use, set tsig_key value to the name of the key
+ to use from the key ring.
+> <userinput>config set Xfrin/zones[0]/tsig_key "<option>example.key</option>"</userinput>
+ </section>
+
<section>
<title>Enabling IXFR</title>
<para>
<varname>master_addr</varname> (the zone master to transfer from),
<varname>master_port</varname> (defaults to 53),
<varname>use_ixfr</varname> (defaults to false), and
- <varname>tsig_key</varname> (optional TSIG key to use).
- The <varname>tsig_key</varname> is specified using a full string
- colon-delimited name:key:algorithm representation (e.g.
- <quote>foo.example.org:EvABsfU2h7uofnmqaRCrhHunGsd=:hmac-sha1</quote>).
+ <varname>tsig_key</varname> (optional TSIG key name to use).
+ The <varname>tsig_key</varname> is specified using a name that
+ corresponds to one of the TSIG keys configured in the global
+ TSIG key ring (/tsig_keys/keys).</quote>).
</para>
<!-- TODO: document this better -->
-<!-- TODO: the tsig_key format may change -->
<para>
(The site-wide <varname>master_addr</varname> and
<varname>master_port</varname> configurations are deprecated;
use the <varname>zones</varname> list configuration instead.)
</para>
-<!-- NOTE: also tsig_key but not mentioning since so short lived. -->
<!-- TODO: formating -->
<para>
if identifier == "zones/use_ixfr":
return False
+ def get_remote_config_value(self, module, identifier):
+ if module == 'tsig_keys' and identifier == 'keys':
+ return (['example.com.key.:EvAAsfU2h7uofnmqaTCrhHunGsc=',
+ 'bad.key.:EvAAsfU2h7uofnmqaTCrhHu' ], True)
+ else:
+ raise Exception('MockCC requested for unknown config value ' +
+ + module + "/" + identifier)
+
def remove_remote_config(self, module_name):
pass
self.assertEqual(str(zone_info.master_addr), zone_config['master_addr'])
self.assertEqual(zone_info.master_port, zone_config['master_port'])
if 'tsig_key' in zone_config:
- self.assertEqual(zone_info.tsig_key.to_text(), TSIGKey(zone_config['tsig_key']).to_text())
+ self.assertEqual(zone_info.tsig_key_name.to_text(),
+ Name(zone_config['tsig_key']).to_text())
else:
- self.assertIsNone(zone_info.tsig_key)
+ self.assertIsNone(zone_info.tsig_key_name)
if 'use_ixfr' in zone_config and\
zone_config.get('use_ixfr'):
self.assertTrue(zone_info.use_ixfr)
{ 'name': 'test2.example.',
'master_addr': '192.0.2.9',
'master_port': 53,
- 'tsig_key': 'badkey'
+ 'tsig_key': 'badkey..'
}
]}
self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
self.assertEqual(self.xfr.config_handler(config)['result'][0], 0)
self._check_zones_config(config)
- def common_ixfr_setup(self, xfr_mode, use_ixfr):
+ def common_ixfr_setup(self, xfr_mode, use_ixfr, tsig_key_str = None):
# This helper method explicitly sets up a zone configuration with
# use_ixfr, and invokes either retransfer or refresh.
# Shared by some of the following test cases.
config = {'zones': [
{'name': 'example.com.',
'master_addr': '192.0.2.1',
+ 'tsig_key': tsig_key_str,
'use_ixfr': use_ixfr}]}
self.assertEqual(self.xfr.config_handler(config)['result'][0], 0)
self.assertEqual(self.xfr.command_handler(xfr_mode,
self.common_ixfr_setup('refresh', True)
self.assertEqual(RRType.IXFR(), self.xfr.xfrin_started_request_type)
+ def test_command_handler_retransfer_with_tsig(self):
+ self.common_ixfr_setup('retransfer', False, 'example.com.key')
+ self.assertEqual(RRType.AXFR(), self.xfr.xfrin_started_request_type)
+
+ def test_command_handler_retransfer_with_tsig_bad_key(self):
+ # bad keys should not reach xfrin, but should they somehow,
+ # they are ignored (and result in 'key not found' + error log).
+ self.assertRaises(XfrinZoneInfoException, self.common_ixfr_setup,
+ 'retransfer', False, 'bad.key')
+
+ def test_command_handler_retransfer_with_tsig_unknown_key(self):
+ self.assertRaises(XfrinZoneInfoException, self.common_ixfr_setup,
+ 'retransfer', False, 'no.such.key')
+
+ def test_command_handler_refresh_with_tsig(self):
+ self.common_ixfr_setup('refresh', False, 'example.com.key')
+ self.assertEqual(RRType.AXFR(), self.xfr.xfrin_started_request_type)
+
+ def test_command_handler_refresh_with_tsig_bad_key(self):
+ # bad keys should not reach xfrin, but should they somehow,
+ # they are ignored (and result in 'key not found' + error log).
+ self.assertRaises(XfrinZoneInfoException, self.common_ixfr_setup,
+ 'refresh', False, 'bad.key')
+
+ def test_command_handler_refresh_with_tsig_unknown_key(self):
+ self.assertRaises(XfrinZoneInfoException, self.common_ixfr_setup,
+ 'refresh', False, 'no.such.key')
+
def test_command_handler_retransfer_ixfr_disabled(self):
# Similar to the previous case, but explicitly disabled. AXFR should
# be used.
AUTH_MODULE_NAME = 'Auth'
XFROUT_MODULE_NAME = 'Xfrout'
+
+# Remote module and identifiers (according to their spec files)
ZONE_MANAGER_MODULE_NAME = 'Zonemgr'
+TSIG_KEYS_MODULE_NAME = 'tsig_keys'
+TSIG_KEYS_IDENTIFIER = 'keys'
+
REFRESH_FROM_ZONEMGR = 'refresh_from_zonemgr'
# Constants for debug levels.
self.set_master_port(config_data.get('master_port'))
self.set_zone_class(config_data.get('class'))
- self.set_tsig_key(config_data.get('tsig_key'))
+ self.set_tsig_key_name(config_data.get('tsig_key'))
self.set_use_ixfr(config_data.get('use_ixfr'))
def set_name(self, name_str):
errmsg = "invalid zone class: " + zone_class_str
raise XfrinZoneInfoException(errmsg)
- def set_tsig_key(self, tsig_key_str):
+ def set_tsig_key_name(self, tsig_key_str):
"""Set the tsig_key for this zone, given a TSIG key string
representation. If tsig_key_str is None, no TSIG key will
be set. Raises XfrinZoneInfoException if tsig_key_str cannot
- be parsed."""
+ be parsed. TODO UPDATE"""
if tsig_key_str is None:
- self.tsig_key = None
+ self.tsig_key_name = None
else:
+ # can throw a number of exceptions but it is just one
+ # call, so Exception should be OK here
+ try:
+ self.tsig_key_name = Name(tsig_key_str)
+ except Exception as exc:
+ raise XfrinZoneInfoException("Bad TSIG key name: " + str(exc))
+
+ def get_tsig_key(self):
+ if self.tsig_key_name is None:
+ return None
+ key_strings, _ = self._module_cc.get_remote_config_value(
+ TSIG_KEYS_MODULE_NAME,
+ TSIG_KEYS_IDENTIFIER)
+ # Find the TSIG key in the keyring
+ for possible_key_string in key_strings:
try:
- self.tsig_key = TSIGKey(tsig_key_str)
+ key = TSIGKey(possible_key_string)
except InvalidParameter as ipe:
- logger.error(XFRIN_BAD_TSIG_KEY_STRING, tsig_key_str)
- errmsg = "bad TSIG key string: " + tsig_key_str
- raise XfrinZoneInfoException(errmsg)
+ # In theory, bad keys should never end up here (but be refused
+ # by the validator for TSIG keys config. However,
+ # should they do, we simply log and ignore them
+ logger.error(XFRIN_BAD_TSIG_KEY_STRING, possible_key_string)
+ if key.get_key_name() == self.tsig_key_name:
+ return key
+ logger.error(XFRIN_TSIG_KEY_NOT_FOUND, self.tsig_key_name.to_text())
+ errmsg = "TSIG key not found in keyring: " +\
+ self.tsig_key_name.to_text()
+ raise XfrinZoneInfoException(errmsg)
def set_use_ixfr(self, use_ixfr):
"""Set use_ixfr. If set to True, it will use
self.config_handler(config_data)
self._module_cc.add_remote_config(AUTH_SPECFILE_LOCATION,
self._auth_config_handler)
+ self._module_cc.add_remote_config_by_name(TSIG_KEYS_MODULE_NAME)
def _cc_check_command(self):
'''This is a straightforward wrapper for cc.check_command,
rrclass,
self._get_db_file(),
master_addr,
- zone_info.tsig_key, request_type,
+ zone_info.get_tsig_key(), request_type,
True)
answer = create_answer(ret[0], ret[1])
else:
tsig_key = None
request_type = RRType.AXFR()
if zone_info:
- tsig_key = zone_info.tsig_key
+ tsig_key = zone_info.get_tsig_key()
if zone_info.use_ixfr:
request_type = RRType.IXFR()
db_file = args.get('db_file') or self._get_db_file()
% XFRIN_BAD_TSIG_KEY_STRING bad TSIG key string: %1
The TSIG key string as read from the configuration does not represent
-a valid TSIG key.
+a valid TSIG key. The key is ignored.
% XFRIN_BAD_ZONE_CLASS Invalid zone class: %1
The zone class as read from the configuration is not a valid DNS class.
bytes/second: Transfer speed
+% XFRIN_TSIG_KEY_NOT_FOUND TSIG key not found in key ring: %1
+An attempt to start a transfer with TSIG was made, but the configured TSIG
+key name was not found in the TSIG key ring (configuration option
+tsig_keys/keys). The transfer is aborted. The key name that could not be
+found is shown in the log message. Check the configuration and the
+TSIG key ring.
+
% XFRIN_UNKNOWN_ERROR unknown error: %1
An uncaught exception was raised while running the xfrin daemon. The
exception message is printed in the log message.
When I send bind10 the following commands:
"""
config add tsig_keys/keys "example.key.:c2VjcmV0"
- config set Xfrin/zones[0]/tsig_key "example.key.:c2VjcmV0"
+ config set Xfrin/zones[0]/tsig_key "example.key."
config commit
"""