Prevents DNS Amplification Attack and allow to customize named

While [1] did open recursion, it also opened widely a security flaw.

This patch intends to close it back, while allowing operators to easily
add their open configuration within Bind9.

In order to allow operators to still open Bind recursion, a new file is
introduced, "ipa-ext.conf" (path might change according to the OS). This
file is not managed by the installer, meaning changes to it won't be
overridden.
Since it's included at the very end of the main configuration file, it
also allows to override some defaults - of course, operators have to be
careful with that.

Related-Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1754530
Fixes: https://pagure.io/freeipa/issue/8079

[1] 5f4c75eb28

Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Stanislav Levin <slev@altlinux.org>
This commit is contained in:
Cédric Jeanneret
2019-09-24 14:00:55 +02:00
committed by Alexander Bokovoy
parent f58fb573d1
commit 6c27104467
9 changed files with 86 additions and 2 deletions

View File

@@ -1121,6 +1121,7 @@ fi
%{_usr}/share/ipa/*.ldif
%{_usr}/share/ipa/*.uldif
%{_usr}/share/ipa/*.template
%{_usr}/share/ipa/bind.ipa-ext.conf
%dir %{_usr}/share/ipa/advise
%dir %{_usr}/share/ipa/advise/legacy
%{_usr}/share/ipa/advise/legacy/*.template
@@ -1165,6 +1166,7 @@ fi
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa-pki-proxy.conf
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ipa/kdcproxy/ipa-kdc-proxy.conf
%ghost %attr(0644,root,root) %config(noreplace) %{_usr}/share/ipa/html/ca.crt
%ghost %attr(0640,root,named) %config(noreplace) %{_sysconfdir}/named/ipa-ext.conf
%ghost %attr(0644,root,root) %{_usr}/share/ipa/html/krb.con
%ghost %attr(0644,root,root) %{_usr}/share/ipa/html/krb5.ini
%ghost %attr(0644,root,root) %{_usr}/share/ipa/html/krbrealm.con

View File

@@ -45,6 +45,7 @@ dist_app_DATA = \
domainlevel.ldif \
kerberos.ldif \
indices.ldif \
bind.ipa-ext.conf \
bind.named.conf.template \
certmap.conf.template \
kdc.conf.template \

View File

@@ -0,0 +1,15 @@
// Custom managed file.
// Here you can set your own options, for instance ACL for recursion access:
//
// acl "trusted_network" {
// localnets;
// localhost;
// 234.234.234.0/24;
// 2001::co:ffee:babe:1/48;
// };
// options {
// allow-recursion {trusted_network;};
// allow-query-cache {trusted_network;};
// };
//
// This file will NOT be overridden during updates!

View File

@@ -8,8 +8,12 @@ options {
statistics-file "${NAMED_DATA_DIR}named_stats.txt";
memstatistics-file "${NAMED_DATA_DIR}named_mem_stats.txt";
// Any host is permitted to issue recursive queries
allow-recursion { any; };
// If not explicitly set, the ACLs for "allow-query-cache" and
// "allow-recursion" are set to "localnets; localhost;".
// If either "allow-query-cache" or "allow-recursion" is set,
// the other would be set the same value.
// Please refer to $CUSTOM_CONFIG
// for more informations
tkey-gssapi-keytab "$NAMED_KEYTAB";
pid-file "$NAMED_PID";
@@ -46,6 +50,9 @@ ${NAMED_ZONE_COMMENT}};
include "$RFC1912_ZONES";
include "$ROOT_KEY";
/* custom configuration snippet */
include "$CUSTOM_CONFIG";
/* WARNING: This part of the config file is IPA-managed.
* Modifications may break IPA setup or upgrades.
*/

View File

@@ -79,6 +79,8 @@ class BasePathNamespace:
LDAP_CONF = "/etc/ldap.conf"
LIBNSS_LDAP_CONF = "/etc/libnss-ldap.conf"
NAMED_CONF = "/etc/named.conf"
NAMED_CUSTOM_CONFIG = "/etc/named/ipa-ext.conf"
NAMED_CUSTOM_CFG_SRC = '/usr/share/ipa/bind.ipa-ext.conf'
NAMED_VAR_DIR = "/var/named"
NAMED_KEYTAB = "/etc/named.keytab"
NAMED_RFC1912_ZONES = "/etc/named.rfc1912.zones"

View File

