diff --git a/examples/msn0.yml b/examples/msn0.yml index 8ef73a6..8cc8e8f 100644 --- a/examples/msn0.yml +++ b/examples/msn0.yml @@ -43,6 +43,8 @@ all: ciphersuite: "!NULL:!SSLv2:!SSLv3:!TLSv1:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH" Aether_nodes: - DedSec.msn0.aninix.net + operational_countries: + - 'US' children: managed: diff --git a/precommit-hooks/find-passwords-in-files b/precommit-hooks/find-passwords-in-files index a2e8dd2..a0b30aa 100644 --- a/precommit-hooks/find-passwords-in-files +++ b/precommit-hooks/find-passwords-in-files @@ -30,8 +30,10 @@ if [ $? -ne 1 ]; then fi IFS=" " + for i in `ansible-vault decrypt --output - ${ANSIBLE_VAULT_FILE} | sed 's/\s\?-\?\s\?[A-Za-z0-9_]\+://' | grep -vE '\||password|^\s\?$|#|https://' | sed "s/^ \+['\"]\?//" | sed "s/[\"']\s\?//" | sort | uniq`; do - grep -rl "${i}" . 2>/dev/null + + grep -rlF "${i}" . if [ $? -ne 1 ]; then echo "A secret starting with $(echo "$i" | cut -c 1-7) was found in the files above." exit 1; diff --git a/roles/WebServer/files/nginx.conf b/roles/WebServer/files/nginx.conf index 8408f35..2400b08 100644 --- a/roles/WebServer/files/nginx.conf +++ b/roles/WebServer/files/nginx.conf @@ -7,6 +7,7 @@ error_log logs/error.log notice; error_log logs/error.log info; load_module /usr/lib/nginx/modules/ngx_http_modsecurity_module.so; +load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so; events { worker_connections 1024; @@ -24,6 +25,8 @@ http { keepalive_timeout 65; gzip on; + include conf/geoip.conf; + # Redirect all HTTP to HTTPS server { diff --git a/roles/WebServer/tasks/main.yml b/roles/WebServer/tasks/main.yml index ba67acd..6cc61b4 100644 --- a/roles/WebServer/tasks/main.yml +++ b/roles/WebServer/tasks/main.yml @@ -9,6 +9,7 @@ - nginx - libmodsecurity - nginx-mod-modsecurity + - nginx-mod-geoip2 - php - php-fpm @@ -103,6 +104,27 @@ mode: 0660 register: secconf + - name: Populate GeoIP config + become: yes + template: + src: conf/geoip.conf.j2 + dest: /etc/nginx/conf/geoip.conf + owner: http + group: http + mode: 0660 + register: geoipconf + + - name: Ensure MaxMindDB is present + become: yes + file: + path: /etc/nginx/conf/maxmind-geoip2.mmdb + state: file + owner: http + group: http + mode: 0440 + # This requires a https://maxmind.com/ account, so the source will have to come from that site. + # This file should be the current country database. + - name: Clone OWASP-CRS ignore_errors: true become: yes @@ -148,7 +170,7 @@ - name: Ensure service is started become: yes - when: conf.changed or confd.changed or secconf.changed or baseconf.changed or modsecconf.changed + when: conf.changed or confd.changed or geoipconf.changed or secconf.changed or baseconf.changed or modsecconf.changed service: name: "{{ item }}" enabled: yes diff --git a/roles/WebServer/templates/conf/geoip.conf.j2 b/roles/WebServer/templates/conf/geoip.conf.j2 new file mode 100644 index 0000000..04ddff5 --- /dev/null +++ b/roles/WebServer/templates/conf/geoip.conf.j2 @@ -0,0 +1,28 @@ +# Load database and set variables from the database. +geoip2 /etc/nginx/conf/maxmind-geoip2.mmdb { + auto_reload 60m; + $geoip2_metadata_country_build metadata build_epoch; + $geoip2_data_country_code country iso_code; + $geoip2_data_country_name country names en; +} +fastcgi_param COUNTRY_CODE $geoip2_data_country_code; +fastcgi_param COUNTRY_NAME $geoip2_data_country_name; + +# Allow LAN and operational countries. +geo $lan { + default 0; + {{ main_subnet }}/{{ netmask }} 1; +} +map $geoip2_data_country_code $allowed_country { + default 0; +{% for country in operational_countries %} + {{ country }} 1; +{% endfor %} +} + +# Define the deny variable such that LAN & country requests are allowed. +# Thanks to https://stackoverflow.com/a/64071860 for the example +map $lan$allowed_country $deny { + default 0; + 00 1; +}