diff --git a/roles/nginx/cfg.schema.json b/roles/nginx/cfg.schema.json new file mode 100644 index 0000000..13a8fcb --- /dev/null +++ b/roles/nginx/cfg.schema.json @@ -0,0 +1,28 @@ +{ + "nullable": false, + "type": "object", + "properties": { + "auto_reload_interval": { + "nullable": true, + "type": "integer", + "description": "in hours", + "default": null + }, + "dhparam_size": { + "nullable": true, + "type": "integer", + "default": null + }, + "improved_security": { + "nullable": false, + "type": "boolean", + "default": false + } + }, + "additionalProperties": false, + "required": [ + "auto_reload_interval", + "dhparam_size", + "improved_security" + ] +} diff --git a/roles/nginx/defaults/main.json b/roles/nginx/defaults/main.json index 997702e..e59898d 100644 --- a/roles/nginx/defaults/main.json +++ b/roles/nginx/defaults/main.json @@ -1,3 +1,7 @@ { - "var_nginx_auto_reload_interval": null + "cfg_nginx_defaults": { + "auto_reload_interval": null, + "dhparam_size": null, + "improved_security": false + } } diff --git a/roles/nginx/tasks/main.json b/roles/nginx/tasks/main.json index 9748e6d..b03c46c 100644 --- a/roles/nginx/tasks/main.json +++ b/roles/nginx/tasks/main.json @@ -1,4 +1,11 @@ [ + { + "name": "show vars", + "when": "switch_show_vars", + "ansible.builtin.debug": { + "var": "vars.cfg_nginx" + } + }, { "name": "install packages", "become": true, @@ -12,9 +19,10 @@ }, { "name": "generate dhparams file", + "when": "cfg_nginx.dhparam_size != None", "become": true, "ansible.builtin.command": { - "cmd": "openssl dhparam -out /etc/nginx/dhparam 4096" + "cmd": "openssl dhparam -out /etc/nginx/dhparam {{cfg_nginx.dhparam_size | string}}" }, "args": { "creates": "/etc/nginx/dhparam" @@ -23,49 +31,54 @@ { "name": "place hardening config", "become": true, - "ansible.builtin.copy": { - "src": "ssl-hardening.conf", + "ansible.builtin.template": { + "src": "ssl-hardening.conf.j2", "dest": "/etc/nginx/ssl-hardening.conf" } }, { - "name": "ufw | check", - "become": true, - "check_mode": true, - "community.general.ufw": { - "state": "enabled" - }, - "register": "ufw_enable_check" - }, - { - "name": "ufw | allow port 80", - "when": "not ufw_enable_check.changed", - "become": true, - "community.general.ufw": { - "rule": "allow", - "port": "80", - "proto": "tcp" - } - }, - { - "name": "ufw | allow port 443", - "when": "not ufw_enable_check.changed", - "become": true, - "community.general.ufw": { - "rule": "allow", - "port": "443", - "proto": "tcp" - } + "name": "ufw", + "block": [ + { + "name": "check", + "become": true, + "check_mode": true, + "community.general.ufw": { + "state": "enabled" + }, + "register": "ufw_enable_check" + }, + { + "name": "allow port 80", + "when": "not ufw_enable_check.changed", + "become": true, + "community.general.ufw": { + "rule": "allow", + "port": "80", + "proto": "tcp" + } + }, + { + "name": "allow port 443", + "when": "not ufw_enable_check.changed", + "become": true, + "community.general.ufw": { + "rule": "allow", + "port": "443", + "proto": "tcp" + } + } + ] }, { "name": "auto reload", - "when": "var_nginx_auto_reload_interval == None", + "when": "cfg_nginx.auto_reload_interval == None", "become": true, "ansible.builtin.cron": { "name": "nginx_auto_reload", "disabled": true, "minute": "0", - "hour": "*/{{var_nginx_auto_reload_interval | string}}", + "hour": "*/{{cfg_nginx.auto_reload_interval | string}}", "day": "*", "month": "*", "weekday": "*", @@ -74,13 +87,13 @@ }, { "name": "auto reload", - "when": "var_nginx_auto_reload_interval != None", + "when": "cfg_nginx.auto_reload_interval != None", "become": true, "ansible.builtin.cron": { "name": "nginx_auto_reload", "disabled": false, "minute": "0", - "hour": "*/{{var_nginx_auto_reload_interval | string}}", + "hour": "*/{{cfg_nginx.auto_reload_interval | string}}", "day": "*", "month": "*", "weekday": "*", diff --git a/roles/nginx/templates/ssl-hardening.conf.j2 b/roles/nginx/templates/ssl-hardening.conf.j2 new file mode 100644 index 0000000..26d4e15 --- /dev/null +++ b/roles/nginx/templates/ssl-hardening.conf.j2 @@ -0,0 +1,20 @@ +ssl_session_timeout 1d; +ssl_session_cache shared:MozSSL:10m; # about 40000 sessions +ssl_session_tickets off; + +# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam +{% if cfg_nginx.dhparam_size != None %} +ssl_dhparam /etc/nginx/dhparam; +{% endif %} + +# intermediate configuration +ssl_protocols TLSv1.2 TLSv1.3; +ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305; +ssl_prefer_server_ciphers off; + +# HSTS (ngx_http_headers_module is required) (63072000 seconds) +add_header Strict-Transport-Security "max-age=63072000" always; + +# OCSP stapling +ssl_stapling on; +ssl_stapling_verify on;