Nginx Learning Note
Nginx Learning Note
Nginx VS Apache
Apache: prefork: each process handle one request at a time
Nginx: asynchronous design: dynamic content is handled by another process separately
Faster static resources
High concurrency
thousands of requests per process
Load balancer
Mail server
⭐ Nginx interprets incoming requests as URI locations, Apache prefers to interpret requests as filesystem locations.
Nginx Features:
High performance
High Concurrency
Low Resource Usage
Installation
apt-get update apt-get install nginx ps aux | grep nginx ifconfig ssh-keygen -R 111.11.11.11 yum install epel-release yum install nginx systemctl start nginx.service ps aux | grep nginx
Another way to install
1 2 3 4 5 6 7 8 9 10 11 apt-get update wget https://nginx.org/download/nginx-1.21.4.tar.gz ls -l > nginx-1.21.4.tar.gz tar -zxvf nginx-1.21.4.tar.gzcd ./nginx-1.21.4 apt-get build-essential ./configure > ... apt-get install libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev ./configure
Then, we can configure our Nginx server
https://nginx.org/en/docs/configure.html
1 2 3 4 5 6 7 8 ./configure --sbin-path=/usr/bin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log /nginx/error.log --http-log-path=/var/log /nginx/access.log --with-pcre --pid-path=/var/run/nginx.pid --with-http_ssl_module make make install ls -l /etc/nginx/ nginx -V > nginx version: nginx/1.xx.xx ps aux | grep nginx
Two types of modules:
Nginx 3rd party modules
Bundle modules —with
https://nginx.org/en/docs/ Modules reference
Systemd: Add Service/ Command
https://www.nginx.com/resources/wiki/start/topics/examples/systemd/
Save this file as /lib/systemd/system/nginx.service
1 2 3 4 5 6 7 8 9 10 11 12 13 [Unit] Description =The NGINX HTTP and reverse proxy serverAfter =syslog.target network-on line.target remote-fs.target nss-lookup.targetWants =network-on line.target[Service] Type =forkingPIDFile =/var/run/nginx.pid ExecStartPre =/usr/bin/nginx -t ExecStart =/usr/bin/nginxExecReload =/usr/bin/nginx -s reloadExecStop =/bin/kill -s QUIT $MAINPID PrivateTmp =true [Install] WantedBy =multi-user.target
Use systemd
1 2 3 4 systemctl start nginx systemctl status nginx systemctl stop nginx systemctl enable nginx
Nginx Windows Limits
Poor performance
Single worker process
Unsupported modules
Configuration ⚙️
nginx.conf
Directive: server_name mydomain.com
Context: essentially the scope: http {...}
The conf file itself is included in a global context
The important context:
Create a virtual host
a virtual host is a server context
port : 80 for http, 443 for https
1 2 ls -l /etc/nginx/ > nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 events {} http { server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; } }
1 2 3 nginx -t systemctl reload nginx systemctl restart nginx
Right now nginx is not sending the correct Content-Type as text/plain not stylesheets
To change this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 events {} http { types { text/html html; text/css css; } server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; } }
/etc/nginx/mime.types has already set all common types we need, so we only need:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 events {} http { include mime.types; server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; } }
types : This context is again used for mapping. This context is used to map MIME types to the file extensions that should be associated with them. This is usually provided with Nginx through a file that is sourced into the main nginx.conf config file.
https://www.digitalocean.com/community/tutorials/understanding-the-nginx-configuration-file-structure-and-configuration-contexts
Match and intercept an incoming request URI and override the server context’s configuration inside the location context
location
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 events {} http { include mime.types; server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; location /greet { return 200 'Hello from /greet location' ; } location = /greet { return 200 'Hello from /greet location - EXACT MATCH' ; } location ~ /greet[0 -9] { return 200 'Hello from /greet location - REGEX MATCH' ; } location ~* /greet[0 -9] { return 200 'Hello from /greet location - REGEX MATCH INSENSITIVE' ; } } }
REGEX match has higher priority than the prefix match
This overwrites the priority for the prefix match
1 2 3 4 location ^~ /greet { return 200 'Hello from /greet location' ; }
Priority order
Exact Match
Preferential Prefix Match
REGEX Match
Prefix Match
Variables
http://nginx.org/en/docs/varindex.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 events {} http { include mime.types; server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; location /inspect { return 200 "$host \n$uri \n$args " ; } } }
Then when we go to the web 167.99.xx.xx/inspect?name=ray
we will have
1 2 3 167.88.xx.xx /inspect name=ray
We can output the exact arg to query
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 events {} http { include mime.types; server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; if ( $arg_apikey != 1234 ) { return 401 "incorrect api key" } set $weekend 'No' ; if ( $date_local ~ 'Saturday|Sunday' ) { set $weekend 'Yes' ; } location /inspect { return 200 "Name: $arg_name " ; } } }
Rewrite/ Redirect 🍥
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 events {} http { include mime.types; server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; location /logo { return 307 /thumb.png; } } }
/logo is redirect to /thumb.png
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 events {} http { include mime.types; server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; rewrite ^/user/(\w+) /greet/$1 ; rewrite ^/greet/john /thumb.png; location /greet { return 200 "Hello user rewrite" ; } location = /greet/john { return 200 "Hello John" ; } } }
try_files 📁
check if current URL exsits, if not try if /sites/demo/thumb.pngexitst, show it, if not try next one
Only last one would be seen as internal rewrite; meaning others refer to files URI, last one refers to address URL;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 events {} http { include mime.types; server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; try_files $uri /thumb.png /greet /friendly_404; location /friendly_404 { return 404 "not found" } location /greet { return 200 "Hello user rewrite" ; } } }
Named location 📛
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 events {} http { include mime.types; server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; try_files $uri /thumb.png /greet @friendly_404; location @friendly_404 { return 404 "not found" } location /greet { return 200 "Hello user rewrite" ; } } }
Logging 💬
We have set the logging location when we are configuring Nginx
Create log for a certain location
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 events {} http { include mime.types; server{ listen 80; server_name 167.99.xx.xx; root /sites/demo; location /greet { access_log /var/log /nginx/secure.access.log return 200 "Hello user rewrite" ; } } }
Inheritance ⭐
Array directive: inherit straight down recursively in the scope (multiple allows)
Standard directive: inherit straight down recursively in the scope
Action directive: just there ~ perform some action
http → server → location
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 events {} access_log /var/log /nginx/access.log; access_log /var/log /nginx/custom.log.gz custom_format; http { include mime.types; server { listen 80; server_name site1.com; } server { listen 80; server_name site2.com; root /sites/site2; access_log off; location /images { try_files $uri /stock.png; } location /secret { return 403 "You do not have permission to view this." ; } } }
Worker process
nginx worker is asynchronous, it will handle as much requests as possible as long as hardware is capable of.
number of process ←→ number of cores
1 2 3 4 5 6 7 systemctl status nginx nproc > 1 lscpu > ... cpu infoulimit -n > 1024 ...number of files reading at once
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 user www-data; worker_processes auto; events { worker_connections 1024; } http { include mime.types; server { listen 80; server_name 167.99.93.26; root /sites/demo; index index.php index.html; location / { try_files $uri $uri / =404; } location ~\.php$ { include fastcgi.conf; fastcgi_pass unix:/run/php/php7.1-fpm.sock; } } }
max connections = worker_processes * worker_connections
1 ls -l /var/run/nginx.pid
1 2 pid /var/run/new_nginx.pid;
Buffers
Nginx worker recieves request from a TCP port 80
Nginx worker writes the data to memory RAM (Buffering)
If overflow writes into Disk
Nginx worker reads data from disk to memory (Buffering)
sends to client from memory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 user www-data; worker_processes auto; events { worker_connections 1024; } http { include mime.types; client_body_buffer_size 10K; client_max_body_size 8m; client_header_buffer_size 1k; client_body_timeout 12; client_header_timeout 12; keepalive_timeout 15; send_timeout 10; sendfile on; tcp_nopush on; server { listen 80; server_name 167.99.93.26; root /sites/demo; index index.php index.html; location / { try_files $uri $uri / =404; } location ~\.php$ { include fastcgi.conf; fastcgi_pass unix:/run/php/php7.1-fpm.sock; } } }
http://nginx.org/en/docs/syntax.html
Adding new modules 🆕
New modules require to build Nginx from the source
1 2 3 4 5 6 nginx -V > ./configure --sbin-path=/usr/bin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log /nginx/error.log --http-log-path=/var/log /nginx/access.log --with-pcre --pid-path=/var/run/nginx.pid --with-http_ssl_module ./configure --help > ...all help config ./configure -- help | grep dynamic
1 2 ./configure --sbin-path=/usr/bin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log /nginx/error.log --http-log-path=/var/log /nginx/access.log --with-pcre --pid-path=/var/run/nginx.pid --with-http_ssl_module --with-http_image_filter_module=dynamic
we need to append --modules-path=/etc/nginx/modules
to make dynamic modules to be loaded to the corresponding module
1 2 3 4 5 6 apt-get install libgd-dev ./configure --sbin-path=/usr/bin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log /nginx/error.log --http-log-path=/var/log /nginx/access.log --with-pcre --pid-path=/var/run/nginx.pid --with-http_ssl_module --with-http_image_filter_module=dynamic make make install nginx -V systemctl reload nginx
http://nginx.org/en/docs/http/ngx_http_image_filter_module.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 user www-data; worker_processes auto; load_module modules/ngx_http_image_filter_module.so; events { worker_connections 1024; } http { include mime.types; client_body_buffer_size 10K; client_max_body_size 8m; client_header_buffer_size 1k; client_body_timeout 12; client_header_timeout 12; keepalive_timeout 15; send_timeout 10; sendfile on; tcp_nopush on; server { listen 80; server_name 167.99.93.26; root /sites/demo; index index.php index.html; location / { try_files $uri $uri / =404; } location ~\.php$ { include fastcgi.conf; fastcgi_pass unix:/run/php/php7.1-fpm.sock; } location = /thumb.png { image_filter rotate 180; } } }
Defines the duration of how long a static file a browser should cache
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 user www-data; worker_processes auto; events { worker_connections 1024; } http { include mime.types; server { listen 80; server_name 167.99.93.26; root /sites/demo; index index.php index.html; location / { try_files $uri $uri / =404; } location ~\.php$ { include fastcgi.conf; fastcgi_pass unix:/run/php/php7.1-fpm.sock; } location ~* \.(css|js|jpg|png)$ { access_log off; add_header Cache-Control public; add_header Pragma public; add_header Vary Accept-Encoding; expires 1M; } } }
gzip
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 user www-data; worker_processes auto; events { worker_connections 1024; } http { include mime.types; gzip on; gzip_comp_level 3; gzip_types text/css; gzip_types text/javascript; server { listen 80; server_name 167.99.93.26; root /sites/demo; index index.php index.html; location / { try_files $uri $uri / =404; } location ~\.php$ { include fastcgi.conf; fastcgi_pass unix:/run/php/php7.1-fpm.sock; } location ~* \.(css|js|jpg|png)$ { access_log off; add_header Cache-Control public; add_header Pragma public; add_header Vary Accept-Encoding; expires 1M; } } }
FastCGI Cache
cache between Nginx and backend-server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 user www-data; worker_processes auto; events { worker_connections 1024; } http { include mime.types; fastcgi_cache_path /tmp/nginx_cache levels=1:2 keys_zone=ZONE_1:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri " ; add_header X-Cache $upstream_cache_status ; server { listen 80; server_name 167.99.93.26; root /sites/demo; index index.php index.html; set $no_cache 0; if ($arg_skipcache = 1) { set $no_cache 1; } location / { try_files $uri $uri / =404; } location ~\.php$ { include fastcgi.conf; fastcgi_pass unix:/run/php/php7.1-fpm.sock; fastcgi_cache ZONE_1; fastcgi_cache_valid 200 60m; fastcgi_cache_bypass $no_cache ; fastcgi_no_cache $no_cache ; } } }
Security
HTTPS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 user www-data; worker_processes auto; events { worker_connections 1024; } http { include mime.types; server { listen 80; server_name 167.99.93.26; return 301 https://$host$request_uri ; } server { listen 443 ssl http2; server_name 167.99.93.26; root /sites/demo; index index.html; ssl_certificate /etc/nginx/ssl/self.crt; ssl_certificate_key /etc/nginx/ssl/self.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5; ssl_dhparam /etc/nginx/ssl/dhparam.pem; add_header Strict-Transport-Security "max-age=31536000" always; ssl_session_cache shared:SSL:40m; ssl_session_timeout 4h; ssl_session_tickets on; location / { try_files $uri $uri / =404; } location ~\.php$ { include fastcgi.conf; fastcgi_pass unix:/run/php/php7.1-fpm.sock; } } }
Rate Limiting
Security - Brute Force Protection
Reliability - Prevent Traffic Spikes
Shaping - Service Priority
。。。要用到再看吧https://www.udemy.com/course/nginx-fundamentals/learn/lecture/10617504#questions
Reverse Proxy
The proxy allows users to be anonymous to the server.
The reverse proxy allows the server to be anonymous to users
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
Load balancer
Distribute requests to multiple servers
Provide redundancy (if one fails, Nginx can redirect to another server)
upstream is the key. Round-Robben: We then distribute requests to all upstream servers equally!!
See docs for detail
http://nginx.org/en/docs/http/ngx_http_upstream_module.html
https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/
http://nginx.org/en/docs/http/load_balancing.html
If one server is down, Nginx will automatically redirect requests to the available server! So cool!
Other load balance option
Sticky Session: ip_hash; (for example: session state )
Avoid heavy connections on a server: least_conn
Some docs:
https://www.digitalocean.com/community/search?q=nginx
http://nginx.org/en/docs/
https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
Other Adds -on | My Notes 📒
http:// 80
https:// 443
Benefits of proxy
Anonymity
Caching
Blocking unwanted sites
GeoFencing
Benefits of reverse proxy
Load balancing
Caching
Isolating internal traffic
Canary Deployment