diff --git a/.gitignore b/.gitignore index 61a7b329..733d3f6e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ docker/env_file.backup.* docker/env_file_postgres.backup.* .env .env.backup.* +configuration/nginx/ssl.conf __pycache__/ mlmodels/ # Backups created by gbctl diff --git a/configuration/nginx/django_server.conf b/configuration/nginx/django_server.conf index 4fc17319..d4ca908b 100644 --- a/configuration/nginx/django_server.conf +++ b/configuration/nginx/django_server.conf @@ -1,13 +1,16 @@ server { - listen 80; + listen 80 default_server; - server_name greedybear.com; - - server_tokens off; charset utf-8; - # Locations - include locations.conf; + location = /hc { + return 200; + } + + location = /favicon.ico { + access_log off; + log_not_found off; + } location /static/ { alias /var/www/static/; diff --git a/configuration/nginx/http.conf b/configuration/nginx/http.conf index 85c14f32..bfdc7042 100644 --- a/configuration/nginx/http.conf +++ b/configuration/nginx/http.conf @@ -4,52 +4,13 @@ upstream django_main { } server { - listen 80; - server_name localhost; + listen 80 default_server; server_tokens off; # Locations include locations.conf; - location /static/ { - alias /var/www/static/; - } - - location ^~/admin { - uwsgi_pass django_main; - uwsgi_pass_header Authorization; - uwsgi_pass_request_headers on; - uwsgi_read_timeout 45; - include uwsgi_params; - uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; - client_max_body_size 20m; - } - - location ~^/api/feeds { - uwsgi_pass django_main; - uwsgi_pass_header Authorization; - uwsgi_pass_request_headers on; - uwsgi_read_timeout 600; - include uwsgi_params; - uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; - - gzip on; - gzip_types application/json application/x-ndjson text/csv text/plain; - gzip_min_length 1000; - } - - location / { - uwsgi_pass django_main; - uwsgi_pass_header Authorization; - uwsgi_pass_request_headers on; - uwsgi_read_timeout 45; - include uwsgi_params; - uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; - client_max_body_size 20m; - } - # Error pages include errors.conf; - -} \ No newline at end of file +} diff --git a/configuration/nginx/https.conf b/configuration/nginx/https.conf index caa106a2..70b7f025 100644 --- a/configuration/nginx/https.conf +++ b/configuration/nginx/https.conf @@ -4,68 +4,26 @@ upstream django_main { } server { - listen 80; - server_name greedybear.honeynet.com; + listen 80 default_server; - include locations.conf; + server_tokens off; - return 301 https://greedybear.honeynet.com$request_uri; + return 301 https://$host$request_uri; } server { - listen 443 ssl; - server_name greedybear.honeynet.com; - - ssl_protocols TLSv1.2 TLSv1.3; - ssl_certificate /usr/local/share/ca-certificates/greedybear.crt; - ssl_certificate_key /etc/ssl/private/greedybear.key; - ssl_password_file /etc/ssl/private/ssl_passwords.txt; - ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; - ssl_prefer_server_ciphers on; + listen 443 ssl default_server; server_tokens off; + # SSL configuration. + # Create it manually from ssl.conf.template before + # bringing the application up with HTTPS enabled. + include ssl.conf; + # Locations include locations.conf; - location /static/ { - alias /var/www/static/; - } - - location ^~/admin { - uwsgi_pass django_main; - uwsgi_pass_header Authorization; - uwsgi_pass_request_headers on; - uwsgi_read_timeout 45; - include uwsgi_params; - uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; - client_max_body_size 20m; - } - - location ~^/api/feeds { - uwsgi_pass django_main; - uwsgi_pass_header Authorization; - uwsgi_pass_request_headers on; - uwsgi_read_timeout 600; - include uwsgi_params; - uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; - - gzip on; - gzip_types application/json application/x-ndjson text/csv text/plain; - gzip_min_length 1000; - } - - location / { - uwsgi_pass django_main; - uwsgi_pass_header Authorization; - uwsgi_pass_request_headers on; - uwsgi_read_timeout 45; - include uwsgi_params; - uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; - client_max_body_size 20m; - } - # Error pages include errors.conf; - } diff --git a/configuration/nginx/locations.conf b/configuration/nginx/locations.conf index 46cef190..50fc67c0 100644 --- a/configuration/nginx/locations.conf +++ b/configuration/nginx/locations.conf @@ -1,8 +1,39 @@ -location /hc { - return 200; +uwsgi_pass_header Authorization; +uwsgi_pass_request_headers on; +uwsgi_read_timeout 45; +include uwsgi_params; +uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; +client_max_body_size 100m; + +location = /hc { + return 200; } location = /favicon.ico { - access_log off; - log_not_found off; -} \ No newline at end of file + access_log off; + log_not_found off; +} + +location /static/ { + alias /var/www/static/; + add_header Cache-Control "public, max-age=3600"; + + gzip on; + gzip_vary on; + gzip_min_length 1000; + gzip_types text/css text/javascript application/javascript application/json image/svg+xml; +} + +location / { + uwsgi_pass django_main; +} + +location ~^/api/feeds { + uwsgi_pass django_main; + uwsgi_read_timeout 600; + + gzip on; + gzip_vary on; + gzip_min_length 1000; + gzip_types application/json application/x-ndjson text/csv text/plain; +} diff --git a/configuration/nginx/ssl.conf.template b/configuration/nginx/ssl.conf.template new file mode 100644 index 00000000..56c02009 --- /dev/null +++ b/configuration/nginx/ssl.conf.template @@ -0,0 +1,19 @@ +# SSL settings for HTTPS deployment +# +# This is a template. Copy it and adapt the paths to your certificate and key: +# +# cp ssl.conf.template ssl.conf +# +# ssl.conf itself is git-ignored, so your settings survive updates of this repo. +# nginx refuses to start without it, since https.conf includes it. +# +# The commented directives are optional. +# Only uncomment them to deviate from the defaults. +# Set ssl_password_file if your private key is encrypted. + +ssl_certificate /usr/local/share/ca-certificates/greedybear.crt; +ssl_certificate_key /etc/ssl/private/greedybear.key; +# ssl_password_file /etc/ssl/private/ssl_passwords.txt; +# ssl_protocols TLSv1.2 TLSv1.3; +# ssl_ciphers HIGH:!aNULL:!MD5; +# ssl_prefer_server_ciphers on; diff --git a/docker/https.override.yml b/docker/https.override.yml index e57a6cc1..570df648 100644 --- a/docker/https.override.yml +++ b/docker/https.override.yml @@ -6,6 +6,7 @@ services: nginx: volumes: - ../configuration/nginx/https.conf:/etc/nginx/conf.d/default.conf + - ../configuration/nginx/ssl.conf:/etc/nginx/ssl.conf - /usr/local/share/ca-certificates:/usr/local/share/ca-certificates - /etc/ssl/private:/etc/ssl/private ports: diff --git a/gbctl b/gbctl index 8c3b5547..2447c5d5 100755 --- a/gbctl +++ b/gbctl @@ -512,6 +512,22 @@ ensure_django_secret() { fi } +# Ensures the nginx SSL config exists before starting with HTTPS enabled. +ensure_ssl_config() { + [ "$ENABLE_HTTPS" != true ] && return + + local ssl_conf="${SCRIPT_DIR}/configuration/nginx/ssl.conf" + + if [ -f "$ssl_conf" ]; then + return + fi + + log_error "HTTPS is enabled but configuration/nginx/ssl.conf is missing." + log_info "Create it from the template and adapt the certificate paths:" + log_info " cp configuration/nginx/ssl.conf.template configuration/nginx/ssl.conf" + exit 1 +} + # Execute docker compose command # --project-directory points to docker/ so that relative env_file paths # in compose files resolve correctly. --env-file loads .env from the @@ -662,6 +678,7 @@ cmd_up() { check_git_version_mismatch ensure_django_secret + ensure_ssl_config execute_compose up -d "$@" log_success "GreedyBear services started successfully!" }