title: NGINX
category: Server
time: 1483942490486
---
# Normal NGINX Configuration

## Proxy (HTTP)
```
resolver 8.8.8.8;
server {
  listen 1188;
  location / {
    proxy_pass http://$http_host$request_uri;
  }
}
```

## Reverse Proxy
```
server {
  listen 80;
  server_name example.com;

  location / {
    proxy_pass http://google.com/;
    proxy_redirect default;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    port_in_redirect on;
    server_name_in_redirect off;
    proxy_connect_timeout 300;
  }
}
```

## Cached Reverse Proxy
**Need `cache` and `temp` directories for cache**

Following code should added below `log_format` directive in `nginx.conf`:
```
client_body_buffer_size  512k;
proxy_connect_timeout    5;
proxy_read_timeout       60;
proxy_send_timeout       5;
proxy_buffer_size        16k;
proxy_buffers            4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_temp_path   /var/cache/nginx/temp;
proxy_cache_path  /var/cache/nginx/cache levels=1:2 keys_zone=cache_one:500m inactive=7d max_size=30g;
```

VHost configuration:
```
proxy_cache cache_one;
proxy_cache_valid  200 304 3d;
proxy_cache_key $host$uri$is_args$args;
expires 10d;
```

## Reverse proxy for subdirectory
```
server {
  listen 80;
  server_name example.com;
  
  location / {
    proxy_pass http://sub.example.com/path;
    sub_filter /path/ /; # You may need this, otherwise comment it out.
    proxy_redirect off;
  }
}
```

## Set Expires Headers For Static Content
```
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
  expires 1y;
  log_not_found off;
}
```

## Increase HTTP Post Size Limit
```
http {
  #...
  client_max_body_size 100m;
  #...
}
```

## Set Correct Files/Folders Permissions
```
# Some server may using `www:www` instead of `www-data`
chown -R www-data:www-data .

# Find files type and change it to 644 (rw-r--r--)
# Find directory type and change it to 755 (drwxr-xr-x)
find . -type f -exec chmod 644 {} \;
find . -type d -exec chmod 755 {} \;
```

## Setup Basic-Auth on NGINX
Install `apache2-utils`
```
apt-get install apache2-utils
```

Create User and Password
```
htpasswd -c /etc/nginx/.htpasswd user
```

NGINX Configuration
```
server {
  #...
  location / {
    ...
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth User and Password
  }
  #...
}
```

# NGINX with SSL

## Global Configuration
```
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";

keepalive_timeout    70;
ssl_session_cache    shared:SSL:10m;
ssl_session_timeout  10m;
```

IE8/XP support
```
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS +RC4 RC4";
```

## Site Configuration
```
server {
  listen 443 ssl;
  ssl_certificate /etc/nginx/server.crt;
  ssl_certificate_key /etc/nginx/server.key;  
}
```

## Redirect to HTTPS
```
server {
  listen 80;
  server_name example.com;

  # Main part for redirect
  location / {
    return 301 https://example.com$request_uri;
  }
}
```

### As A Force-HTTPS Reverse Proxy
```
proxy_redirect   http:// $scheme://
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Scheme $scheme;
```

## HSTS
```
location / {
  add_header Strict-Transport-Security max-age=63072000;
  add_header X-Frame-Options DENY;
  add_header X-Content-Type-Options nosniff;
}
```

## Enable CORS (Wide-open CORS configuration for NGINX)
```
location / {
  add_header 'Access-Control-Allow-Origin' "*"; # Change this to domain name 
  add_header 'Access-Control-Allow-Credentials' 'true';
  add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
  add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With';
}
```

Tell client that this pre-flight info is valid for 20 days
```
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
```

# SSL

## Verify A .crt matches A .key
```
openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5
```

## Generating a .csr
```
openssl req -new -newkey rsa:2048 -nodes -keyout $DOMAIN.key -out $DOMAIN.csr
```

## Concatenate Certificates
```
cat domain.crt intermediate.pem root.pem > domain.signed.crt
```

## Avoid using SHA-1 as key exchange method, use Diffie Hellman Ephemeral parameters.
Generating DHE key
```
openssl dhparam -out dhparam.pem 4096 # use 2048 if you are on a low-end-box.
```

Set Nginx to use DHE key-exchange
```
ssl_dhparam /etc/ssl/certs/dhparam.pem;
```


***Reference***:
- [Nginx - PhoenixWiki](https://wiki.phoenixlzx.com/page/NGINX/)
- [Nginx - FelixWiki](http://wiki.felixc.at/nginx) && [Nginx SSL - FelixWiki](http://wiki.felixc.at/nginx_ssl)
- [CORS on Nginx](http://enable-cors.org/server_nginx.html)
