Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor NGINX configuration: add build dependencies, enhance security headers, and modularize configuration files #108

Merged
merged 1 commit into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -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
132 changes: 132 additions & 0 deletions nginx/default.conf
Original file line number Diff line number Diff line change
@@ -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/;
}
}
129 changes: 10 additions & 119 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -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;
}
Loading