diff --git a/salt/nginx/config.map.jinja b/salt/nginx/config.map.jinja new file mode 100644 index 000000000..10121c7a8 --- /dev/null +++ b/salt/nginx/config.map.jinja @@ -0,0 +1,3 @@ +{% import_yaml 'nginx/defaults.yaml' as NGDEFAULTS %} + +{% set NGMERGED = salt['pillar.get']('nginx', NGDEFAULTS.nginx, merge=True) %} diff --git a/salt/nginx/defaults.yaml b/salt/nginx/defaults.yaml index cf051274b..0e222c29e 100644 --- a/salt/nginx/defaults.yaml +++ b/salt/nginx/defaults.yaml @@ -1,3 +1,5 @@ nginx: config: - replace_cert: False \ No newline at end of file + replace_cert: False + throttle_login_burst: 6 + throttle_login_rate: 10 \ No newline at end of file diff --git a/salt/nginx/etc/nginx.conf b/salt/nginx/etc/nginx.conf index 502f6302a..f2525b6a9 100644 --- a/salt/nginx/etc/nginx.conf +++ b/salt/nginx/etc/nginx.conf @@ -1,5 +1,6 @@ {%- from 'vars/globals.map.jinja' import GLOBALS %} {%- from 'docker/docker.map.jinja' import DOCKER %} +{%- from 'nginx/config.map.jinja' import NGMERGED %} {%- set role = grains.id.split('_') | last %} {%- set influxpass = salt['pillar.get']('secrets:influx_pass') %} {%- set influxauth = ('so:' + influxpass) | base64_encode %} @@ -33,6 +34,8 @@ http { include /etc/nginx/mime.types; default_type application/octet-stream; + limit_req_zone $binary_remote_addr zone=auth_throttle:10m rate={{ NGMERGED.config.throttle_login_rate }}r/m; + include /etc/nginx/conf.d/*.conf; {%- if role in ['eval', 'managersearch', 'manager', 'standalone', 'import'] %} @@ -143,7 +146,21 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } - location ~ ^/auth/.*?(whoami|login|logout|settings) { + location ~ ^/auth/.*?(login) { + rewrite /auth/(.*) /$1 break; + limit_req zone=auth_throttle burst={{ NGMERGED.config.throttle_login_burst }} nodelay; + limit_req_status 429; + proxy_pass http://{{ GLOBALS.manager }}:4433; + proxy_read_timeout 90; + proxy_connect_timeout 90; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Proxy ""; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location ~ ^/auth/.*?(whoami|logout|settings) { rewrite /auth/(.*) /$1 break; proxy_pass http://{{ GLOBALS.manager }}:4433; proxy_read_timeout 90; @@ -276,6 +293,7 @@ http { error_page 401 = @error401; error_page 403 = @error403; + error_page 429 = @error429; location @error401 { add_header Set-Cookie "AUTH_REDIRECT=$request_uri;Path=/;Max-Age=14400"; @@ -287,6 +305,10 @@ http { return 302 /auth/self-service/login/browser; } + location @error429 { + return 302 /login/?thr={{ (120 / NGMERGED.config.throttle_login_rate) | round | int }}; + } + error_page 500 502 503 504 /50x.html; location = /usr/share/nginx/html/50x.html { } diff --git a/salt/nginx/html/favicon-16x16.png b/salt/nginx/html/favicon-16x16.png deleted file mode 100644 index a0a818d20..000000000 Binary files a/salt/nginx/html/favicon-16x16.png and /dev/null differ diff --git a/salt/nginx/html/favicon-32x32.png b/salt/nginx/html/favicon-32x32.png deleted file mode 100644 index b1b38d711..000000000 Binary files a/salt/nginx/html/favicon-32x32.png and /dev/null differ diff --git a/salt/nginx/html/favicon.ico b/salt/nginx/html/favicon.ico deleted file mode 100644 index 41e85a108..000000000 Binary files a/salt/nginx/html/favicon.ico and /dev/null differ diff --git a/salt/nginx/html/index.html b/salt/nginx/html/index.html deleted file mode 100644 index 70d1ddfb0..000000000 --- a/salt/nginx/html/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - -Security Onion - Hybrid Hunter - - - - - - -Security Onion - - diff --git a/salt/nginx/init.sls b/salt/nginx/init.sls index c66af0837..3551c2920 100644 --- a/salt/nginx/init.sls +++ b/salt/nginx/init.sls @@ -2,6 +2,7 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls in allowed_states %} {% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'nginx/config.map.jinja' import NGMERGED %} include: - ssl @@ -9,18 +10,11 @@ include: # Drop the correct nginx config based on role nginxconfdir: file.directory: - - name: /opt/so/conf/nginx/html + - name: /opt/so/conf/nginx - user: 939 - group: 939 - makedirs: True -nginxhtml: - file.recurse: - - name: /opt/so/conf/nginx/html - - source: salt://nginx/html/ - - user: 939 - - group: 939 - nginxconf: file.managed: - name: /opt/so/conf/nginx/nginx.conf diff --git a/salt/nginx/soc_nginx.yaml b/salt/nginx/soc_nginx.yaml index b78550c2b..b18e83f42 100644 --- a/salt/nginx/soc_nginx.yaml +++ b/salt/nginx/soc_nginx.yaml @@ -20,3 +20,11 @@ nginx: advanced: True global: True helpLink: nginx.html + throttle_login_burst: + description: Number of login requests that can burst without triggering request throttling. Higher values allow more repeated login attempts. Values greater than zero are required in order to provide a usable login flow. + global: True + helpLink: nginx.html + throttle_login_rate: + description: Number of login API requests per minute that can be processed without triggering a rate limit. Higher values allow more repeated login attempts. Requests are counted by unique client IP and averaged over time. Note that a single login flow will perform multiple requests to the login API, so this value will need to be adjusted accordingly. + global: True + helpLink: nginx.html