diff --git a/README.md b/README.md index 3edfbf7..ff2ad45 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,47 @@ -# role_modele +# role_nftables -Modèle \ No newline at end of file +Ce rôle permet d'installer et configurer nftables. + +## Variables + +### nftables_rules_* + +Liste contenant un nom de fichier et une liste de règles. Les règles doivent être au format nftables. + +*Valeur par défaut: aucune* + +### nftables_tables_* + +Liste contenant un nom de fichier et la configuration de la table. La table doit être au format nftables. + +*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: +``` + +### host_vars/host1.ykn.local.yml + +```yaml +--- + +nftables_rules: + - filename: ansible + rules: + - ip saddr 192.168.50.12 tcp dport 22 accept + - ip6 saddr fd00:ff50::d012 tcp dport 22 accept +``` diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..bedd20a --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,5 @@ +--- +# defaults file for nftables + +nftables_rules: [] +nftables_tables: [] diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..b4120a6 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,10 @@ +--- +# handlers file for nftables + +- name: Redémarrer nftables.service + ansible.builtin.systemd: + state: restarted + enabled: true + masked: false + name: nftables.service + become: true diff --git a/meta/main.yml b/meta/main.yml index c58bebf..23a4d0c 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,7 +1,7 @@ galaxy_info: namespace: ykn author: pulsar89.5 - description: Rôle modèle + description: Rôle de déploiement de nftables (pare-feu) license: GPL-3.0-or-later diff --git a/tasks/configuration.yml b/tasks/configuration.yml new file mode 100644 index 0000000..026396f --- /dev/null +++ b/tasks/configuration.yml @@ -0,0 +1,54 @@ +--- +# tasks file for nftables + +- name: Déployer la configuration générale + ansible.builtin.template: + owner: root + group: root + mode: u=rw,g=,o= + src: nftables.conf.j2 + dest: /etc/nftables.conf + become: true + notify: Redémarrer nftables.service + +- name: Construire la liste des règles + ansible.builtin.set_fact: + nftables_rules: "{{ nftables_rules + specific }}" + when: specific | length > 0 + loop: "{{ lookup('ansible.builtin.varnames', '^nftables_rules_.+', wantlist=True) }}" + vars: + specific: "{{ lookup('ansible.builtin.vars', item, default='') }}" + +- name: Construire la liste des tables + ansible.builtin.set_fact: + nftables_tables: "{{ nftables_tables + specific }}" + when: specific | length > 0 + loop: "{{ lookup('ansible.builtin.varnames', '^nftables_tables_.+', wantlist=True) }}" + vars: + specific: "{{ lookup('ansible.builtin.vars', item, default='') }}" + +- name: Déployer les règles + ansible.builtin.template: + owner: root + group: root + mode: u=rw,g=,o= + src: "{{ role_path }}/templates/rules.conf.j2" + dest: "/srv/nftables/rules_{{ item.filename }}.conf" + loop: "{{ nftables_rules }}" + loop_control: + label: "{{ item.filename }}" + become: true + notify: Redémarrer nftables.service + +- name: Déployer les tables + ansible.builtin.template: + owner: root + group: root + mode: u=rw,g=,o= + src: "{{ role_path }}/templates/tables.conf.j2" + dest: "/srv/nftables/tables_{{ item.filename }}.conf" + loop: "{{ nftables_tables }}" + loop_control: + label: "{{ item.filename }}" + become: true + notify: Redémarrer nftables.service diff --git a/tasks/installation.yml b/tasks/installation.yml new file mode 100644 index 0000000..6c30564 --- /dev/null +++ b/tasks/installation.yml @@ -0,0 +1,17 @@ +--- +# tasks file for nftables + +- name: Installer le paquet + become: true + ansible.builtin.package: + state: present + name: nftables + +- name: Créer le dossier contenant la configuration + ansible.builtin.file: + owner: root + group: root + mode: u=rwx,g=rx,o=rx + state: directory + path: /srv/nftables + become: true diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..a157ecc --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,8 @@ +--- +# tasks file for nftables + +- name: Importer les tâches d'installation + ansible.builtin.import_tasks: installation.yml + +- name: Importer les tâches de configuration + ansible.builtin.import_tasks: configuration.yml diff --git a/templates/nftables.conf.j2 b/templates/nftables.conf.j2 new file mode 100644 index 0000000..8df2dd3 --- /dev/null +++ b/templates/nftables.conf.j2 @@ -0,0 +1,28 @@ +#!/usr/sbin/nft -f +# {{ ansible_managed }} + +flush ruleset + +table inet filter { + chain input { + type filter hook input priority 0; + + # accept any localhost traffic + iif lo accept + + # accept traffic originated from us + ct state established,related accept + + # accept neighbour discovery otherwise IPv6 connectivity breaks. + ip6 nexthdr icmpv6 icmpv6 type {nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert} accept + + # include specifics rules + include "/srv/nftables/rules_*.conf" + + # count and drop any other traffic + counter drop + } +} + +# include more tables +include "/srv/nftables/tables_*.conf" diff --git a/templates/rules.conf.j2 b/templates/rules.conf.j2 new file mode 100644 index 0000000..81e015c --- /dev/null +++ b/templates/rules.conf.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} + +{% for rule in item.rules %} +{{ rule }} +{% endfor %} diff --git a/templates/tables.conf.j2 b/templates/tables.conf.j2 new file mode 100644 index 0000000..cf8f928 --- /dev/null +++ b/templates/tables.conf.j2 @@ -0,0 +1,57 @@ +# {{ ansible_managed }} + +{% if + item.ipv4_rules.prerouting | length > 0 + or + item.ipv4_rules.postrouting | length > 0 +%} +table ip {{ item.filename }} { +{% if item.ipv4_rules.prerouting | length > 0 %} + chain prerouting { + type nat hook prerouting priority 0; + +{% for rule in item.ipv4_rules.prerouting %} + {{ rule }} +{% endfor %} + } +{% endif %} + +{% if item.ipv4_rules.postrouting | length > 0 %} + chain postrouting { + type nat hook postrouting priority 100; policy accept; + +{% for rule in item.ipv4_rules.postrouting %} + {{ rule }} +{% endfor %} + } +{% endif %} +} +{% endif %} + +{% if + item.ipv6_rules.prerouting | length > 0 + or + item.ipv6_rules.postrouting | length > 0 +%} +table ip6 {{ item.filename }} { +{% if item.ipv6_rules.prerouting | length > 0 %} + chain prerouting { + type nat hook prerouting priority 0; + +{% for rule in item.ipv6_rules.prerouting %} + {{ rule }} +{% endfor %} + } +{% endif %} + +{% if item.ipv6_rules.postrouting | length > 0 %} + chain postrouting { + type nat hook postrouting priority 100; policy accept; + +{% for rule in item.ipv6_rules.postrouting %} + {{ rule }} +{% endfor %} + } +{% endif %} +} +{% endif %}