[[http://tmade.de|Home tmade.de]] [[http://wiki.tmade.de|Home Wiki]] ===== Nginx ===== Required packages (ubuntu 12.4 LTS): build-essential libpcre3-dev libssl-dev zlib1g-dev Required packages (SLES11): C/C++-Compiler pcre-devel-7.8-2.18.x86_64.rpm openssl-1.0.1e.tar.gz zlib-devel-1.2.3-106.34.x86_64.rpm Compile options: ./configure --prefix=/usr/local/nginx --with-http_ssl_module --add-module=/root/temp/sticky make make install ==== Links ==== http://nginx.org/en/docs/ http://wiki.nginx.org/CommandLine http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream_conf http://code.google.com/p/nginx-sticky-module/source/browse/trunk/README http://spin.atomicobject.com/2013/07/08/nignx-load-balancing-reverse-proxy-updated/ http://forum.nginx.org/ http://dak1n1.com/blog/12-nginx-performance-tuning ==== Certificate ==== http://wiki.tmade.de/doku.php?id=server:apache#ssl_authentification http://nginx.org/en/docs/http/configuring_https_servers.html ==== Init (Ubuntu Server 12.4) ==== Example init-script: #!/bin/bash ### BEGIN INIT INFO # Provides: nginx # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts the nginx web server # Description: starts nginx using start-stop-daemon ### END INIT INFO # An init.d script that works under Ubuntu 12.04 FFS # load with sudo /usr/sbin/update-rc.d -f nginx defaults # CHANGE ME. PATH=/usr/local/nginx/sbin:$PATH DAEMON=/usr/local/nginx/sbin/nginx NAME=nginx DESC=nginx test -x $DAEMON || exit 0 # Include nginx defaults if available if [ -f /etc/default/nginx ] ; then . /etc/default/nginx fi set -e function start { echo -n "Starting $DESC: " start-stop-daemon --make --start --pidfile /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS echo "$NAME." } function stop { echo -n "Stopping $DESC: " $DAEMON -s stop echo "$NAME." } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart}" >&2 exit 1 ;; esac exit 0 ==== Init (SLES 11 SP2) ==== Example init-script: #!/bin/bash ### BEGIN INIT INFO # Provides: nginx # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts the nginx web server # Description: starts nginx using start-stop-daemon ### END INIT INFO # An init.d script that works under Ubuntu 12.04 FFS # load with sudo /usr/sbin/update-rc.d -f nginx defaults # CHANGE ME. PATH=/usr/local/nginx/sbin:$PATH DAEMON=/usr/local/nginx/sbin/nginx CONF=/usr/local/nginx/conf/nginx.conf DESCRIBE=nginx test -x $DAEMON || exit 0 # Include nginx defaults if available #if [ -f /etc/default/nginx ] ; then #. /etc/default/nginx #fi set -e function start { echo -n "Starting $DESCRIBE: " $DAEMON -c $CONF sleep 3; } function stop { echo -n "Stopping $DESCRIBE: " PID=`cat /usr/local/nginx/sbin/nginx.pid` echo "Nginx is running with PID $PID" kill $PID echo "PID $PID has been stopped" } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; *) #N=/etc/init.d/$PID echo "Usage: $DESCRIBE {start|stop|restart}" >&2 exit 1 ;; esac exit 0 ==== Manuell Start ==== For testing issues the nginx-service can be executed via: /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf See also on: http://wiki.nginx.org/CommandLine ==== Check ==== Show version and all configured modules: nginx -V ==== Configuration ==== Example configuration "nginx.conf": #user nobody; worker_processes 5; worker_rlimit_nofile 30000; #error_log logs/error.log; #default #error_log /var/log/nginxerror.log emerg; #error_log logs/error.log notice; #error_log logs/error.log info; pid /usr/local/nginx/sbin/nginx.pid; events { worker_connections 1024; #worker_connections 16384; } http { include mime.types; default_type application/octet-stream; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Queue-Start "t=${msec}000"; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; #default #log_format upstreamlog '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request upstream_response_time $upstream_response_time msec $msec request_time $request_time'; #access_log logs/nginx.log upstreamlog; #logging log_format main '[$time_local] Client: $remote_addr - Server: $server_name to Webserver: $upstream_addr - Request: $request - UpstreamResponse: $upstream_response_time msec - Status: $status'; access_log /var/log/nginxaccess.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 0; #gzip on; upstream webserver { sticky expires=1m; server 10.0.0.191:80; server 10.0.0.192:80; } upstream swebserver { sticky expires=1m; server 10.0.0.191:443; server 10.0.0.192:443; } geo $maintenance { default 0; #0 = using upstream webserver; 1 = using maintenance 10.0.0.193 0; # allow our office subnet to skip http 503 mode #202.54.1.5 0; # allow webmaster remote ip to skip http 503 mode } server { listen 10.0.0.188:80; server_name nginx.local; location / { if ($maintenance) { return 503; } proxy_pass http://webserver; #redirect to https ("proxy_pass" has to be commented!!): #rewrite ^(.*) https://hostname.com$1 permanent; } error_page 503 @maintenance; location @maintenance { rewrite ^(.*)$ /50x.html break; } } server { listen 10.0.0.188:443 ssl; server_name nginx.local; ssl_certificate /usr/local/nginx/keys/server.crt; ssl_certificate_key /usr/local/nginx/keys/server.key; location / { if ($maintenance) { return 503; } proxy_pass https://swebserver; } error_page 503 @maintenance; location @maintenance { rewrite ^(.*)$ /50x.html break; } #charset koi8-r; #access_log logs/host.access.log main; #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # #error_page 500 502 503 504 /50x.html; #location = /50x.html { # root html; #} # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443; # server_name localhost; # ssl on; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_timeout 5m; # ssl_protocols SSLv2 SSLv3 TLSv1; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} } Example configuration "nginx.conf" with "letsencrypt": # You may add here your # server { # ... # } # statements for each of your virtual hosts to this file ## # You should look at the following URL's in order to grasp a solid understanding # of Nginx configuration files in order to fully unleash the power of Nginx. # http://wiki.nginx.org/Pitfalls # http://wiki.nginx.org/QuickStart # http://wiki.nginx.org/Configuration # # Generally, you will want to move this file somewhere, and start with a clean # file but keep this around for reference. Or just disable in sites-enabled. # # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. ## server { #root /usr/share/nginx/html; #index index.html index.htm; listen 443 ssl; # Make site accessible from http://localhost/ server_name localhost my.domain.de; ssl_certificate /etc/letsencrypt/live/my.domain.de/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/my.domain.de/privkey.pem; # ssl configuration # visit ssl-labs to check ssl config. Should report with A+ # https://www.ssllabs.com/ssltest/analyze.html?d=my.domain.de ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security max-age=15768000; root /opt/www/mywebsite/app/current/public; passenger_enabled on; #location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. # try_files $uri /index.html; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules #} # lets encrypt host validation location ~ /\.well-known\/acme-challenge { allow all; } #location ^~ /app/assets/ { # gzip_static on; # expires 1h; # add_header Cache-Control public; #} location ~ ^/app(/.*|$) { alias /opt/www/website-app/app/current/public$1; # <-- be sure to point to 'public'! passenger_base_uri /app; passenger_app_root /opt/www/website-app/app/current; passenger_document_root /opt/www/website-app/app/current/public; passenger_enabled on; } # Only for nginx-naxsi used with nginx-naxsi-ui : process denied requests # location /RequestDenied { # proxy_pass http://127.0.0.1:8080; # } # error_page 404 /404.html; # redirect server error pages to the static page /50x.html # # error_page 500 502 503 504 /50x.html; # location = /50x.html { # root /usr/share/nginx/html; # } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # # location ~ \.php$ { # fastcgi_split_path_info ^(.+\.php)(/.+)$; # # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini # # # With php5-cgi alone: # fastcgi_pass 127.0.0.1:9000; # # With php5-fpm: # fastcgi_pass unix:/var/run/php5-fpm.sock; # fastcgi_index index.php; # include fastcgi_params; # } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # # location ~ /\.ht { # deny all; # } } # redirect http-traffic to secure https server { listen 80; server_name my.domain.de; return 301 https://$host$request_uri; } Example "server" config: server { listen 192.168.1.1:80; server_name example.org www.example.org; ... } server { listen 192.168.1.1:80; server_name example.net www.example.net; ... } server { listen 192.168.1.2:80; server_name example.com www.example.com; ... } ==== Pacemaker ==== OCF-Script (/usr/lib/ocf/resource.d/heartbeat): #!/bin/sh # # usage: $0 {start|stop|status|monitor|meta-data} # # The "start" arg starts nginx. # # The "stop" arg stops it. # # OCF parameters: # OCF_RESKEY_conffile # # Note:This RA requires that the nginx config files has a "pid file" # entry so that it is able to act on the correct process ########################################################################## # Initialization: OCF_ROOT=/usr/lib/ocf . ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs USAGE="Usage: $0 {start|stop|status|validate-all}"; COMMAND=/usr/local/nginx/sbin/nginx TESTCMD=" -t" OCF_RESKEY_conffile=/usr/local/nginx/conf/nginx.conf ########################################################################## usage() { echo $USAGE >&2 } meta_data() { cat < 1.0 This script manages nginx OCF Resource Agent compliant nginx script. The nginx configuration file name with full path. For example, "/opt/cfg/common/nginx-edge/https1.conf" Configuration file name with full path END exit $OCF_SUCCESS } nginx_status() { if [ -n "$PIDFILE" -a -f $PIDFILE ]; then # nginx is probably running if [ -s $PIDFILE ]; then PID=`cat $PIDFILE` if kill -0 $PID; then ocf_log info "nginx daemon running" return $OCF_SUCCESS else ocf_log info "nginx daemon is not running but pid file exists" rm -f $PIDFILE 2>/dev/null return $OCF_ERR_GENERIC fi else ocf_log err "PID file empty!" rm -f $PIDFILE 2>/dev/null return $OCF_ERR_GENERIC fi fi # nginx is not running ocf_log info "nginx is not running" return $OCF_NOT_RUNNING } nginx_start() { # if nginx is running return success echo "status" nginx_status retVal=$? if [ $retVal -eq $OCF_SUCCESS ]; then exit $OCF_SUCCESS elif [ $retVal -ne $OCF_NOT_RUNNING ]; then ocf_log err "Error. Unknown status. Trying to start anyway." # kill the orphaned processes with no pid files ORPHAN=`ps auxw | grep nginx | grep -v "grep" | grep -c "$OCF_RESKEY_conffile"` if [ $ORPHAN -eq 1 ]; then # kill the orphans kill -TERM `ps auxw | grep nginx | grep -v "grep" | grep "$OCF_RESKEY_conffile" | awk '// {print $2}'` fi fi echo "test start" COMMAND="$COMMAND -c $OCF_RESKEY_conffile" if grep -v "#" "$OCF_RESKEY_conffile" | grep "pid" > /dev/null ; then $COMMAND; if [ $? -ne 0 ]; then ocf_log err "Error. nginx returned error $?." rm -f $PIDFILE 2>/dev/null exit $OCF_ERR_GENERIC fi else ocf_log err "Error. \"pid\" entry required in the nginx config file." return $OCF_ERR_GENERIC fi ocf_log info "Started nginx." exit $OCF_SUCCESS } nginx_stop() { if nginx_status ; then PID=`cat $PIDFILE` if [ -n "$PID" ] ; then kill -TERM $PID if [ $? -ne 0 ]; then kill -9 $PID if [ $? -ne 0 ]; then ocf_log err "Error. Could not stop nginx daemon." return $OCF_ERR_GENERIC fi fi fi rm -f $PIDFILE 2>/dev/null fi ocf_log info "Stopped nginx daemon." exit $OCF_SUCCESS } nginx_validate_all() { if [ -n "$OCF_RESKEY_conffile" -a ! -f "$OCF_RESKEY_conffile" ]; then ocf_log err "Config file $OCF_RESKEY_conffile does not exist." exit $OCF_ERR_ARGS fi if grep -v "#" "$OCF_RESKEY_conffile" | grep "pid" > /dev/null ; then : else ocf_log err "Error. \"pid\" entry required in the nginx config file." return $OCF_ERR_GENERIC fi return $OCF_SUCCESS } # # Main # if [ $# -ne 1 ]; then usage exit $OCF_ERR_ARGS fi PIDFILE=`grep -v "#" $OCF_RESKEY_conffile | grep "pid" | awk '/pid/ {print $2}' | sed -e 's/;//'` case $1 in start) nginx_start;; stop) nginx_stop;; status) nginx_status;; monitor) nginx_status;; meta-data) meta_data;; validate-all) nginx_validate_all;; usage) usage exit $OCF_SUCCESS ;; *) usage exit $OCF_ERR_UNIMPLEMENTED ;; esac