Questions about this topic? Sign up to ask in the talk tab.

NGINX

From NetSec
(Redirected from Nginx troubleshooting)
Jump to: navigation, search

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
    • 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+);
  • 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

Nginx Configuration Reference

Directive Index

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

c3el4.png You can now get the real-time updated list of backend IPs from CloudFlare here

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:

Terminal

localhost:~ $ nginx -s reload


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 interface 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>

NGINX is part of a series on administration.