Narzędzia użytkownika

Narzędzia witryny


nginx

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

nginx [2018/07/16 11:47] (aktualna)
Linia 1: Linia 1:
 +===== Wstęp =====
  
 +Ostatnio przeszedłem z Apache na Nginx'a i postanowiłem napisać małe "how to" jak to wykonać - może komuś się przyda. Czemu się zdecydowałem na Nginx'a? Apache zajmuje dużo pamięci oraz jest mniej wydajny.
 +
 +===== Instalacja =====
 +
 +  poldek:/all-avail> install nginx-light
 +
 +===== Konfiguracja =====
 +
 +Opis pliku konfiguracji **/etc/nginx/nginx-light.conf** (opisuje to co możemy zmieniać):
 +<file>
 +user                    nginx nginx;
 +worker_processes        5;
 +error_log               /var/log/nginx/nginx-light_error.log;
 +pid                     /var/run/nginx-light.pid;
 +</file>
 +Kolejno:
 +     * pierwsza linia definiuje na jakim użytkowniku ma być uruchomiona usługa,
 +     * worker_process - ile ma być uruchomionych wątków Nginx'a,
 +     * error_log definiuje plik, gdzie będą zapisywane błędy,
 +     * pid - gdzie ma być zapisywany process ID - nie zmieniamy.
 +<file>
 +events {
 +        worker_connections      2048;
 +        use epoll;
 +}
 +</file>
 +Worker_connections - ilość requestów na wątek.
 +<file>
 +http {
 +        include         /etc/nginx/mime.types;
 +        default_type    application/octet-stream;
 +
 +        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      /var/log/nginx/nginx-light_access.log   main;
 +        sendfile        on;
 +        tcp_nopush      on;
 +        tcp_nodelay     on;
 +        server_names_hash_bucket_size   128;
 +        types_hash_max_size     2048;
 +        types_hash_bucket_size  64;
 +        #keepalive_timeout      0;
 +        keepalive_timeout       65;
 +        limit_zone      test-limit      $binary_remote_addr     10m;
 +        #gzip   on;
 +        server {
 +                listen          80;
 +                server_name     localhost;
 +                access_log      /var/log/nginx/nginx-light_access.log  main;
 +                client_max_body_size    10M;
 +
 +                location / {
 +                        autoindex       on;
 +                        root    /home/services/nginx/html;
 +                        index   index.html index.htm index.php;
 +                        limit_conn      test-limit      15;
 +                }
 +
 +
 +#               location /nginx_status {
 +#                       stub_status     on;
 +#                       access_log      off;
 +#                       allow   127.0.0.1;
 +#                       deny    all;
 +#               }
 +
 +#               error_page      404     /404.html;
 +#               error_page      500 502 503 504 /50x.html;
 +#               location = /50x.html {
 +#                       root    /home/services/http/error-pages;
 +#               }
 +#               location = /404.html {
 +#                       root    /home/services/http/error-pages;
 +#               }
 +
 +#               location ~ \.php$ {
 +#                       include         /etc/nginx/fastcgi.params;
 +#                       fastcgi_pass    127.0.0.1:1026;
 +#                       fastcgi_index   index.php;
 +#                       fastcgi_param   SCRIPT_FILENAME /home/services/nginx/html$fastcgi_script_name;
 +#               }
 +
 +        }
 +
 +}
 +</file>
 +Sekcja http:
 +     * log_format - definiujemy jak ma wyglądać wpis w logach - listę zmiennych znajdziemy tu: http://wiki.nginx.org/HttpCoreModule#Variables,
 +     * access_log - plik gdzie zapisujemy logi,
 +     * gzip - kompresja (opis niżej),
 +
 +Sekcja server:
 +     * listen - na jakim porcie ma nasłuchiwać vhost, pierwszy vhost jest domyslnym vhostem, możliwe kombinacje co do portu i adres IP to: listen IP:port; gdzie * = 0.0.0.0 (np *:80),
 +     * server_name - definiujemy vhost'a, a po spacji definiujemy aliasy, aczkolwiek przy domyślnym vhoście nie ma to znaczenia,
 +     * location / - tu ustawiamy opcje dotyczącego katalogu root w vhoście,
 +     * autoindex - on włącza tworzenie się autoindeksów,
 +     * root - definiowania katalogu root dla danego vhost'a,
 +     * index - tu definiujemy domyslne pliki, które będą otwierane po wejściu do katalogu,
 +     * location /nginx_status - włącza status Nginx'a pod danym virtualnym katalogiem vhost'a - przydatne do statystyk (opis niżej),
 +     * error_page - definiowanie plików w przypadku błędów - 404, 500, itp,
 +     * location ~ \.php$ - definiowanie obsługi plików PHP przez demona FastCGI (opis niżej).
 +
 +Wszelkie zmiany powinny zostać przetestowane składniowo przez Nginx'a, służy to tego komenda:
 +  $ nginx-light -t
 +
 +i powinna ona zwrócic coś takiego:
 +
 +  $ the configuration file /etc/nginx/nginx-light.conf syntax is ok
 +  $ configuration file /etc/nginx/nginx-light.conf test is successful
 +
 +w przypadku błędu pojawi się informacja gdzie jest błąd.
 +
 +Logi z błędami w krótkim czasie robią się bardzo duże - to głównie za sprawą różnego rodzaju botów. Przydatną opcją jest wyłączenie logownia próby pobrania plików/katalogów których nie ma na serwerze, a ślady w logach są. Wyłączyć możemy za pomocą przydatnej opcji:
 +<file>
 +http {
 +...
 +           log_not_found off;
 +...
 +}
 +</file>
 +
 +==== IPv6 ====
 +
 +Najpierw trzeba sprawdzić czy Nginx został skompilowany z opcją --with-ipv6. Aby to sprawdzić wykonajmy:
 +  $ nginx-light -V
 +
 +Jeśli Nginx obsługuje IPv6 to w sekcji serwer danego vhosta modyfikujemy listen:
 +<file>
 +listen          [::]:80;
 +</file>
 +
 +taki wpis oznacza, że serwer nasłuchuje na IPv4 oraz IPv6, jeśli chcemy, aby tylko i wyłącznie nasłuchiwał na IPv6 ustawiamy:
 +<file>
 +listen          [::]:80 ipv6only=on;
 +</file>
 +zamiast [::] możemy podać adres (np: [ffff:a:b:c::01]).
 +
 +==== SSL ====
 +
 +Tworzymy certyfikaty SSL. Aby to zrobić trzeba zainstalować narzędzia Openssl'a:
 +
 +  $ install openssl-tools
 +
 +Generowanie certyfikatów:
 +
 +  $ openssl genrsa -out /etc/nginx/server.key 1024
 +  $ openssl req -new -x509 -days 365 -key /etc/nginx/server.key -out /etc/nginx/server.crt
 +  $ chmod 600 /etc/nginx/server.*
 +
 +Do sekcji http dopisujemy:
 +<file>
 +ssl_certificate      server.crt;
 +ssl_certificate_key  server.key;
 +</file>
 +w sekcji **server** głównego vhosta wpisujemy:
 +<file>
 +listen          443 default_server ssl;
 +</file>
 +w przypadku IPv6:
 +<file>
 +listen          [::]:443 default_server ssl;
 +</file>
 +w kolejnych vhostach wystarczy wpisać:
 +<file>
 +listen          443;
 +</file>
 +Oczywiście każdy vhost może mieć osobny certyfikat, np:
 +<file>
 +server {
 +...
 + listen          443;
 + ssl_certificate      server1.crt;
 + ssl_certificate_key  server1.key;
 +...
 +}
 +...
 +server {
 +...
 + listen          443;
 + ssl_certificate      server2.crt;
 + ssl_certificate_key  server2.key;
 +...
 +}
 +</file>
 +
 +==== Vhosty ====
 +
 +Domyślnie działa nam główny vhost - czyli domyślny. Aby utworzyć kolejnego trzeba dodać do konfiguracji kolejną sekcje **server** w sekcji **http**. Aby mieć porządek w pliku konfiguracji polecam dodanie na końcu sekcji **http** (przed **}**) opcji:
 +<file>
 +include         /etc/nginx/vhosts.d/*.conf;
 +</file>
 +która będzie dodawała konfiguracje z plików (z rozszerzeniem **conf**) z katalogu **/etc/nginx/vhosts.d/**. Tego katalogu nie ma więc musimy go stworzyć:
 +
 +  $ mkdir /etc/nginx/vhosts.d/
 +  $ chmod 700 /etc/nginx/vhosts.d/
 +
 +Przykładowy konfig vhosta:
 +<file>
 +server {
 +        listen          [::]:80;
 +        server_name     nasz.vhost.ltd;
 +        access_log      /home/users/kamil/www/nasz.vhost.ltd/access.log main;
 +        error_log       /home/users/kamil/www/nasz.vhost.ltd/error.log error;
 +
 +        location / {
 + autoindex on;
 +                        root    /home/users/kamil/www/nasz.vhost.ltd/htdocs;
 +                        index   index.html index.htm;
 +        }
 +
 +}
 +</file>
 +Z czasem on się zmieni w zależności co będziemy chcieli osiągnąć w danym vhoście.
 +
 +==== CGI ====
 +
 +CGI będzie nam potrzebne, aby uruchomić np Mailman'a. Ale żeby to zrobić musimy sobie skompilować program do obsługi CGI. A więc zatem instalujemy kompilator:
 +
 +  poldek:/all-avail> install gcc gcc-c++ gcc-objc++ gcc-objc libstdc++- libstdc++-devel git-core autoconf automake fcgi fcgi-devel
 +
 +Ściągamy i kompilujemy **FcgiWrap**:
 +  
 +  $ mkdir ~/install
 +  $ cd ~/install
 +  $ git clone git://github.com/gnosek/fcgiwrap.git
 +  $ cd fcgiwrap
 +  $ ./configure
 +  $ make
 +
 +Jeśli podczas make będziecie mieć taki błąd:
 +  fcgiwrap.c:30:24: fatal error: fcgi_stdio.h: No such file or directory
 +edytujemy plik **fcgiwrap.c** i zmieniamy w nim **linię nr 30** z:
 +<file>
 +#include <fcgi_stdio.h>
 +</file>
 +na:
 +<file>
 +#include <fastcgi/fcgi_stdio.h>
 +</file>
 +
 +Po skompilowaniu kopiujemy binarkę do **/usr/local/bin/**
 +
 +  $ cp ~/install/fcgiwrap/fcgiwrap /usr/local/bin/
 +
 +Tworzymy plik **/etc/init.d/fcgiwrap** i zapisujemy w nim:
 +<file>
 +#!/usr/bin/perl
 +
 +use strict;
 +use warnings FATAL => qw( all );
 +
 +use IO::Socket::UNIX;
 +
 +my $bin_path = '/usr/local/bin/fcgiwrap';
 +my $socket_path = $ARGV[0] || '/tmp/cgi.sock';
 +my $num_children = $ARGV[1] || 1;
 +
 +close STDIN;
 +
 +unlink $socket_path;
 +my $socket = IO::Socket::UNIX->new(
 +    Local => $socket_path,
 +    Listen => 100,
 +);
 +
 +die "Cannot create socket at $socket_path: $!\n" unless $socket;
 +
 +for (1 .. $num_children) {
 +    my $pid = fork;
 +    die "Cannot fork: $!" unless defined $pid;
 +    next if $pid;
 +
 +    exec $bin_path;
 +    die "Failed to exec $bin_path: $!\n";
 +}
 +</file>
 +Nadajemy odpowiednie uprawnienia:
 +  $ chmod 750 /etc/init.d/fcgiwrap
 +  $ chown root:nginx /etc/init.d/fcgiwrap
 +
 +Uruchamiamy:
 +  $ sudo -u nginx /etc/init.d/fcgiwrap
 +  $ chmod 770 /tmp/cgi.sock
 +
 +Dodpisujemy na koniec pliku **/etc/rc.d/rc.local** dwa powyższe polecenia.
 +
 +Przykładowa konfiguracja vhosta Mailmana:
 +<file>
 +server {
 +        listen          [::]:80;
 +        listen          [::]:443;
 +
 +        server_name     mailman.host.ltd lists.host.ltd;
 +        access_log      /var/log/httpd/mailman.orchia.pl_access.log main;
 +        error_log       /var/log/httpd/mailman.orchia.pl_error.log error;
 +
 +        root    /usr/lib/mailman/cgi-bin;
 +
 +        location = / {
 +                rewrite ^ /mailman/listinfo permanent;
 +        }
 +
 +        location / {
 +                rewrite ^ /mailman$uri;
 +        }
 +
 +        location ~ ^/mailman(/[^/]*)(/.*)?$ {
 +                fastcgi_split_path_info (^/mailman/[^/]*)(.*)$;
 +                include fastcgi.params;
 +                fastcgi_param GATEWAY_INTERFACE CGI/1.1;
 +                fastcgi_param SCRIPT_FILENAME $document_root$1;
 +                fastcgi_param PATH_INFO $fastcgi_path_info;
 +                fastcgi_param PATH_TRANSLATED $document_root$2;
 +                fastcgi_pass unix:/tmp/cgi.sock;
 +        }
 +
 +        location /icons {
 +                alias /usr/lib/mailman/icons;
 +        }
 +
 +        location /mailman/pipermail {
 +                alias /var/lib/mailman/archives/public;
 +                autoindex on;
 +        }
 +
 +}
 +</file>
 +
 +==== PHP ====
 +
 +Instalujemy PHP'a:
 +
 +  poldek:/all-avail> install php-common php-cgi php-cli php-fpm
 +
 +Ustawiamy zmienne w pliku **/etc/php/php-fpm.conf**
 +<file>
 +pid = run/php/fpm.pid
 +daemonize = yes
 +listen = 127.0.0.1:9000
 +listen.allowed_clients = 127.0.0.1
 +user = nginx
 +group = nginx
 +pm = dynamic
 +pm.min_spare_servers = 5
 +pm.max_spare_servers = 35
 +</file>
 +
 +Tworzymy strukturę katalogów pod vhosta:
 +  $ mkdir -p /home/users/user/www/moj.vhost.ltd/htdocs
 +  $ mkdir -p /home/users/user/www/moj.vhost.ltd/tmp
 +  $ chmod -R 750 /home/users/user/www/moj.vhost.ltd/htdocs
 +  $ chmod -R 770 /home/users/user/www/moj.vhost.ltd/tmp
 +  $ chown -R user:http /home/users/user/www/moj.vhost.ltd
 +
 +Tworzymy plik **/etc/nginx/vhosts.d/moj.vhost.ltd** i zapisujemy w nim konfigurację:
 +<file>
 +server {
 +        listen          [::]:80;
 +        server_name     cp.kamilm.net;
 +        access_log      /home/users/user/www/moj.vhost.ltd/access.log main;
 +        error_log       /home/users/user/www/moj.vhost.ltd/error.log error;
 +
 +        location / {
 +                        root    /home/users/user/www/moj.vhost.ltd/htdocs;
 +                        index   index.html index.htm index.php;
 +        }
 +
 +        location ~ \.php$ {
 +                include         /etc/nginx/fastcgi/moj.vhost.ltd.param;
 +                fastcgi_pass    127.0.0.1:9000;
 +                fastcgi_index   index.php;
 +                fastcgi_param   SCRIPT_FILENAME /home/users/user/www/moj.vhost.ltd/htdocs$fastcgi_script_name;
 +        }
 +
 +}
 +</file>
 +Tworzymy katalog na konfigurację paramterów PHP'a dla vhostów:
 +
 +  $ mkdir /etc/nginx/fastcgi
 +  $ chmod 700 /etc/nginx/fastcgi
 +
 +Tworzymy plik **/etc/nginx/fastcgi/moj.vhost.ltd.param** i zapisujemy w nim:
 +<file>
 +fastcgi_param  QUERY_STRING       $query_string;
 +fastcgi_param  REQUEST_METHOD     $request_method;
 +fastcgi_param  CONTENT_TYPE       $content_type;
 +fastcgi_param  CONTENT_LENGTH     $content_length;
 +
 +fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
 +fastcgi_param  REQUEST_URI        $request_uri;
 +fastcgi_param  DOCUMENT_URI       $document_uri;
 +fastcgi_param  DOCUMENT_ROOT      $document_root;
 +fastcgi_param  SERVER_PROTOCOL    $server_protocol;
 +
 +fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
 +fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
 +
 +fastcgi_param  REMOTE_ADDR        $remote_addr;
 +fastcgi_param  REMOTE_PORT        $remote_port;
 +fastcgi_param  SERVER_ADDR        $server_addr;
 +fastcgi_param  SERVER_PORT        $server_port;
 +fastcgi_param  SERVER_NAME        $server_name;
 +
 +# PHP only, required if PHP was built with --enable-force-cgi-redirect
 +fastcgi_param  REDIRECT_STATUS    200;
 +
 +fastcgi_param  PHP_VALUE "open_basedir=/home/users/user/www/moj.vhost.ltd/htdocs:/home/users/user/www/moj.vhost.ltd/tmp:/usr/share/php/:/usr/share/pear/
 +upload_tmp_dir=/home/users/user/www/moj.vhost.ltd/tmp
 +session.save_path=/home/users/user/www/moj.vhost.ltd/tmp
 +sendmail_path='/usr/sbin/sendmail -f user -t -i'";
 +</file>
 +Robimy reload Nginx'a:
 +
 +  $ /etc/init.d/nginx-light reload
 +
 +Gdy normalne strony działają, a w PHP nie chcą - pisze np: **Bad Gateway** to najpierw sprawdźmy czy konfiguracja PHP'a jest dobra. Sprawdzić możemy prostym przykładem:
 +
 +  $ echo "<?php echo \"dupa\"; " | php
 +
 +
 +
 +
 +==== PERL ====
 +
 +czekam aż ktoś kopnie nowszą wersję perla do repo wtedy dokończe z wraperem perla.
 +
 +==== Statystyki ====
 +
 +W konfiguracji Nginx'a danego vhosta musimy mieć zapis:
 +
 +<file>
 +               location /nginx_status {
 +                       stub_status     on;
 +                       access_log      off;
 +                       allow   127.0.0.1;
 +                       deny    all;
 +               }
 +</file>
 +
 +Czasem bywa tak, że danego vhosta możemy odpytywać nie z localhost'a tylko z wew/zew IP - należy go dopisać do **allow**. Wystarczy przeładować Nginx'a i możemy się odwoływać do http://vhost.ltd/nginx_status - gdy to zadziała możemy pobierać dane i wciągać je do naszego systemu statystyk. Np w MRTG:
 +
 +Tworzymy plik nginx_vhost.ltd.conf:
 +<file>
 +#
 +# Nginx stat
 +#
 +# connections
 +
 +WorkDir: /home/users/vftp/www/stats.sun.orchia.pl/htdocs
 +
 +Target[nginx_con]: `/etc/mrtg/conf.d/mrtg-nginx con`
 +Options[nginx_con]: growright, integer, nobanner, nopercent, transparent
 +Title[nginx_con]: Nginx Connections
 +MaxBytes[nginx_con]: 2048
 +YLegend[nginx_con]: Connections
 +ShortLegend[nginx_con]: con
 +LegendI[nginx_con]:
 +LegendO[nginx_con]: con:
 +Legend1[nginx_con]: Connections
 +Legend2[nginx_con]: Connections
 +PageTop[nginx_con]: <h1>Nginx Connections</h1>
 +# requests
 +Target[nginx_req]: `/etc/mrtg/conf.d/mrtg-nginx req`
 +Options[nginx_req]: gauge, growright, nobanner, nopercent, transparent
 +Title[nginx_req]: Nginx Requests
 +MaxBytes[nginx_req]: 2048
 +YLegend[nginx_req]: request/s
 +ShortLegend[nginx_req]: req/s
 +Legend1[nginx_req]: Requests per Second
 +Legend2[nginx_req]: Requests per Second
 +LegendI[nginx_req]:
 +LegendO[nginx_req]: Requests:
 +PageTop[nginx_req]: <h1>Nginx Requests</h1>
 +</file>
 +
 +Do pliku **/etc/mrtg/conf.d/mrtg-nginx** zapisujemy:
 +<file>
 +#!/usr/bin/perl
 +# $Revision: 2 $
 +# $Date: 2008-09-12 15:11:40 +0300 (Fri, 12 Sep 2008) $
 +
 +my %opt = (
 +# http link to nginx stub_status, be sure turn on stub_status in nginx conf
 +    nginx_status   => 'http://localhost:80/nginx_status',
 +# path for program what may dump web page, normaly lynx -dump
 +#    lynx            => 'lynx -dump',
 +    lynx            => 'wget -q -Y off -O -',
 +);
 +
 +$opt{var} = $ARGV[0] if $ARGV[0];
 +$opt{nginx_status} = $ARGV[1] if $ARGV[1] and $ARGV[1]=~/^http:\/\/\w+/;
 +$opt{var} ||= '';
 +
 +my $do = `$opt{lynx} $opt{nginx_status}`;
 +
 +if ($opt{var} eq 'req') {
 +    $do=~/^Active connections:\s*(\d+)\s*$/ms or warn "Error! Can't find data!\nIN :\n$do";
 +    $opt{d2} = $opt{d1} = $1;
 +}
 +elsif ($opt{var} eq 'con') {
 +    $do=~/^\s*(\d+)\s+(\d+)\s+(\d+)\s*$/ms or warn "Error! Can't find data!\nIN :\n$do";
 +    $opt{d2} = $opt{d1} = $3;
 +}
 +#elsif { $do=~/^Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)/; }
 +else {
 +    $opt{var} = 'ERROR';
 +    $opt{d2} = $opt{d1} = 0;
 +    warn "Error! Please read the help and set (req|con)\n";
 +}
 +
 +print "$opt{d1}\n";
 +print "$opt{d2}\n";
 +#print "$opt{up}\n" if $opt{up};
 +print "Nginx $opt{var}\n";
 +</file>
 +
 +
 +===== Inne =====
 +
 +**HTTP Auth**:
 +<file>
 +server {
 +...
 +        location / {
 +...
 +                        auth_basic            "Restricted";
 +                        auth_basic_user_file  /home/users/user/www/moj.vhost.ltd/.htpasswd;
 +        }
 + }
 +</file>
 +Plik **/home/users/user/www/moj.vhost.ltd/.htpasswd** możemy wygenerować za pomocą skryptu, który musimy pobrać:
 +  $ wget http://trac.edgewall.org/browser/trunk/contrib/htpasswd.py?format=txt
 +  $ mv ./htpasswd.py?format=txt ./htpasswd.py
 +  $ chmod 755 ./htpasswd.py
 +
 +Aby plik działał musimy mieć zainstalowany pakier **python-modules**:
 +
 +  poldek:/all-avail> install python-modules
 +
 +Uruchamiamy wg składni:
 +
 +  $ ./htpasswd.py -c -b /home/users/user/www/moj.vhost.ltd/.htpasswd admin tajne_haslo
 +
 +**HTTP -> HTTPS**:
 +
 +<file>
 +server {
 +...
 +                listen 80;
 +                rewrite          ^(.*)          https://$server_name$1 permanent;
 +...
 +}
 +
 +server {
 +...
 +                listen 443;
 +                fastcgi_param HTTPS on;
 +...
 +}
 +
 +</file>
 +
 +**Zend**:
 +<file>
 +server {
 +...
 + location / {
 +...
 + if (!-f $request_filename) {
 +    rewrite  ^(.*)$  /index.php  last;
 +    break;
 + }
 + }
 +</file>
nginx.txt · ostatnio zmienione: 2018/07/16 11:47 (edycja zewnętrzna)