configure traefik http security headers

This commit is contained in:
James Williams 2020-09-23 12:24:59 +01:00
parent a18ccd3523
commit da0a683f2f
No known key found for this signature in database
GPG Key ID: 7809F159246C673E
4 changed files with 46 additions and 8 deletions

1
.gitignore vendored
View File

@ -215,3 +215,4 @@ tags
.idea/ .idea/
.pytest_cache/ .pytest_cache/
.vscode/

View File

@ -1,6 +1,7 @@
{ {
"project_name": "My Awesome Project", "project_name": "My Awesome Project",
"project_slug": "{{ cookiecutter.project_name.lower()|replace(' ', '_')|replace('-', '_')|replace('.', '_')|trim() }}", "project_slug": "{{ cookiecutter.project_name.lower()|replace(' ', '_')|replace('-', '_')|replace('.', '_')|trim() }}",
"_extensions": ["cookiecutter.extensions.RandomStringExtension"],
"description": "Behold My Awesome Project!", "description": "Behold My Awesome Project!",
"author_name": "Daniel Roy Greenfeld", "author_name": "Daniel Roy Greenfeld",
"domain_name": "example.com", "domain_name": "example.com",

View File

@ -1,3 +1,4 @@
---
log: log:
level: INFO level: INFO
@ -30,6 +31,20 @@ certificatesResolvers:
httpChallenge: httpChallenge:
entryPoint: web entryPoint: web
tls:
# https://docs.traefik.io/https/tls/#tls-options
options:
default:
# see https://caniuse.com/tls1-2 for browsers that support TLS 1.2
minVersion: VersionTLS12
# see https://caniuse.com/sni for browsers that support SNI
sniStrict: true
# https://wiki.mozilla.org/Security/Server_Side_TLS
cipherSuites: # use only elliptic curve (the strongest) ciphers
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
http: http:
routers: routers:
web-secure-router: web-secure-router:
@ -42,6 +57,7 @@ http:
- web-secure - web-secure
middlewares: middlewares:
- csrf - csrf
- security-headers
service: django service: django
tls: tls:
# https://docs.traefik.io/master/routing/routers/#certresolver # https://docs.traefik.io/master/routing/routers/#certresolver
@ -52,6 +68,8 @@ http:
rule: "Host(`{{ cookiecutter.domain_name }}`)" rule: "Host(`{{ cookiecutter.domain_name }}`)"
entryPoints: entryPoints:
- flower - flower
middlewares:
- security-headers
service: flower service: flower
tls: tls:
# https://docs.traefik.io/master/routing/routers/#certresolver # https://docs.traefik.io/master/routing/routers/#certresolver
@ -64,6 +82,19 @@ http:
# https://docs.djangoproject.com/en/dev/ref/csrf/#ajax # https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
headers: headers:
hostsProxyHeaders: ["X-CSRFToken"] hostsProxyHeaders: ["X-CSRFToken"]
security-headers:
# https://docs.traefik.io/middlewares/headers/#general
headers:
# TODO increase stsSeconds to *at least* 31536000 (1 year) once HTTPS works
stsSeconds: 60
stsIncludeSubdomains: true
stsPreload: true
frameDeny: true
contentTypeNosniff: true
browserXssFilter: true
customResponseHeaders:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server
server: {{ random_ascii_string(10) }} # hide server version
services: services:
django: django:

View File

@ -43,17 +43,14 @@ CACHES = {
# SECURITY # SECURITY
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header {%- if cookiecutter.use_docker -%}
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") # NOTE headers are managed by the security-headers middleware in traefik.yml
{%- else -%}
# TODO set security headers in your load balancer if possible and remove these
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-ssl-redirect # https://docs.djangoproject.com/en/dev/ref/settings/#secure-ssl-redirect
SECURE_SSL_REDIRECT = env.bool("DJANGO_SECURE_SSL_REDIRECT", default=True) SECURE_SSL_REDIRECT = env.bool("DJANGO_SECURE_SSL_REDIRECT", default=True)
# https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-secure
SESSION_COOKIE_SECURE = True
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-secure
CSRF_COOKIE_SECURE = True
# https://docs.djangoproject.com/en/dev/topics/security/#ssl-https
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-seconds # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-seconds
# TODO: set this to 60 seconds first and then to 518400 once you prove the former works # TODO increase this to *at least* 31536000 (1 year) once HTTPS works
SECURE_HSTS_SECONDS = 60 SECURE_HSTS_SECONDS = 60
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains
SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool(
@ -65,6 +62,14 @@ SECURE_HSTS_PRELOAD = env.bool("DJANGO_SECURE_HSTS_PRELOAD", default=True)
SECURE_CONTENT_TYPE_NOSNIFF = env.bool( SECURE_CONTENT_TYPE_NOSNIFF = env.bool(
"DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True "DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True
) )
{%- endif -%}
# https://docs.djangoproject.com/en/dev/topics/security/#ssl-https
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
# https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-secure
SESSION_COOKIE_SECURE = True
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-secure
CSRF_COOKIE_SECURE = True
{% if cookiecutter.cloud_provider != 'None' -%} {% if cookiecutter.cloud_provider != 'None' -%}
# STORAGES # STORAGES