Tag Archives: nginx

Ubuntu: Create own deb package

I'll show you how to create own deb package using modified nginx
1) we download nginx sources
2) we download some external nginx modules
3) we run

1
2
3
4
5
6
7
./configure --with-cc-opt="-static -static-libgcc" --with-ld-opt="-Bstatic" --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
    --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx \
    --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Wp,-D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed' \
    --add-module=./modules/naxsi/naxsi_src \
    --add-module=./modules/nginx-goodies-nginx-sticky-module-ng-bd312d586752 \
    --add-module=./modules/headers-more-nginx-module-0.25

4) make
after make we have out/nginx file so we could create own package using it

$ mkdir -p /opt/nginx/deb/nginx-ng
$ cd /opt/nginx/deb/nginx-ng
$ ls -1

1
2
3
4
DEBIAN
etc
usr
var

I downloaded original nginx deb and unpack it, after that I took DEBIAN, usr, var and etc folders from it
Continue reading Ubuntu: Create own deb package

HAProxy: tcp + http on the same port

haparoxy.conf:

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
global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # Default ciphers to use on SSL-enabled listening sockets.
        # For more information, see ciphers(1SSL). This list is from:
        #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
        ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
        ssl-default-bind-options no-sslv3

defaults
        log     global
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http
  maxconn 2000

frontend mixed_frontend
    bind :8080
    mode tcp
    option tcplog
    tcp-request inspect-delay 5s
    tcp-request content accept if HTTP
    # here is magic: check for that string "SSH 2.0"
    acl client_attempts_ssh payload(0,7) -m bin 5353482d322e30
    use_backend tcp_backend if client_attempts_ssh
    use_backend tcp_backend if !HTTP
    use_backend http_backend if HTTP
    default_backend tcp_backend

   backend tcp_backend
     mode tcp
     server ssh :22

   backend http_backend
     mode http
     server s1_http 127.0.0.1:80 send-proxy

nginx.conf:

1
2
3
4
5
6
7
8
9
10
server {
  listen 80 default_server proxy_protocol;

  set_real_ip_from 127.0.0.1;
  real_ip_header proxy_protocol;
    location / {
      root /var/www/html;
      index index.html index.htm;
    }
}

ssh 127.0.0.1 -p8080
user@127.0.0.1's password:

curl 127.0.0.1:8080


HELLO WORLD!

Nginx: sticky sessions

If you have several backends and your clients should get access to only one of them during their session, you need in sticky sessions.
In case of nginx you have 2 ways:
1) Buy nginx plus
2) Build nginx from source with sticky sessions module

In this article we'll how to for 2nd variant.

Download latest stable sources from http://nginx.org/ru/download.html
Download module from https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/overview
Unpack all.
Setup necessary packages for building from sources

1
apt-get install libpcre3-dev build-essential libssl-dev gcc

cd to folder with nginx sources:

1
./configure --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_gunzip_module --with-http_gzip_static_module --add-module=../nginx-goodies-nginx-sticky-module-ng-f2adff04b8e3

where .../nginx-goodies-nginx-sticky-module-ng-f2adff04b8e3 path to module

1
2
3
make -j6
sudo checkinstal
sudo dpkg -i /home/alter/nginx/nginx-1.6.2/nginx_1.6.2-1_amd64.deb

where /home/alter/nginx/nginx-1.6.2/nginx_1.6.2-1_amd64.deb — path to deb file checkinstall generated for you.
Nginx will be installed in /usr/local/nginx/
If you have configs from previous nginx in /etc/nginx, you could make symlink for configs:

1
rm /usr/local/nginx/config/nginx.conf && ln -sf /etc/nginx/nginx.conf /usr/local/nginx/config/nginx.conf

Your upstream section should looks like:

1
2
3
4
5
6
upstream backends {
    sticky; # this is necessary option.

    server web1.domain.net:80 fail_timeout=60 max_fails=10;
    server web2.domain.net:80 fail_timeout=60 max_fails=10;
}

logstash+kibana+rabbitmq+elasticsearch

Install logstash rabbitmq-server elasticsearch from repository.
Download kibana from its site and unpack to your webroot folder.
I'll add nginx logs to logstash.

Nginx

set ngixn logs format in nginx.conf:

1
2
log_format logstash '$http_host ' '$remote_addr [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time ' '$upstream_response_time ' '$upstream_addr';
access_log /var/log/nginx/access.log logstash;

Logstash

add in /etc/logstash/conf.d 2 files,
logstash-nginx:

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
input {
tcp {
type => "nginx_agupcom"
data_timeout => 10
mode => "server"
host => "127.0.0.1"
port => 14001
}
}

filter {
if [type] == "nginx_agupcom" {
grok {
match => [
"message", "%{IPORHOST:http_host} %{IPORHOST:clientip} \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NUMBER:request_time:float} %{NUMBER:upstream_time:float} %{HOSTPORT:upstream_addr}",
"message", "%{IPORHOST:http_host} %{IPORHOST:clientip} \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NUMBER:request_time:float}"
]
}
date {
match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
}
geoip {
source => "clientip"
}
}
}

output {
rabbitmq {
exchange => "logstash_agupcom"
exchange_type => direct
host => "127.0.0.1" # string (required)
key => "logstash_agupcom"
workers => 2
durable => true
persistent => true
}
}

nginx_agupcom — name of my log type
logstash_agupcom name of queue in rabbitmq.
Continue reading logstash+kibana+rabbitmq+elasticsearch

nginx: ssl ciphers

1
2
3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4";
ssl_prefer_server_ciphers on;

Zoneminder: video surveillance system

Ubuntu 12.04.2 LTS

