Implemented chroot feature for RHEL/CentOS7

This commit is contained in:
Cédric Defortis 2017-05-02 17:41:53 +02:00 committed by Cedric DEFORTIS
parent f2c32aaf37
commit bcaafc05e1
10 changed files with 186 additions and 27 deletions

View File

@ -64,6 +64,30 @@ server's upstream resolvers are controlled using `forwarders`, enabling of DNSSe
using `dnssec`, and the reported version is controlled using `version`. It is unlikely that you will need to define an using `dnssec`, and the reported version is controlled using `version`. It is unlikely that you will need to define an
alternate value for `confdir` or `cachedir`. alternate value for `confdir` or `cachedir`.
#### Run bind daemon with chroot
You can setup bind with chroot using the `$chroot` parameter:
Example for CentOS7:
```
class { 'bind':
chroot => true,
# Note: this file MUST be into the /etc/named directory so the
# RHEL7 specific setup-named-chroot.sh script will make it available into
# the chroot.
default_zones_include => '/etc/named/default-zones.conf',
forwarders => [
'8.8.8.8',
'8.8.4.4',
],
dnssec => true,
version => 'Controlled by Puppet',
}
```
Note: chroot is not supported for all operating systems. For now only
RHEL7/CentOS7 is supported.
### `bind::updater` ### `bind::updater`
The `bind::updater` class is an alternate entrypoint into the module. This class installs the BIND client tools but not The `bind::updater` class is an alternate entrypoint into the module. This class installs the BIND client tools but not

View File

@ -1,5 +1,6 @@
--- ---
bind::defaults::supported: false bind::defaults::supported: false
bind::defaults::chroot_supported: false
bind::defaults::random_device: '/dev/random' bind::defaults::random_device: '/dev/random'
bind::forwarders: '' bind::forwarders: ''

View File

@ -0,0 +1 @@
bind::defaults::chroot_supported: true

View File

@ -13,3 +13,4 @@ bind::defaults::default_zones_include: '/etc/bind/named.conf.default-zones'
bind::defaults::isc_bind_keys: '/etc/bind/bind.keys' bind::defaults::isc_bind_keys: '/etc/bind/bind.keys'
bind::updater::keydir: '/etc/bind/keys' bind::updater::keydir: '/etc/bind/keys'
bind::defaults::bind_chroot_dir: '/var/lib/named/chroot'

View File

@ -14,4 +14,8 @@ bind::defaults::default_zones_include: '/etc/named.default-zones.conf'
bind::defaults::default_zones_source: 'puppet:///modules/bind/RedHat/named.default-zones.conf' bind::defaults::default_zones_source: 'puppet:///modules/bind/RedHat/named.default-zones.conf'
bind::defaults::isc_bind_keys: '/etc/named.iscdlv.key' bind::defaults::isc_bind_keys: '/etc/named.iscdlv.key'
bind::defaults::bind_chroot_package: 'bind-chroot'
bind::defaults::bind_chroot_service: 'named-chroot'
bind::defaults::bind_chroot_dir: '/var/named/chroot'
bind::updater::keydir: '/etc/named/keys' bind::updater::keydir: '/etc/named/keys'

View File

@ -5,5 +5,6 @@ hierarchy:
- name: "Platform" - name: "Platform"
backend: yaml backend: yaml
paths: paths:
- "osfamily/%{facts.os.name}-%{facts.os.release.major}"
- "osfamily/%{facts.os.family}" - "osfamily/%{facts.os.family}"
- "common" - "common"

View File

