diff --git a/states/nginx/config.sls b/states/nginx/config.sls index f2d93c1..93959bb 100644 --- a/states/nginx/config.sls +++ b/states/nginx/config.sls @@ -11,10 +11,10 @@ nginx-config-{{ configfile }}: - group: {{ nginx.config.group }} - watch_in: - service: nginx-service - - watch: - - pki: pki-fetched - - require: - - sls: acme.* + #- watch: + # - pki: pki-fetched + #- require: + # - sls: acme.* {%- endfor %} nginx-config-wipe-default: @@ -58,6 +58,7 @@ nginx-sites-available-{{ key }}: dirs: {{ vhost.dirs|default([]) }} headers: {{ vhost.headers|default({}) }} php_socket_file: {{ nginx.config.php_socket_file }} + geoip: {{ nginx.config.geoip }} nginx-site-enabled-{{ key }}: file.symlink: diff --git a/states/nginx/defaults.yaml b/states/nginx/defaults.yaml index 27fdb8f..e6b9df9 100644 --- a/states/nginx/defaults.yaml +++ b/states/nginx/defaults.yaml @@ -6,8 +6,12 @@ nginx: - nginx-extras config: dir: /etc/nginx + geoip: false user: www-data group: www-data + workers: 4 + http_port: 8080 + https_port: 4443 php_socket_file: /run/php/php-fpm.sock subdirs: - auth diff --git a/states/nginx/map.jinja b/states/nginx/map.jinja index f5b1159..21baa15 100644 --- a/states/nginx/map.jinja +++ b/states/nginx/map.jinja @@ -2,5 +2,5 @@ {%- set nginx = salt['pillar.get']('nginx', default=defaults.nginx, merge=True) -%} -{%- set users = salt['pillar.get']('htpasswds', merge=True) -%} +{%- set users = salt['pillar.get']('htpasswds') -%} {%- set net = salt['pillar.get']('net') -%} \ No newline at end of file diff --git a/states/nginx/templates/access.j2 b/states/nginx/templates/access.j2 index 99fafea..abae1af 100644 --- a/states/nginx/templates/access.j2 +++ b/states/nginx/templates/access.j2 @@ -1,9 +1,14 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} {%- from "nginx/map.jinja" import net with context %} -{%- for key, value in net.ipv4_networks.items() %} -allow {{ value.ip }}/{{ value.mask }}; -{%- endfor %} -{%- for key, value in net.ipv6_networks.items() %} -allow {{ value.ip }}/{{ value.mask }}; -{%- endfor %} -deny all; \ No newline at end of file +real_ip_header X-Forwarded-For; +geo $allow { + {%- for key, value in net.ipv4_networks.items() %} + #allow {{ value.ip }}/{{ value.mask }}; + {{ value.ip }}/{{ value.mask }} 1; + {%- endfor %} + {%- for key, value in net.ipv6_networks.items() %} + #allow {{ value.ip }}/{{ value.mask }}; + {{ value.ip }}/{{ value.mask }} 1; + {%- endfor %} + default 0; +} \ No newline at end of file diff --git a/states/nginx/templates/fastcgi_params.j2 b/states/nginx/templates/fastcgi_params.j2 index 3dcd9d2..1092f36 100644 --- a/states/nginx/templates/fastcgi_params.j2 +++ b/states/nginx/templates/fastcgi_params.j2 @@ -1,27 +1,27 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} -fastcgi_param QUERY_STRING $query_string; -fastcgi_param REQUEST_METHOD $request_method; -fastcgi_param CONTENT_TYPE $content_type; -fastcgi_param CONTENT_LENGTH $content_length; +fastcgi_param QUERY_STRING $query_string; +fastcgi_param REQUEST_METHOD $request_method; +fastcgi_param CONTENT_TYPE $content_type; +fastcgi_param CONTENT_LENGTH $content_length; -fastcgi_param SCRIPT_NAME $fastcgi_script_name; -fastcgi_param REQUEST_URI $request_uri; -fastcgi_param DOCUMENT_URI $document_uri; -fastcgi_param DOCUMENT_ROOT $document_root; -fastcgi_param SERVER_PROTOCOL $server_protocol; -fastcgi_param HTTPS $https if_not_empty; +fastcgi_param SCRIPT_NAME $fastcgi_script_name; +fastcgi_param REQUEST_URI $request_uri; +fastcgi_param DOCUMENT_URI $document_uri; +fastcgi_param DOCUMENT_ROOT $document_root; +fastcgi_param SERVER_PROTOCOL $server_protocol; +fastcgi_param HTTPS $https if_not_empty; -fastcgi_param GATEWAY_INTERFACE CGI/1.1; -fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; +fastcgi_param GATEWAY_INTERFACE CGI/1.1; +fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; -fastcgi_param REMOTE_ADDR $remote_addr; -fastcgi_param REMOTE_PORT $remote_port; -fastcgi_param SERVER_ADDR $server_addr; -fastcgi_param SERVER_PORT $server_port; -fastcgi_param SERVER_NAME $server_name; +fastcgi_param REMOTE_ADDR $remote_addr; +fastcgi_param REMOTE_PORT $remote_port; +fastcgi_param SERVER_ADDR $server_addr; +fastcgi_param SERVER_PORT $server_port; +fastcgi_param SERVER_NAME $server_name; -fastcgi_param REDIRECT_STATUS 200; +fastcgi_param REDIRECT_STATUS 200; -fastcgi_pass_header Cookie; -fastcgi_ignore_headers Expires Cache-Control Set-Cookie; \ No newline at end of file +fastcgi_pass_header Cookie; +fastcgi_ignore_headers Expires Cache-Control Set-Cookie; \ No newline at end of file diff --git a/states/nginx/templates/http.j2 b/states/nginx/templates/http.j2 index bf8b0a3..491e2c2 100644 --- a/states/nginx/templates/http.j2 +++ b/states/nginx/templates/http.j2 @@ -1,4 +1,5 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "nginx/map.jinja" import nginx with context %} -listen 80; -listen [::]:80; \ No newline at end of file +listen {{ nginx.config.http_port }}; +listen [::]:{{ nginx.config.http_port }}; \ No newline at end of file diff --git a/states/nginx/templates/https.j2 b/states/nginx/templates/https.j2 index 1545f49..3efdf7f 100644 --- a/states/nginx/templates/https.j2 +++ b/states/nginx/templates/https.j2 @@ -1,4 +1,5 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "nginx/map.jinja" import nginx with context %} -listen 443 ssl http2; -listen [::]:443 ssl http2; \ No newline at end of file +listen {{ nginx.config.https_port }} ssl http2; +listen [::]:{{ nginx.config.https_port }} ssl http2; \ No newline at end of file diff --git a/states/nginx/templates/nginx.conf.j2 b/states/nginx/templates/nginx.conf.j2 index 39c0dd4..abb7953 100644 --- a/states/nginx/templates/nginx.conf.j2 +++ b/states/nginx/templates/nginx.conf.j2 @@ -1,57 +1,82 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "nginx/map.jinja" import nginx with context %} -user www-data; +{%- if nginx.config.geoip %} +load_module modules/ngx_http_geoip2_module.so; +{%- endif%} -worker_processes 4; +user {{ nginx.config.user }}; -error_log /var/log/nginx/error.log; -error_log syslog:server=localhost:514 info; +worker_processes {{ nginx.config.workers }}; + +error_log /var/log/nginx/error.log; +error_log syslog:server=localhost:514 info; events { worker_connections 1024; } http { - include fastcgi_params; - include proxy_params; - include mime.types; - include ssl_params; - charset utf-8; + include fastcgi_params; + include proxy_params; + include mime.types; + include ssl_params; + charset utf-8; - include sites-enabled/*; + include access; - log_format main '$remote_addr - $remote_user [$time_iso8601] ' - '"$request" $status $body_bytes_sent ' - '"$http_referer" "$http_user_agent"'; + {%- if nginx.config.geoip %} + geoip2 /usr/share/GeoIP/GeoLite2-ASN.mmdb { + $geoip2_asn default=0 autonomous_system_number; + $geoip2_org default=ISP autonomous_system_organization; + } - access_log /var/log/nginx/$host.access.log main; - access_log syslog:server=localhost:514 main; + geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb { + $geoip2_country_name default=England country names en; + $geoip2_city_name default=London city names en; + } + {%- endif %} - default_type application/octet-stream; - sendfile on; - keepalive_timeout 60; - server_tokens off; + include sites-enabled/*; - proxy_intercept_errors on; - fastcgi_intercept_errors on; - fastcgi_read_timeout 300; + log_format main '$http_x_forwarded_for - $remote_user [$time_iso8601] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent"'; + + access_log /var/log/nginx/$host.access.log main; + access_log syslog:server=localhost:514 main; + + default_type application/octet-stream; + sendfile on; + keepalive_timeout 60; + server_tokens off; + + proxy_intercept_errors on; + fastcgi_intercept_errors on; + fastcgi_read_timeout 300; + + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_proxied expired no-cache no-store private auth; + gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml; server { - listen 80 default_server; - listen 443 default_server ssl; + listen {{ nginx.config.http_port }} default_server; + listen [::]:{{ nginx.config.http_port }} default_server; - listen [::]:80 default_server; - listen [::]:443 default_server ssl; + listen {{ nginx.config.https_port }} default_server ssl http2; + listen [::]:{{ nginx.config.https_port }} default_server ssl http2; - root /var/www/html; - index index.html; + root /var/www/html; + index index.html; location /status { - stub_status on; - access_log off; - allow 127.0.0.1; - allow ::1; - deny all; + stub_status on; + access_log off; + allow 127.0.0.1; + allow ::1; + deny all; } } } diff --git a/states/nginx/templates/proxy_params.j2 b/states/nginx/templates/proxy_params.j2 index f802624..935c3e7 100644 --- a/states/nginx/templates/proxy_params.j2 +++ b/states/nginx/templates/proxy_params.j2 @@ -1,17 +1,17 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} -proxy_redirect off; -proxy_set_header Host $host; -proxy_set_header X-Real-IP $remote_addr; -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -client_max_body_size 0; -client_body_buffer_size 8192k; -proxy_connect_timeout 600; -proxy_send_timeout 600; -proxy_read_timeout 600; -proxy_buffers 32 4k; +proxy_redirect off; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +client_max_body_size 0; +client_body_buffer_size 8192k; +proxy_connect_timeout 600; +proxy_send_timeout 600; +proxy_read_timeout 600; +proxy_buffers 32 4k; -proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=cache:10m inactive=24h max_size=1g; -proxy_cache cache; -proxy_cache_valid 200 302 1h; -proxy_cache_valid 404 1d; \ No newline at end of file +proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=cache:10m inactive=24h max_size=1g; +proxy_cache cache; +proxy_cache_valid 200 302 1h; +proxy_cache_valid 404 1d; \ No newline at end of file diff --git a/states/nginx/templates/scgi_params.j2 b/states/nginx/templates/scgi_params.j2 index fe44b29..6c63cdd 100644 --- a/states/nginx/templates/scgi_params.j2 +++ b/states/nginx/templates/scgi_params.j2 @@ -1,18 +1,18 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} -scgi_param REQUEST_METHOD $request_method; -scgi_param REQUEST_URI $request_uri; -scgi_param QUERY_STRING $query_string; -scgi_param CONTENT_TYPE $content_type; +scgi_param REQUEST_METHOD $request_method; +scgi_param REQUEST_URI $request_uri; +scgi_param QUERY_STRING $query_string; +scgi_param CONTENT_TYPE $content_type; -scgi_param DOCUMENT_URI $document_uri; -scgi_param DOCUMENT_ROOT $document_root; -scgi_param SCGI 1; -scgi_param SERVER_PROTOCOL $server_protocol; -scgi_param REQUEST_SCHEME $scheme; -scgi_param HTTPS $https if_not_empty; +scgi_param DOCUMENT_URI $document_uri; +scgi_param DOCUMENT_ROOT $document_root; +scgi_param SCGI 1; +scgi_param SERVER_PROTOCOL $server_protocol; +scgi_param REQUEST_SCHEME $scheme; +scgi_param HTTPS $https if_not_empty; -scgi_param REMOTE_ADDR $remote_addr; -scgi_param REMOTE_PORT $remote_port; -scgi_param SERVER_PORT $server_port; -scgi_param SERVER_NAME $server_name; \ No newline at end of file +scgi_param REMOTE_ADDR $remote_addr; +scgi_param REMOTE_PORT $remote_port; +scgi_param SERVER_PORT $server_port; +scgi_param SERVER_NAME $server_name; \ No newline at end of file diff --git a/states/nginx/templates/ssl_params.j2 b/states/nginx/templates/ssl_params.j2 index 6207986..ef8de29 100644 --- a/states/nginx/templates/ssl_params.j2 +++ b/states/nginx/templates/ssl_params.j2 @@ -1,19 +1,19 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} -add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; -add_header X-Content-Type-Options nosniff; -add_header X-Frame-Options DENY; -add_header X-XSS-Protection "1; mode=block"; -resolver_timeout 5s; -ssl_certificate /etc/acme/certs/paulbsd.com.cert; -ssl_certificate_key /etc/acme/keys/paulbsd.com.key; -ssl_ciphers EECDH+AESGCM:EECDH+CHACHA20; -ssl_dhparam /etc/acme/dh/dh.pem; -ssl_ecdh_curve secp384r1; +add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; +add_header X-Content-Type-Options nosniff; +add_header X-Frame-Options DENY; +add_header X-XSS-Protection "1; mode=block"; +resolver_timeout 5s; +ssl_certificate /etc/acme/certs/paulbsd.com.cert; +ssl_certificate_key /etc/acme/keys/paulbsd.com.key; +ssl_ciphers EECDH+AESGCM:EECDH+CHACHA20; +ssl_dhparam /etc/acme/dh/dh.pem; +ssl_ecdh_curve secp384r1; ssl_prefer_server_ciphers on; -ssl_protocols TLSv1.3 TLSv1.2; -ssl_session_cache shared:SSL:10m; -ssl_session_tickets off; -ssl_session_timeout 5m; -ssl_stapling on; -ssl_stapling_verify on; +ssl_protocols TLSv1.3 TLSv1.2; +ssl_session_cache shared:SSL:10m; +ssl_session_tickets off; +ssl_session_timeout 5m; +ssl_stapling on; +ssl_stapling_verify on; diff --git a/states/nginx/templates/types/dip.j2 b/states/nginx/templates/types/dip.j2 index c45d181..64538b2 100644 --- a/states/nginx/templates/types/dip.j2 +++ b/states/nginx/templates/types/dip.j2 @@ -2,16 +2,16 @@ server { include http; - server_name {{ vhost_name }}; - if ($http_accept != '*/*') { - return 301 https://$server_name$request_uri; - } server_name {{ vhost_name }}; {%- if not proxy %} root "{{ root_dir }}"; {%- endif %} + if ($http_accept != '*/*') { + return 301 https://$server_name$request_uri; + } + {%- for key,value in headers.items() %} add_header {{ key }} "{{ value }}"; {%- endfor %} @@ -46,7 +46,10 @@ server { server { include https; {%- if internal_access %} - include access; + #include access; + if ($allow = 0) { + return 403; + } {%- endif %} server_name {{ vhost_name }}; {%- if not proxy %} diff --git a/states/nginx/templates/types/fdp.j2 b/states/nginx/templates/types/fdp.j2 deleted file mode 100644 index ff3194c..0000000 --- a/states/nginx/templates/types/fdp.j2 +++ /dev/null @@ -1,67 +0,0 @@ -## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} - -server { - include http; - server_name {{ vhost_name }}; - return 301 https://$server_name$request_uri; -} - -server { - include https; - {%- if internal_access %} - include access; - {%- endif %} - server_name {{ vhost_name }}; - {%- if not proxy %} - root "{{ root_dir }}"; - {%- endif %} - - {%- for key,value in headers.items() %} - add_header {{ key }} "{{ value }}"; - {%- endfor %} - - location / { - {%- if proxy %} - proxy_pass {{ proxy_pass }}; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $host; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header AppVhost $host; - {%- if not cache %} - proxy_no_cache 1; - proxy_cache_bypass 1; - {%- endif %} - {%- endif %} - {%- if autoindex %} - autoindex on; - autoindex_localtime on; - {%- else %} - index index.html index.rss; - {% endif %} - {%- if auth %} - auth_basic "Restricted area"; - auth_basic_user_file {{ config_dir }}/auth/htpasswd; - {%- endif %} - } - - {%- for dir in dirs %} - location {{ dir.name }} { - alias {{ dir.alias }}; - } - {%- endfor %} - location /socket.io { - proxy_pass {{ proxy_pass }}; - - proxy_http_version 1.1; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $host; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header AppVhost $host; - } - - location /robots.txt { - return 200 "User-agent: *\r\nDisallow: /"; - } -} diff --git a/states/nginx/templates/types/rd.j2 b/states/nginx/templates/types/rd.j2 index c72d6c4..94d76a9 100644 --- a/states/nginx/templates/types/rd.j2 +++ b/states/nginx/templates/types/rd.j2 @@ -9,7 +9,10 @@ server { server { include https; {%- if internal_access %} - include access; + #include access; + if ($allow = 0) { + return 403; + } {%- endif %} server_name {{ vhost_name }}; {%- if not proxy %} diff --git a/states/nginx/templates/types/simple.j2 b/states/nginx/templates/types/simple.j2 index 3a4c29c..6656a36 100644 --- a/states/nginx/templates/types/simple.j2 +++ b/states/nginx/templates/types/simple.j2 @@ -9,7 +9,10 @@ server { server { include https; {%- if internal_access %} - include access; + #include access; + if ($allow = 0) { + return 403; + } {%- endif %} server_name {{ vhost_name }}; {%- if not proxy %} @@ -17,7 +20,7 @@ server { {%- endif %} {%- for key,value in headers.items() %} - add_header {{ key }} "{{ value }}"; + add_header {{ key }} "{{ value }}"; {%- endfor %} location / { diff --git a/states/nginx/templates/types/vaultwarden.j2 b/states/nginx/templates/types/vaultwarden.j2 index d24a67e..9542744 100644 --- a/states/nginx/templates/types/vaultwarden.j2 +++ b/states/nginx/templates/types/vaultwarden.j2 @@ -9,7 +9,10 @@ server { server { include https; {%- if internal_access %} - include access; + #include access; + if ($allow = 0) { + return 403; + } {%- endif %} server_name {{ vhost_name }}; {%- if not proxy %} diff --git a/states/nginx/templates/uwsgi_params.j2 b/states/nginx/templates/uwsgi_params.j2 index d992536..d925b74 100644 --- a/states/nginx/templates/uwsgi_params.j2 +++ b/states/nginx/templates/uwsgi_params.j2 @@ -1,18 +1,18 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} -uwsgi_param QUERY_STRING $query_string; -uwsgi_param REQUEST_METHOD $request_method; -uwsgi_param CONTENT_TYPE $content_type; -uwsgi_param CONTENT_LENGTH $content_length; +uwsgi_param QUERY_STRING $query_string; +uwsgi_param REQUEST_METHOD $request_method; +uwsgi_param CONTENT_TYPE $content_type; +uwsgi_param CONTENT_LENGTH $content_length; -uwsgi_param REQUEST_URI $request_uri; -uwsgi_param PATH_INFO $document_uri; -uwsgi_param DOCUMENT_ROOT $document_root; -uwsgi_param SERVER_PROTOCOL $server_protocol; -uwsgi_param REQUEST_SCHEME $scheme; -uwsgi_param HTTPS $https if_not_empty; +uwsgi_param REQUEST_URI $request_uri; +uwsgi_param PATH_INFO $document_uri; +uwsgi_param DOCUMENT_ROOT $document_root; +uwsgi_param SERVER_PROTOCOL $server_protocol; +uwsgi_param REQUEST_SCHEME $scheme; +uwsgi_param HTTPS $https if_not_empty; -uwsgi_param REMOTE_ADDR $remote_addr; -uwsgi_param REMOTE_PORT $remote_port; -uwsgi_param SERVER_PORT $server_port; -uwsgi_param SERVER_NAME $server_name; \ No newline at end of file +uwsgi_param REMOTE_ADDR $remote_addr; +uwsgi_param REMOTE_PORT $remote_port; +uwsgi_param SERVER_PORT $server_port; +uwsgi_param SERVER_NAME $server_name; \ No newline at end of file