---
- name: Installing WAF
  block:
    - name: Set SSH port
      set_fact:
        ansible_port: "{{SSH_PORT}}"

    - name: Check that WAF has been installed
      stat:
        path: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"
      register: stat_result

    - name: Fail if has been installed
      fail:
        msg="info HAProxy WAF has already installed"
      when: stat_result.stat.exists

    - name: erase the RPMS for HAProxy
      yum:
        name:
          - ssdeep
          - ssdeep-devel
        state: absent
      when:
        - ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS'
      environment:
        http_proxy: "{{PROXY}}"
        https_proxy: "{{PROXY}}"

    - name: install the el7 RPMS for HAProxy
      yum:
        name:
          - yajl-devel
          - http://repo.haproxy-wi.org/libevent-devel-2.0.21-4.el7.x86_64.rpm
        state: latest
      when:
        - ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS'
        - ansible_facts['distribution_major_version'] == '7'
      environment:
        http_proxy: "{{PROXY}}"
        https_proxy: "{{PROXY}}"

    - name: install the el8 RPMS for HAProxy
      yum:
        name:
          - https://repo.roxy-wi.org/yajl-devel-2.1.0-10.el8.x86_64.rpm
        state: latest
      when:
        - ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS'
        - ansible_facts['distribution_major_version'] == '8'
      environment:
        http_proxy: "{{PROXY}}"
        https_proxy: "{{PROXY}}"

    - name: install the el9 RPMS for HAProxy
      yum:
        name:
          - yajl-devel
        state: latest
      when:
        - ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS'
        - ansible_facts['distribution_major_version'] == '9'
      environment:
        http_proxy: "{{PROXY}}"
        https_proxy: "{{PROXY}}"

    - name: install the common RPMS for HAProxy
      yum:
        name:
          - httpd-devel
          - libxml2-devel
          - gcc
          - curl-devel
          - pcre-devel
          - wget
          - automake
          - libevent-devel
          - libtool
          - make
          - gcc-c++
          - git
        state: latest
      when:
        - ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS'
      environment:
        http_proxy: "{{PROXY}}"
        https_proxy: "{{PROXY}}"

    - name: Install needed packages
      apt:
        name:
          - libevent-dev
          - apache2-dev
          - libpcre3-dev
          - libxml2-dev
          - gcc
          - libpcre3-dev
          - wget
          - libcurl4-nss-dev
          - libyajl-dev
          - libxml2
          - automake
          - g++
          - make
          - git
        state: present
      when: ansible_facts['os_family'] == 'Debian' or ansible_facts['os_family'] == 'Ubuntu'
      environment:
        http_proxy: "{{PROXY}}"
        https_proxy: "{{PROXY}}"

    - name: Download Modsec tarball
      become: false
      get_url:
        url: "https://github.com/SpiderLabs/ModSecurity/releases/download/v{{ modsec_ver }}/modsecurity-{{ modsec_ver }}.tar.gz"
        dest: /tmp/modsecurity.tar.gz
        owner: "{{ ansible_user }}"

    - name: Create HAProxy directory
      become: false
      file:
        path: /tmp/modsecurity
        state: directory

    - name: Untar Modsec tarball
      become: false
      unarchive:
        src: /tmp/modsecurity.tar.gz
        dest: /tmp/modsecurity
        remote_src: true

    - name: Set ModSec src foleder
      set_fact:
        mod_sec_src: /tmp/modsecurity/modsecurity-{{ modsec_ver }}

    - name: Re configure Modsecurity
      become: true
      command: "chdir={{ mod_sec_src }} autoreconf -f -i"

    - name: Configure Modsecurity
      become: true
      command: "chdir={{ mod_sec_src }} ./configure --prefix=/tmp/modsecurity --enable-standalone-module --disable-mlogc --enable-pcre-study --without-lua --enable-pcre-jit"

    - name: Make Modsecurity
      command: "chdir={{ mod_sec_src }} make"

    - name: Make Install Modsecurity
      command: "chdir={{ mod_sec_src }} make -C standalone install"

    - name: Creates directory
      file:
        path: "{{ mod_sec_src }}INSTALL/include"
        state: directory

    - name: Copy Modsec libs
      copy:
        src: "{{ mod_sec_src }}/{{ item }}"
        dest: "{{ mod_sec_src }}/INSTALL/include/"
        remote_src: yes
      with_items:
        - standalone/.libs/
        - standalone/
        - apache2/

    - name: Git clone spoa-modsecurity
      command: chdir=/tmp/ git clone https://github.com/haproxy/spoa-modsecurity.git

    - name: Set ModSec foleder
      set_fact:
        mod_sec_dir: /tmp/spoa-modsecurity

    - name: Make APT Modsecurity module for HAProxy
      command: "chdir={{ mod_sec_dir }} make MODSEC_INC={{ mod_sec_src }}/INSTALL/include MODSEC_LIB={{ mod_sec_src }}/INSTALL/include APACHE2_INC=/usr/include/apache2/ APR_INC=/usr/include/apr-1.0"
      when: ansible_facts['os_family'] == 'Debian' or ansible_facts['os_family'] == 'Ubuntu'

    - name: Make EL Modsecurity module for HAProxy
      command: "chdir={{ mod_sec_dir }} make MODSEC_INC={{ mod_sec_src }}/INSTALL/include MODSEC_LIB={{ mod_sec_src }}/INSTALL/include APACHE2_INC=/usr/include/httpd/ APR_INC=/usr/include/apr-1"
      when: ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS'

    - name: Make WAF rules directory
      file:
        path: "{{ HAPROXY_PATH }}/waf/{{ item }}"
        state: directory
      with_items:
        - rules
        - bin

    - name: Copy Modsec module to HAProxy dir
      copy:
        src: "{{ mod_sec_dir }}/modsecurity"
        dest: "{{ HAPROXY_PATH }}/waf/bin"
        mode: '0744'
        remote_src: true

    - name: Download modsecurity conf
      get_url:
        url: https://github.com/SpiderLabs/ModSecurity/raw/v2/master/modsecurity.conf-recommended
        dest: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"

    - name: Insert Modsec rules
      blockinfile:
        path: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"
        block: |
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_10_ignore_static.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_10_setup.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_11_avs_traffic.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_11_brute_force.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_11_dos_protection.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_13_xml_enabler.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_16_authentication_tracking.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_16_scanner_integration.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_16_username_tracking.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_20_protocol_violations.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_21_protocol_anomalies.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_23_request_limits.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_25_cc_known.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_25_cc_track_pan.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_30_http_policy.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_35_bad_robots.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_40_generic_attacks.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_40_http_parameter_pollution.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_41_sql_injection_attacks.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_41_xss_attacks.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_42_comment_spam.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_42_tight_security.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_45_trojans.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_av_scanning.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_scanner_integration.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_slr_et_xss_attacks.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_slr_et_lfi_attacks.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_slr_et_sqli_attacks.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_47_common_exceptions.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_49_inbound_blocking.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_50_outbound.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_55_marketing.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_56_pvi_checks.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_59_outbound_blocking.conf
          Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_60_correlation.conf

    - name: Download unicode.mapping
      get_url:
        url: https://github.com/SpiderLabs/ModSecurity/raw/v2/master/unicode.mapping
        dest: "{{ HAPROXY_PATH }}/waf/unicode.mapping"

    - name: Download owasp-modsecurity-crs
      get_url:
        url: https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/2.2.9.tar.gz
        dest: /tmp/owasp.tar.gz

    - name: Create owasp directory
      file:
        path: /tmp/owasp-modsecurity-crs-2.2.9
        state: directory

    - name: Untar owasp-modsecurity-crs tarball
      become: true
      become_user: root
      unarchive:
        src: /tmp/owasp.tar.gz
        dest: /tmp/owasp-modsecurity-crs-2.2.9
        remote_src: true

    - name: Copy owasp files
      copy:
        src: "/tmp/owasp-modsecurity-crs-2.2.9/owasp-modsecurity-crs-2.2.9/{{ item }}"
        dest: "{{ HAPROXY_PATH }}/waf/rules"
        remote_src: yes
      with_items:
        - base_rules/
        - experimental_rules/
        - optional_rules/
        - slr_rules/

    - name: Copy Modsec crs conf file
      copy:
        src: /tmp/owasp-modsecurity-crs-2.2.9/owasp-modsecurity-crs-2.2.9/modsecurity_crs_10_setup.conf.example
        dest: "{{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_10_setup.conf"
        remote_src: true

    - name: Ensure ModSec engine mode on
      ansible.builtin.lineinfile:
        path: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"
        regexp: '^SecRuleEngine DetectionOnly'
        line: SecRuleEngine On

    - name: Change ModSec audit log
      ansible.builtin.lineinfile:
        path: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"
        regexp: '^SecAuditLogParts ABIJDEFHZ'
        line: SecAuditLogParts ABIJDEH

    - name: Create modsecurity_crs_10_setup
      template:
        src: modsecurity_crs_10_setup.conf.j2
        dest: "{{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_10_setup.conf"

    - name: Create WAF service file
      template:
        src: waf.service.j2
        dest: /etc/systemd/system/waf.service
        mode: 0644

    - name: Create WAF rsyslog file
      template:
        src: waf_rsyslog.conf.j2
        dest: /etc/rsyslog.d/waf.conf
        mode: 0644
      notify: restart rsyslog

    - name: Create WAF conf file
      template:
        src: waf.conf.j2
        dest: "{{ HAPROXY_PATH }}/waf.conf"
        mode: 0644

    - name: Insert Modsec backend
      blockinfile:
        path: "{{ HAPROXY_PATH }}/haproxy.cfg"
        block: |
          backend waf
              mode tcp
              fullconn   2000
              timeout connect 5s
              timeout server  3m
              server waf 127.0.0.1:12345 check

    - name: Daemon-reload for WAF service
      systemd:
        daemon_reexec: yes

    - name: Start and enable WAF service
      systemd:
        name: waf
        state: started
        enabled: yes

  always:
    - name: Clean up
      ansible.builtin.file:
        path: "{{ item }}"
        state: absent
      with_items:
        - /tmp/modsecurity.tar.gz
        - "{{ mod_sec_dir }}"
        - "/tmp/haproxy-{{ VERSION }}"
        - /tmp/owasp.tar.gz
        - /tmp/owasp-modsecurity-crs-2.2.9
        - /tmp/spoa-modsecurity
