Nginx

HTTP protocol GET /documentary.mp4  I Want to watch only first 20 second of the documentary.mp4 -->
 * partial GET Request- GET /documentary.mp4 HTTP/1.1 Host:example.com Range:0-1024

<--- HTTP/1.1 206 Partial Content. Here is first 20 second worth of data curl -I example.com/partial.txt curl --header "Range: bytes=10-20" example.com/partial.txt curl -I --header "If-Modified-SInce: Sat, 05 Dec 2015 09:49:22 GMT" example.com/partial.txt
 * conditional GET Request   - GET /sanple.html HTTP 1.1 Host:example.com If-Modified-Since, 29 Oct 2015 19:43:31 GMT. If is not modified it responds with code 205 not modified


 *  HTTP - POST   -   Used  to send some data to the server to be processed in some way.

​      Example: POST/login.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Lenght: 32 user=admin password=test123 Below are HEADER FIELDS from HTTP request ​       HTTP/1.0 200 OK         DATE: Fri, 31 Dec 2015 23:59:59 GMT Content-Type: text/html Content-Lenght:1354 Cache-Control: public  Below is message body                           
 * HTTP-HEAD - 

Happy New Millenium! (more file content)  HEAD - Identical to GET request execpt Server should not return message-body in response

          curl -I example.com

         Used to find a lot of information about a particular file without downloading it.
 * 1)         Last modified Date
 * 2)        Content Lenght, Content type
 * 3)        Cache Timings associated with it

Curl -X "Trace" example.com ​          curl -X OPTIONS http://example.com/login.html -i
 * HTTP TRACE - 
 *  HTTP -OPTIONS

Some files like mp3 allow for GET,HEAD and some login.php allow also for POST Indicates that action received by client is: Received, Understood, Accepted, Processed For example: 200 OK '''     3. 300-399 - Redirection Status codes''' Indicates that client must take additional steps to complete the requests. Many of them are used in URL redirection. For example : 301 Moved Permamently, 304 Not Modified      4. 400-499  Client Error Status codes Indicates that client seemed to have sent some errored request. Example: 401-Unauthorized, 403: Forbidden, 404 - Page Not Found      5. 500-599  Server Error Status codes Server failed to fulfill a valid client request. Example: 500 - internal server error Nginx Features:
 * HTTP Response status Code:
 * 1) 100-199 - Informational status 
 * 2) 200-299 - Success Status codes 
 * Is an open source reverse proxy server for HTTP,HTTPS,SMTP,POP3 and IMAP protocol as well as load balancer, HTTP cache and a web server.
 * Nginx uses asynchronous event-driver handler for requests. This allows nginx to more accurately provide predictable performance under very high load
 * Handles static files, index files and auto-indexing
 * Reverse proxy with caching abilities
 * Load balancing of nodes
 * Support fault tolerance
 * Open SSL support for certficates
 * FastCGI, PHP-FPM and SCGI support
 * Fully IPv6 compatibile
 * Websockets and HTTP/1.1
 * Live stream file compression
 * URL redirects and rewriting
 * Bandwidth throttling
 * Geolocations of Ips
 * Very low memory footprint - more than 10k concurrent connections with only ~2.5 mb of memory fo keep-alive sessions

