NGINX
Contents
Nginx
nginx serves as:
- HTTP server
- HTTPS server
- Reverse Proxy
- Load Balancer
- Mail Proxy
Basic HTTP Features
- Serving static and index files, and autoindexing; open file descriptor cache;
- Accelerated reverse proxying with caching; simple load balancing and fault tolerance;
- Accelerated support with caching of remote FastCGI servers; simple load balancing and fault tolerance;
- Modular architecture. Filters include gzipping, byte ranges, chunked responses, XSLT, SSI, and image resizing filter.
- Multiple SSI inclusions within a single page can be processed in parallel if they are handled by FastCGI or proxied servers.
- SSL and TLS SNI support.
Additional HTTP Features
- Name-based and IP-based virtual servers;
- Keep-alive and pipelined connections support;
- Flexible configuration;
- Reconfiguration and online upgrade without interruption of the client processing;
- Access log formats, bufferred log writing, and quick log rotation;
- 3xx-5xx error codes redirection;
- The rewrite module;
- Access control based on client IP address and HTTP Basic authentication;
- The PUT, DELETE, MKCOL, COPY and MOVE methods;
- FLV streaming;
- Speed limitation;
- Limitation of simultaneous connections or requests from one address.
- Embedded Perl
Mail Proxy Server Features
- User redirection to IMAP/POP3 backend using an external HTTP authentication server;
- User authentication using an external HTTP authentication server and connection redirection to internal SMTP backend;
- Authentication methods:
- POP3: USER/PASS, APOP, AUTH LOGIN/PLAIN/CRAM-MD5;
- IMAP: LOGIN, AUTH LOGIN/PLAIN/CRAM-MD5;
- SMTP: AUTH LOGIN/PLAIN/CRAM-MD5;
- SSL support;
- STARTTLS and STLS support.
Architecture and Scalability
- One master process and several workers processes. The workers run as unprivileged user;
- The notification methods:
- kqueue (FreeBSD 4.1+)
- The support of the various kqueue features including:
- EV_CLEAR
- EV_DISABLE (to disable event temporalily)
- NOTE_LOWAT
- EV_EOF
- The support of the various kqueue features including:
- epoll (Linux 2.6+)
- rt signals (Linux 2.2.19+)
- /dev/poll (Solaris 7 11/99+)
- event ports (Solaris 10)
- select, and poll;
- sendfile (FreeBSD 3.1+, Linux 2.2+, Mac OS X 10.5)
- sendfile64 (Linux 2.4.21+)
- sendfilev (Solaris 8 7/01+)
- File AIO (FreeBSD 4.3+, Linux 2.6.22+);
- kqueue (FreeBSD 4.1+)
- Accept-filters (FreeBSD 4.1+) and TCP_DEFER_ACCEPT (Linux 2.4+) support;
- 10,000 inactive HTTP keep-alive connections take about 2.5M memory;
- Data copy operations are kept to a minimum.
Nginx Configuration Directives
error_log
The error log for the domain, this is set by default the same on all vhosts(/var/log/nginx/vhost-error_log).
error_log file [ debug | info | notice | warn | error | crit ]
Disabling error logging
error_log /dev/null crit;
access_log
access_log path [format [buffer=size]]|off
access_log /usr/local/apache/domlogs/YOURDOMAIN.COM-bytes_log bytes_log; access_log /usr/local/apache/domlogs/YOURDOMAIN.COM combined;
proxy_pass
This directive sets the address of the proxied server and the URI to which location will be mapped.
- Target address may be given as Hostname|IP:PORT|Backend, for example:
proxy_pass http://ws2:example.com:8081/; proxy_pass http://10.0.1.1:8080/; proxy_pass backend;
root
This is equivalent to DocumentRoot in Apache. Used in location blocks to serve matched content from this document root.
root /srv/web/example.com/htdocs/;
Location Block
location [=|~|~*|^~|@] /uri/ { ... };
Case-Insensitive
location ~* /images/ { ... };
Case-Sensitive
location ~ /images/ { ... };
Match "/"
location = / { ... };
Match everything
location / { ... };
Regex Matching
location ~* \.(bmp|gif|jpe?g|png|tiff)$ { root /srv/web/cdn.example.com/images/; }; location ~* \.(swf|(j|cs)s)$ { root /srv/web/cdn.example.com/lib/; };
VirtualHost Equivalents
server { error_log /var/log/nginx/error_log warn; access_log /usr/local/apache/domlogs/YOURDOMAIN.COM.com-bytes_log bytes_log; access_log /usr/local/apache/domlogs/YOURDOMAIN.COM combined; listen 80; server_name YOURDOMAIN.COM WWW.YOURDOMAIN.COM; # Redirect media file or static content extensions to a specific document_root location ~* \.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css)$ { root /home/user/public_html; } location / { client_max_body_size 10m; client_body_buffer_size 128k; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; # fixes upstream response buffering warning proxy_buffers 16 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_connect_timeout 30s; proxy_redirect http://www.YOURDOMAIN.COM:8081 http://www.YOURDOMAIN.COM; proxy_redirect http://YOURDOMAIN.COM:8081 http://YOURDOMAIN.COM; proxy_pass http://IP_ADDRESS:8081/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
Main Configuration
Log Format
log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $bytes_sent ' '"$http_referer" "$http_user_agent" ' '"$gzip_ratio"';
Timeouts
client_header_timeout 10; client_body_timeout 10; send_timeout 30; keepalive_timeout 40 20;
Socket settings
connection_pool_size 8192; client_header_buffer_size 4k; large_client_header_buffers 8 8k; request_pool_size 8k;
Character Encoding
charset utf-8; source_charset utf-8;
Security
server { server_name _; return 444; } server_tokens off; ignore_invalid_headers on; server_name_in_redirect off;
Performance
sendfile off; postpone_output 0; tcp_nopush on; tcp_nodelay off;
GZIP Compression
gzip on; gzip_comp_level 4; gzip_min_length 1100; gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_buffers 16 8k;
Output Buffering
output_buffers 8 32k;
DirectoryIndex Equivalent
index index.html index.php;
Upstream Example
upstream backend { ip_hash; server 172.16.10.4:8080 weight=5 max_fails=3 fail_timeout=30; server 172.16.10.3:8080 weight=4 max_fails=5 fail_timeout=45; server 172.16.10.2:8080 weight=3 max_fails=7 fail_timeout=60 down; server 172.16.10.1:8080 weight=2 max_fails=9 fail_timeout=90; }
NGINX & CloudFlare
HttpRealIpModule
http://wiki.nginx.org/NginxHttpRealIpModule
set_real_ip_from 204.93.240.0/24; set_real_ip_from 204.93.177.0/24; set_real_ip_from 199.27.128.0/21; set_real_ip_from 173.245.48.0/20; set_real_ip_from 103.22.200.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 108.162.192.0/18; set_real_ip_from 190.93.240.0/20; real_ip_header CF-Connecting-IP;
Troubleshooting
.xml ISE 500
Remove XML being handled by nginx if the back end of the customer's site uses xml files for configurations.
Status Page
- Requires --with-http_stub_status_module flag at compile time.
server { listen 80; server_name 0.0.0.0; location /nginx_status { stub_status on; access_log off; allow MANAGEMENT_IP; } }
Then restart NGINX with:
nginx -s reload
- MANAGEMENT_IP then becomes authorized to view http://YOURDOMAIN.COM/nginx_status
Status Page Details
Active connections: 17802 server accepts handled requests 219633918 2198306548 21970465 Reading: 195 Writing: 1979 Waiting: 850
Status Stub Variables
Key | Value |
---|---|
active connections | # of open connections +backends |
reading | # of sockets currently reading request headers |
writing | # of sockets currently reading request body, processing a request, or in response phase |
waiting | # of active keep-alive sockets |
Reverse Proxy & Load Balancer
Upstream (proxy/load_balancer)
Context: http
http://wiki.nginx.org/HttpUpstreamModule
upstream backend { # If upstreaming to >1 servers, uncomment next line # ip_hash; server 172.16.10.4:8080; server 172.16.10.3:8080; server 172.16.10.2:8080; server 172.16.10.1:8080; } server { location / { proxy_pass http://backend; } }
LimitZone (DoS Prevention)
Context: http
http { # limit_zone <zone_name> <$variable> <max_zone_sizeM> limit_zone limit0 $binary_remote_addr 10m; server { location /download/ { # limit_conn <zone_name> <max_clients_per_ip> limit_conn limit0 4; } } }
Apache Rewrites to NGINX Rewrites
http://www.anilcetin.com/convert-apache-htaccess-to-nginx/
Examples
#rewrite /page200.html to /page.php?id=200 rewrite ^/page([0-9]+)\.html$ /page.php?id=$1 last;
# rewrite /profile/user15 to /profile.php?user=user15 rewrite ^/profile/([A-Za-z0-9]{4,12})$ /profile.php?user=$1 last;
SpawnFCGI Script
#! /bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin NAME=spawn-fcgi-php PID=/var/run/fcgi.pid NCHILDREN=100 BINDIP=127.0.0.1 BINDPORT=10001 BINDUSER=nobody BINDGROUP=nobody DAEMON=/usr/bin/spawn-fcgi DAEMON_OPTS="-f /usr/bin/php -C $NCHILDREN -a $BINDIP -p $BINDPORT -u $BINDUSER -g $BINDGROUP -P $PID" test -x $DAEMON || exit 0 set -e case "$1" in start) echo "Starting $NAME: " $DAEMON $DAEMON_OPTS echo "OK" ;; stop) echo "Stopping $NAME: " kill -15 `cat $PID` rm -f $PID echo "OK" ;; restart) echo "Stopping $NAME: " kill -15 `cat $PID` rm -f $PID echo "OK" sleep 3 echo "Starting $NAME: " $DAEMON $DAEMON_OPTS echo "OK" ;; *) echo "USAGE: /etc/init.d/$NAME {start|stop|restart}" >&2 exit 1 ;; esac exit 0
PHP Configuration
The easiest way to get PHP working under NGINX, is to install and configure PHP-CGI, usually used in a FastCGI setup. php-cgi usually runs locally via a UNIX Socket, or via TCP on loopback device at 127.0.0.1:9000.
The following configuration block is meant to pass PHP script requests to a FastCGI listener for processing:
<syntaxhighlight lang="bash"> location ~* \.php$ {
include fastcgi_params; fastcgi_intercept_errors on; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; try_files $uri =404; error_page 404 /404page.html; # return default 404 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; # If you used php-fpm installed as a TCP service, change the above to: # fastcgi_pass 127.0.0.1:9000 # If you have more than one fcgi listener open, you can create an upstream backend, and use # fastcgi_pass backend; # Example: # upstream backend { # server 127.0.0.1:9000; # server 127.0.0.1:9001; # }
} </syntaxhighlight>