From 6556e1b50c4fa9c662ed6e022a76e19c88ab17f8 Mon Sep 17 00:00:00 2001 From: Bastian de Byl Date: Fri, 25 Sep 2020 23:44:53 -0400 Subject: [PATCH 1/2] CU-cunmby Added nginx mod_security to http role --- ansible/roles/http/defaults/main.yml | 31 +++++++++-- .../http/files/nginx/modsec_includes.conf | 3 ++ ansible/roles/http/files/nginx/nginx.conf | 13 ++++- ansible/roles/http/tasks/main.yml | 1 + ansible/roles/http/tasks/modsec.yml | 51 ++++++++++++++++++ .../nginx/sites/ci.bdebyl.net.https.conf.j2 | 17 +++--- ansible/vars/vault.yml | Bin 1673 -> 1802 bytes 7 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 ansible/roles/http/files/nginx/modsec_includes.conf create mode 100644 ansible/roles/http/tasks/modsec.yml diff --git a/ansible/roles/http/defaults/main.yml b/ansible/roles/http/defaults/main.yml index 6cd2ba6..741c708 100644 --- a/ansible/roles/http/defaults/main.yml +++ b/ansible/roles/http/defaults/main.yml @@ -1,8 +1,31 @@ --- -ci_server_email: bastian@bdebyl.net -ci_server_name: ci.bdebyl.net - deps: [ certbot, - nginx + nginx, + nginx-mod-modsecurity ] + +nginx_dir: /etc/nginx +nginx_conf_dir: "{{ nginx_dir }}/conf" +modsec_rules_dir: "{{ nginx_conf_dir }}/rules" +modsec_crs_before_rule_conf: + "{{ modsec_rules_dir }}/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf" +modsec_crs_after_rule_conf: + "{{ modsec_rules_dir }}/REQUEST-999-EXCLUSION-RULES-AFTER-CRS.conf" + +ci_server_name: ci.bdebyl.net + +modsec_conf_url: + https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended + +modsec_unicode_url: + https://github.com/SpiderLabs/ModSecurity/raw/v3/master/unicode.mapping + +crs_setup_url: + https://github.com/coreruleset/coreruleset/raw/v3.4/dev/crs-setup.conf.example + +crs_before_url: + https://github.com/coreruleset/coreruleset/raw/v3.4/dev/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example + +crs_after_url: + https://github.com/coreruleset/coreruleset/raw/v3.4/dev/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example diff --git a/ansible/roles/http/files/nginx/modsec_includes.conf b/ansible/roles/http/files/nginx/modsec_includes.conf new file mode 100644 index 0000000..123966e --- /dev/null +++ b/ansible/roles/http/files/nginx/modsec_includes.conf @@ -0,0 +1,3 @@ +include modsecurity.conf +include conf/crs-setup.conf +include conf/rules/*.conf diff --git a/ansible/roles/http/files/nginx/nginx.conf b/ansible/roles/http/files/nginx/nginx.conf index fce002d..8fc5fbd 100644 --- a/ansible/roles/http/files/nginx/nginx.conf +++ b/ansible/roles/http/files/nginx/nginx.conf @@ -1,14 +1,17 @@ user http; worker_processes 1; -error_log /var/log/nginx/error.log; +load_module /usr/lib/nginx/modules/ngx_http_modsecurity_module.so; + +error_log /var/log/nginx/error.log info; events { worker_connections 1024; } http { - include mime.types; + include mime.types; + default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' @@ -18,6 +21,7 @@ http { access_log /var/log/nginx/access.log main; sendfile on; + server_tokens off; #tcp_nopush on; keepalive_timeout 65; @@ -25,6 +29,11 @@ http { gzip on; gzip_disable "mise6"; + client_body_buffer_size 1k; + client_header_buffer_size 1k; + client_max_body_size 2k; + large_client_header_buffers 2 1k; + add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; diff --git a/ansible/roles/http/tasks/main.yml b/ansible/roles/http/tasks/main.yml index 8558561..8f657d3 100644 --- a/ansible/roles/http/tasks/main.yml +++ b/ansible/roles/http/tasks/main.yml @@ -1,5 +1,6 @@ --- - import_tasks: deps.yml +- import_tasks: modsec.yml - import_tasks: http.yml - import_tasks: ssl.yml - import_tasks: cron.yml diff --git a/ansible/roles/http/tasks/modsec.yml b/ansible/roles/http/tasks/modsec.yml new file mode 100644 index 0000000..c549fc0 --- /dev/null +++ b/ansible/roles/http/tasks/modsec.yml @@ -0,0 +1,51 @@ +--- +- name: create nginx/conf directory + become: true + file: + path: "{{ item }}" + state: directory + owner: root + group: root + mode: 0644 + with_items: + - "{{ nginx_conf_dir }}" + - "{{ modsec_rules_dir }}" + tags: modsec + +- name: create modsec_includes.conf + become: true + copy: + src: files/nginx/modsec_includes.conf + dest: "{{ nginx_dir }}/modsec_includes.conf" + mode: 0644 + notify: restart_nginx + tags: modsec + +- name: fetch core rule set files for mod-security + become: true + get_url: + url: "{{ item.url }}" + dest: "{{ item.dest }}" + mode: 0644 + with_items: + - {"url": "{{ modsec_conf_url }}", + "dest": "{{ nginx_dir }}/modsecurity.conf"} + - {"url": "{{ modsec_unicode_url }}", + "dest": "{{ nginx_dir }}/unicode.mapping"} + - {"url": "{{ crs_setup_url }}", + "dest": "{{ nginx_conf_dir }}/crs-setup.conf"} + - {"url": "{{ crs_before_url }}", + "dest": "{{ modsec_crs_before_rule_conf }}"} + - {"url": "{{ crs_after_url }}", + "dest": "{{ modsec_crs_after_rule_conf }}"} + notify: restart_nginx + tags: modsec + +- name: activate mod-security + become: true + lineinfile: + path: /etc/nginx/modsecurity.conf + regexp: '^SecRuleEngine' + line: 'SecRuleEngine On' + notify: restart_nginx + tags: modsec diff --git a/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.https.conf.j2 b/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.https.conf.j2 index bdeb554..7aeee15 100644 --- a/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.https.conf.j2 +++ b/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.https.conf.j2 @@ -10,7 +10,7 @@ server { add_header Strict-Transport-Security max-age=6307200; add_header Allow "GET, POST, HEAD" always; - limit_except GET POST { deny all; } + #limit_except GET POST { deny all; } ssl_certificate /etc/letsencrypt/live/{{ ci_server_name }}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/{{ ci_server_name }}/privkey.pem; @@ -28,14 +28,17 @@ server { ssl_prefer_server_ciphers off; location / { - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $http_host; + modsecurity on; + modsecurity_rules_file {{ nginx_dir }}/modsec_includes.conf; - proxy_pass http://drone; - proxy_redirect off; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + + proxy_pass http://drone; + proxy_redirect off; proxy_http_version 1.1; - proxy_buffering off; + proxy_buffering off; chunked_transfer_encoding off; } diff --git a/ansible/vars/vault.yml b/ansible/vars/vault.yml index 1a512d414d8881b93c403e729ccf8d08b1cd7ece..6088c9de8b31de4dd0075c64c48fd77d3a8d4d32 100644 GIT binary patch literal 1802 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 T&hwGIjIKBbg^O-KXFCR}s!~J% From a22cbd440cb7ba17d656c9159a96009d303e7085 Mon Sep 17 00:00:00 2001 From: Bastian de Byl Date: Fri, 25 Sep 2020 23:47:33 -0400 Subject: [PATCH 2/2] Updated .drone.yml trigger --- .drone.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.drone.yml b/.drone.yml index ab3ead5..b0f6ba4 100644 --- a/.drone.yml +++ b/.drone.yml @@ -11,3 +11,8 @@ steps: image: bdebyl/yamllint command: - make lint-ci + +trigger: + event: + - pull_request + - push