Nginx proxy and Common setup Examples

Nginx proxy and Common setup Examples

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.