Nginx proxy and Common setup Examples

As a passionate DevOps Engineer with 3+ years of experience, I specialize in building robust, scalable, and secure infrastructures. My expertise spans Kubernetes, Jenkins, Docker, AWS, Ansible, Flask, Apache, Nginx, Kibana, Uyuni, Percona PMM, MySQL, and more.
Nginx drop invalid requests
(Commonly, configuration must be done in production.)
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}
server {
listen 443 ssl;
server_name _;
ssl on;
ssl_certificate /home/ubuntu.pem;
ssl_certificate_key /home/ubuntu.key;
return 444;
}
Common security headers
### headers ####
proxy_hide_header X-Powered-By;
add_header X-Frame-Options SAMEORIGIN;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy "strict-origin";
add_header X-XSS-Protection "1; mode=block";
add_header Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()";
server_tokens off;
#####headers close ####
Note : use CSP carefully as it may break code in browsers
More Header type
common CORS headers
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow_Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
Block request by type
(can be used inside proxy directive and multiple times in server directive )
# Only allow these request methods, Do not accept DELETE, SEARCH and other methods
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 404;
}
Common Proxy config
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://127.0.0.1:8888/";
try_files $uri $uri/ =404;
}
or
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Referrer-Policy strict-origin;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass "http://127.0.0.1:8888/";
try_files $uri $uri/ =404;
}
or
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_pass "http://127.0.0.1:8888/";
try_files $uri $uri/ =404;
}
WebSocket proxy
location / {
proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
Turn OFF server tokens
server_tokens off;
add above in server directive or directly include in nginx.conf
Set Expiry for objects
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
Denying request and turning off logs
location = /robots.txt {
deny all;
access_log off;
}
SSL headers
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
php hosting
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Redirection by host
if ($host = www.example.com) {
return 301 https://$host$request_uri;
}
if ($host = example.com) {
return 301 https://$host$request_uri;
}
Match and alias a folder
location /static/ {
alias /var/www/example/examplecore/static/;
}
logging and client upload size
client_max_body_size 250m;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
Nginx timeouts
client_header_timeout 10s;
client_body_timeout 10s;
send_timeout 10s;
keepalive_timeout 60s;
proxy_read_timeout 120s;
proxy_connect_timeout 10s;
As Load balancer
http {
upstream backend {
server backend1.example.com:80;
server backend2.example.com:80;
server backend3.example.com:80;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
Nginx cache
add the below lines in nginx.conf
proxy_cache_path /data/nginx/cache keys_zone=mycache:200m;
Add the below to the server block
server{
## other configs
proxy_cache mycache;
add_header X-Proxy-Cache $upstream_cache_status;
}
Nginx Status
location = /nginx_status {
stub_status on;
#allow 192.168.10.0/24;
allow 172.16.0.0/24;
allow 127.0.0.1;
deny all;
# auth_basic "No Welcome X";
# auth_basic_user_file /etc/nginx/.htpasswd;# can also add auth
}
Match multiple paths
location ~* ^/(path1|path2|path3|path4|path5|path6)/ {
try_files $uri /$1/index.php?$query_string; ###other blocks
}
Adding multiple redirections
include conf.d/redirect/url_redirects;
add redirects as below block
if ($request_uri = /ind/mint ) {return 301 https://example.co ; }
if ($request_uri = /ind/mint2 ) {return 301 https://example.co/mint ; }
Optional headers
resolver 8.8.8.8 8.8.4.4;
ssl_stapling on;
ssl_stapling_verify on;
There are many configs. you can take a look at nginx official docs.






