From 9f3af7d10c7c60ff1a88a3ccaa33246f523e505b Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Tue, 2 Feb 2021 18:36:31 +0000 Subject: [PATCH] Add tripleo_unbound role This patch adds a TripleO Ansible role that configures the Unbound DNS resolver. Depends-On: https://review.opendev.org/c/openstack/tripleo-heat-templates/+/779048 Change-Id: I87d21e03974965bf742a46364cae02457481e793 --- doc/source/roles/role-tripleo_unbound.rst | 6 ++ ...tripleo-unbound-role-fb072294f074adf1.yaml | 5 + .../roles/tripleo_unbound/defaults/main.yml | 27 ++++++ .../roles/tripleo_unbound/meta/main.yml | 42 +++++++++ .../molecule/default/Dockerfile | 37 ++++++++ .../molecule/default/converge.yml | 21 +++++ .../molecule/default/molecule.yml | 48 ++++++++++ .../molecule/default/prepare.yml | 21 +++++ .../roles/tripleo_unbound/tasks/main.yml | 52 +++++++++++ .../templates/tripleo-base-unbound.conf.j2 | 91 +++++++++++++++++++ .../templates/unbound_build_vars.j2 | 41 +++++++++ zuul.d/molecule.yaml | 10 ++ 12 files changed, 401 insertions(+) create mode 100644 doc/source/roles/role-tripleo_unbound.rst create mode 100644 releasenotes/notes/Add-tripleo-unbound-role-fb072294f074adf1.yaml create mode 100644 tripleo_ansible/roles/tripleo_unbound/defaults/main.yml create mode 100644 tripleo_ansible/roles/tripleo_unbound/meta/main.yml create mode 100644 tripleo_ansible/roles/tripleo_unbound/molecule/default/Dockerfile create mode 100644 tripleo_ansible/roles/tripleo_unbound/molecule/default/converge.yml create mode 100644 tripleo_ansible/roles/tripleo_unbound/molecule/default/molecule.yml create mode 100644 tripleo_ansible/roles/tripleo_unbound/molecule/default/prepare.yml create mode 100644 tripleo_ansible/roles/tripleo_unbound/tasks/main.yml create mode 100644 tripleo_ansible/roles/tripleo_unbound/templates/tripleo-base-unbound.conf.j2 create mode 100644 tripleo_ansible/roles/tripleo_unbound/templates/unbound_build_vars.j2 diff --git a/doc/source/roles/role-tripleo_unbound.rst b/doc/source/roles/role-tripleo_unbound.rst new file mode 100644 index 000000000..25a841ece --- /dev/null +++ b/doc/source/roles/role-tripleo_unbound.rst @@ -0,0 +1,6 @@ +====================== +Role - tripleo_unbound +====================== + +.. ansibleautoplugin:: + :role: tripleo_ansible/roles/tripleo_unbound diff --git a/releasenotes/notes/Add-tripleo-unbound-role-fb072294f074adf1.yaml b/releasenotes/notes/Add-tripleo-unbound-role-fb072294f074adf1.yaml new file mode 100644 index 000000000..b1bf2d73a --- /dev/null +++ b/releasenotes/notes/Add-tripleo-unbound-role-fb072294f074adf1.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added a new role for ``tripleo_unbound`` to configure the Unbound DNS + resolver for TripleO deployments. diff --git a/tripleo_ansible/roles/tripleo_unbound/defaults/main.yml b/tripleo_ansible/roles/tripleo_unbound/defaults/main.yml new file mode 100644 index 000000000..cf38bd35b --- /dev/null +++ b/tripleo_ansible/roles/tripleo_unbound/defaults/main.yml @@ -0,0 +1,27 @@ +--- +# Copyright 2021 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +# All variables intended for modification should be placed in this file. + +# All variables within this role should have a prefix of "tripleo_unbound" +tripleo_unbound_debug: "{{ (ansible_verbosity | int) >= 2 | bool }}" +tripleo_unbound_hide_sensitive_logs: true + +tripleo_unbound_config_basedir: "/var/lib/config-data/ansible-generated/unbound" +tripleo_unbound_allowed_cidrs: [] +tripleo_unbound_log_queries: false +tripleo_unbound_security_harden: true diff --git a/tripleo_ansible/roles/tripleo_unbound/meta/main.yml b/tripleo_ansible/roles/tripleo_unbound/meta/main.yml new file mode 100644 index 000000000..a2c3063f5 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_unbound/meta/main.yml @@ -0,0 +1,42 @@ +--- +# Copyright 2021 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +galaxy_info: + author: OpenStack + description: TripleO OpenStack Role -- tripleo_unbound + company: Red Hat + license: Apache-2.0 + min_ansible_version: 2.7 + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + platforms: + - name: CentOS + versions: + - 7 + - 8 + + galaxy_tags: + - tripleo + + +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. +dependencies: [] diff --git a/tripleo_ansible/roles/tripleo_unbound/molecule/default/Dockerfile b/tripleo_ansible/roles/tripleo_unbound/molecule/default/Dockerfile new file mode 100644 index 000000000..90646fff5 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_unbound/molecule/default/Dockerfile @@ -0,0 +1,37 @@ +# Molecule managed +# Copyright 2021 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install sudo python*-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi + +{% for pkg in item.easy_install | default([]) %} +# install pip for centos where there is no python-pip rpm in default repos +RUN easy_install {{ pkg }} +{% endfor %} + + +CMD ["sh", "-c", "while true; do sleep 10000; done"] diff --git a/tripleo_ansible/roles/tripleo_unbound/molecule/default/converge.yml b/tripleo_ansible/roles/tripleo_unbound/molecule/default/converge.yml new file mode 100644 index 000000000..fefe69cb5 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_unbound/molecule/default/converge.yml @@ -0,0 +1,21 @@ +--- +# Copyright 2021 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +- name: Converge + hosts: all + roles: + - role: "tripleo_unbound" diff --git a/tripleo_ansible/roles/tripleo_unbound/molecule/default/molecule.yml b/tripleo_ansible/roles/tripleo_unbound/molecule/default/molecule.yml new file mode 100644 index 000000000..f448198fe --- /dev/null +++ b/tripleo_ansible/roles/tripleo_unbound/molecule/default/molecule.yml @@ -0,0 +1,48 @@ +--- +driver: + name: podman + +log: true + +platforms: + - name: ubi8 + hostname: ubi8 + image: ubi8/ubi-init + registry: + url: registry.access.redhat.com + dockerfile: Dockerfile + pkg_extras: python*setuptools + volumes: + - /etc/ci/mirror_info.sh:/etc/ci/mirror_info.sh:ro + - /etc/pki/rpm-gpg:/etc/pki/rpm-gpg + privileged: true + environment: &env + http_proxy: "{{ lookup('env', 'http_proxy') }}" + https_proxy: "{{ lookup('env', 'https_proxy') }}" + ulimits: &ulimit + - host + +provisioner: + inventory: + hosts: + all: + hosts: + ubi8: + ansible_python_interpreter: /usr/bin/python3 + name: ansible + log: true + env: + ANSIBLE_STDOUT_CALLBACK: yaml + +scenario: + test_sequence: + - destroy + - create + - prepare + - converge + - check + - verify + - destroy + +verifier: + name: testinfra diff --git a/tripleo_ansible/roles/tripleo_unbound/molecule/default/prepare.yml b/tripleo_ansible/roles/tripleo_unbound/molecule/default/prepare.yml new file mode 100644 index 000000000..6e7049237 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_unbound/molecule/default/prepare.yml @@ -0,0 +1,21 @@ +--- +# Copyright 2021 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +- name: Prepare + hosts: all + roles: + - role: test_deps diff --git a/tripleo_ansible/roles/tripleo_unbound/tasks/main.yml b/tripleo_ansible/roles/tripleo_unbound/tasks/main.yml new file mode 100644 index 000000000..0b806adf7 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_unbound/tasks/main.yml @@ -0,0 +1,52 @@ +--- +# Copyright 2021 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: create directory {{ tripleo_unbound_config_basedir }} + become: true + ansible.builtin.file: + path: "{{ tripleo_unbound_config_basedir }}" + recurse: true + state: directory + selevel: s0 + setype: container_file_t + +- name: Create the base TripleO Unbound configuration file + become: true + ansible.builtin.template: + src: tripleo-base-unbound.conf.j2 + dest: "{{ tripleo_unbound_config_basedir }}/tripleo-base-unbound.conf" + mode: '0640' + selevel: s0 + setype: container_file_t + register: _unbound_config_result + +- name: Restart Unbound + when: + - _unbound_config_result.changed + block: + - name: check if tripleo_unbound systemd service is active + become: true + shell: systemctl is-active --quiet tripleo_unbound + failed_when: false + register: unbound_active_service + + - name: Restart the Unbound container + become: true + systemd: + name: tripleo_unbound + state: restarted + when: + - unbound_active_service.rc == 0 diff --git a/tripleo_ansible/roles/tripleo_unbound/templates/tripleo-base-unbound.conf.j2 b/tripleo_ansible/roles/tripleo_unbound/templates/tripleo-base-unbound.conf.j2 new file mode 100644 index 000000000..6c52b5719 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_unbound/templates/tripleo-base-unbound.conf.j2 @@ -0,0 +1,91 @@ +# {{ ansible_managed }} +{# +This template is for the TripleO base Unbound configuration file. + +No service specific settings should be made in this file. + +It will be placed in the /etc/unbound/conf.d directory and will override the +configuration settings provided in the base Unbound package from the +distribution. +#} +# +# These settings are made by TripleO, do not modify directly. +# The settings in this file will override the package provided settings. +# + +{% import 'unbound_build_vars.j2' as unbound_vars with context %} + +server: + +{# The interface unbound should listen on. x.x.x.x x::x #} +{% for interface in unbound_vars.tripleo_unbound_listen_interfaces %} + interface: {{ interface }} +{% endfor %} +{# We are in a container, stay in the foreground #} + do-daemonize: no + +{# +Define CIDRs that are allowed to use this resolver. +Note: This is a security feature. Do not open the resolver to the world or + it can be used for DDoS amplification attacks. +#} +# Allow cloud internal subnet CIDRs. +{% for cidr in unbound_vars.tripleo_unbound_allowed_internal_cidrs %} + access-control: {{ cidr }} allow +{% endfor %} + +# Allow cloud external subnet CIDRs. +{% for cidr in unbound_vars.tripleo_unbound_allowed_external_cidrs %} + access-control: {{ cidr }} allow +{% endfor %} + +# Allow deployment configured CIDRs. +{% for cidr in tripleo_unbound_allowed_cidrs %} + access-control: {{ cidr }} allow +{% endfor %} + +{# Set the container log file name and location. #} + logfile: /var/log/unbound/unbound.log + +{# +Only log queries if the user has enabled it. +This can generate very large log files. +#} +{% if tripleo_unbound_log_queries %} + log-queries: yes +{% else %} + log-queries: no +{% endif %} + +{# Set various security hardening settings. This defaults to on. #} +{% if tripleo_unbound_security_harden %} + hide-identity: yes + hide-version: yes + hide-trustanchor: yes + harden-short-bufsize: yes + harden-large-queries: yes +{% endif %} + +{# Allow PTR lookups for private IP address spaces. #} + unblock-lan-zones: yes + +{# Do not try to DNSSEC validate private IP address spaces. #} + insecure-lan-zones: yes +{# Setup the TLS endpoint for TCP queries. #} +{# Not implemented yet + tls-service-key: + tls-service-pem: + tls-port: 853 +#} +{# +Optimize the cache for cloud usage. +https://www.nlnetlabs.nl/documentation/unbound/howto-optimise/ +#} + rrset-cache-size: 100m + msg-cache-size: 50m + +{# +The remote control interface is not needed until we startcollecting metrics. +#} +remote-control: + control-enable: no diff --git a/tripleo_ansible/roles/tripleo_unbound/templates/unbound_build_vars.j2 b/tripleo_ansible/roles/tripleo_unbound/templates/unbound_build_vars.j2 new file mode 100644 index 000000000..565ef8564 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_unbound/templates/unbound_build_vars.j2 @@ -0,0 +1,41 @@ +# {{ ansible_managed }} +{# +This template is for the TripleO base Unbound configuration file. + +No service specific settings should be made in this file. + +This template will generate the required variables needed for the Unbound +configuration file template. + +We were requested to handle the variables in a jinja template instead of in +the ansible task due to an ansible performance issue here: +https://review.opendev.org/c/openstack/tripleo-ansible/+/773784 +#} + +{# Get the unbound listen interface IP address #} + +{% if tripleo_unbound_listen_interfaces is not defined or tripleo_unbound_listen_interfaces == "" %} + {% if tripleo_unbound_network_name is defined and tripleo_unbound_network_name != "" %} + {% set tripleo_unbound_listen_interfaces = [hostvars[inventory_hostname][tripleo_unbound_network_name + "_ip"]] %} + {% else %} + {% set tripleo_unbound_listen_interfaces = ['127.0.0.1'] %} + {% endif %} +{% endif %} + +{# Get the cloud "external" subnet CIDRs to allow for queries #} +{% if tripleo_unbound_allowed_external_cidrs is not defined or tripleo_unbound_allowed_external_cidrs == "" %} + {% if tripleo_unbound_external_network_name is defined and tripleo_unbound_external_network_name != "" %} + {% set tripleo_unbound_allowed_external_cidrs = vars['net_cidr_map'][tripleo_unbound_external_network_name] %} + {% else %} + {% set tripleo_unbound_allowed_external_cidrs = [] %} + {% endif %} +{% endif %} + +{# Get the cloud "internal" subnet CIDRs to allow for queries #} +{% if tripleo_unbound_allowed_internal_cidrs is not defined or tripleo_unbound_allowed_internal_cidrs == "" %} + {% if tripleo_unbound_internal_network_name is defined and tripleo_unbound_internal_network_name != "" %} + {% set tripleo_unbound_allowed_internal_cidrs = vars['net_cidr_map'][tripleo_unbound_internal_network_name] %} + {% else %} + {% set tripleo_unbound_allowed_internal_cidrs = [] %} + {% endif %} +{% endif %} diff --git a/zuul.d/molecule.yaml b/zuul.d/molecule.yaml index 91d5a3fa5..66189dd89 100644 --- a/zuul.d/molecule.yaml +++ b/zuul.d/molecule.yaml @@ -53,6 +53,7 @@ - tripleo-ansible-centos-8-molecule-tripleo_systemd_wrapper - tripleo-ansible-centos-8-molecule-tripleo_timezone - tripleo-ansible-centos-8-molecule-tripleo_transfer + - tripleo-ansible-centos-8-molecule-tripleo_unbound - tripleo-ansible-centos-8-molecule-tripleo_update_trusted_cas - tripleo-ansible-centos-8-molecule-tripleo_upgrade_hiera - tripleo-ansible-centos-8-molecule-tripleo_validations_package @@ -109,6 +110,7 @@ - tripleo-ansible-centos-8-molecule-tripleo_systemd_wrapper - tripleo-ansible-centos-8-molecule-tripleo_timezone - tripleo-ansible-centos-8-molecule-tripleo_transfer + - tripleo-ansible-centos-8-molecule-tripleo_unbound - tripleo-ansible-centos-8-molecule-tripleo_update_trusted_cas - tripleo-ansible-centos-8-molecule-tripleo_upgrade_hiera - tripleo-ansible-centos-8-molecule-tripleo_validations_package @@ -164,6 +166,7 @@ - tripleo-ansible-centos-8-molecule-tripleo_systemd_wrapper - tripleo-ansible-centos-8-molecule-tripleo_timezone - tripleo-ansible-centos-8-molecule-tripleo_transfer + - tripleo-ansible-centos-8-molecule-tripleo_unbound - tripleo-ansible-centos-8-molecule-tripleo_upgrade_hiera - tripleo-ansible-centos-8-molecule-tripleo_validations_package - tripleo-ansible-centos-8-molecule-tuned @@ -528,6 +531,13 @@ parent: tripleo-ansible-centos-8-base vars: tripleo_role_name: tripleo_transfer +- job: + files: + - ^tripleo_ansible/roles/tripleo_unbound/.* + name: tripleo-ansible-centos-8-molecule-tripleo_unbound + parent: tripleo-ansible-centos-8-base + vars: + tripleo_role_name: tripleo_unbound - job: files: - ^tripleo_ansible/roles/tripleo_update_trusted_cas/.*