From fd7394941204bc33b870bcbbf6551690db79688e Mon Sep 17 00:00:00 2001 From: Ruakij Date: Thu, 8 Oct 2026 09:19:51 +0000 Subject: [PATCH] Whitelist the public_ips of every inventory host in crowdsec and keep a LAPI allowlist equal to the whitelist --- crowdsec/defaults/main.yml | 9 +++++++- crowdsec/tasks/main.yml | 34 ++++++++++++++++++++++++++++ crowdsec/templates/whitelist.yaml.j2 | 4 ++-- crowdsec/vars/main.yml | 4 ++++ 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 crowdsec/vars/main.yml diff --git a/crowdsec/defaults/main.yml b/crowdsec/defaults/main.yml index 140c6c2..30212ae 100644 --- a/crowdsec/defaults/main.yml +++ b/crowdsec/defaults/main.yml @@ -10,8 +10,15 @@ crowdsec: scenarios: {} # path below /etc/crowdsec -> content, for local parsers and scenarios. local_files: {} - # name -> CIDR (single addresses as /32 or /128) never acted upon by this agent. + # name -> CIDR (single addresses as /32 or /128) never acted upon. Joined by + # the public_ips (same format) of every inventory host, then whitelisted by + # this agent and, when lapi_allowlist is set, allowlisted on the LAPI. whitelist: {} + # LAPI allowlist kept equal to the whitelist; it also drops alerts on ranges + # holding a whitelisted address, which a parser whitelist cannot. + lapi_allowlist: "" + # Host whose k3s kubectl reaches the LAPI pod (crowdsec/crowdsec-lapi). + lapi_kubectl_host: "" # name -> acquisition datasource, written to /etc/crowdsec/acquis.d/.yaml. acquisition: {} # packagecloud has no trixie suite yet; the bookworm build is static Go. diff --git a/crowdsec/tasks/main.yml b/crowdsec/tasks/main.yml index 02570d4..623587a 100644 --- a/crowdsec/tasks/main.yml +++ b/crowdsec/tasks/main.yml @@ -187,3 +187,37 @@ enabled: true state: started loop: [crowdsec.service, crowdsec-firewall-bouncer.service] + +- name: Sync the LAPI allowlist + when: crowdsec.lapi_allowlist | length > 0 + run_once: true + delegate_to: "{{ crowdsec.lapi_kubectl_host }}" + vars: + crowdsec_lapi_cscli: k3s kubectl -n crowdsec exec deploy/crowdsec-lapi -c crowdsec-lapi -- cscli + block: + - name: Read the LAPI allowlist + ansible.builtin.command: "{{ crowdsec_lapi_cscli }} allowlists inspect {{ crowdsec.lapi_allowlist }} -o json" + register: crowdsec_allowlist_json + changed_when: false + failed_when: false + check_mode: false + + - name: Create the LAPI allowlist + ansible.builtin.command: >- + {{ crowdsec_lapi_cscli }} allowlists create {{ crowdsec.lapi_allowlist }} + -d "Internal ranges and the public addresses of all hosts, managed by Ansible" + when: crowdsec_allowlist_json.rc != 0 + + # cscli stores single addresses without their /32 or /128. + - name: Update the LAPI allowlist + ansible.builtin.command: "{{ crowdsec_lapi_cscli }} allowlists {{ item.action }} {{ crowdsec.lapi_allowlist }} {{ item.cidrs | join(' ') }}" + vars: + crowdsec_allowlist_wanted: "{{ crowdsec_whitelist | map('regex_replace', '/(32|128)$', '') | list }}" + crowdsec_allowlist_present: >- + {{ ((crowdsec_allowlist_json.stdout | default('{}', true) | from_json).get('items') or []) | map(attribute='value') | list }} + loop: + - { action: add, cidrs: "{{ crowdsec_allowlist_wanted | difference(crowdsec_allowlist_present) }}" } + - { action: remove, cidrs: "{{ crowdsec_allowlist_present | difference(crowdsec_allowlist_wanted) }}" } + loop_control: + label: "{{ item.action }} {{ item.cidrs | join(' ') }}" + when: item.cidrs | length > 0 diff --git a/crowdsec/templates/whitelist.yaml.j2 b/crowdsec/templates/whitelist.yaml.j2 index 072ca8f..86f83cc 100644 --- a/crowdsec/templates/whitelist.yaml.j2 +++ b/crowdsec/templates/whitelist.yaml.j2 @@ -1,9 +1,9 @@ # {{ ansible_managed }} name: local/host-whitelist -description: Internal ranges and admin addresses +description: Internal ranges and the public addresses of all hosts whitelist: reason: internal or admin source cidr: -{% for cidr in crowdsec.whitelist | dict2items | rejectattr('value', 'none') | map(attribute='value') | unique %} +{% for cidr in crowdsec_whitelist %} - "{{ cidr }}" {% endfor %} diff --git a/crowdsec/vars/main.yml b/crowdsec/vars/main.yml new file mode 100644 index 0000000..36c6064 --- /dev/null +++ b/crowdsec/vars/main.yml @@ -0,0 +1,4 @@ +--- +crowdsec_whitelist: >- + {{ (crowdsec.whitelist | dict2items | rejectattr('value', 'none') | map(attribute='value') | list + + groups['all'] | map('extract', hostvars, 'public_ips') | select('defined') | flatten) | unique }}