apt-get update
apt-get install zoneminder
/etc/init.d/apache2 stop
update-rc.d -f apache2 remove
apt-get install nginx-full
cat > /etc/nginx/sites-available/zm << EOF

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
server {
listen   80;
server_name  zm.lobotomy.me;
access_log  /var/log/nginx/zm.access.log;
root   /usr/share/zoneminder;

location / {
root /usr/share/zoneminder;
index index.php;

auth_basic            "closed site";
auth_basic_user_file  /etc/nginx/passwd;

if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
}

}

location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico)$ {
access_log off;
expires 30d;
}

error_page 404 /index.php;
error_page 500 502 503 504 /50x.html;

location = /50x.html {
root /var/www/nginx-default;
}

location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/zoneminder/$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
include /etc/nginx/fastcgi_params;
}

location ~ /\.ht {
deny all;
}

location  /cgi-bin/ {
proxy_pass              http://localhost:85;

proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        Host            localhost:85;
proxy_set_header        REQUEST_METHOD  $request_method;
proxy_set_header        REMOTE_USER     $remote_user;
proxy_set_header        REMOTE_ADDR     $remote_addr;
proxy_set_header        SERVER_NAME     localhost;
proxy_set_header        SERVER_PORT     85;
proxy_set_header        HTTP_COOKIE     $http_cookie;
}
}
EOF

cd /etc/nginx/sites-enabled/
ln -s .../sites-available/zm
rm default
apt-get install xinetd

1
2
3
4
5
6
7
8
9
10
11
12
cat &gt; /etc/xinetd.d/zms-inetd &lt;&lt; EOF
service zms-inetd
{
disable         = no
id              = zms-inetd
socket_type     = stream
protocol        = tcp
user            = www-data
wait            = no
server          = /usr/local/bin/zms-inetd
}
EOF

cat > /usr/local/bin/zms-inetd << EOF

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
63
64
65
66
#!/bin/bash
#
# Inetd-wrapper for ZMS (Zoneminder Streaming Server)
#
# Version: 2007-09-27
# Author: Kurt Zankl &lt;kz@xon.uni.cc&gt;
# Inspiration: http://www.debian-administration.org/articles/371
# Requirements: bash, inetd
# License: GNU General Public License, Version 2
#
# /etc/services:
# zms-inetd 85/tcp # Zoneminder ZMS inetd-wrapper
#
# /etc/inetd.conf:
# zms-inetd stream tcp nowait www-data /usr/local/bin/zms-inetd zms-inetd
#
# ZM Options / Paths / Web path to zms streaming server:
# ZM_PATH_ZMS = http://:85/
#

# configuration
ZMCONF="/etc/zm/zm.conf"
CGIBIN="zms"

# error handler
function errormsg {
echo "HTTP/1.0 500 Internal Server Error"
echo "Content-Type: text/html"
echo
echo "ERROR
<h1>ERROR</h1>
"
echo -e "
<pre escaped="true">$1"
  exit 1
}</pre>
# get request
read REQUEST
# skip headers
HEADER="nothing"; while [ "$HEADER" != $'\r' -a -n "$HEADER" ]; do read HEADER; done

# read ZM configuration
[ -r $ZMCONF ] || errormsg "Error reading Zoneminder configuration \"$ZMCONF\""
. $ZMCONF
ZMS="$ZM_PATH_CGI/$CGIBIN"
[ -x $ZMS ] || errormsg "Error finding ZMS executable \"$ZMS\""

# check request
[ -z "$REQUEST" ] &amp;&amp; errormsg "Request is empty"

# split request
URL="${REQUEST#GET }"
URL="${URL% HTTP/*}"
QUERY="${URL#*\?}"
URL="${URL%%\?*}"

# check query
[ "$QUERY" == "$URL" ] &amp;&amp; errormsg "Invalid query"

# execute ZMS
# (STDERR output is discarded as this confuses MPEG streaming clients)
export QUERY_STRING="$QUERY"
echo "HTTP/1.0 200 OK"
"$ZMS" 2&gt;/dev/null
echo
exit 0

set right path in option:
ZMCONF="/etc/zm/zm.conf"
/etc/init.d/xinetd restart

apt-get install php-fpm php-mysql php-gd
/etc/init.d/php-fpm restart

cd /usr/share/zoneminder/
ln -s .../javascript/ javascript

/etc/init.d/nginx restart

cat >> /etc/modules << EOF
uvcvideo
pwc
EOF

modprobe uvcvideo
modprobe pwc

Settings for Logitech QuickCam Pro 4000
Source: Local
Type: Modect
Source: /dev/video0
Channel: 0
Format: PAL
Capture type: YUV420
Width: 320
Height: 240

Nginx: set REMOTE_ADDR to HTTP_X_FORWARDED_FOR

I use apache2 as frontend proxy (on the gateway) and nginx as backend (on the internal host).
Apache sends its IP as REMOTE_ADDR and IP of client as HTTP_X_FORWARDER_FOR.
Statistics of unique IPs in my blog was destructed, but I found solution.
In the nginx settings set option AFTER include:
1
location ~ .php$ {
1
    
1
fastcgi_pass 127.0.0.1:9000;
1
    

1
include fastcgi.conf;
1
    

1
fastcgi_param REMOTE_ADDR $http_x_forwarded_for;
1
}

nginx: file not found

I have nginx + php but got message «File not found»,
this is a part of my config where i set proxy for php-fpm:

    location ~ .php$ {
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/test$fastcgi_script_name;
        include fastcgi_params;
    }

Fix is simple as a piece of cake:

    location ~ .php$ {
        root /var/www/test;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/test$fastcgi_script_name;
        include fastcgi_params;
    }