diff --git a/ansible/arcodange/factory/playbooks/01_system.yml b/ansible/arcodange/factory/playbooks/01_system.yml index dab36e4..db55d7d 100644 --- a/ansible/arcodange/factory/playbooks/01_system.yml +++ b/ansible/arcodange/factory/playbooks/01_system.yml @@ -327,6 +327,7 @@ # format: json access: enabled: true + timezone: Europe/Paris # format: json podSecurityContext: runAsGroup: 65532 diff --git a/ansible/arcodange/factory/playbooks/tools/crowdsec.yml b/ansible/arcodange/factory/playbooks/tools/crowdsec.yml index bfe67da..fa63e20 100644 --- a/ansible/arcodange/factory/playbooks/tools/crowdsec.yml +++ b/ansible/arcodange/factory/playbooks/tools/crowdsec.yml @@ -5,77 +5,6 @@ # debugger: on_failed tasks: - - name: Récupérer le nom du pod CrowdSec LAPI - kubernetes.core.k8s_info: - kind: Pod - namespace: tools - label_selectors: - - k8s-app = crowdsec - - type = lapi - register: crowdsec_lapi_pods - - - name: Vérifier qu'un pod a été trouvé - assert: - that: crowdsec_lapi_pods.resources | length > 0 - fail_msg: "Aucun pod CrowdSec LAPI trouvé dans le namespace 'tools' avec les labels 'k8s-app=crowdsec, type=lapi'." - - - name: Définir le nom du pod CrowdSec LAPI - set_fact: - crowdsec_lapi_pod_name: "{{ crowdsec_lapi_pods.resources[0].metadata.name }}" - - - name: Récupérer la clé API du bouncer CrowdSec - kubernetes.core.k8s_exec: - namespace: tools - pod: "{{ crowdsec_lapi_pod_name }}" - container: crowdsec-lapi - command: > - cscli bouncers add traefik-plugin - register: bouncer_key_result - ignore_errors: yes - - - name: Supprimer le bouncer existant en cas d'échec - kubernetes.core.k8s_exec: - namespace: tools - pod: "{{ crowdsec_lapi_pod_name }}" - container: crowdsec-lapi - command: > - cscli bouncers delete traefik-plugin - when: bouncer_key_result.failed - - - name: Réessayer de récupérer la clé API - kubernetes.core.k8s_exec: - namespace: tools - pod: "{{ crowdsec_lapi_pod_name }}" - container: crowdsec-lapi - command: > - cscli bouncers add traefik-plugin - register: bouncer_key_result - when: bouncer_key_result.failed - - - name: Créer le Middleware Traefik pour CrowdSec - kubernetes.core.k8s: - state: present - definition: - apiVersion: traefik.io/v1alpha1 - kind: Middleware - metadata: - name: crowdsec - namespace: kube-system - spec: - plugin: - crowdsec-bouncer: - enabled: true - crowdsecMode: stream - crowdsecLapiScheme: http - crowdsecLapiHost: crowdsec-service.tools.svc.cluster.local:8080 - crowdsecLapiKey: "{{ bouncer_key_result.stdout_lines[2].strip() }}" - htttTimeoutSeconds: 60 - crowdsecAppsecEnabled: false - crowdsecAppsecHost: crowdsec:7422 - crowdsecAppsecFailureBlock: true - crowdsecAppsecUnreachableBlock: true - forwardedHeadersTrustedIPs: - - 10.0.10.23/32 - - 10.0.20.0/24 - clientTrustedIPs: - - 192.168.1.0/24 \ No newline at end of file + - name: Setup crowdsec middleware for traefik + include_role: + name: crowdsec \ No newline at end of file diff --git a/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/defaults/main.yml b/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/defaults/main.yml new file mode 100644 index 0000000..bd004f5 --- /dev/null +++ b/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/defaults/main.yml @@ -0,0 +1 @@ +traefik_pvc_name: traefik \ No newline at end of file diff --git a/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/tasks/inject_captcha_html.yml b/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/tasks/inject_captcha_html.yml new file mode 100644 index 0000000..4460234 --- /dev/null +++ b/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/tasks/inject_captcha_html.yml @@ -0,0 +1,94 @@ +--- +- name: Inject captcha.html into Traefik PVC + block: + + # --------------------- + # Scale to 0 + # --------------------- + - name: Scale Traefik to 0 + kubernetes.core.k8s_scale: + api_version: apps/v1 + kind: Deployment + namespace: kube-system + name: traefik + replicas: 0 + + # --------------------- + # Create Job + # --------------------- + - name: Deploy captcha injection Job + kubernetes.core.k8s: + state: present + namespace: kube-system + definition: + apiVersion: batch/v1 + kind: Job + metadata: + name: inject-captcha + spec: + backoffLimit: 0 + template: + spec: + restartPolicy: Never + volumes: + - name: traefik-data + persistentVolumeClaim: + claimName: "{{ traefik_pvc_name }}" + containers: + - name: write-captcha + image: alpine:3.20 + command: + - /bin/sh + - -c + - | + echo "Writing captcha.html into PVC..." + cat << 'EOF' > /data/captcha.html + {{ lookup('template', 'captcha.html.j2') | indent(20) }} + EOF + volumeMounts: + - name: traefik-data + mountPath: /data + + # --------------------- + # Wait for job success + # --------------------- + - name: Wait for Job completion + kubernetes.core.k8s_info: + api_version: batch/v1 + kind: Job + name: inject-captcha + namespace: kube-system + register: job_status + until: job_status.resources[0].status.succeeded | default(0) | int > 0 + retries: 20 + delay: 5 + + # --------------------- + # Clean Job + # --------------------- + - name: Remove captcha injection Job + kubernetes.core.k8s: + state: absent + api_version: batch/v1 + kind: Job + name: inject-captcha + namespace: kube-system + + rescue: + - name: Log failure + ansible.builtin.debug: + msg: "An error occurred during captcha injection. Traefik will still be scaled back up." + + always: + # --------------------- + # Ensure Traefik is scaled back to 1 NO MATTER WHAT + # --------------------- + - name: Ensure Traefik is scaled back to 1 + kubernetes.core.k8s_scale: + api_version: apps/v1 + kind: Deployment + namespace: kube-system + name: traefik + replicas: 1 + wait: yes + wait_timeout: 300 diff --git a/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/tasks/main.yml b/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/tasks/main.yml new file mode 100644 index 0000000..a6a4760 --- /dev/null +++ b/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/tasks/main.yml @@ -0,0 +1,143 @@ +- name: Créer le ServiceAccount pour l'authentification Vault + kubernetes.core.k8s: + state: present + definition: + apiVersion: v1 + kind: ServiceAccount + metadata: + name: factory-ansible-tool-crowdsec-traefik-plugin + namespace: kube-system + wait: yes + wait_timeout: 30 + +- name: Créer la ressource VaultAuth + kubernetes.core.k8s: + state: present + definition: + apiVersion: secrets.hashicorp.com/v1beta1 + kind: VaultAuth + metadata: + name: factory-ansible-tool-crowdsec + namespace: kube-system + spec: + method: kubernetes + mount: kubernetes + kubernetes: + role: factory_crowdsec_conf + serviceAccount: factory-ansible-tool-crowdsec-traefik-plugin + audiences: + - vault + wait: yes + wait_timeout: 30 + +- name: Créer la ressource VaultStaticSecret + kubernetes.core.k8s: + state: present + definition: + apiVersion: secrets.hashicorp.com/v1beta1 + kind: VaultStaticSecret + metadata: + name: factory-ansible-tool-crowdsec-turnstile-secret + namespace: kube-system + spec: + type: kv-v2 + mount: kvv2 + path: cms/factory/turnstile + destination: + name: factory-ansible-tool-crowdsec-traefik-plugin-captcha-params + create: true + refreshAfter: 30s + vaultAuthRef: factory-ansible-tool-crowdsec + wait: yes + wait_timeout: 30 + +- name: Récupérer le secret Kubernetes + kubernetes.core.k8s_info: + kind: Secret + name: factory-ansible-tool-crowdsec-traefik-plugin-captcha-params + namespace: kube-system + register: crowdsec_captcha_secret + +- name: Récupérer le nom du pod CrowdSec LAPI + kubernetes.core.k8s_info: + kind: Pod + namespace: tools + label_selectors: + - k8s-app = crowdsec + - type = lapi + register: crowdsec_lapi_pods + +- name: Vérifier qu'un pod a été trouvé + assert: + that: crowdsec_lapi_pods.resources | length > 0 + fail_msg: "Aucun pod CrowdSec LAPI trouvé dans le namespace 'tools' avec les labels 'k8s-app=crowdsec, type=lapi'." + +- name: Définir le nom du pod CrowdSec LAPI + set_fact: + crowdsec_lapi_pod_name: "{{ crowdsec_lapi_pods.resources[0].metadata.name }}" + +- name: Récupérer la clé API du bouncer CrowdSec + kubernetes.core.k8s_exec: + namespace: tools + pod: "{{ crowdsec_lapi_pod_name }}" + container: crowdsec-lapi + command: > + cscli bouncers add traefik-plugin + register: bouncer_key_result + ignore_errors: yes + +- name: Supprimer le bouncer existant en cas d'échec + kubernetes.core.k8s_exec: + namespace: tools + pod: "{{ crowdsec_lapi_pod_name }}" + container: crowdsec-lapi + command: > + cscli bouncers delete traefik-plugin + when: bouncer_key_result.failed + +- name: Réessayer de récupérer la clé API + kubernetes.core.k8s_exec: + namespace: tools + pod: "{{ crowdsec_lapi_pod_name }}" + container: crowdsec-lapi + command: > + cscli bouncers add traefik-plugin + register: bouncer_key_result + when: bouncer_key_result.failed + +- name: Inject captcha.html into Traefik PVC + include_tasks: inject_captcha_html.yml + +- name: Créer le Middleware Traefik pour CrowdSec + kubernetes.core.k8s: + state: present + definition: + apiVersion: traefik.io/v1alpha1 + kind: Middleware + metadata: + name: crowdsec + namespace: kube-system + spec: + plugin: + crowdsec-bouncer: + enabled: true + logLevel: DEBUG + crowdsecMode: stream + crowdsecLapiScheme: http + crowdsecLapiHost: crowdsec-service.tools.svc.cluster.local:8080 + crowdsecLapiKey: "{{ bouncer_key_result.stdout_lines[2].strip() }}" + htttTimeoutSeconds: 60 + crowdsecAppsecEnabled: false + crowdsecAppsecHost: crowdsec:7422 + crowdsecAppsecFailureBlock: true + crowdsecAppsecUnreachableBlock: true + forwardedHeadersTrustedIPs: + - 10.0.10.23/32 + - 10.0.20.0/24 + clientTrustedIPs: + - 192.168.1.0/24 + - 10.42.0.0/16 + captchaProvider: turnstile + captchaSiteKey: "{{ crowdsec_captcha_secret.resources[0].data.sitekey | b64decode }}" + captchaSecretKey: "{{ crowdsec_captcha_secret.resources[0].data.secret | b64decode }}" + captchaHTMLFilePath: "/data/captcha.html" \ No newline at end of file diff --git a/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/templates/captcha.html.j2 b/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/templates/captcha.html.j2 new file mode 100644 index 0000000..6a967ea --- /dev/null +++ b/ansible/arcodange/factory/playbooks/tools/roles/crowdsec/templates/captcha.html.j2 @@ -0,0 +1,18 @@ + + +
+ +