diff --git a/app/create_db.py b/app/create_db.py index b819a9a0..f0180032 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -859,7 +859,7 @@ def update_db_v_5_3_2_2(**kwargs): def update_ver(): - query = Version.update(version='5.3.5.0') + query = Version.update(version='5.3.6.0') try: query.execute() except: diff --git a/app/funct.py b/app/funct.py index 6f82c0e9..0c0b72b7 100644 --- a/app/funct.py +++ b/app/funct.py @@ -743,10 +743,15 @@ def install_haproxy(server_ip, **kwargs): def waf_install(server_ip): import sql script = "waf.sh" - tmp_config_path = sql.get_setting('tmp_config_path') proxy = sql.get_setting('proxy') haproxy_dir = sql.get_setting('haproxy_dir') ver = check_haproxy_version(server_ip) + service = ' WAF' + ssh_enable, ssh_user_name, ssh_user_password, ssh_key_name = return_ssh_keys_path(server_ip) + ssh_port = '22' + + if ssh_enable == 0: + ssh_key_name = '' os.system("cp scripts/%s ." % script) @@ -755,22 +760,20 @@ def waf_install(server_ip): else: proxy_serv = '' - commands = ["sudo chmod +x " + tmp_config_path+script + " && " + tmp_config_path+script + " PROXY=" + proxy_serv + - " HAPROXY_PATH=" + haproxy_dir + " VERSION=" + ver] + commands = ["chmod +x " + script + " && ./" + script + " PROXY=" + proxy_serv + " HAPROXY_PATH=" + haproxy_dir + + " VERSION='" + ver + "' SSH_PORT=" + ssh_port + " HOST=" + server_ip + + " USER=" + ssh_user_name + " PASS='" + ssh_user_password + "' KEY=" + ssh_key_name] - error = str(upload(server_ip, tmp_config_path, script)) + output, error = subprocess_execute(commands[0]) - if error: - print('error: '+error) - logging('localhost', error, haproxywi=1) + if show_installation_output(error, output, service): + ssh_command(server_ip, commands, print_out="1") + + sql.insert_waf_metrics_enable(server_ip, "0") + sql.insert_waf_rules(server_ip) os.system("rm -f %s" % script) - ssh_command(server_ip, commands, print_out="1") - - sql.insert_waf_metrics_enable(server_ip, "0") - sql.insert_waf_rules(server_ip) - def install_nginx(server_ip, **kwargs): import sql diff --git a/app/options.py b/app/options.py index 19b10961..3f60400f 100644 --- a/app/options.py +++ b/app/options.py @@ -632,42 +632,61 @@ if act == "overview": ioloop.close() if act == "overviewwaf": - import asyncio import http.cookies + from jinja2 import Environment, FileSystemLoader + env = Environment(loader=FileSystemLoader('templates/ajax'), autoescape=True, + extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do']) + template = env.get_template('overivewWaf.html') - async def async_get_overviewWaf(serv1, serv2): - haproxy_path = sql.get_setting('haproxy_dir') - commands0 = ["ps ax |grep waf/bin/modsecurity |grep -v grep |wc -l"] - commands1 = ["cat %s/waf/modsecurity.conf |grep SecRuleEngine |grep -v '#' |awk '{print $2}'" % haproxy_path] + servers = sql.select_servers(server=serv) + cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + user_id = cookie.get('uuid') - server_status = (serv1, serv2, - funct.ssh_command(serv2, commands0), - funct.ssh_command(serv2, commands1).strip(), - sql.select_waf_metrics_enable_server(serv2)) - return server_status + haproxy_path = '' + returned_servers = [] + waf = '' + metrics_en = 0 + waf_process = '' + waf_mode = '' + for server in servers: + haproxy = sql.select_haproxy(server[2]) + if haproxy == 1: + haproxy_path = sql.get_setting('haproxy_dir') + waf = sql.select_waf_servers(server[2]) + metrics_en = sql.select_waf_metrics_enable_server(server[2]) + try: + waf_len = len(waf) + except: + waf_len = 0 - async def get_runner_overviewWaf(): - env = Environment(loader=FileSystemLoader('templates/ajax'), autoescape=True, - extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do']) - template = env.get_template('overivewWaf.html') + if waf_len >= 1: + command = ["ps ax |grep waf/bin/modsecurity |grep -v grep |wc -l"] + commands1 = [ + "cat %s/waf/modsecurity.conf |grep SecRuleEngine |grep -v '#' |awk '{print $2}'" % haproxy_path] + waf_process = funct.ssh_command(server[2], command) + waf_mode = funct.ssh_command(server[2], commands1).strip() - servers = [] - cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) - user_id = cookie.get('uuid') - futures = [async_get_overviewWaf(server[1], server[2]) for server in sql.select_servers(server=serv)] - for i, future in enumerate(asyncio.as_completed(futures)): - result = await future - servers.append(result) - servers_sorted = sorted(servers, key=funct.get_key) - template = template.render(service_status=servers_sorted, role=sql.get_user_role_by_uuid(user_id.value)) - print(template) + server_status = (server[1], + server[2], + waf_process, + waf_mode, + metrics_en, + waf_len) + else: + server_status = (server[1], + server[2], + waf_process, + waf_mode, + metrics_en, + waf_len) + returned_servers.append(server_status) - ioloop = asyncio.get_event_loop() - ioloop.run_until_complete(get_runner_overviewWaf()) - ioloop.close() + servers_sorted = sorted(returned_servers, key=funct.get_key) + template = template.render(service_status=servers_sorted, role=sql.get_user_role_by_uuid(user_id.value)) + print(template) if act == "overviewServers": diff --git a/app/scripts/ansible/roles/waf.yml b/app/scripts/ansible/roles/waf.yml new file mode 100644 index 00000000..204a30db --- /dev/null +++ b/app/scripts/ansible/roles/waf.yml @@ -0,0 +1,11 @@ +--- +- name: Install WAF + hosts: "{{ variable_host }}" + become: yes + become_method: sudo + gather_facts: yes + roles: + - role: waf + environment: + http_proxy: "{{PROXY}}" + https_proxy: "{{PROXY}}" \ No newline at end of file diff --git a/app/scripts/ansible/roles/waf/defaults/main.yml b/app/scripts/ansible/roles/waf/defaults/main.yml new file mode 100644 index 00000000..f2fbef5b --- /dev/null +++ b/app/scripts/ansible/roles/waf/defaults/main.yml @@ -0,0 +1,2 @@ +--- +modsec_ver: "2.9.5" \ No newline at end of file diff --git a/app/scripts/ansible/roles/waf/tasks/haproxy_above_2.4.0.yml b/app/scripts/ansible/roles/waf/tasks/haproxy_above_2.4.0.yml new file mode 100644 index 00000000..90045725 --- /dev/null +++ b/app/scripts/ansible/roles/waf/tasks/haproxy_above_2.4.0.yml @@ -0,0 +1,12 @@ +--- +- name: Install git + package: + name: git + state: present + +- 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 \ No newline at end of file diff --git a/app/scripts/ansible/roles/waf/tasks/haproxy_under_2.4.0.yml b/app/scripts/ansible/roles/waf/tasks/haproxy_under_2.4.0.yml new file mode 100644 index 00000000..162e3627 --- /dev/null +++ b/app/scripts/ansible/roles/waf/tasks/haproxy_under_2.4.0.yml @@ -0,0 +1,27 @@ +--- +- name: Download HAProxy tarball + get_url: + url: "http://www.haproxy.org/download/{{ VERSION_MAJ }}/src/haproxy-{{ VERSION }}.tar.gz" + dest: "/tmp/haproxy-{{ VERSION }}.tar.gz" + +- name: Create HAProxy directory + file: + path: "/tmp/haproxy-{{ VERSION }}" + state: directory + +- name: Untar HAProxy tarball + become: true + become_user: root + unarchive: + src: "/tmp/haproxy-{{ VERSION }}.tar.gz" + dest: "/tmp/haproxy-{{ VERSION }}" + remote_src: true + +- name: Copy HAProxy files + synchronize: + src: "/tmp/haproxy-{{ VERSION }}/haproxy-{{ VERSION }}/" + dest: "/tmp/haproxy-{{ VERSION }}" + +- name: Set ModSec foleder + set_fact: + mod_sec_dir: "/tmp/haproxy-{{ VERSION }}/contrib/modsecurity" diff --git a/app/scripts/ansible/roles/waf/tasks/main.yml b/app/scripts/ansible/roles/waf/tasks/main.yml new file mode 100644 index 00000000..966b488b --- /dev/null +++ b/app/scripts/ansible/roles/waf/tasks/main.yml @@ -0,0 +1,389 @@ +--- +- 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: 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: + - http://repo.haproxy-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 common RPMS for HAProxy + yum: + name: + - httpd-devel + - libxml2-devel + - gcc + - curl-devel + - pcre-devel + - wget + - automake + - libevent-devel + - libtool + 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 + 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://www.modsecurity.org/tarball/2.9.5/modsecurity-2.9.5.tar.gz + 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: Copy modsecurity + copy: + src: "/tmp/modsecurity/modsecurity-{{ modsec_ver }}/" + dest: /tmp/modsecurity/ + remote_src: yes + + - name: Set execute permision to configure + become: true + command: chdir=/tmp/modsecurity/ chmod +x configure + args: + warn: no + + - name: Re configure Modsecurity + become: true + command: chdir=/tmp/modsecurity/ autoreconf -f -i + + - name: Configure Modsecurity + become: true + command: chdir=/tmp/modsecurity/ ./configure --prefix=/tmp/modsecurity --enable-standalone-module --disable-mlogc --enable-pcre-study --without-lua --enable-pcre-jit + + - name: Make Modsecurity + command: chdir=/tmp/modsecurity/ make + + - name: Make Install Modsecurity + command: chdir=/tmp/modsecurity/ make -C standalone install + + - name: Creates directory + file: + path: /tmp/modsecurity/INSTALL/include + state: directory + + - name: Copy Modsec libs + copy: + src: /tmp/modsecurity/standalone/.libs/ + dest: /tmp/modsecurity/INSTALL/include/ + remote_src: yes + + - name: Copy Modsec files + copy: + src: /tmp/modsecurity/standalone/ + dest: /tmp/modsecurity/INSTALL/include/ + remote_src: yes + + - name: Copy Modsec apache files + copy: + src: /tmp/modsecurity/apache2/ + dest: /tmp/modsecurity/INSTALL/include/ + remote_src: yes + + - name: Include task for HAProxy <= 2.3.16 + include: haproxy_under_2.4.0.yml + when: VERSION is version('2.3.16', '<=') + + - name: Include task for HAProxy >= 2.4.0 + include: haproxy_above_2.4.0.yml + when: VERSION is version('2.4.0', '>=') + + - name: Make APT Modsecurity module for HAProxy + command: "chdir={{ mod_sec_dir }} make MODSEC_INC=/tmp/modsecurity/INSTALL/include MODSEC_LIB=/tmp/modsecurity/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=/tmp/modsecurity/INSTALL/include MODSEC_LIB=/tmp/modsecurity/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/rules" + state: directory + + - name: Make WAF bin directory + file: + path: "{{ HAPROXY_PATH }}/waf/bin" + state: directory + + - 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/ + dest: /tmp/owasp-modsecurity-crs-2.2.9 + remote_src: yes + + - name: Copy Modsec crs conf file + copy: + src: /tmp/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: Copy Modsec crs activated_rules files + copy: + src: /tmp/owasp-modsecurity-crs-2.2.9/activated_rules/ + dest: "{{ HAPROXY_PATH }}/waf/rules/" + remote_src: yes + + - name: Copy Modsec crs base_rules files + copy: + src: /tmp/owasp-modsecurity-crs-2.2.9/base_rules/ + dest: "{{ HAPROXY_PATH }}/waf/rules/" + remote_src: yes + + - name: Copy Modsec crs experimental_rules files + copy: + src: /tmp/owasp-modsecurity-crs-2.2.9/experimental_rules/ + dest: "{{ HAPROXY_PATH }}/waf/rules/" + remote_src: yes + + - name: Copy Modsec crs optional_rules files + copy: + src: /tmp/owasp-modsecurity-crs-2.2.9/optional_rules/ + dest: "{{ HAPROXY_PATH }}/waf/rules/" + remote_src: yes + + - name: Copy Modsec crs slr_rules files + copy: + src: /tmp/owasp-modsecurity-crs-2.2.9/slr_rules/ + dest: "{{ HAPROXY_PATH }}/waf/rules/" + remote_src: yes + + - 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 + + - 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 + 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: Remove modsecurity.tar.gz + ansible.builtin.file: + path: /tmp/modsecurity.tar.gz + state: absent + + - name: Remove modsecurity-2.9.2 + ansible.builtin.file: + path: /tmp/modsecurity-2.9.2 + state: absent + + - name: Remove HAProxy + ansible.builtin.file: + path: "/tmp/haproxy-{{ VERSION }}" + state: absent + + - name: Remove modsecurity + ansible.builtin.file: + path: /tmp/modsecurity + state: absent + + - name: Remove modsecurity.conf + ansible.builtin.file: + path: /tmp/modsecurity.conf + state: absent + + - name: Remove owasp.tar.gz + ansible.builtin.file: + path: /tmp/owasp.tar.gz + state: absent + + - name: Remove owasp-modsecurity-crs-2.2.9 + ansible.builtin.file: + path: /tmp/owasp-modsecurity-crs-2.2.9 + state: absent + + - name: Remove spoa-modsecurity + ansible.builtin.file: + path: /tmp/spoa-modsecurity + state: absent diff --git a/app/scripts/ansible/roles/waf/templates/modsecurity_crs_10_setup.conf.j2 b/app/scripts/ansible/roles/waf/templates/modsecurity_crs_10_setup.conf.j2 new file mode 100644 index 00000000..06daec52 --- /dev/null +++ b/app/scripts/ansible/roles/waf/templates/modsecurity_crs_10_setup.conf.j2 @@ -0,0 +1,435 @@ +# --------------------------------------------------------------- +# Core ModSecurity Rule Set ver.2.2.9 +# Copyright (C) 2006-2012 Trustwave All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENCE file for full details. +# --------------------------------------------------------------- + + +# +# -- [[ Recommended Base Configuration ]] ------------------------------------------------- +# +# The configuration directives/settings in this file are used to control +# the OWASP ModSecurity CRS. These settings do **NOT** configure the main +# ModSecurity settings such as: +# +# - SecRuleEngine +# - SecRequestBodyAccess +# - SecAuditEngine +# - SecDebugLog +# +# You should use the modsecurity.conf-recommended file that comes with the +# ModSecurity source code archive. +# +# Ref: https://github.com/SpiderLabs/ModSecurity/blob/master/modsecurity.conf-recommended +# + + +# +# -- [[ Rule Version ]] ------------------------------------------------------------------- +# +# Rule version data is added to the "Producer" line of Section H of the Audit log: +# +# - Producer: ModSecurity for Apache/2.7.0-rc1 (http://www.modsecurity.org/); OWASP_CRS/2.2.4. +# +# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecComponentSignature +# +SecComponentSignature "OWASP_CRS/2.2.9" + + +# +# -- [[ Modes of Operation: Self-Contained vs. Collaborative Detection ]] ----------------- +# +# Each detection rule uses the "block" action which will inherit the SecDefaultAction +# specified below. Your settings here will determine which mode of operation you use. +# +# -- [[ Self-Contained Mode ]] -- +# Rules inherit the "deny" disruptive action. The first rule that matches will block. +# +# -- [[ Collaborative Detection Mode ]] -- +# This is a "delayed blocking" mode of operation where each matching rule will inherit +# the "pass" action and will only contribute to anomaly scores. Transactional blocking +# can be applied +# +# -- [[ Alert Logging Control ]] -- +# You have three options - +# +# - To log to both the Apache error_log and ModSecurity audit_log file use: "log" +# - To log *only* to the ModSecurity audit_log file use: "nolog,auditlog" +# - To log *only* to the Apache error_log file use: "log,noauditlog" +# +# Ref: http://blog.spiderlabs.com/2010/11/advanced-topic-of-the-week-traditional-vs-anomaly-scoring-detection-modes.html +# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecDefaultAction +# +SecDefaultAction "phase:1,deny,log" +SecDefaultAction "phase:2,deny,log" + +# +# -- [[ Collaborative Detection Severity Levels ]] ---------------------------------------- +# +# These are the default scoring points for each severity level. You may +# adjust these to you liking. These settings will be used in macro expansion +# in the rules to increment the anomaly scores when rules match. +# +# These are the default Severity ratings (with anomaly scores) of the individual rules - +# +# - 2: Critical - Anomaly Score of 5. +# Is the highest severity level possible without correlation. It is +# normally generated by the web attack rules (40 level files). +# - 3: Error - Anomaly Score of 4. +# Is generated mostly from outbound leakage rules (50 level files). +# - 4: Warning - Anomaly Score of 3. +# Is generated by malicious client rules (35 level files). +# - 5: Notice - Anomaly Score of 2. +# Is generated by the Protocol policy and anomaly files. +# +SecAction \ + "id:'900001', \ + phase:1, \ + t:none, \ + setvar:tx.critical_anomaly_score=5, \ + setvar:tx.error_anomaly_score=4, \ + setvar:tx.warning_anomaly_score=3, \ + setvar:tx.notice_anomaly_score=2, \ + nolog, \ + pass" + + +# +# -- [[ Collaborative Detection Scoring Initialization and Threshold Levels ]] ------------------------------ +# +# These variables are used in macro expansion in the 49 inbound blocking and 59 +# outbound blocking files. +# +# **MUST HAVE** ModSecurity v2.5.12 or higher to use macro expansion in numeric +# operators. If you have an earlier version, edit the 49/59 files directly to +# set the appropriate anomaly score levels. +# +# You should set the score level (rule 900003) to the proper threshold you +# would prefer. If set to "5" it will work similarly to previous Mod CRS rules +# and will create an event in the error_log file if there are any rules that +# match. If you would like to lessen the number of events generated in the +# error_log file, you should increase the anomaly score threshold to something +# like "20". This would only generate an event in the error_log file if there +# are multiple lower severity rule matches or if any 1 higher severity item matches. +# +SecAction \ + "id:'900002', \ + phase:1, \ + t:none, \ + setvar:tx.anomaly_score=0, \ + setvar:tx.sql_injection_score=0, \ + setvar:tx.xss_score=0, \ + setvar:tx.inbound_anomaly_score=0, \ + setvar:tx.outbound_anomaly_score=0, \ + nolog, \ + pass" + + +SecAction \ + "id:'900003', \ + phase:1, \ + t:none, \ + setvar:tx.inbound_anomaly_score_level=5, \ + setvar:tx.outbound_anomaly_score_level=4, \ + nolog, \ + pass" + + +# +# -- [[ Collaborative Detection Blocking ]] ----------------------------------------------- +# +# This is a collaborative detection mode where each rule will increment an overall +# anomaly score for the transaction. The scores are then evaluated in the following files: +# +# Inbound anomaly score - checked in the modsecurity_crs_49_inbound_blocking.conf file +# Outbound anomaly score - checked in the modsecurity_crs_59_outbound_blocking.conf file +# +# If you want to use anomaly scoring mode, then uncomment this line. +# +SecAction \ + "id:'900004', \ + phase:1, \ + t:none, \ + setvar:tx.anomaly_score_blocking=on, \ + nolog, \ + pass" + + +# +# -- [[ GeoIP Database ]] ----------------------------------------------------------------- +# +# There are some rulesets that need to inspect the GEO data of the REMOTE_ADDR data. +# +# You must first download the MaxMind GeoIP Lite City DB - +# +# http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz +# +# You then need to define the proper path for the SecGeoLookupDb directive +# +# Ref: http://blog.spiderlabs.com/2010/10/detecting-malice-with-modsecurity-geolocation-data.html +# Ref: http://blog.spiderlabs.com/2010/11/detecting-malice-with-modsecurity-ip-forensics.html +# +#SecGeoLookupDb /opt/modsecurity/lib/GeoLiteCity.dat + +# +# -- [[ Regression Testing Mode ]] -------------------------------------------------------- +# +# If you are going to run the regression testing mode, you should uncomment the +# following rule. It will enable DetectionOnly mode for the SecRuleEngine and +# will enable Response Header tagging so that the client testing script can see +# which rule IDs have matched. +# +# You must specify the your source IP address where you will be running the tests +# from. +# +#SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \ + "id:'900005', \ + phase:1, \ + t:none, \ + ctl:ruleEngine=DetectionOnly, \ + setvar:tx.regression_testing=1, \ + nolog, \ + pass" + + +# +# -- [[ HTTP Policy Settings ]] ---------------------------------------------------------- +# +# Set the following policy settings here and they will be propagated to the 23 rules +# file (modsecurity_common_23_request_limits.conf) by using macro expansion. +# If you run into false positives, you can adjust the settings here. +# +# Only the max number of args is uncommented by default as there are a high rate +# of false positives. Uncomment the items you wish to set. +# +# +# -- Maximum number of arguments in request limited +SecAction \ + "id:'900006', \ + phase:1, \ + t:none, \ + setvar:tx.max_num_args=255, \ + nolog, \ + pass" + +# +# -- Limit argument name length +SecAction \ + "id:'900007', \ + phase:1, \ + t:none, \ + setvar:tx.arg_name_length=100, \ + nolog, \ + pass" + +# +# -- Limit value name length +SecAction \ + "id:'900008', \ + phase:1, \ + t:none, \ + setvar:tx.arg_length=400, \ + nolog, \ + pass" + +# +# -- Limit arguments total length +SecAction \ + "id:'900009', \ + phase:1, \ + t:none, \ + setvar:tx.total_arg_length=64000, \ + nolog, \ + pass" + +# +# -- Individual file size is limited +SecAction \ + "id:'900010', \ + phase:1, \ + t:none, \ + setvar:tx.max_file_size=1048576, \ + nolog, \ + pass" + +# +# -- Combined file size is limited +SecAction \ + "id:'900011', \ + phase:1, \ + t:none, \ + setvar:tx.combined_file_sizes=1048576, \ + nolog, \ + pass" + + +# +# Set the following policy settings here and they will be propagated to the 30 rules +# file (modsecurity_crs_30_http_policy.conf) by using macro expansion. +# If you run into false positves, you can adjust the settings here. +# +SecAction \ + "id:'900012', \ + phase:1, \ + t:none, \ + setvar:'tx.allowed_methods=GET HEAD POST OPTIONS', \ + setvar:'tx.allowed_request_content_type=application/x-www-form-urlencoded|multipart/form-data|text/xml|application/xml|application/x-amf|application/json', \ + setvar:'tx.allowed_http_versions=HTTP/0.9 HTTP/1.0 HTTP/1.1', \ + setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .resources/ .resx/ .sql/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/', \ + setvar:'tx.restricted_headers=/Proxy-Connection/ /Lock-Token/ /Content-Range/ /Translate/ /via/ /if/', \ + nolog, \ + pass" + + +# +# -- [[ Content Security Policy (CSP) Settings ]] ----------------------------------------- +# +# The purpose of these settings is to send CSP response headers to +# Mozilla FireFox users so that you can enforce how dynamic content +# is used. CSP usage helps to prevent XSS attacks against your users. +# +# Reference Link: +# +# https://developer.mozilla.org/en/Security/CSP +# +# Uncomment this SecAction line if you want use CSP enforcement. +# You need to set the appropriate directives and settings for your site/domain and +# and activate the CSP file in the experimental_rules directory. +# +# Ref: http://blog.spiderlabs.com/2011/04/modsecurity-advanced-topic-of-the-week-integrating-content-security-policy-csp.html +# +SecAction \ + "id:'900013', \ + phase:1, \ + t:none, \ + setvar:tx.csp_report_only=1, \ + setvar:tx.csp_report_uri=/csp_violation_report, \ + setenv:'csp_policy=allow \'self\'; img-src *.yoursite.com; media-src *.yoursite.com; style-src *.yoursite.com; frame-ancestors *.yoursite.com; script-src *.yoursite.com; report-uri %{tx.csp_report_uri}', \ + nolog, \ + pass" + + +# +# -- [[ Brute Force Protection ]] --------------------------------------------------------- +# +# If you are using the Brute Force Protection rule set, then uncomment the following +# lines and set the following variables: +# - Protected URLs: resources to protect (e.g. login pages) - set to your login page +# - Burst Time Slice Interval: time interval window to monitor for bursts +# - Request Threshold: request # threshold to trigger a burst +# - Block Period: temporary block timeout +# +SecAction \ + "id:'900014', \ + phase:1, \ + t:none, \ + setvar:'tx.brute_force_protected_urls=#/login.jsp# #/partner_login.php#', \ + setvar:'tx.brute_force_burst_time_slice=60', \ + setvar:'tx.brute_force_counter_threshold=10', \ + setvar:'tx.brute_force_block_timeout=300', \ + nolog, \ + pass" + + +# +# -- [[ DoS Protection ]] ---------------------------------------------------------------- +# +# If you are using the DoS Protection rule set, then uncomment the following +# lines and set the following variables: +# - Burst Time Slice Interval: time interval window to monitor for bursts +# - Request Threshold: request # threshold to trigger a burst +# - Block Period: temporary block timeout +# +SecAction \ + "id:'900015', \ + phase:1, \ + t:none, \ + setvar:'tx.dos_burst_time_slice=60', \ + setvar:'tx.dos_counter_threshold=100', \ + setvar:'tx.dos_block_timeout=600', \ + nolog, \ + pass" + + +# +# -- [[ Check UTF enconding ]] ----------------------------------------------------------- +# +# We only want to apply this check if UTF-8 encoding is actually used by the site, otherwise +# it will result in false positives. +# +# Uncomment this line if your site uses UTF8 encoding +SecAction \ + "id:'900016', \ + phase:1, \ + t:none, \ + setvar:tx.crs_validate_utf8_encoding=1, \ + nolog, \ + pass" + + +# +# -- [[ Enable XML Body Parsing ]] ------------------------------------------------------- +# +# The rules in this file will trigger the XML parser upon an XML request +# +# Initiate XML Processor in case of xml content-type +# +SecRule REQUEST_HEADERS:Content-Type "text/xml" \ + "id:'900017', \ + phase:1, \ + t:none,t:lowercase, \ + nolog, \ + pass, \ + chain" + SecRule REQBODY_PROCESSOR "!@streq XML" \ + "ctl:requestBodyProcessor=XML" + + +# +# -- [[ Global and IP Collections ]] ----------------------------------------------------- +# +# Create both Global and IP collections for rules to use +# There are some CRS rules that assume that these two collections +# have already been initiated. +# +SecRule REQUEST_HEADERS:User-Agent "^(.*)$" \ + "id:'900018', \ + phase:1, \ + t:none,t:sha1,t:hexEncode, \ + setvar:tx.ua_hash=%{matched_var}, \ + nolog, \ + pass" + + +SecRule REQUEST_HEADERS:x-forwarded-for "^\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b" \ + "id:'900019', \ + phase:1, \ + t:none, \ + capture, \ + setvar:tx.real_ip=%{tx.1}, \ + nolog, \ + pass" + + +SecRule &TX:REAL_IP "!@eq 0" \ + "id:'900020', \ + phase:1, \ + t:none, \ + initcol:global=global, \ + initcol:ip=%{tx.real_ip}_%{tx.ua_hash}, \ + nolog, \ + pass" + + +SecRule &TX:REAL_IP "@eq 0" \ + "id:'900021', \ + phase:1, \ + t:none, \ + initcol:global=global, \ + initcol:ip=%{remote_addr}_%{tx.ua_hash}, \ + setvar:tx.real_ip=%{remote_addr}, \ + nolog, \ + pass" diff --git a/app/scripts/ansible/roles/waf/templates/waf.conf.j2 b/app/scripts/ansible/roles/waf/templates/waf.conf.j2 new file mode 100644 index 00000000..fb9c76da --- /dev/null +++ b/app/scripts/ansible/roles/waf/templates/waf.conf.j2 @@ -0,0 +1,12 @@ +[modsecurity] +spoe-agent modsecurity-agent + messages check-request + option var-prefix modsec + timeout hello 100ms + timeout idle 30s + timeout processing 15ms + use-backend waf + +spoe-message check-request + args unique-id method path query req.ver req.hdrs_bin req.body_size req.body + event on-frontend-http-request \ No newline at end of file diff --git a/app/scripts/ansible/roles/waf/templates/waf.service.j2 b/app/scripts/ansible/roles/waf/templates/waf.service.j2 new file mode 100644 index 00000000..d45cae41 --- /dev/null +++ b/app/scripts/ansible/roles/waf/templates/waf.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=HAProxy WAF +After=syslog.target network.target + +[Service] +ExecStart={{HAPROXY_PATH}}/waf/bin/modsecurity -n 4 -f {{HAPROXY_PATH}}/waf/modsecurity.conf +ExecReload=/bin/kill -USR2 $MAINPID +KillMode=mixed + +StandardOutput=syslog +StandardError=syslog +SyslogIdentifier=waf + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/app/scripts/ansible/roles/waf/templates/waf_rsyslog.conf.j2 b/app/scripts/ansible/roles/waf/templates/waf_rsyslog.conf.j2 new file mode 100644 index 00000000..c3b0b7ab --- /dev/null +++ b/app/scripts/ansible/roles/waf/templates/waf_rsyslog.conf.j2 @@ -0,0 +1,2 @@ +if $programname startswith "waf" then /var/log/waf.log +& stop diff --git a/app/scripts/waf.sh b/app/scripts/waf.sh index 50cee663..d98a1c31 100644 --- a/app/scripts/waf.sh +++ b/app/scripts/waf.sh @@ -9,218 +9,42 @@ do PROXY) PROXY=${VALUE} ;; VERSION) VERSION=${VALUE} ;; HAPROXY_PATH) HAPROXY_PATH=${VALUE} ;; + HOST) HOST=${VALUE} ;; + USER) USER=${VALUE} ;; + PASS) PASS=${VALUE} ;; + KEY) KEY=${VALUE} ;; + SSH_PORT) SSH_PORT=${VALUE} ;; *) esac done -VERSION=$(echo 2.1.3| awk -F"-" '{print $1}') +VERSION=$(echo "$VERSION"| awk -F"-" '{print $1}') VERSION_MAJ=$(echo "$VERSION" | awk -F"." '{print $1"."$2}') -function do_clean() { - sudo rm -f /tmp/modsecurity.tar.gz - sudo rm -rf /tmp/modsecurity - sudo rm -rf /tmp/haproxy-* - sudo rm -f /tmp/modsecurity.conf - sudo rm -f /tmp/owasp.tar.gz - sudo rm -rf /tmp/owasp-modsecurity-crs-2.2.9 -} - if (( $(awk 'BEGIN {print ("'$VERSION_MAJ'" < "'1.8'")}') )); then echo 'error: Need HAProxy version 1.8 or later' exit 1 fi -if [[ $PROXY != "" ]] +export ANSIBLE_HOST_KEY_CHECKING=False +export ANSIBLE_DISPLAY_SKIPPED_HOSTS=False +export ACTION_WARNINGS=False +export LOCALHOST_WARNING=False +export COMMAND_WARNINGS=False + +PWD=$(pwd) +PWD=$PWD/scripts/ansible/ +echo "$HOST ansible_port=$SSH_PORT" > $PWD/$HOST + +if [[ $KEY == "" ]]; then + ansible-playbook $PWD/roles/waf.yml -e "ansible_user=$USER ansible_ssh_pass='$PASS' variable_host=$HOST PROXY=$PROXY HAPROXY_PATH=$HAPROXY_PATH VERSION=$VERSION VERSION_MAJ=$VERSION_MAJ SSH_PORT=$SSH_PORT" -i $PWD/$HOST +else + ansible-playbook $PWD/roles/waf.yml --key-file $KEY -e "ansible_user=$USER variable_host=$HOST PROXY=$PROXY HAPROXY_PATH=$HAPROXY_PATH VERSION=$VERSION VERSION_MAJ=$VERSION_MAJ SSH_PORT=$SSH_PORT" -i $PWD/$HOST +fi + +if [ $? -gt 0 ] then - export http_proxy="$PROXY" - export https_proxy="$PROXY" -fi - -if [ -f "$HAPROXY_PATH"/waf/modsecurity.conf ];then - echo -e 'info: Haproxy WAF has already installed.' - exit 0 -fi -if hash apt-get 2>/dev/null; then - sudo apt install libevent-dev apache2-dev libpcre3-dev libxml2-dev gcc pcre-devel wget libxml2 -y + echo "error: Cannot install WAF" else - if [[ $(cat /etc/*rele* |grep VERSION_ID |awk -F"\"" '{print $2}') -eq 7 ]]; then - sudo yum install -y http://rpmfind.net/linux/centos/7/os/x86_64/Packages/yajl-devel-2.0.4-4.el7.x86_64.rpm >> /dev/null - sudo yum install -y http://mirror.centos.org/centos/7/os/x86_64/Packages/libevent-devel-2.0.21-4.el7.x86_64.rpm >> /dev/null - else - sudo rpm -ivh ftp://ftp.ntua.gr/pub/linux/centos/8.3.2011/PowerTools/x86_64/kickstart/Packages/yajl-devel-2.1.0-10.el8.x86_64.rpm - fi - sudo yum install -y httpd-devel libxml2-devel gcc curl-devel pcre-devel wget libevent-devel -y >> /dev/null + echo "success" fi - -wget -O /tmp/modsecurity.tar.gz https://www.modsecurity.org/tarball/2.9.2/modsecurity-2.9.2.tar.gz >> /dev/null - -if [ $? -eq 1 ]; then - echo -e "Can't download WAF application. Check the Internet connection" - do_clean - exit 1 -fi -cd /tmp || exit -sudo tar xf modsecurity.tar.gz -sudo mv modsecurity-2.9.2 modsecurity -sudo bash -c 'cd /tmp/modsecurity && \ -sudo ./configure --prefix=/tmp/modsecurity --enable-standalone-module --disable-mlogc --enable-pcre-study --without-lua --enable-pcre-jit >> /dev/null && \ -sudo make >> /dev/null && \ -sudo make -C standalone install >> /dev/null' -if [ $? -eq 1 ]; then - echo -e "error: Can't compile waf application" - do_clean - exit 1 -fi -sudo mkdir -p /tmp/modsecurity/INSTALL/include -sudo cp -R /tmp/modsecurity/standalone/.libs/ /tmp/modsecurity/INSTALL/include -sudo cp -R /tmp/modsecurity/standalone/ /tmp/modsecurity/INSTALL/include -sudo cp -R /tmp/modsecurity/apache2/ /tmp/modsecurity/INSTALL/include -sudo chown -R $(whoami):$(whoami) /tmp/modsecurity/ -mv /tmp/modsecurity/INSTALL/include/.libs/* /tmp/modsecurity/INSTALL/include -mv /tmp/modsecurity/INSTALL/include/apache2/* /tmp/modsecurity/INSTALL/include -mv /tmp/modsecurity/INSTALL/include/standalone/* /tmp/modsecurity/INSTALL/include - -wget -O /tmp/haproxy-"$VERSION".tar.gz http://www.haproxy.org/download/$VERSION_MAJ/src/haproxy-"$VERSION".tar.gz - -if [ $? -eq 1 ]; then - echo -e "error: Can't download Haproxy application. Check the Internet connection" - do_clean - exit 1 -fi -cd /tmp || exit -sudo tar xf /tmp/haproxy-"$VERSION".tar.gz -sudo mkdir "$HAPROXY_PATH"/waf -sudo mkdir "$HAPROXY_PATH"/waf/bin -sudo mkdir "$HAPROXY_PATH"/waf/rules -cd /tmp/haproxy-"$VERSION"/contrib/modsecurity || exit -if hash apt-get 2>/dev/null; then - sudo make MODSEC_INC=/tmp/modsecurity/INSTALL/include MODSEC_LIB=/tmp/modsecurity/INSTALL/include APR_INC=/usr/include/apr-1 >> /dev/null -else - sudo make MODSEC_INC=/tmp/modsecurity/INSTALL/include MODSEC_LIB=/tmp/modsecurity/INSTALL/include APACHE2_INC=/usr/include/httpd/ APR_INC=/usr/include/apr-1 >> /dev/null -fi -if [ $? -eq 1 ]; then - echo -e "error: Can't compile WAF application" - do_clean - exit 1 -fi -sudo mv /tmp/haproxy-"$VERSION"/contrib/modsecurity/modsecurity "$HAPROXY_PATH"/waf/bin -if [ $? -eq 1 ]; then - echo -e "error: Can't compile WAF application" - do_clean - exit 1 -fi -wget -O /tmp/modsecurity.conf https://github.com/SpiderLabs/ModSecurity/raw/v2/master/modsecurity.conf-recommended - -sudo bash -c cat << EOF >> /tmp/modsecurity.conf -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_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 -EOF - -sudo mv /tmp/modsecurity.conf "$HAPROXY_PATH"/waf/modsecurity.conf -wget -O /tmp/unicode.mapping https://github.com/SpiderLabs/ModSecurity/raw/v2/master/unicode.mapping -sudo mv /tmp/unicode.mapping "$HAPROXY_PATH"/waf/unicode.mapping -wget -O /tmp/owasp.tar.gz https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/2.2.9.tar.gz -cd /tmp/ || exit -sudo tar xf /tmp/owasp.tar.gz -sudo mv /tmp/owasp-modsecurity-crs-2.2.9/modsecurity_crs_10_setup.conf.example $HAPROXY_PATH/waf/rules/modsecurity_crs_10_setup.conf -sudo mv /tmp/owasp-modsecurity-crs-2.2.9/*rules/* "$HAPROXY_PATH"/waf/rules/ -sudo sed -i 's/#SecAction/SecAction/' "$HAPROXY_PATH"/waf/rules/modsecurity_crs_10_setup.conf -sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' "$HAPROXY_PATH"/waf/modsecurity.conf -sudo sed -i 's/SecAuditLogParts ABIJDEFHZ/SecAuditLogParts ABIJDEH/' "$HAPROXY_PATH"/waf/modsecurity.conf - -sudo bash -c cat << EOF > /tmp/waf.service -[Unit] -Description=Haproxy WAF -After=syslog.target network.target - -[Service] -ExecStart=$HAPROXY_PATH/waf/bin/modsecurity -n 4 -f $HAPROXY_PATH/waf/modsecurity.conf -ExecReload=/bin/kill -USR2 $MAINPID -KillMode=mixed - -StandardOutput=syslog -StandardError=syslog -SyslogIdentifier=waf - -[Install] -WantedBy=multi-user.target -EOF -sudo mv /tmp/waf.service /etc/systemd/system/waf.service -sudo bash -c 'cat << EOF > /etc/rsyslog.d/waf.conf -if $programname startswith "waf" then /var/log/waf.log -& stop -EOF' - -sudo bash -c cat << EOF > /tmp/waf.conf -[modsecurity] -spoe-agent modsecurity-agent - messages check-request - option var-prefix modsec - timeout hello 100ms - timeout idle 30s - timeout processing 15ms - use-backend waf - -spoe-message check-request - args unique-id method path query req.ver req.hdrs_bin req.body_size req.body - event on-frontend-http-request -EOF - -sudo mv /tmp/waf.conf "$HAPROXY_PATH"/waf.conf -if sudo grep -q "backend waf" "$HAPROXY_PATH"/haproxy.cfg; then - echo -e "Backend for WAF exists" -else - sudo bash -c 'cat << EOF >> /etc/haproxy/haproxy.cfg - -backend waf - mode tcp - timeout connect 5s - timeout server 3m - server waf 127.0.0.1:12345 check -EOF' -fi - -do_clean - -sudo systemctl daemon-reload -sudo systemctl enable waf -sudo systemctl restart waf - -if [ $? -eq 1 ]; then - echo "error: Can't start Haproxy WAF service" - exit 1 -fi -echo "success" \ No newline at end of file +rm -f $PWD/$HOST diff --git a/app/templates/ajax/overivewWaf.html b/app/templates/ajax/overivewWaf.html index 58fb3f6c..1a5aef4f 100644 --- a/app/templates/ajax/overivewWaf.html +++ b/app/templates/ajax/overivewWaf.html @@ -1,74 +1,67 @@ +{% set waf_modes = [] %} +{% do waf_modes.append("On") %} +{% do waf_modes.append("Off") %} +{% do waf_modes.append("DetectionOnly") %} {% for service in service_status %} - {% if service.3 == "On" or service.3 == "Off" or service.3 == "DetectionOnly" %} -