From fcc87d0949f7fac7b9f12b83745b93619066ec14 Mon Sep 17 00:00:00 2001 From: kseen Date: Sun, 1 Dec 2024 09:48:02 +0300 Subject: [PATCH] Refactor NGINX configuration: add build dependencies, enhance security headers, and modularize configuration files --- nginx/Dockerfile | 37 +++++++++++-- nginx/default.conf | 132 +++++++++++++++++++++++++++++++++++++++++++++ nginx/nginx.conf | 129 ++++---------------------------------------- 3 files changed, 175 insertions(+), 123 deletions(-) create mode 100644 nginx/default.conf diff --git a/nginx/Dockerfile b/nginx/Dockerfile index d4a1a394..b326ada1 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -1,8 +1,37 @@ FROM nginx:1.27-alpine-slim -# Install curl for healthcheck -RUN apk add --no-cache curl +# Install build dependencies +RUN apk add --no-cache \ + curl \ + gcc \ + libc-dev \ + make \ + openssl-dev \ + pcre-dev \ + zlib-dev \ + linux-headers \ + wget \ + git -COPY ./nginx.conf /etc/nginx/conf.d/default.conf +# Get NGINX source and headers-more module +RUN cd /tmp && \ + wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz && \ + tar zxf nginx-${NGINX_VERSION}.tar.gz && \ + git clone https://github.com/openresty/headers-more-nginx-module.git && \ + cd nginx-${NGINX_VERSION} && \ + ./configure \ + --with-compat \ + --add-dynamic-module=../headers-more-nginx-module && \ + make modules && \ + cp objs/ngx_http_headers_more_filter_module.so /etc/nginx/modules/ && \ + cd / && \ + rm -rf /tmp/* -HEALTHCHECK --interval=1m30s --timeout=10s --start-period=40s --retries=3 CMD curl -so /dev/null http://localhost/ || exit 1 +# Clean up build dependencies +RUN apk del gcc libc-dev make openssl-dev pcre-dev zlib-dev linux-headers wget git + +# Copy configuration +COPY ./nginx.conf /etc/nginx/nginx.conf +COPY ./default.conf /etc/nginx/conf.d/default.conf + +HEALTHCHECK --interval=1m30s --timeout=10s --start-period=40s --retries=3 CMD curl -so /dev/null http://localhost/ || exit 1 \ No newline at end of file diff --git a/nginx/default.conf b/nginx/default.conf new file mode 100644 index 00000000..dbcf4d34 --- /dev/null +++ b/nginx/default.conf @@ -0,0 +1,132 @@ +upstream client { + server frontend; + server django; + server redis-commander; + server rabbitmq; +} + +server { + # Remove server information headers + server_tokens off; + + more_clear_headers Server; + more_clear_headers X-Powered-By; + more_clear_headers X-Runtime; + more_clear_headers X-Version; + more_clear_headers X-AspNet-Version; + more_clear_headers X-AspNetMvc-Version; + + # Add security headers + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN"; + # add_header X-Frame-Options "DENY" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + proxy_hide_header X-Powered-By; + proxy_hide_header Server; + proxy_hide_header X-Runtime; + proxy_hide_header X-Version; + proxy_hide_header Content-Security-Policy; + # Add Content Security Policy headers + add_header Content-Security-Policy " + default-src 'self'; + script-src 'self' 'unsafe-inline' 'unsafe-eval' + https://cdn.jsdelivr.net; + style-src 'self' 'unsafe-inline' + https://cdn.jsdelivr.net + https://fonts.googleapis.com; + img-src 'self' data: + https://cdn.jsdelivr.net + https://avatars.mds.yandex.net; + font-src 'self' data: + https://fonts.gstatic.com; + connect-src 'self' + ws://localhost:3000/ws + wss://localhost:3000/ws + ws://localhost:3000/socket + wss://localhost:3000/socket + http://127.0.0.1:8000 + https://127.0.0.1:8000; + frame-ancestors 'none'; + base-uri 'self'; + form-action 'self'; + object-src 'none'; + media-src 'self'; + " always; + + # Block access to metadata + location ~ ^/latest/meta-data/ { + deny all; + return 404; + } + + # Block direct access to AWS metadata IP + location ~ ^/169\.254\.169\.254 { + deny all; + return 404; + } + + listen 80; + + location / { + # Add security headers + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + + # Prevent proxy redirects to metadata + proxy_redirect off; + + proxy_pass http://frontend:3000/; + } + + location /api/ { + # Add security headers + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + + # Prevent proxy redirects to metadata + proxy_redirect off; + + proxy_pass http://django:8000/api/; + } + + location /static-dj/ { + # Add security headers + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + + # Prevent proxy redirects to metadata + proxy_redirect off; + + proxy_pass http://django:8000/static-dj/; + } + + location /redis-commander/ { + # Add security headers + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + + # Prevent proxy redirects to metadata + proxy_redirect off; + + proxy_pass http://redis-commander:8081/; + } + + location /rabbitmq/ { + # Add security headers + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + + # Prevent proxy redirects to metadata + proxy_redirect off; + + proxy_pass http://rabbitmq:15672/; + } +} \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 0c509178..40c04fb4 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -1,122 +1,13 @@ -upstream client { - server frontend; - server django; - server redis-commander; - server rabbitmq; -} - -server { - # Remove server information headers - server_tokens off; - proxy_hide_header X-Powered-By; - - # Add security headers - add_header X-Content-Type-Options "nosniff" always; - add_header X-Frame-Options "SAMEORIGIN"; - # add_header X-Frame-Options "DENY" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - - proxy_hide_header Content-Security-Policy; - # Add Content Security Policy headers - add_header Content-Security-Policy " - default-src 'self'; - script-src 'self' 'unsafe-inline' 'unsafe-eval' - https://cdn.jsdelivr.net; - style-src 'self' 'unsafe-inline' - https://cdn.jsdelivr.net - https://fonts.googleapis.com; - img-src 'self' data: - https://cdn.jsdelivr.net - https://avatars.mds.yandex.net; - font-src 'self' data: - https://fonts.gstatic.com; - connect-src 'self' - ws://localhost:3000/ws - wss://localhost:3000/ws - ws://localhost:3000/socket - wss://localhost:3000/socket - http://127.0.0.1:8000 - https://127.0.0.1:8000; - frame-ancestors 'none'; - base-uri 'self'; - form-action 'self'; - object-src 'none'; - media-src 'self'; - " always; - - # Block access to metadata - location ~ ^/latest/meta-data/ { - deny all; - return 404; - } - - # Block direct access to AWS metadata IP - location ~ ^/169\.254\.169\.254 { - deny all; - return 404; - } - - listen 80; +user nginx; +worker_processes auto; +load_module /etc/nginx/modules/ngx_http_headers_more_filter_module.so; - location / { - # Add security headers - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $http_host; - - # Prevent proxy redirects to metadata - proxy_redirect off; - - proxy_pass http://frontend:3000/; - } - - location /api/ { - # Add security headers - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $http_host; - - # Prevent proxy redirects to metadata - proxy_redirect off; - - proxy_pass http://django:8000/api/; - } - - location /static-dj/ { - # Add security headers - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $http_host; - - # Prevent proxy redirects to metadata - proxy_redirect off; - - proxy_pass http://django:8000/static-dj/; - } - - location /redis-commander/ { - # Add security headers - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $http_host; - - # Prevent proxy redirects to metadata - proxy_redirect off; - - proxy_pass http://redis-commander:8081/; - } +events { + worker_connections 1024; +} - location /rabbitmq/ { - # Add security headers - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $http_host; - - # Prevent proxy redirects to metadata - proxy_redirect off; - - proxy_pass http://rabbitmq:15672/; - } +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + include /etc/nginx/conf.d/*.conf; } \ No newline at end of file