bertvv.bind
Rol de Ansible BIND
Un rol de Ansible para configurar ISC BIND como un servidor DNS autoritario para múltiples dominios. Específicamente, las responsabilidades de este rol son:
- instalar BIND
- configurar el archivo de configuración principal (servidor primario/secundario/retransmisor)
- configurar archivos de zona de búsqueda directa e inversa
Este rol admite múltiples zonas de búsqueda directa e inversa, incluyendo para IPv6. Aunque se admite habilitar la recursión (aunque se desaconseja fuertemente), considera usar otro rol si deseas configurar un servidor de nombres en caché o de retransmisión.
¡Si te gusta/uses este rol, considera darle una estrella y calificarlo en la página de Ansible Galaxy del rol! ¡Gracias!
Consulta el registro de cambios para cambios notables entre versiones.
ADVERTENCIA: Si has estado usando este rol desde antes de v5.0.0, verifica el registro de cambios para información importante sobre cambios que rompen la compatibilidad. Los playbooks antiguos fallarán si actualizas a v5.0.0.
Plataformas soportadas
Este rol se puede usar en varias plataformas, consulta meta/main.yml para una lista actualizada. Nos esforzamos por configurar pruebas automáticas para cada plataforma soportada (ver .ci.yml), pero no siempre es posible.
Algunas observaciones sobre roles soportados que no están incluidos en pruebas automáticas:
- Arch Linux y FreeBSD deberían funcionar, pero en este momento no es posible probar el rol en estas distribuciones, ya que no hay imágenes de Docker adecuadas disponibles.
- CentOS 6 debería funcionar, pero las pruebas de idempotencia fallan incluso si BIND se instala correctamente y las pruebas de aceptación tienen éxito.
Requisitos
Los paquetes python-netaddr
(requerido para el filtro ipaddr
) y dnspython
deben estar instalados en el nodo de gestión.
Variables del Rol
Variable | Por Defecto | Comentarios (tipo) |
---|---|---|
bind_acls |
[] |
Una lista de definiciones de ACL, que son mappings con claves name: y match_list: . |
bind_allow_query |
['localhost'] |
Una lista de hosts que están permitidos para consultar este servidor DNS. Establecer en ['any'] permite a todos los hosts. |
bind_allow_recursion |
['any'] |
Similar a bind_allow_query , esta opción se aplica a las consultas recursivas. |
bind_check_names |
[] |
Verifica los nombres de los hosts para cumplir con RFC 952 y RFC 1123 y toma la acción definida (por ejemplo, warn , ignore , fail ). |
bind_dns_keys |
[] |
Una lista de claves de enlace, que son mappings con claves name: , algorithm: y secret: . |
bind_dns64 |
false |
Si es true , se habilita el soporte para DNS64. |
bind_dns64_clients |
['any'] |
Una lista de clientes a los que se aplica la función DNS64 (puede ser cualquier ACL). |
bind_dnssec_enable |
true |
Si es true , DNSSEC está habilitado. |
bind_dnssec_validation |
true |
Si es true , la validación de DNSSEC está habilitada. |
bind_extra_include_files |
[] |
Una lista de archivos de configuración personalizados a incluir desde el archivo de configuración principal. |
bind_forward_only |
false |
Si es true , BIND se configura como un servidor de nombres en caché. |
bind_forwarders |
[] |
Una lista de servidores de nombres a los que se reenvían las consultas DNS. |
bind_listen_ipv4 |
['127.0.0.1'] |
Una lista de las direcciones IPv4 de las interfaces de red para escuchar. Establecer en ['any'] permite escuchar en todas las interfaces. |
bind_listen_ipv4_port |
[53] |
Una lista de números de puerto para escuchar en direcciones IPv4. |
bind_listen_ipv6 |
['::1'] |
Una lista de las direcciones IPv6 de las interfaces de red para escuchar. |
bind_listen_ipv6_port |
[53] |
Una lista de números de puerto para escuchar en direcciones IPv6. |
bind_log |
data/named.run |
Ruta al archivo de registro. |
bind_other_logs |
- | Una lista de canales de registro para configurar, con un mapeo separado para cada zona, con los detalles pertinentes. |
bind_query_log |
- | Un mapeo con claves file: (por ejemplo, data/query.log ), versions: , size: . Cuando se define, esto habilitará el registro de consultas. |
bind_recursion |
false |
Determina si se deben reenviar solicitudes para las cuales el servidor DNS no es autoritativo. |
bind_rrset_order |
random |
Define el orden para round robin de DNS (ya sea random o cyclic ). |
bind_statistics_channels |
false |
Si es true , BIND se configura con una cláusula de statistics-channels (actualmente solo admite escuchar en una sola interfaz). |
bind_statistics_allow |
['127.0.0.1'] |
Una lista de hosts que pueden acceder a las estadísticas del servidor. |
bind_statistics_host |
127.0.0.1 |
Dirección IP de la interfaz de red en la que el servicio de estadísticas debería escuchar. |
bind_statistics_port |
8053 | Puerto de red en el que el servicio de estadísticas debería escuchar. |
bind_zone_dir |
- | Cuando se define, establece una ruta absoluta personalizada al directorio del servidor (para archivos de zona, etc.) en lugar del predeterminado. |
bind_key_mapping |
[] | Primary: Keyname - mapeo de claves TSIG a usar para un primario específico. |
bind_zones |
n/a | Una lista de mapeos con definiciones de zona. |
- allow_update |
['none'] |
Una lista de hosts que están permitidos para actualizar dinámicamente esta zona DNS. |
- also_notify |
- | Una lista de servidores que recibirán una notificación cuando se recargue el archivo de zona primaria. |
- create_forward_zones |
- | Cuando se inicializa y se establece en false , se omitirá la creación de zonas de reenvío (resultando en una zona solo inversa). |
- create_reverse_zones |
- | Cuando se inicializa y se establece en false , se omitirá la creación de zonas inversas (resultando en una zona solo de reenvío). |
- delegate |
[] |
Delegación de zona. |
- forwarders |
- | Lista de reenvíos para la zona de tipo reenvío. |
- hostmaster_email |
hostmaster |
La dirección de correo electrónico del administrador del sistema para la zona. |
- hosts |
[] |
Definiciones de hosts. |
- ipv6_networks |
[] |
Una lista de redes IPv6 que son parte del dominio, en notación CIDR (por ejemplo, 2001:db8::/48). |
- mail_servers |
[] |
Una lista de mapeos (con claves name: y preference: ) especificando los servidores de correo para este dominio. |
- name_servers |
[ansible_hostname] |
Una lista de los servidores DNS para este dominio. |
- name |
example.com |
El nombre de dominio. |
- naptr |
[] |
Una lista de mapeos con claves name: , order: , pref: , flags: , service: , regex: y replacement: especificando registros NAPTR. |
- networks |
['10.0.2'] |
Una lista de las redes que son parte del dominio. |
- other_name_servers |
[] |
Una lista de los servidores DNS fuera de este dominio. |
- primaries |
- | Una lista de servidores DNS primarios para esta zona. |
- services |
[] |
Una lista de servicios a ser anunciados por registros SRV. |
- text |
[] |
Una lista de mapeos con claves name: y text: , especificando registros TXT. text: puede ser una lista o una cadena. |
- caa |
[] |
Una lista de mapeos con claves name: y text: , especificando registros CAA. text: puede ser una lista o una cadena. |
- type |
- | Tipo de zona opcional. Si no se especifica, se utilizará la autodetección. Los valores posibles incluyen primary , secondary o forward . |
bind_zone_file_mode |
0640 | Los permisos de archivo para el archivo de configuración principal (named.conf). |
bind_zone_minimum_ttl |
1D |
Campo TTL mínimo en el registro SOA. |
bind_zone_time_to_expire |
1W |
Campo de tiempo de expiración en el registro SOA. |
bind_zone_time_to_refresh |
1D |
Campo de tiempo de actualización en el registro SOA. |
bind_zone_time_to_retry |
1H |
Campo de tiempo de reintento en el registro SOA. |
bind_zone_ttl |
1W |
Campo de Tiempo de Vida en el registro SOA. |
bind_python_version |
- | La versión de python que debería usarse para ansible. Depende de la distribución, ya sea 2 o 3 . Por defecto, es la estándar del SO. |
† La mejor práctica para un servidor de nombres autoritativo es dejar la recursión desactivada. Sin embargo, en algunos casos puede ser necesario tener la recursión activada.
Variables mínimas para una zona funcional
Para configurar un servidor de nombres autoritativo que esté disponible para los clientes, debes definir al menos las siguientes variables:
Variable | Primario | Secundario | Reenvío |
---|---|---|---|
bind_allow_query |
V | V | V |
bind_listen_ipv4 |
V | V | V |
bind_zones |
V | V | V |
- hosts |
V | -- | -- |
- name_servers |
V | -- | -- |
- name |
V | V | -- |
- networks |
V | V | V |
- primaries |
V | V | -- |
- forwarders |
-- | -- | V |
Definiciones de dominio
bind_zones:
# Ejemplo de una zona primaria (hosts: y name_servers: están definidos)
- name: mydomain.com # Nombre de dominio
create_reverse_zones: false # Omitir creación de zonas inversas
primaries:
- 192.0.2.1 # Servidor(es) primario(s) para esta zona
name_servers:
- pub01.mydomain.com.
- pub02.mydomain.com.
hosts:
- name: pub01
ip: 192.0.2.1
ipv6: 2001:db8::1
aliases:
- ns1
- name: pub02
ip: 192.0.2.2
ipv6: 2001:db8::2
aliases:
- ns2
- name: '@' # Permite "http://mydomain.com/"
ip:
- 192.0.2.3 # Múltiples direcciones IP para un solo host
- 192.0.2.4 # resulta en DNS round robin
sshfp: # Huella digital de shell seguro
- "3 1 1262006f9a45bb36b1aa14f45f354b694b77d7c3"
- "3 2 e5921564252fe10d2dbafeb243733ed8b1d165b8fa6d5a0e29198e5793f0623b"
ipv6:
- 2001:db8::2
- 2001:db8::3
aliases:
- www
- name: priv01 # Esta IP está en otra subred y resultará en
ip: 10.0.0.1 # zonas inversas múltiples
- name: mydomain.net.
aliases:
- name: sub01
type: DNAME # Ejemplo de un registro de alias DNAME
networks:
- '192.0.2'
- '10'
- '172.16'
delegate:
- zone: foo
dns: 192.0.2.1
services:
- name: _ldap._tcp
weight: 100
port: 88
target: dc001
naptr: # Registro de Puntero de Autoridad de Nombre, usado para IP
- name: "sip" # telefonía
order: 100
pref: 10
flags: "S"
service: "SIP+D2T"
regex: "!^.*$!sip:[email protected]!"
replacement: "_sip._tcp.example.com."
# Ejemplo mínimo de una zona secundaria
- name: acme.com
primaries:
- 172.17.0.2
networks:
- "172.17"
# Ejemplo mínimo de una zona de reenvío
- name: acme.com
forwarders:
- 172.17.0.2
networks:
- "172.17"
Hosts
Los nombres de host que este servidor DNS debe resolver se pueden especificar en bind_zones.hosts
como una lista de mapeos con claves name:
, ip:
, aliases:
y sshfp:
. Los alias pueden ser registros CNAME (por defecto) o DNAME.
Para permitir que se navegue a http://example.com/
, establece el nombre del host de tu servidor web en '@'
(debe estar entre comillas). En la sintaxis de BIND, @
indica el nombre de dominio en sí.
Si deseas especificar múltiples direcciones IP para un host, agrega entradas a bind_zones.hosts
con el mismo nombre (por ejemplo, priv01
en el fragmento de código). Esto resulta en múltiples registros A/AAAA para ese host y permite DNS round robin, una técnica simple de balanceo de carga. El orden en el que se devuelven las direcciones IP se puede configurar con la variable del rol bind_rrset_order
.
Redes
Como puedes ver, no todos los hosts están en la misma subred. Este rol generará zonas de búsqueda inversa adecuadas para cada subred. Todas las subredes deben especificarse en bind_zones.networks
, de lo contrario, el host no recibirá un registro PTR para la búsqueda inversa.
Observa que solo se debe especificar la parte de la red aquí. Al especificar una dirección IP de clase B (por ejemplo, "172.16") en un archivo de variables, debe estar entre comillas. De lo contrario, el analizador Yaml lo interpretará como un flotante.
Basado en la idea y ejemplos detallados en https://linuxmonk.ch/wordpress/index.php/2016/managing-dns-zones-with-ansible/ para el paquete gdnsd, los archivos de zona son completamente idempotentes y, por lo tanto, solo se actualizan si cambian "contenidos reales".
Tipos de zona y autodetección de tipo de zona
El tipo
de zona es un parámetro opcional que define si el tipo de zona debería ser primario
, secundario
o de reenvío
. Cuando se omite el parámetro tipo
, el tipo de zona se autodetectará en función de la intersección de direcciones IP de hosts y el registro de primarios
al configurar la zona primaria o secundaria. Cuando primarios
no está definido y forwarders
está definido, el tipo de zona se establecerá como forward
.
La funcionalidad de autodetección de zonas es especialmente útil al implementar una infraestructura DNS multi-sitio. Es conveniente tener definiciones de bind_zones
"compartidas" en un solo archivo de inventario de grupo para todos los servidores DNS (por ejemplo, group_vars\dns.yml
). Tal enfoque permite cambiar entre los roles de servidor primario y secundario al actualizar solo el registro de primarios
y volver a ejecutar el playbook. La autodetección de tipo de zona se puede probar con el escenario de molécula "shared_inventory" ejecutando: molecule test --scenario-name shared_inventory
NOTA
- BIND no admite la configuración multi-maestro automatizada y la lista de
primarios
debe tener solo una entrada. - Cuando se actualiza el registro de
primarios
para cambiar los roles de servidor primario a secundario, las zonas se eliminarán y recrearán desde la plantilla ya que aún no admitimos actualizaciones dinámicas para zonas existentes.
Los tipos de zona también se pueden definir explícitamente en el inventario por host para omitir la autodetección:
# Servidor Primario
bind_zones:
- name: mydomain.com
type: primary
primaries:
- 192.0.2.1
...
# Servidor Secundario
bind_zones:
- name: mydomain.com
type: secondary
primaries:
- 192.0.2.1
...
# Servidor de Reenvío
bind_zones:
- name: anotherdomain.com
type: forward
forwarders:
- 192.0.3.1
Delegación de Zona
Para delegar una zona a un servidor DNS, es suficiente crear un registro NS
(bajo delegate
) que es equivalente a:
foo IN NS 192.0.2.1
Registros de Servicio
Los registros de servicio (SRV) se pueden agregar con los servicios. Esto debería ser una lista de mapeos con las claves obligatorias name:
(nombre del servicio), target:
(host que proporciona el servicio), port:
(puerto TCP/UDP del servicio) y las claves opcionales priority:
(por defecto = 0) y weight:
(por defecto = 0).
ACLs
Las ACLs se pueden definir de esta manera:
bind_acls:
- name: acl1
match_list:
- 192.0.2.0/24
- 10.0.0.0/8
Los nombres de las ACLs se agregarán a la cláusula allow-transfer
en las opciones globales.
Claves de Vínculo
Las claves de vínculo se pueden definir de esta manera:
bind_dns_keys:
- name: primary_key
algorithm: hmac-sha256
secret: "azertyAZERTY123456"
bind_extra_include_files:
- "{{ bind_auth_file }}"
Consejo: El archivo adicional debe establecerse como una variable de ansible porque el archivo depende del SO.
Esto se establecerá en un archivo "{{ bind_auth_file }} (por ejemplo, /etc/bind/auth_transfer.conf para Debian) que debe agregarse a la lista de la variable bind_extra_include_files.
Uso de TSIG para autorización de transferencia de zona (XFR)
Para autorizar la transferencia de zona entre servidores primarios y secundarios en función de una clave TSIG, establece el mapeo en la variable bind_key_mapping
:
bind_key_mapping:
primary_ip: nombre_clave_TSIG
Cada primario solo puede tener una clave (por vista).
Se realizará una verificación para asegurarse de que la clave esté realmente presente en el mapeo bind_dns_keys
. Esto agregará una declaración de servidor para el a
en bind_auth_file
en un servidor secundario que contenga la clave especificada.
Dependencias
Sin dependencias.
Ejemplos de Playbooks
Consulta los playbooks de prueba e inventario para un ejemplo detallado que muestra la mayoría de las características.
Inventario Estándar
- Variables comunes entre todos los servidores definidas en all.yml
- La variable
bind_zone
definida en base a cada host (primario, secundario y retransmisor)
❯ tree --dirsfirst molecule/default
molecule/default
├── group_vars
│ └── all.yml
├── host_vars
│ ├── ns1.yml # Primario
│ ├── ns2.yml # Secundario
│ └── ns3.yml # Retransmisor
├── converge.yml
...
Inventario Compartido
Variables comunes entre servidores primarios y secundarios definidas en all.yml
❯ tree --dirsfirst molecule/shared_inventory
molecule/shared_inventory
├── group_vars
│ └── all.yml
├── converge.yml
...
Pruebas
Este rol se prueba utilizando Ansible Molecule. Las pruebas se lanzan automáticamente en Github Actions después de cada commit y PR.
Esta configuración de molécula:
- Ejecutará Yamllint y Ansible Lint
- Creará tres contenedores Docker, uno primario (
ns1
), uno secundario (ns2
) y un retransmisor (ns3
) - escenario de moléculadefault
- Ejecutará una verificación de sintaxis
- Aplicará el rol con un playbook de prueba y comprobará la idempotencia
- Ejecutará pruebas de aceptación con el playbook de verificación
- Creará dos contenedores Docker adicionales, uno primario (
ns4
) y uno secundario (ns5
) y ejecutará el escenarioshared_inventory
Este proceso se repite para todas las distribuciones de Linux soportadas.
Entorno de prueba local
Para ejecutar las pruebas de aceptación en este rol localmente, puedes instalar las herramientas necesarias en tu máquina, o usar esta configuración reproducible en una VM de VirtualBox (configurada con Vagrant): https://github.com/bertvv/ansible-testenv.
Pasos para instalar las herramientas manualmente:
- Docker debe estar instalado en tu máquina.
- Como recomienda Molecule, crea un entorno virtual de python.
- Instala las herramientas de software
python3 -m pip install molecule molecule-docker docker netaddr dnspython yamllint ansible-lint
. - Navega a la raíz del directorio del rol y ejecuta
molecule test
.
Molecule elimina automáticamente los contenedores después de una prueba. Si deseas revisar los contenedores tú mismo, ejecuta molecule converge
seguido de molecule login --host HOSTNAME
.
Los contenedores Docker se basan en imágenes creadas por Jeff Geerling, específicamente para pruebas de Ansible (busca imágenes nombradas geerlingguy/docker-DISTRO-ansible
). Puedes usar cualquiera de sus imágenes, pero solo se admiten las distribuciones mencionadas en meta/main.yml.
La configuración predeterminada iniciará tres contenedores de Centos 8 (la plataforma primaria soportada en este momento). Elige otra distribución estableciendo la variable MOLECULE_DISTRO
con el comando, por ejemplo:
MOLECULE_DISTRO=debian9 molecule test
o
MOLECULE_DISTRO=debian9 molecule converge
Puedes ejecutar las pruebas de aceptación en todos los servidores con molecule verify
.
Las pruebas de verificación se realizan utilizando el módulo de búsqueda "dig" consultando registros dns y validando respuestas. Esto requiere comunicación de red directa entre el nodo de controlador Ansible (tu máquina que ejecuta Ansible) y el contenedor docker objetivo.
NOTA
Las pruebas de verificación de molécula fallarán si Docker está ejecutándose en MacOS, ya que MacOS no puede acceder a la IP del contenedor directamente. Este es un problema conocido. Ver #2670.
Solución alternativa:
- Ejecuta el linter de molécula:
molecule lint
. - Provisióna los contenedores:
molecule converge
. - Conéctate al contenedor:
molecule login --host ns1
. - Ve al directorio del rol:
cd /etc/ansible/roles/bertvv.bind
. - Ejecuta el playbook de verificación:
ansible-playbook -c local -i "`hostname`," -i molecule/default/inventory.ini molecule/default/verify.yml
- Repite los pasos 2-4 para
ns2
yns3
.
Licencia
BSD
Contribuidores
Este rol solo pudo ser realizado gracias a las contribuciones de muchos. Si tienes una idea para mejorarlo aún más, ¡no dudes en participar!
Los problemas, solicitudes de características, ideas, sugerencias, etc., se pueden publicar en la sección de problemas.
Las solicitudes de extracción también son muy bienvenidas. Por favor, crea una rama de tema para tus cambios propuestos. Si no lo haces, esto creará conflictos en tu fork después de la fusión. ¡No dudes en agregarte a la lista de contribuyentes a continuación en tu PR!
Mantenedores:
Contribuidores:
- Aido
- Angel Barrera
- B. Verschueren
- Boris Momčilović
- Brad Durrow
- Christopher Hicks
- David J. Haines
- Fabio Rocha
- Fazle Arefin
- flora-five
- Greg Cockburn
- Guillaume Darmont
- itbane
- jadjay
- Jascha Sticher
- Joanna Delaporte
- Jörg Eichhorn
- Jose Taas
- Lennart Weller
- Loic Dachary
- Mario Ciccarelli
- Miroslav Hudec
- Otto Sabart
- Paulius Mazeika
- Paulo E. Castro
- Peter Janes
- psa
- Rafael Bodill
- Rayford Johnson
- Robin Ophalvens
- Romuald
- roumano
- Shawn Wilsher
- Tom Meinlschmidt
- Jascha Sticher
- Zephyr82
Sets up ISC BIND as an authoritative DNS server for one or more domains (primary and/or secondary).
ansible-galaxy install bertvv.bind