Configuration changes:
 * /etc/nginx/nginx.conf:
 * include /etc/nginx/vhost.d/*.conf;
 * mkdir -p /var/www/html
 * vim /etc/nginx/vhost.d/default
 * server {

    listen 80 default_server;     server_name _; } location / { root /var/www/html;  index index.html index.htm;      }
 * echo "NEW configuration" >> /var/www/html/index.html
 * nginx -t to check configuration
 * example of new vhost :
 * mkdir -p /var/www/html/myexample
 * echo "www.myexample.local >> /var/www/html/myexample/index.html'
 * echo "private IP www.myexample.local myexample >> /etc/hosts
 * vim /etc/nginx/vhost.d/www.myexample.local
 * server {

   listen 80;    root /var/www/html/myexample;    index index.html index.htm index.php;    server_name www.myexample.local myexample;          } Location block
 * nginx -t
 * systemctl reload nginx
 * lynx http://myexample.local
 * location ~/greet[0-9] { return 200 'Hello from NGINX case sensitive regex match location block' };
 * location *~ /greet[0-9] { return 200 'Hello from NGINX case insensitive regex match location block' }
 * location ^~/greet { return 200 'Hello from Nginx match with preference over regex location block!' ;
 * Matching order :
 * 1) ​ = Exact match
 * 2) ^~ Preferential Prefix - same as standard match but more important than regex
 * 3) ~&*~ Regex match
 * 4) no modifier Prefix Match no modifier

Nginx as reverse proxy, what can do:
 * It hides existence of the orgin backend servers
 * Can protect the server from web-based attacks,DOS
 * Can provide great Caching functionality
 * can optimize content by compressing it
 * can act as SSL terminating proxy
 * request routing

Understanding proxy_pass directive


 * Forwards the request to the proxied serves specified along with this directive
 * location / { proxy pass http://192.168.10.50;}
 * location /admin { proxy_pass http:192.168.10.50; }
 * location /app { proxy_pass http://192.168.10.100/application;}

Need for X-REAL-IP
 * If we request to server1 which is reverse proxy to backed server2, the backed server only sees that server1 is requesting connection not computer client
 * proxy_set_header X-Real IP $remote_addr; after proxy_pass!
 * a in log format we can add "$http_x_real_ip"

Proxy Host header


 * Client sends request to the nginx reverse proxy as GET/index.html GET/HTTP 1.1 host kp.in
 * Nginx reverse proxy remove additional header host kp.in and sends only to backend  GET/HTTP 1.1
 * This is not problem since backend server serves only one site
 * to resolve that add proxy_set_header Host $host;

Example of using upstream module
 * vim /etc/nginx/vhost.d/www.mynode.local
 * upstream mynode {

         server localhost:8888;}  server {            server_name www.mynode.local mynode; }  location / {                 proxy_pass http://mynode<span style="font-family:Helvetica,Arial,sans-serif;">; <span style="font-family:Helvetica,Arial,sans-serif;">              }
 * echo "private IP www.mynode.local mynode >> /etc/hosts
 * yum install npm node-js
 * mkdir -p /var/www/html/mynode
 * touch myserver.js and paste to it code from : https://gist.github.com/ryanflorence/701407
 * nodejs myserver.js &
 * nginx -t
 * systemctl reload nginx
 * echo " this is our nodejs html file" >> /var/www/html/nodejs/index.html
 * first check with lynx http://localhost:8888
 * turn off selinux for while when you have error 502

Basic load balancing
 * cp ​/var/www/html/mynode/myserver.js to myserver2.js
 * cp ​ /var/www/html/mynode/index.html to index2.html
 * edit myserver2.js to support 8889 port and index2.html file
 * run new server2
 * edit /etc/nginx/vhost.d/www.mynode.local. In normal version it would be round robin but we can add weight so server2 will be 4 times more used.
 * if we add after ip address directive down; it means that that server won't be used, server 192.169.122.32 down;
 * upstream mynode {

server localhost:8888 weight=1; <span style="font-family:Helvetica,Arial,sans-serif;"> server localhost:8889 weight=4; <span style="font-family:Helvetica,Arial,sans-serif;">} <span style="font-family:Helvetica,Arial,sans-serif;">server { listen 80; server_name example.com; } <span style="font-family:Helvetica,Arial,sans-serif;">location / { <span style="font-family:Helvetica,Arial,sans-serif;">proxy_pass http://mynode<span style="font-family:Helvetica,Arial,sans-serif;">; <span style="font-family:Helvetica,Arial,sans-serif;">}

Active health monitoring nginx plus  - every 5 seconds by default, by defult check uri is /

location / { proxy_pass http://backend; health_check interval=10 fails=3 passes=2; uri=/test.txt match=server_test; } } match server_test { status 200-399; body !~maintenence; or if body ~ Welcome to nginx zone server_test 64k; --shared memory that worker process will be using }
 * sends interval by two consecutive health check to 10 sec, if fails 3 times, serves is treated as down, after passes two checks server will be considered healthy, uri to check is /test.txt and if in body is not maintence, the server is up and running
 * match means if body in /test.txt we find maintence  and status is 200-399, the server is considered dead
 * or if body ~ Welcome to nginx in /test.txt and status is 200-399, server is considered health

Passive health monitoring - support in free version <span style="font-family:Helvetica,Arial,sans-serif;">server 52.4.121.83 max_fails=3 fail_timeout=50; <span style="font-family:Helvetica,Arial,sans-serif;">server 52.4.121.82; } <span style="font-family:Helvetica,Arial,sans-serif;">bad is that client can wait some more time to request, because first request will be go to bad server, a the next to the good one
 * max_fails<span style="color:rgb(0,0,0);font-family:'AktivGroteskW01','HelveticaNeue',Arial,sans-serif;font-size:16px;font-weight:200;line-height:22.4px;"> parameter sets the number of failed attempts that should happen during the specified time to still consider the server unavailable.
 * fail_timeout<span style="color:rgb(0,0,0);font-family:'AktivGroteskW01','HelveticaNeue',Arial,sans-serif;font-size:16px;font-weight:200;line-height:22.4px;"> parameter sets the time during which the specified number of failed attempts should happen and still consider the server unavailable. In other words, the server is unavailable for the interval set by  fail_timeout<span style="color:rgb(0,0,0);font-family:'AktivGroteskW01','HelveticaNeue',Arial,sans-serif;font-size:16px;font-weight:200;line-height:22.4px;">. So if max_fails=3 and fail_timeout=50, server waits 50 sec to check again.
 * upstream backend {

Least conn <span style="font-family:Helvetica,Arial,sans-serif;"> least_conn; <span style="font-family:Helvetica,Arial,sans-serif;"> server 52.4.121.83 max_fails=3 fail_timeout=50; <span style="font-family:Helvetica,Arial,sans-serif;"> server 52.4.121.82; }
 * <span style="color:rgb(0,0,0);font-family:sans-serif;font-size:medium;font-weight:normal;line-height:22.4px;text-align:justify;">Specifies that a group should use a load balancing method where a request is passed to the server with the least number of active connections, taking into account weights of servers. If there are several such servers, they are tried in turn using a weighted round-robin balancing method.
 * upstream backend {

Cache  <p style="margin-top:8px;margin-bottom:8px;">location !\.(png) {
 * Cache-Control Headers:
 * 1) max-age=[seconds] — specifies the maximum amount of time that a representation will be considered fresh. Similar to Expires, this directive is relative to the time of the request, rather than absolute. [seconds] is the number of seconds from the time of the request you wish the representation to be fresh for.
 * 2) s-maxage=[seconds] — similar to max-age, except that it only applies to shared (e.g., proxy) caches.
 * 3) public — marks authenticated responses as cacheable; normally, if HTTP authentication is required, responses are automatically private.
 * 4) private — allows caches that are specific to one user (e.g., in a browser) to store the response; shared caches (e.g., in a proxy) may not.
 * 5) no-cache — forces caches to submit the request to the origin server for validation before releasing a cached copy, every time. This is useful to assure that authentication is respected (in combination with public), or to maintain rigid freshness, without sacrificing all of the benefits of caching.
 * 6) no-store — instructs caches not to keep a copy of the representation under any conditions.
 * 7) must-revalidate — tells caches that they must obey any freshness information you give them about a representation. HTTP allows caches to serve stale representations under special conditions; by specifying this header, you’re telling the cache that you want it to strictly follow your rules.
 * 8) proxy-revalidate — similar to must-revalidate, except that it only applies to proxy caches.

<p style="margin-top:8px;margin-bottom:8px;">root /var/www/website/example;

<p style="margin-top:8px;margin-bottom:8px;">expires 1h;

<p style="margin-top:8px;margin-bottom:8px;">add-header Cache-Control max-age=120;

<p style="margin-top:8px;margin-bottom:8px;">} it means that in the header will be Cache-Control: max-age=3600 and Expires date

<p style="margin-top:8px;margin-bottom:8px;">

<p style="margin-top:8px;margin-bottom:8px;">

      <span style="font-weight:normal;font-family:Helvetica,Arial,sans-serif;">location !\.(png) { <span style="font-family:Helvetica,Arial,sans-serif;font-weight:normal;">                     root /var/www/website/example; add_header Cache-Control max-age=120; it means that it will be cache for 120s, in the private cache       add_header Cache-Control no-store; - means that it no be cached- only in memory        add_header Cache-Control s-maxage=200; -      it will be cached on intermediate servers(public) for 200s       add_header Cache-Control no-cache; - it means that download fresh, no-cache means that it will be in cache, but it must be revalidate query to back to the server,        add_header Pragma no-cache;       add_header Cache-Control must-revalidate; expires -1; - means that it will be no-cache } - ,check in about:cache,no cache  must-revalidate means Cache should must be revalidate every time for document freshness

it means that download fresh, no-cache means that it will be in cache, but it must be revalidate query to back to the server  (public cache) 

Access Control      location /downloads/ {         root /var/www/html/example;         index index.html;        allow 10.4.4.4;        allow 192.168.10.0/24;        deny all;         } ​             location /downloads { /var/www/websites/example; limit_rate 50k; } This below allows for only one connection at time from 1 IP limit_conn_zone $binary_remote_addr zone=addr:10m; server { location /download/ { limit_conn addr 1; } ​        yum install httpd-tools
 * limit connection module
 * Basic authentication

        htpasswd -c /etc/nginx/.htpasswd fgtuser       location /downloads {             auth_basic " Basic authentication ";           auth_basic_user_file "/etc/nginx/.htpasswd";  <span style="font-family:Helvetica,Arial,sans-serif;line-height:21px;background-color:rgb(255,255,255);">                  }      http {          geoip_country /usr/share/GeoIP/GeoIP.dat;         map "$host:$geoip country_code" $deny_by country {          -^example.com:(?!PL) 1; -if is not from Poland, this mean that is forbidden            default 0;      }       server {     server_name example.com;       listen 80;      if ($deny_by_country) { return 403; }     location / {      root /var/www/websites/example;     }       }         iso3166 country code              
 * GeoIP




 * SSL cerficate management


 * cd ssl
 * openssl genrsa -des3 -out server.key 1024
 * openssl req -new -key server.key -out server.csr
 * cp server.key server.key.org
 * openssl rsa -in server.key.org -out server.key
 * openssl x509 -req -days 365 -i server.csr -signkey server.key -out server.crt
 * vim /etc/nginx/vhost.d/www.myexample.local  and add:

server {

listen 443;

root /var/www/html/myexample;

index index.html index.htm index.php;

server_name www.myexample.local myexample;

ssl on;

ssl_certificate /etc/nginx/ssl/server.crt;

ssl_certificate_key /etc/nginx/ssl/server.key;

}


 * systemctl reload nginx
 * lynx https://www.myexample.local