add unbound_resolver role

This commit is contained in:
kirby 2025-05-28 11:15:47 +02:00
parent 6679277418
commit dd1900fffe
10 changed files with 275 additions and 0 deletions

View File

@ -0,0 +1,13 @@
extends: default
rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
line-length: disable
# NOTE(retr0h): Templates no longer fail this lint rule.
# Uncomment if running old Molecule templates.
# truthy: disable

View File

@ -0,0 +1,81 @@
# Unbound
This role install and configure an Unbound resolver.
It also install a prometheus exporter compiled from [letsencrypt/unbound_exporter](https://github.com/letsencrypt/unbound_exporter)
## Targets
- Debian
## Role variables
- ``unbound_interfaces``: list of interfaces Unbound has to listen on. If not specified, Unbound will listen on 0.0.0.0.
- ``unbound_authorized_cidrs``: list of authorized CIDRS to query the resolver. As Unbound rejects everything by default, if none is set, the resolver won't answer to anyone.
- ``unbound_threads``: number of threads Unbound runs on. (default: 1)
- ``unbound_cache_size``: size of Unbound cache, in Mb. (default: 100)
- ``unbound_zones``: dictionnary about zones that need to be forwarded to another DNS server. It contains info for every managed zone :
``name``: name of the zone
``forward_ip``: list of the servers to forward queries to
``private``: boolean, has to be specified for dummies zones (ex: .priv). It disables DNSSEC validation for thoses zones.
Zones that are not explicitely specified in forwards will be forwarded to root servers.
## Prometheus exporter
* For the exporter to work properly you need to run the following command on each resolver :
```
unbound-control-setup
```
* You also need to ensure that the "extended-statistics: yes" directive is in the conf (it is here).
* The exporter configuration can be change by modifying the systemd service template.
## Unbound logging
In order to enable query log, you need to do the following :
* Add the following directives to the config :
```
logfile: "/var/log/unbound/unbound.log"
log-time-ascii: yes
log-queries: yes
log-replies: yes # will log informations about the reply, slows response time.
```
* Add the following line in /etc/apparmor.d/usr.sbin.unbound (with the comma) :
```
/var/log/unbound/unbound.log rw,
```
* Run the following commands to create both directory and file for logging :
```
mkdir /var/log/unbound
touch /var/log/unbound/unbound.log
chown -R unbound:unbound /var/log/unbound
apparmor_parser -r /etc/apparmor.d/usr.sbin.unbound
```
* Restart unbound.
## Example
In this example, we specify to forward queries for domain aaa.com to xxx.xxx.xxx.xxx, bbb.com to yyy.yyy.yyy.yyy or xxx.xxx.xxx.xxx as a failover, and requests for a private zone to zzz.zzz.zzz.zzz :
```yml
unbound_interfaces:
- "aaa.aaa.aaa.aaa"
unbound_authorized_cidrs:
- "aaa.aaa.aaa.0/24"
- "bbb.bbb.bbb.bbb/32"
unbound_threads: 2
unbound_cache_size: 1536
unbound_zones:
- name: "aaa.com"
forward_ip:
- xxx.xxx.xxx.xxx
- name: "bbb.com"
forward_ip:
- yyy.yyy.yyy.yyy
- xxx.xxx.xxx.xxx
- name: "mysuperprivatezone.priv"
forward_ip:
- zzz.zzz.zzz.zzz
private: true
```

View File

@ -0,0 +1,6 @@
---
unbound_interfaces:
- "0.0.0.0"
unbound_threads: 1
unbound_cache_size: 100
unbound_loglevel: 1

View File

@ -0,0 +1,10 @@
/var/log/unbound/*.log {
weekly
missingok
rotate 52
compress
notifempty
postrotate
/usr/sbin/unbound-control log_reopen
endscript
}

Binary file not shown.

View File

@ -0,0 +1,15 @@
---
- name: Daemon reload
ansible.builtin.systemd_service:
daemon_reload: true
- name: Restart unbound exporter
ansible.builtin.systemd_service:
name: unbound_exporter
state: restarted
- name: Reload Unbound
ansible.builtin.systemd_service:
name: unbound
state: reloaded

View File

@ -0,0 +1,76 @@
---
- name: Set specific variables for distributions
ansible.builtin.include_vars: "{{ item }}"
with_first_found:
- files:
- '{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml' # CentOS-6.5
- '{{ ansible_os_family }}-{{ ansible_distribution_version }}.yml' # RedHat-6.5
- '{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml' # CentOS-6
- '{{ ansible_os_family }}-{{ ansible_distribution_major_version }}.yml' # RedHat-6
- '{{ ansible_distribution }}.yml' # CentOS
- '{{ ansible_os_family }}.yml' # RedHat
- 'default.yml'
- name: Enhance socket buffer size in UDP
ansible.posix.sysctl:
name: "{{ item }}"
value: 4194304
reload: true
with_items:
- "net.core.rmem_max"
- "net.core.wmem_max"
- name: Install Unbound
ansible.builtin.apt:
name: "{{ unbound_package }}"
update_cache: true
state: present
when: ansible_os_family == "Debian"
- name: Setup service configuration
ansible.builtin.template:
src: unbound.conf.j2
dest: /etc/unbound/unbound.conf.d/custom.conf
owner: unbound
group: unbound
mode: "0755"
notify: Reload Unbound
- name: Set permission on conf directory
ansible.builtin.file:
path: /etc/unbound
owner: unbound
group: unbound
recurse: true
- name: Ensure service is enabled at boot and started
ansible.builtin.systemd_service:
name: "unbound"
enabled: true
state: started
- name: Deploy unbound exporter
ansible.builtin.copy:
src: unbound_exporter
dest: /usr/local/bin/unbound_exporter
mode: "0755"
- name: Deploy unbound exporter service
ansible.builtin.template:
src: unbound_exporter.service.j2
dest: /etc/systemd/system/unbound_exporter.service
owner: root
group: root
mode: "0644"
notify:
- Daemon reload
- Restart unbound exporter
- name: Deploy logrotate config file
ansible.builtin.copy:
src: logrotate
dest: /etc/logrotate.d/unbound
owner: root
group: root
mode: "0644"

View File

@ -0,0 +1,58 @@
## {{ ansible_managed }}
server:
verbosity: {{unbound_loglevel }}
extended-statistics: yes
do-udp: yes
do-tcp: yes
do-ip6: no
num-threads: {{ unbound_threads }}
msg-cache-slabs: {{ unbound_threads }}
rrset-cache-slabs: {{ unbound_threads }}
infra-cache-slabs: {{ unbound_threads }}
key-cache-slabs: {{ unbound_threads }}
rrset-cache-size: {{ unbound_cache_size }}m
key-cache-size: {{ ((unbound_cache_size/2) | int) }}m
msg-cache-size: {{ ((unbound_cache_size/2) | int) }}m
neg-cache-size: {{ ((unbound_cache_size/4) | int) }}m
prefetch: yes
cache-min-ttl: 300
cache-max-ttl: 86400
outgoing-range: 8192
num-queries-per-thread: 4096
so-rcvbuf: 4m
so-sndbuf: 4m
so-reuseport: yes
rrset-roundrobin: yes
val-log-level:1
{% for iface in unbound_interfaces %}
interface: {{ iface }}
{% endfor %}
{% for cidr in unbound_authorized_cidrs %}
access-control: {{ cidr }} allow
{% endfor %}
{% if unbound_zones is defined %}
{% for zone in unbound_zones %}
{% if zone.private is defined and zone.private %}
domain-insecure: "{{ zone.name }}"
{% endif %}
{% endfor %}
{% for zone in unbound_zones %}
forward-zone:
name: "{{ zone.name }}"
{% for fwa in zone.forward_ip %}
forward-addr: {{ fwa }}
{% endfor -%}
{% endfor %}
{% endif %}

View File

@ -0,0 +1,13 @@
[Unit]
Description=Unbound exporter for prometheus
Documentation=https://github.com/letsencrypt/unbound_exporter
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/unbound_exporter -unbound.host="unix:///run/unbound.ctl"
Restart=always
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,3 @@
---
unbound_package: "unbound"