@@ -33,6 +33,7 @@ class DebianPathNamespace(BasePathNamespace):
OLD_IPA_KEYTAB = "/etc/apache2/ipa.keytab"
HTTPD_PASSWORD_CONF = "/etc/apache2/password.conf"
NAMED_CONF = "/etc/bind/named.conf"
NAMED_CUSTOM_CONFIG = "/etc/bind/ipa-ext.conf"
NAMED_VAR_DIR = "/var/cache/bind"
NAMED_KEYTAB = "/etc/bind/named.keytab"
NAMED_RFC1912_ZONES = "/etc/bind/named.conf.default-zones"

View File

@@ -295,6 +295,26 @@ def find_reverse_zone(ip_address, api=api):
return None
def named_add_ext_conf_file(src, dest, t_params={}):
"""
Ensure included file is present, but don't override it.
:param src: String. Absolute path to source template
:param dest: String. Absolute path to destination
:param t_params: Dict. Parameters for source template
"""
if not os.path.exists(dest):
ipa_ext_txt = ipautil.template_file(src, t_params)
gid = pwd.getpwnam(constants.NAMED_USER).pw_gid
with open(dest, 'w') as ipa_ext:
os.fchmod(ipa_ext.fileno(), 0o640)
os.fchown(ipa_ext.fileno(), 0, gid)
ipa_ext.write(ipa_ext_txt)
return True
return False
def read_reverse_zone(default, ip_address, allow_zone_overlap=False):
while True:
zone = ipautil.user_input("Please specify the reverse zone name", default=default)
@@ -818,6 +838,7 @@ class BindInstance(service.Service):
NAMED_VAR_DIR=paths.NAMED_VAR_DIR,
BIND_LDAP_SO=paths.BIND_LDAP_SO,
INCLUDE_CRYPTO_POLICY=crypto_policy,
CUSTOM_CONFIG=paths.NAMED_CUSTOM_CONFIG,
NAMED_DATA_DIR=constants.NAMED_DATA_DIR,
NAMED_ZONE_COMMENT=constants.NAMED_ZONE_COMMENT,
)
@@ -975,6 +996,9 @@ class BindInstance(service.Service):
named_fd.write(named_txt)
named_fd.close()
named_add_ext_conf_file(paths.NAMED_CUSTOM_CFG_SRC,
paths.NAMED_CUSTOM_CONFIG)
if self.no_dnssec_validation:
# disable validation
named_conf_set_directive("dnssec-validation", "no",
@@ -1237,5 +1261,6 @@ class BindInstance(service.Service):
if named_regular_running:
self.named_regular.start()
ipautil.remove_file(paths.NAMED_CUSTOM_CONFIG)
ipautil.remove_keytab(self.keytab)
ipautil.remove_ccache(run_as=self.service_user)

View File

@@ -124,6 +124,7 @@ class Backup(admintool.AdminTool):
files = (
paths.NAMED_CONF,
paths.NAMED_CUSTOM_CONFIG,
paths.NAMED_KEYTAB,
paths.RESOLV_CONF,
paths.SYSCONFIG_PKI_TOMCAT,

View File

@@ -551,6 +551,34 @@ def named_remove_deprecated_options():
return True
def named_add_ipa_ext_conf_include():
"""
Ensures named.conf does include the ipa-ext.conf file
"""
if not bindinstance.named_conf_exists():
logger.info('DNS is not configured.')
return False
if not bindinstance.named_conf_include_exists(paths.NAMED_CUSTOM_CONFIG):
bindinstance.named_conf_add_include(paths.NAMED_CUSTOM_CONFIG)
return True
return False
def named_add_ipa_ext_conf_file():
"""
Wrapper around bindinstance.named_add_ext_conf_file().
Ensures named is configured before pushing the file.
"""
if not bindinstance.named_conf_exists():
logger.info('DNS is not configured.')
return False
return bindinstance.named_add_ext_conf_file(
paths.NAMED_CUSTOM_CFG_SRC,
paths.NAMED_CUSTOM_CONFIG)
def named_set_minimum_connections():
"""
Sets the minimal number of connections.
@@ -2053,6 +2081,8 @@ def upgrade_configuration():
# has been altered
named_conf_changes = (
named_remove_deprecated_options(),
named_add_ipa_ext_conf_file(),
named_add_ipa_ext_conf_include(),
named_set_minimum_connections(),
named_update_gssapi_configuration(),
named_update_pid_file(),