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