@ -2,6 +2,7 @@
class bind::defaults ( class bind::defaults (
$supported = undef, $supported = undef,
$chroot_supported = undef,
$confdir = undef, $confdir = undef,
$namedconf = undef, $namedconf = undef,
$cachedir = undef, $cachedir = undef,
@ -10,7 +11,10 @@ class bind::defaults (
$bind_user = undef, $bind_user = undef,
$bind_group = undef, $bind_group = undef,
$bind_package = undef, $bind_package = undef,
$bind_chroot_package = undef,
$bind_service = undef, $bind_service = undef,
$bind_chroot_service = undef,
$bind_chroot_dir = undef,
$nsupdate_package = undef, $nsupdate_package = undef,
$managed_keys_directory = undef, $managed_keys_directory = undef,
$default_zones_include = undef, $default_zones_include = undef,

View File

@ -12,7 +12,28 @@ class bind (
$include_local = false, $include_local = false,
$tkey_gssapi_credential = undef, $tkey_gssapi_credential = undef,
$tkey_domain = undef, $tkey_domain = undef,
$chroot = false,
$chroot_supported = $::bind::defaults::chroot_supported,
$chroot_dir = $::bind::defaults::bind_chroot_dir,
# NOTE: we need to be able to override this parameter when declaring class,
# especially when not using hiera (i.e. when using Foreman as ENC):
$default_zones_include = $::bind::defaults::default_zones_include,
) inherits bind::defaults { ) inherits bind::defaults {
if $chroot and !$chroot_supported {
fail('Chroot for bind is not supported on your OS')
}
if $chroot {
if $::bind::defaults::bind_chroot_service {
$real_bind_service = $::bind::defaults::bind_chroot_service
}
if $::bind::defaults::bind_chroot_package {
$real_bind_package = $::bind::defaults::bind_chroot_package
}
} else {
$real_bind_service = $::bind::defaults::bind_service
$real_bind_package = $::bind::defaults::bind_package
}
File { File {
ensure => present, ensure => present,
@ -27,7 +48,7 @@ class bind (
package { 'bind': package { 'bind':
ensure => latest, ensure => latest,
name => $::bind::defaults::bind_package, name => $real_bind_package,
} }
if $dnssec { if $dnssec {
@ -67,7 +88,7 @@ class bind (
} }
if $include_default_zones and $::bind::defaults::default_zones_source { if $include_default_zones and $::bind::defaults::default_zones_source {
file { $::bind::defaults::default_zones_include: file { $default_zones_include:
source => $::bind::defaults::default_zones_source, source => $::bind::defaults::default_zones_source,
} }
} }
@ -105,11 +126,29 @@ class bind (
content => "};\n"; content => "};\n";
} }
service { 'bind': if $chroot and $::bind::defaults::bind_chroot_service {
ensure => running, service { 'bind':
name => $::bind::defaults::bind_service, ensure => running,
enable => true, name => $::bind::defaults::bind_chroot_service,
hasrestart => true, enable => true,
hasstatus => true, hasrestart => true,
hasstatus => true,
}
# On RHEL Family, there is a dedicated service named-chroot and we need
# to stop/disable 'named' service:
service { 'bind-no-chroot':
ensure => stopped,
name => $::bind::defaults::bind_service,
enable => false,
}
} else {
service { 'bind':
ensure => running,
name => $::bind::defaults::bind_service,
enable => true,
hasrestart => true,
hasstatus => true,
}
} }
} }

View File

@ -19,11 +19,11 @@
}, },
{ {
"operatingsystem": "CentOS", "operatingsystem": "CentOS",
"operatingsystemrelease": [ "6" ] "operatingsystemrelease": [ "6", "7"]
}, },
{ {
"operatingsystem": "RedHat", "operatingsystem": "RedHat",
"operatingsystemrelease": [ "6" ] "operatingsystemrelease": [ "6", "7" ]
} }
], ],
"dependencies": [ "dependencies": [

View File

@ -7,17 +7,21 @@ describe 'bind' do
let (:facts) {facts} let (:facts) {facts}
case facts[:os]['family'] case facts[:os]['family']
when 'Debian' when 'Debian'
expected_bind_pkg = 'bind9' expected_bind_pkg = 'bind9'
expected_bind_service = 'bind9' expected_bind_service = 'bind9'
expected_named_conf = '/etc/bind/named.conf' expected_bind_chroot_pkg = nil
expected_confdir = '/etc/bind' expected_bind_chroot_service = nil
expected_default_zones_include = '/etc/bind/named.conf.default-zones' expected_named_conf = '/etc/bind/named.conf'
expected_confdir = '/etc/bind'
expected_default_zones_include= '/etc/bind/named.conf.default-zones'
when 'RedHat' when 'RedHat'
expected_bind_pkg = 'bind' expected_bind_pkg = 'bind'
expected_bind_service = 'named' expected_bind_service = 'named'
expected_named_conf = '/etc/named.conf' expected_bind_chroot_pkg = 'bind-chroot'
expected_confdir = '/etc/named' expected_bind_chroot_service = 'named-chroot'
expected_default_zones_include = '/etc/named.default-zones.conf' expected_named_conf = '/etc/named.conf'
expected_confdir = '/etc/named'
expected_default_zones_include= '/etc/named.default-zones.conf'
end end
context 'with defaults for all parameters' do context 'with defaults for all parameters' do
it { is_expected.to contain_class('bind::defaults') } it { is_expected.to contain_class('bind::defaults') }
@ -42,13 +46,6 @@ describe 'bind' do
end end
it { is_expected.to contain_file('/usr/local/bin/rndc-helper') } it { is_expected.to contain_file('/usr/local/bin/rndc-helper') }
case facts[:os]['family']
when 'RedHat'
it { is_expected.to contain_file(expected_default_zones_include) }
when 'Debian'
it { is_expected.not_to contain_file(expected_default_zones_include) }
end
it { is_expected.to contain_concat("#{expected_confdir}/acls.conf") } it { is_expected.to contain_concat("#{expected_confdir}/acls.conf") }
it { is_expected.to contain_concat("#{expected_confdir}/keys.conf") } it { is_expected.to contain_concat("#{expected_confdir}/keys.conf") }
it { is_expected.to contain_concat("#{expected_confdir}/views.conf") } it { is_expected.to contain_concat("#{expected_confdir}/views.conf") }
@ -84,6 +81,93 @@ describe 'bind' do
name: expected_bind_service name: expected_bind_service
}) })
end end
case facts[:os]['family']
when 'RedHat'
it { is_expected.to contain_file(expected_default_zones_include) }
it { is_expected.not_to contain_service('bind-no-chroot') }
when 'Debian'
it { is_expected.not_to contain_file(expected_default_zones_include) }
end
end
context 'with chroot enabled' do
let(:params) do
{
chroot: true,
default_zones_include: '/etc/named/default-zones.conf'
}
end
if not (facts[:os]['name'] == 'CentOS' && facts[:os]['release']['major'] == '7')
it { is_expected.to compile.and_raise_error(/Chroot for bind is not supported on your OS/) }
else
it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_class('bind::defaults') }
it { is_expected.to contain_class('bind::keydir') }
it { is_expected.to contain_class('bind::updater') }
it { is_expected.to contain_class('bind') }
it { is_expected.to compile.with_all_deps }
it do
is_expected.to contain_package('bind').with({
ensure: 'latest',
name: expected_bind_chroot_pkg
})
end
it { is_expected.to contain_file('/usr/local/bin/dnssec-init') }
it do
is_expected.to contain_bind__key('rndc-key').with(
algorithm: 'hmac-md5',
secret_bits: '512',
keydir: expected_confdir,
keyfile: 'rndc.key'
)
end
it { is_expected.to contain_file('/usr/local/bin/rndc-helper') }
case facts[:os]['family']
when 'RedHat'
it { is_expected.to contain_file('/etc/named/default-zones.conf') }
when 'Debian'
it { is_expected.not_to contain_file(expected_default_zones_include) }
end
it { is_expected.to contain_concat("#{expected_confdir}/acls.conf") }
it { is_expected.to contain_concat("#{expected_confdir}/keys.conf") }
it { is_expected.to contain_concat("#{expected_confdir}/views.conf") }
it { is_expected.to contain_concat("#{expected_confdir}/servers.conf") }
it { is_expected.to contain_concat("#{expected_confdir}/logging.conf") }
it { is_expected.to contain_concat("#{expected_confdir}/view-mappings.txt") }
it { is_expected.to contain_concat("#{expected_confdir}/domain-mappings.txt") }
it do
is_expected.to contain_concat__fragment('bind-logging-header').with(
order: '00-header',
target: "#{expected_confdir}/logging.conf",
content: "logging {\n"
)
end
it do
is_expected.to contain_concat__fragment('bind-logging-footer').with(
order: '99-footer',
target: "#{expected_confdir}/logging.conf",
content: "};\n"
)
end
it { is_expected.to contain_file(expected_named_conf).that_requires('Package[bind]') }
it { is_expected.to contain_file(expected_named_conf).that_notifies('Service[bind]') }
it do
is_expected.to contain_service('bind-no-chroot').with({
ensure: 'stopped',
enable: false,
name: expected_bind_service
})
end
it do
is_expected.to contain_service('bind').with({
ensure: 'running',
enable: true,
name: expected_bind_chroot_service
})
end
end
end end
context 'with tkey-* parameters' do context 'with tkey-* parameters' do
let(:params) do let(:params) do