Wiki

Clone wiki

configs / linux / soft / nginx

nginx

Примеры конфигов

Статичный сайт

server {
        listen   80;
        server_name .kilex.ru;
        root /var/www/kilex.ru;
        expires 12h;
        add_header Cache-Control public;
}

Статика+php проброс в апач

server {
        listen   80;
        server_name .kilex.ru;
      location / {
                proxy_buffering   on;
                proxy_pass        http://localhost:80;
                proxy_set_header  Host $host:$server_port;
                proxy_set_header  X-Forwarded-For $remote_addr;
                proxy_set_header  X-Real-IP $remote_addr;
        }
        location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|wav|bmp|rtf|js|mp3)$ {
                root /var/www/kilex.ru;
                 expires 12h;
                 add_header Cache-Control public;
        }
}

Статика + php-fpm

server {
        listen   80;
        server_name .kilex.ru;
        index   index.php;
        root /var/www/kilex.ru;
        location / {
                 try_files $uri $uri/ /index.php?$args;
        }
        location ~ \.php$ {
                 try_files $uri /index.php?$args; 
                 fastcgi_pass unix:/var/run/php5-fpm.sock;
                 fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
                 include fastcgi_params;
        }
        location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|wav|bmp|rtf|js|mp3)$ {
                 expires 12h;
                 add_header Cache-Control public;
        }
}

SSL

Только HTTPS

Перенаправление на https

server {
        listen       80;
        server_name kilex.ru test.kilex.ru;

        if ( $scheme = "http" ) {
                rewrite ^/(.*)$ https://kilex.ru/$1 permanent;
            }
        }
Сам сайт:
server {
        listen       443;
        server_name .kilex.ru;
        access_log  /var/log/nginx/kilex.ru.access.log;

        ssl                     on;
        ssl_protocols           SSLv3 TLSv1;
        ssl_certificate         /etc/nginx/SSL/ssl-bundle.crt; # Цепочка сертификатов
        ssl_certificate_key     /etc/nginx/SSL/private.key;    # закрытый ключ
        ssl_session_timeout 5m;

        location / {
            proxy_pass         http://localhost:80;
        }

}

Можно объеденять https и http

server {
        listen       80;
        listen       443 ssl;
        server_name .kilex.ru;
        access_log  /var/log/nginx/kilex.ru.access.log;


        ssl_protocols           SSLv3 TLSv1;
        ssl_certificate         /etc/nginx/SSL/ssl-bundle.crt; # Цепочка сертификатов
        ssl_certificate_key     /etc/nginx/SSL/private.key;    # закрытый ключ
        ssl_session_timeout 5m;

        location / {
            proxy_pass         http://localhost:80;
        }

}

ssl-bundle.crt

ssl-bundle.crt - цепочка сертификатов. Необходимо добавить в него все сертификаты от корня до вашего.
Для nginx важно соблюдать порядок: - Свой сертификат - Корневой - Промежуточные (их можно в разнобой)

собирают обычно катом:

cat my.crt CA.crt other.crt > ssl-bundle.crt

проброс статуса https в бакенд

Чтобы корректно работала переменная PHP $_SERVER['HTTPS'] необходимо передать эту инфу в бакенд.

apache2

в virtualhost nginx добавляем хэдер в который передаем scheme:

location / {
      ...
      proxy_set_header            X-Forwarded-Proto $scheme;
      ...
}
в virtualhost apache2 добавляем
<VirtualHost 127.0.0.1:8080>
  ServerName kilex.ru
  ...
  SetEnvIf X-Forwarded-Proto https HTTPS=on
  ...
</VirtualHost>

php-fpm

в файл с настройками fastcgi должна быт строка
/etc/nginx/fastcgi_params

fastcgi_param  HTTPS              $https if_not_empty;

Upstreams

Можно иметь несколько бакендов

upstream backend {
    server backend1.example.com       weight=5; # по умолчанию у всех вес - 1
    server backend2.example.com:8080;
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s; # если ошибка - таймаут
    server unix:/tmp/backend3;

    server backup1.example.com:8080   backup;
    server backup2.example.com:8080   backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

Разрешить заливать большие файлы

client_max_body_size 100m;

Ограничение доступа

можно использовать как в контейнере server, так и в location

allow 192.168.0.0/16;
deny all;

также удобно разместить в отдельном файле и просто делать include /etc/nginx/kilexru-allowed-ips; в нужном месте конфига

Доступ с юзерагентов

Можно ограничить доступ только с определенных юзерагентов (ну или забанить зловредные)

location /private {
        proxy_pass         http://127.0.0.1:8080;
        if ($http_user_agent !~* (Safari) ) {
                return 403;
        }
    }
Здесь больше примеров

NAXSI

nginx также способен защитить сайт он sql-иньекций. но делать это надо с осторожностью.

Надо бы добавить инфу о базовой настройке NAXSI

Подробнее про плагин можно почитать здесь

Cache

Чтобы закешировать все запросы к бакенду необходимо в nginx.conf в контейнер http перед инклудом сайтов добавить

proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=cached:30m max_size=1G;
proxy_temp_path /var/lib/nginx/proxy 1 2;
proxy_ignore_headers Expires Cache-Control;
proxy_cache_use_stale error timeout invalid_header http_502;
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;

затем чтобы кешировать какой либо локейшен необходимо добавить перед proxy_pass строки:

location / {
                proxy_cache cached;
                proxy_cache_valid 10m; # все кешить на 10 минут
                proxy_cache_valid 404 1m; # 404 кешить на минуту
                proxy_ignore_headers        X-Accel-Expires Expires Cache-Control;
                proxy_cache_lock    on; # блокировка доступа к бакенду, только один запрос пройдет, остальные ждут кеша
                proxy_cache_use_stale       updating; # разрешает использовать устаревший закэшированный ответ
                proxy_cache_key "$host$scheme$proxy_host$uri$is_args$args";
                expires     24h;

                proxy_buffering   on;
                proxy_pass        http://localhost:80;
                proxy_set_header  Host $host;
                proxy_set_header  X-Forwarded-For $remote_addr;
                proxy_set_header  X-Real-IP $remote_addr;
        }

Custom errors

У nginx-а есть некоторые проблемы при выводе кастомных ошибок с помощью return. Нашел вот такой вариант решения проблемы:

   if ($allow = N) {
    return 503;
    }

   location @503 {
       rewrite  ^(.*)$  /errors/503.json break;
   }

log format

log_format timed_combined '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '$request_time $upstream_response_time $pipe';
log_format custom '$remote_addr [$time_local] "$host" "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time $upstream_response_time';

Updated