Unverified Commit fc77ff08 by Cory Lee Committed by GitHub

Handle http->https redirect internal ip disclosure. Also refactored a… (#4475)

* Handle http->https redirect internal ip disclosure. Also refactored and cleaned up nginx config.

* WIP

* WIP

* WIP

* WIP

* Changed 404 to 403 as it seems more appropriate, and will be easier to find if it causes something to break

* Fixes
parent 2af386c1
...@@ -2,125 +2,30 @@ ...@@ -2,125 +2,30 @@
# {{ ansible_managed }} # {{ ansible_managed }}
# #
{% if nginx_default_sites is defined and edx_django_service_name in nginx_default_sites %} {% include "concerns/upstream.j2"%}
{% set default_site = "default_server" %} {% include "concerns/cors-build-map.j2" %}
{% else %}
{% set default_site = "" %}
{% endif %}
upstream {{ edx_django_service_name }}_app_server {
{% for host in nginx_edx_django_service_gunicorn_hosts %}
server {{ host }}:{{ edx_django_service_gunicorn_port }} fail_timeout=0;
{% endfor %}
}
# The Origin request header indicates where a fetch originates from. It doesn't include any path information, server {
# but only the server name (e.g. https://www.example.com). server_name {{ edx_django_service_hostname }};
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin for details. listen {{ edx_django_service_nginx_port }};
# {% if NGINX_ENABLE_SSL %}
# Here we set the value that is included in the Access-Control-Allow-Origin response header. If the origin is one if ( $host ~ "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}") {
# of our known hosts--served via HTTP or HTTPS--we allow for CORS. Otherwise, we set the "null" value, disallowing CORS. return 403;
map $http_origin $cors_origin { }
default "null"; rewrite ^ https://$host$request_uri? permanent;
{% for host in edx_django_service_cors_whitelist %} {% else %}
"~*^https?:\/\/{{ host|replace('.', '\.') }}$" $http_origin; {% include "concerns/app-common.j2" %}
{% endfor %} {% endif %}
} }
{% if NGINX_ENABLE_SSL %}
server { server {
server_name {{ edx_django_service_hostname }}; server_name {{ edx_django_service_hostname }};
{% if EDX_DJANGO_SERVICE_ENABLE_S3_MAINTENANCE %}
# Do not include a 502 error in NGINX_ERROR_PAGES when
# EDX_DJANGO_SERVICE_ENABLE_S3_MAINTENANCE is enabled.
error_page 502 @maintenance;
{% include "s3_maintenance.j2" %}
{% endif %}
{% if NGINX_ENABLE_SSL %}
listen {{ edx_django_service_nginx_port }} {{ default_site }};
listen {{ edx_django_service_ssl_nginx_port }} ssl; listen {{ edx_django_service_ssl_nginx_port }} ssl;
ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }}; ssl_certificate /etc/ssl/certs/{{ NGINX_SSL_CERTIFICATE|basename }};
ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }}; ssl_certificate_key /etc/ssl/private/{{ NGINX_SSL_KEY|basename }};
# request the browser to use SSL for all connections
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
{% else %} {% include "concerns/app-common.j2" %}
listen {{ edx_django_service_nginx_port }} {{ default_site }};
{% endif %}
location ~ ^/static/(?P<file>.*) {
root {{ COMMON_DATA_DIR }}/{{ edx_django_service_name }};
add_header 'Access-Control-Allow-Origin' $cors_origin;
# Inform downstream caches to take certain headers into account when reading/writing to cache.
add_header 'Vary' 'Accept-Encoding,Origin';
try_files /staticfiles/$file =404;
}
location ~ ^/media/(?P<file>.*) {
root {{ COMMON_DATA_DIR }}/{{ edx_django_service_name }};
try_files /media/$file =404;
}
location / {
{% if edx_django_service_enable_basic_auth|bool %}
{% include 'basic-auth.j2' %}
{% endif %}
try_files $uri @proxy_to_app;
}
location ~ ^/({{ edx_django_service_basic_auth_exempted_paths | join('|') }})/ {
try_files $uri @proxy_to_app;
}
{% if NGINX_DJANGO_ADMIN_ACCESS_CIDRS and EDX_DJANGO_SERVICE_ENABLE_DJANGO_ADMIN_RESTRICTION %}
location /admin {
{% for cidr in NGINX_DJANGO_ADMIN_ACCESS_CIDRS %}
allow {{ cidr }};
{% endfor %}
deny all;
try_files $uri @proxy_to_app;
}
{% endif %}
{% include 'robots.j2' %}
location @proxy_to_app {
{% if NGINX_SET_X_FORWARDED_HEADERS %}
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $remote_addr;
{% else %}
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header X-Forwarded-Port $http_x_forwarded_port;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
{% endif %}
# newrelic-specific header records the time when nginx handles a request.
proxy_set_header X-Queue-Start "t=${msec}";
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://{{ edx_django_service_name }}_app_server;
}
# Forward to HTTPS if we're an HTTP request...
if ($http_x_forwarded_proto = "http") {
set $do_redirect "true";
}
# Run our actual redirect...
if ($do_redirect = "true") {
rewrite ^ https://$host$request_uri? permanent;
}
} }
{% endif %}
{% include "concerns/s3_maintenance.j2" %}
{% include "concerns/static-assets.j2" %}
{% include "concerns/proxy-to-app.j2" %}
satisfy any; {% if edx_django_service_enable_basic_auth|bool %}
satisfy any;
allow 127.0.0.1; allow 127.0.0.1;
{% for cidr in COMMON_BASIC_AUTH_EXCEPTIONS %} {% for cidr in COMMON_BASIC_AUTH_EXCEPTIONS %}
allow {{ cidr }}; allow {{ cidr }};
{% endfor %} {% endfor %}
deny all; deny all;
auth_basic "Restricted"; auth_basic "Restricted";
auth_basic_user_file {{ nginx_htpasswd_file }}; auth_basic_user_file {{ nginx_htpasswd_file }};
index index.html index index.html
proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Proto https;
{% endif %}
# The Origin request header indicates where a fetch originates from. It doesn't include any path information,
# but only the server name (e.g. https://www.example.com).
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin for details.
# Here we set the value that is included in the Access-Control-Allow-Origin response header. If the origin is one
# of our known hosts--served via HTTP or HTTPS--we allow for CORS. Otherwise, we set the "null" value, disallowing CORS.
map $http_origin $cors_origin {
default "null";
{% for host in edx_django_service_cors_whitelist %}
"~*^https?:\/\/{{ host|replace('.', '\.') }}$" $http_origin;
{% endfor %}
}
{% if NGINX_DJANGO_ADMIN_ACCESS_CIDRS and EDX_DJANGO_SERVICE_ENABLE_DJANGO_ADMIN_RESTRICTION %}
location /admin {
{% for cidr in NGINX_DJANGO_ADMIN_ACCESS_CIDRS %}
allow {{ cidr }};
{% endfor %}
deny all;
try_files $uri @proxy_to_app;
}
{% endif %}
location / {
{% include 'concerns/basic-auth.j2' %}
try_files $uri @proxy_to_app;
}
location ~ ^/({{ edx_django_service_basic_auth_exempted_paths | join('|') }})/ {
try_files $uri @proxy_to_app;
}
{% include 'concerns/robots.j2' %}
{% include "concerns/django_admin_access_from_restricted_cidrs.j2" %}
location @proxy_to_app {
{% if NGINX_SET_X_FORWARDED_HEADERS %}
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $remote_addr;
{% else %}
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header X-Forwarded-Port $http_x_forwarded_port;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
{% endif %}
# newrelic-specific header records the time when nginx handles a request.
proxy_set_header X-Queue-Start "t=${msec}";
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://{{ edx_django_service_name }}_app_server;
}
{% if NGINX_ROBOT_RULES|length > 0 %} {% if NGINX_ROBOT_RULES|length > 0 %}
location /robots.txt { location /robots.txt {
root {{ nginx_app_dir }}; root {{ nginx_app_dir }};
try_files $uri /robots.txt =404; try_files $uri /robots.txt =404;
} }
{% endif %} {% endif %}
# This file was copied from playbooks/roles/nginx/templates/edx/app/nginx/sites-available/
# modifications should be made to both files if necessary.
{% if EDX_DJANGO_SERVICE_ENABLE_S3_MAINTENANCE %} {% if EDX_DJANGO_SERVICE_ENABLE_S3_MAINTENANCE %}
location @maintenance { # Do not include a 502 error in NGINX_ERROR_PAGES when
# EDX_DJANGO_SERVICE_ENABLE_S3_MAINTENANCE is enabled.
error_page 502 @maintenance;
# This section of the file was copied from playbooks/roles/nginx/templates/edx/app/nginx/sites-available/
# modifications should be made to both files if necessary.
{% if EDX_DJANGO_SERVICE_ENABLE_S3_MAINTENANCE %}
location @maintenance {
rewrite ^(.*) {{ EDX_DJANGO_SERVICE_S3_MAINTENANCE_FILE }} break; rewrite ^(.*) {{ EDX_DJANGO_SERVICE_S3_MAINTENANCE_FILE }} break;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host s3.amazonaws.com; proxy_set_header Host s3.amazonaws.com;
...@@ -14,5 +20,6 @@ location @maintenance { ...@@ -14,5 +20,6 @@ location @maintenance {
proxy_buffering off; proxy_buffering off;
proxy_intercept_errors on; proxy_intercept_errors on;
proxy_pass https://s3.amazonaws.com; proxy_pass https://s3.amazonaws.com;
} }
{% endif %}
{% endif %} {% endif %}
location ~ ^/static/(?P<file>.*) {
root {{ COMMON_DATA_DIR }}/{{ edx_django_service_name }};
{% include "concerns/cors-add-header.j2" %}
# Inform downstream caches to take certain headers into account when reading/writing to cache.
add_header 'Vary' 'Accept-Encoding,Origin';
try_files /staticfiles/$file =404;
}
location ~ ^/media/(?P<file>.*) {
root {{ COMMON_DATA_DIR }}/{{ edx_django_service_name }};
try_files /media/$file =404;
}
upstream {{ edx_django_service_name }}_app_server {
{% for host in nginx_edx_django_service_gunicorn_hosts %}
server {{ host }}:{{ edx_django_service_gunicorn_port }} fail_timeout=0;
{% endfor %}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment