diff --git a/README.md b/README.md
index 3edfbf7..df69768 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,128 @@
-# role_modele
+# role_dnsmasq
-Modèle
\ No newline at end of file
+Ce rôle permet d'installer et configurer dnsmasq.
+
+## Variables
+
+### dnsmasq_domain
+
+Nom de domain utilisé pour qualifier les noms courts.
+
+*Valeur par défaut: aucune*
+
+### dnsmasq_servers
+
+Liste d'adresses IP auxquelles les requêtes DNS sont transmises si dnsmasq ne porte pas le domaine.
+
+*Valeur par défaut: aucune*
+
+### dnsmasq_hosts
+
+Liste d'IP ou de noms d'hôtes servant de serveur DNS.
+
+*Valeur par défaut: aucune*
+
+### dnsmasq_host_ips
+
+Liste des IP de l'hôte.
+
+*Valeur par défaut: aucune*
+
+### dnsmasq_host_aliases
+
+Liste d'alias pour un hôte (*host_groups*).
+
+*Valeur par défaut: aucune*
+
+### dnsmasq_client_filename
+
+Nom du fichier pour le client.
+
+*Valeur par défaut: `{{ inventory_hostname }}`*
+
+### dnsmasq_client_hostname
+
+Nom d'hôte du client.
+
+*Valeur par défaut: `{{ inventory_hostname }} {{ inventory_hostname_short }}`*
+
+### dnsmasq_specifics
+
+Liste de dictionnaires contenant le nom d'hôte, les alias et la liste d'IP associées.
+
+*Valeur par défaut: aucune*
+
+## Exemple d'utilisation
+
+### inventory.yml
+
+```yaml
+---
+
+all:
+ hosts:
+ host1.ykn.local:
+ host2.ykn.local:
+ children:
+ dnsservers:
+ hosts:
+ dnsmasq1.ykn.local:
+ dnsmasq2.ykn.local:
+```
+
+### group_vars/all.yml
+
+```yaml
+---
+
+dnsmasq_hosts: "{{ groups['dnsservers'] }}"
+```
+
+
+### group_vars/dnsservers.yml
+
+```yaml
+---
+
+dnsmasq_domain: ykn.local
+dnsmasq_servers:
+ - 127.0.0.1#53000
+ - ::1#53000
+```
+
+### host_vars/host1.ykn.local.yml
+
+```yaml
+---
+
+dnsmasq_host_ipv4: [192.168.50.6]
+dnsmasq_host_ipv6: [fd00:ff50::d006]
+
+dnsmasq_host_alias:
+ - monsuperhost1.ykn.local
+ - monsuperhost1
+ - toto.ykn.local
+ - toto
+```
+
+### playbook.yml
+
+```yaml
+---
+
+- name: Déployer les serveurs DNS
+ hosts: dnsservers
+ roles:
+ - name: stubby
+ - name: dnsmasq
+ - name: nftables
+
+- name: Gérer l'enregistrement DNS
+ hosts: 'all:!dnsservers'
+ gather_facts: false
+ tasks:
+ - name: Inclure le rôle
+ ansible.builtin.include_role:
+ name: dnsmasq
+ tasks_from: client
+```
diff --git a/defaults/main.yml b/defaults/main.yml
new file mode 100644
index 0000000..8dcc4ec
--- /dev/null
+++ b/defaults/main.yml
@@ -0,0 +1,36 @@
+---
+# defaults file for dnsmasq
+
+# Directory to deploy override conf of systemd-resolved
+dnsmasq_resolved_directory: /etc/systemd/resolved.conf.d
+
+# Directory to deploy configuration
+dnsmasq_conf_directory: /etc/dnsmasq.d
+
+# Directory to deploy records files
+dnsmasq_records_directory: "{{ dnsmasq_conf_directory }}/records"
+
+# Configuration
+dnsmasq_interface: "{{ ansible_facts['default_ipv4']['interface'] }}"
+dnsmasq_domain: ""
+dnsmasq_servers: []
+dnsmasq_rev_servers: []
+dnsmasq_bogus_priv_enabled: true
+dnsmasq_rebind_domains: []
+
+dnsmasq_hosts: []
+
+dnsmasq_host_ips: []
+dnsmasq_host_aliases: []
+
+dnsmasq_client_filename: "{{ inventory_hostname }}"
+dnsmasq_client_hostname: "{{ inventory_hostname }} {{ inventory_hostname_short }}"
+
+# Ansible group automatically used in records file
+dnsmasq_ansible_group: ""
+
+# IPv6 subnet
+dnsmasq_ipv6_subnet: ""
+
+# Specific records
+dnsmasq_specifics: []
diff --git a/handlers/main.yml b/handlers/main.yml
new file mode 100644
index 0000000..a6389b5
--- /dev/null
+++ b/handlers/main.yml
@@ -0,0 +1,32 @@
+---
+# handlers file for dnsmasq
+
+- name: Apply installation
+ ansible.builtin.command:
+ argv:
+ - /usr/bin/rpm-ostree
+ - apply-live
+ become: true
+
+- name: Restart systemd-resolved.service
+ ansible.builtin.systemd_service:
+ name: systemd-resolved.service
+ state: restarted
+ become: true
+
+- name: Restart dnsmasq.service
+ ansible.builtin.systemd_service:
+ name: dnsmasq.service
+ state: restarted
+ become: true
+ register: dnsmasq_restarted
+
+- name: Restart dnsmasq.service on dns servers
+ ansible.builtin.systemd_service:
+ name: dnsmasq.service
+ state: restarted
+ when: dnsmasq_restarted is undefined
+ become: true
+ loop: "{{ dnsmasq_hosts }}"
+ delegate_to: "{{ item }}"
+ run_once: true
diff --git a/meta/main.yml b/meta/main.yml
index f42fb14..29fb6a3 100644
--- a/meta/main.yml
+++ b/meta/main.yml
@@ -1,14 +1,15 @@
galaxy_info:
+ namespace: ykn
author: pulsar89.5
- description: Rôle modèle
+ description: Rôle de déploiement de dnsmasq
license: GPL-3.0-or-later
- min_ansible_version: 2.1
+ min_ansible_version: '2.1'
platforms:
- - name: Debian (LXD)
+ - name: Debian
versions:
- - 11
+ - all
dependencies: []
diff --git a/tasks/configuration.yml b/tasks/configuration.yml
new file mode 100644
index 0000000..26c7bc3
--- /dev/null
+++ b/tasks/configuration.yml
@@ -0,0 +1,61 @@
+---
+# tasks file for dnsmasq
+
+- name: Create path to override systemd-resolved
+ ansible.builtin.file:
+ path: "{{ dnsmasq_resolved_directory }}"
+ state: directory
+ owner: root
+ group: root
+ mode: u=rwX,g=rX,o=rX
+ become: true
+ notify: Restart systemd-resolved.service
+
+- name: Disable stub resolver of systemd-resolved
+ ansible.builtin.template:
+ src: stub-listener.conf.j2
+ dest: "{{ dnsmasq_resolved_directory }}/stub-listener.conf"
+ owner: root
+ group: root
+ mode: u=rw,g=r,o=r
+ become: true
+ notify: Restart systemd-resolved.service
+
+- name: Flush handlers
+ meta: flush_handlers
+
+- name: Create records directory
+ ansible.builtin.file:
+ path: "{{ dnsmasq_records_directory }}"
+ state: directory
+ owner: dnsmasq
+ group: root
+ mode: u=rwX,g=rX,o=rX
+ become: true
+
+- name: Remove old configuration
+ ansible.builtin.file:
+ path: "{{ dnsmasq_conf_directory }}/cache.conf"
+ state: absent
+ become: true
+
+- name: Deploy configuration
+ ansible.builtin.template:
+ src: dnsmasq.conf.j2
+ dest: "{{ dnsmasq_conf_directory }}/dns.conf"
+ owner: root
+ group: root
+ mode: u=rw,g=r,o=r
+ become: true
+ notify: Restart dnsmasq.service
+
+- name: Deploy specific records
+ ansible.builtin.template:
+ src: "{{ role_path }}/templates/records_specific.conf.j2"
+ dest: "{{ dnsmasq_records_directory }}/specific.conf"
+ owner: dnsmasq
+ group: root
+ mode: u=rw,g=r,o=r
+ when: dnsmasq_specifics | length > 0
+ become: true
+ notify: Restart dnsmasq.service
diff --git a/tasks/installation.yml b/tasks/installation.yml
new file mode 100644
index 0000000..fefda03
--- /dev/null
+++ b/tasks/installation.yml
@@ -0,0 +1,32 @@
+---
+# tasks file for dnsmasq
+
+- name: Install dnsmasq
+ ansible.builtin.package:
+ name: dnsmasq
+ when: ansible_facts['pkg_mgr'] == "apt"
+ become: true
+
+- name: Install dnsmasq
+ ansible.builtin.command:
+ argv:
+ - /usr/bin/rpm-ostree
+ - install
+ - --allow-inactive
+ - --assumeyes
+ - --idempotent
+ - dnsmasq
+ creates: /usr/sbin/dnsmasq
+ when: ansible_facts['pkg_mgr'] == "atomic_container"
+ become: true
+ notify: Apply installation
+
+- name: Flush handlers
+ meta: flush_handlers
+
+- name: Enable dnsmasq.service
+ ansible.builtin.systemd_service:
+ name: dnsmasq.service
+ masked: false
+ enabled: true
+ become: true
diff --git a/tasks/main.yml b/tasks/main.yml
new file mode 100644
index 0000000..d6489b2
--- /dev/null
+++ b/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+# tasks file for dnsmasq
+
+- name: Include installation tasks
+ ansible.builtin.include_tasks:
+ file: installation.yml
+
+- name: Import configuration tasks
+ ansible.builtin.import_tasks:
+ file: configuration.yml
+
+- name: Import records deployment tasks
+ ansible.builtin.import_tasks:
+ file: records.yml
diff --git a/tasks/records.yml b/tasks/records.yml
new file mode 100644
index 0000000..6b010c8
--- /dev/null
+++ b/tasks/records.yml
@@ -0,0 +1,18 @@
+---
+# tasks file for security
+
+- name: Deploy records from ansible group
+ ansible.builtin.template:
+ src: "{{ role_path }}/templates/records_auto.conf.j2"
+ dest: "{{ dnsmasq_records_directory }}/auto-{{ dnsmasq_ansible_group }}.conf"
+ owner: dnsmasq
+ group: root
+ mode: u=rw,g=r,o=r
+ when: dnsmasq_hosts | length > 0
+ become: true
+ delegate_to: "{{ dnsserver }}"
+ loop: "{{ dnsmasq_hosts }}"
+ loop_control:
+ loop_var: dnsserver
+ run_once: true
+ notify: Restart dnsmasq.service on dns servers
diff --git a/templates/dnsmasq.conf.j2 b/templates/dnsmasq.conf.j2
new file mode 100644
index 0000000..0fa638d
--- /dev/null
+++ b/templates/dnsmasq.conf.j2
@@ -0,0 +1,50 @@
+# {{ ansible_managed }}
+
+# Listen only on the specified interface(s)
+interface={{ dnsmasq_interface }}
+
+# Tells dnsmasq to never forward A or AAAA queries for plain names
+domain-needed
+
+# Specifies DNS domains
+domain={{ dnsmasq_domain }}
+local=/{{ dnsmasq_domain }}/
+
+# Add the domain to simple names
+expand-hosts
+
+# Disable negative caching
+no-negcache
+
+# Don't read /etc/resolv.conf
+no-resolv
+
+# Don't read the hostnames in /etc/hosts
+no-hosts
+
+# Specify upstream servers directly
+{% for server in dnsmasq_servers %}
+server={{ server }}
+{% endfor %}
+
+# Specify upstream servers directly (PTR)
+{% for server in dnsmasq_rev_servers %}
+rev-server={{ server }}
+{% endfor %}
+
+# Do not detect and block dns-rebind on queries to these domains
+{% for domain in dnsmasq_rebind_domains %}
+rebind-domain-ok=/{{ domain }}/
+{% endfor %}
+
+# Reject (and log) addresses from upstream nameservers which are in the private ranges
+stop-dns-rebind
+
+# Exempt 127.0.0.0/8 and ::1 from rebinding checks
+rebind-localhost-ok
+
+# Set the size of dnsmasq's cache
+cache-size=4096
+
+# Additional hosts file. Read the specified file as well as /etc/hosts
+addn-hosts={{ dnsmasq_records_directory }}
diff --git a/templates/records_auto.conf.j2 b/templates/records_auto.conf.j2
new file mode 100644
index 0000000..1e3a302
--- /dev/null
+++ b/templates/records_auto.conf.j2
@@ -0,0 +1,12 @@
+# {{ ansible_managed }}
+
+{%- for host in groups[dnsmasq_ansible_group] | sort %}
+{%- set ipv4 = hostvars[host]['ansible_host'] %}
+{%- set ipv6_prefix = dnsmasq_ipv6_subnet | split('/') | first %}
+{%- set ipv6_suffix = hostvars[host]['ansible_host'] | split('.') | last %}
+{%- set aliases = [host] + hostvars[host].get('dnsmasq_host_aliases', []) %}
+
+## {{ host }}
+{{ ipv4 }} {{ aliases | join(' ') }}
+{{ ipv6_prefix }}{{ ipv6_suffix }} {{ aliases | join(' ') }}
+{% endfor %}
diff --git a/templates/records_specific.conf.j2 b/templates/records_specific.conf.j2
new file mode 100644
index 0000000..377737f
--- /dev/null
+++ b/templates/records_specific.conf.j2
@@ -0,0 +1,9 @@
+# {{ ansible_managed }}
+
+{%- for specific in dnsmasq_specifics %}
+
+## {{ specific.hostname }}
+{% for ip in specific.ips %}
+{{ ip }} {{ specific.hostname }}
+{% endfor %}
+{% endfor %}
diff --git a/templates/stub-listener.conf.j2 b/templates/stub-listener.conf.j2
new file mode 100644
index 0000000..2590179
--- /dev/null
+++ b/templates/stub-listener.conf.j2
@@ -0,0 +1,4 @@
+# {{ ansible_managed }}
+
+[Resolve]
+DNSStubListener=no