Whitelist the public_ips of every inventory host in crowdsec and keep a LAPI allowlist equal to the whitelist

This commit is contained in:
2026-10-08 09:19:51 +00:00
parent d345ccf585
commit fd73949412
4 changed files with 48 additions and 3 deletions
+8 -1
View File
@@ -10,8 +10,15 @@ crowdsec:
scenarios: {} scenarios: {}
# path below /etc/crowdsec -> content, for local parsers and scenarios. # path below /etc/crowdsec -> content, for local parsers and scenarios.
local_files: {} 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: {} 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/<name>.yaml. # name -> acquisition datasource, written to /etc/crowdsec/acquis.d/<name>.yaml.
acquisition: {} acquisition: {}
# packagecloud has no trixie suite yet; the bookworm build is static Go. # packagecloud has no trixie suite yet; the bookworm build is static Go.
+34
View File
@@ -187,3 +187,37 @@
enabled: true enabled: true
state: started state: started
loop: [crowdsec.service, crowdsec-firewall-bouncer.service] 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
+2 -2
View File
@@ -1,9 +1,9 @@
# {{ ansible_managed }} # {{ ansible_managed }}
name: local/host-whitelist name: local/host-whitelist
description: Internal ranges and admin addresses description: Internal ranges and the public addresses of all hosts
whitelist: whitelist:
reason: internal or admin source reason: internal or admin source
cidr: cidr:
{% for cidr in crowdsec.whitelist | dict2items | rejectattr('value', 'none') | map(attribute='value') | unique %} {% for cidr in crowdsec_whitelist %}
- "{{ cidr }}" - "{{ cidr }}"
{% endfor %} {% endfor %}
+4
View File
@@ -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 }}