RTFM.WIKI

Ordnung muß sein. Ordnung über alles (18+)

Инструменты пользователя

Инструменты сайта


Боковая панель


Навигация

Линкшэринг

~~socialite Display:icon facebook twitter~~

ALARM!

Добавить новую страницу

You are not allowed to add pages

Реклама

linux:nginx:nginx_tnt

nginx: tips & howto

Генератор конфига

Конфиги сниппеты

Редиректы

Перенаправление на SSL-адрес (HTTPS) с нестандартным портом

via http://www.f-notes.info/nginx:ssl_non-stadard_port

error_page 497 https://$server_name:8443$request_uri;

Редирект на https://foobar.com

server {
    listen 80;
    server_name foobar.com www.foobar.com
    return 301 https://www.foobar.com$request_uri;
}
server {
    listen 443 ssl;
    server_name foobar.com;

    ssl_certificate     /etc/nginx/ssl/www.foobar.com.crt;
    ssl_certificate_key /etc/nginx/ssl/www.foobar.com.key;

    return 301 https://www.foobar.com$request_uri;
}

server {
    listen 443 ssl;
    server_name www.foobar.com;
    root /var/www/html

    ssl_certificate     /etc/nginx/ssl/www.foobar.com.crt;
    ssl_certificate_key /etc/nginx/ssl/www.foobar.com.key;
}

Еще примеры

Банхаммер3000

Блокируем через geoip

http://blog.ls20.com/optimizing-nginx-config-for-your-website-or-blog/

Начиная с версии 1.9.11 введена поддержка динамических модулей

Примеры использования модуля - http://nginx.org/en/docs/http/ngx_http_geoip_module.html

yum install nginx-module-geoip
apt-get install nginx-module-geoip  

Добавляем в самое начало файла /etc/nginx/nginx.conf перед блоком http {}

load_module "modules/ngx_http_geoip_module.so";

Коды названий стран

ISO 3166 Country Codes

В блок http {} перед include добавить

    geoip_country /usr/share/GeoIP/GeoIP.dat;
    map $geoip_country_code $allowed_country {
        default yes;
        RU no;
        UA no;
        BY no;
        CN no;
    }

Для блокировки нужно добавить в server {}

    if ($allowed_country = no) {
        return 444;

444 - закрыть соединение без отправки ответа клиенту.

FIXME почитать про GeoIP2

Блокируем поисковых ботов

map $http_user_agent $bad_bot {
    default 0;
    ~(?i)(alexa.com|AltaVista|ApacheBench|Aport|Ahrefs|AhrefsBot|Baiduspider|BLEXBot|CCBot|CommentReader|Copier|Crowsnest|DISCo|discobot|ExpertSearch|ExpertSearchSpider|FairShare|FeedFetcher|FlaxCrawler|FastSeek|FlappyBot|FlashGet|GetRight|GetWeb!|Grabber|g00g1e|HTTrack|ia_archiver|LeechFTP|LeechGet|Linguee|LinkBot|MauiBot|MJ12|MJ12bot|netvampire|Offline|PycURL|Python|QuerySeekerSpider|Ruby|Seopult|Semrush|SEMrushBot|SputnikBot|spbot|SputnikFaviconBot|SputnikImageBot|Sogou|TalkTalk|Teleport|uTorrent|urllib|Vampire|vkShare|WebCopy|WebCopier|WebCollector|WebSpider|WebStripper|WebWhacker|Yeti|YottosBot) 1;
}

В server {} добавить в нужное место

if ($bad_bot = 1) { return 403; }

Для проверки представимся ahrefsom

curl http://localhost -H 'User-Agent: Ahrefs' -I

Блокируем реферальный спам

1 Добавляес в http {} спам домены

map $http_referer $bad_referer {
    hostnames;
    default                           0;
    "~*best\-seo\-solutions\.com"     1;
    "~*buy\-cheap\-online\.net"       1;
    "~*get\-free\-traffic\-now\.biz"  1;
}

Добавляес в server {} для нужного сайта

server {
	if ($bad_referer) {
		return 444;
	}
}

Можно использовать готовый черный список через include

http {
	include referral-spam.conf;
}

В этом нам поможет ngx_http_map_module

PHP-FPM

ondemand или dynamic

Во-первых пул это просто набор процессов. Это не какой-то отдельный процесс.
При политике ondemand воркеры создаётся только тогда когда приходит запрос. Через несколько секунд (задаётся в настройках) после завершения обработки запроса (если не поступит нового запроса который можно передать воркеру) воркер убивается.
При dynamic демон всегда поддерживает некоторое заданное количество воркеров в пуле, и распределяет запросы между ними. Если для обработки запросов не хватает воркеров то демон создаёт дополнительных (вплоть до некоторого конфигурируемого значения). Когда потребность в дополнительных воркерах отпадает демон убивает лишние, так что-бы осталось нужное количество.
Профит от повторного использования воркеров в том что не тратится время на повторное создание процесса. Но если у тебя тормозной код то на его фоне ты этого времени всё-равно не заметишь.
На сколько я понимаю это происходит как-то так. Попаболь в том что воркеры не особо спешат освобождать память использованную для обработки запроса (кстати я не в курсе баг это или какая-то непонятная фича). По этому если твоё приложение на обработку каждого запроса тратит (например) 100 мб памяти и у тебя есть 3 воркера, каждый из которых за свою жизнь получил хотя-бы один запрос, то у тебя в системе будет висеть три процесса каждый из которых выжирает по 100 мб памяти, даже если запросов в тот пул сейчас нет вообще. Побаболь наступает тогда когда у тебя есть куча малопосещаемых сайтов с жадным до памяти кодом. У меня используется dynamic для пулов которые без запросов не остаются, и ondemand для малопосещаемых сайтов.

Калькулятор max_children

Разное FPM

Дебаг PHP-FPM с помощью strace

Разное

X509_check_private_key:key values mismatch

Нарушен порядок в crt/pem файле.

-----BEGIN CERTIFICATE-----
Сертификат_сервера
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
Сертификат корневого центра сертификации (CA)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
СЕРТИФИКАТ ПРОМЕЖУТОЧНОГО ЦЕНТРА СЕРТИФИКАЦИИ
Сертификат промежуточного центра сертификации (Intermediate)
-----END CERTIFICATE-----

favicon.ico

По стандарту, "картинка (иконка) сайта" должна быть. Поэтому в еррлоги активно пишется на каждый запрос, что favicon.ico not found. Можно для nginx создать секцию

location /favicon.ico {
    root ...
    log_not_found off;
    access_log off;
}

Есть опция empty_gif

location /favicon.ico {
    empty_gif;
    access_log off;
}

Таким образом будет отдаваться прозрачный гиф 1х1px на все запросы иконки.

А теперь объединим.

 location /favicon.ico {
    access_log off;
    try_files $uri @emptygif;
}
location @emptygif {
    internal;
    empty_gif;
}

via

Закрываем сайт на обслуживание

Варианты

1) в location /

## System Maintenance (Service Unavailable)
if (-f $document_root/system_maintenance.html ) {
error_page 503 /system_maintenance.html;
return 503;
}

(if нежелателен - там куча ограничений, нюансов и оно довольно сильно грузит сервер, IfIsEvil)

2) try_files closed.html @apache =503;
(проблема в том, что в таком варианте код ответа при обслуживании будет 200). Хотя можно сделать отдельный location closed.html и в нем выставить код ответа 503, по желанию оттуда же отдать и саму страницу. Можно написать как

try_files /maintenance.html $uri $uri/ @wordpress;

но если индекса нет и апач перекидывает на какую-то внутреннюю страницу с рядом опций - могут быть проблемы, если такой файл вдруг появится, а это не предусмотрено системой. Плюс, если была встроенная фильтрация на бэкенде - так ее можно обойти. Ну и 2 лишние проверки получаем.

С другой стороны, для простых движков этот вариант будет быстрее и если вся статика не вынесена по отдельным location, автоматом начнётся раздача статики. Но снова безопасность, надо тогда создавать location на потенциально опасные места и там запрещать, обязательно. В частности на .ht, .svn, .git, служебные области. В общем, лучше первая версия этого варианта.

3) через переменную и if

set $Maintenance = off;
if ($Maintenance = 'on') ...
но см выше про if.

4) выделить блок, закрывающий сайт на обслуживание в отдельный файл maint.conf, сделать 2 файла maint-on.conf и maint-off.conf, и вешать симлинк на нужную версию файла с именем maint.conf и потом делать reload. Можно не симлинком а копированием. Самый быстрый способ, но требует немного кодинга.

via http://dragonflybsd.blogspot.ru/2012/10/nginx.html

Как убедиться, что работает gzip_static

Нашёл здесь - https://stackoverflow.com/questions/2460821/how-can-i-check-that-the-nginx-gzip-static-module-is-working

Находим PID

# ps ax | grep nginx
 1071 ?        Ss     0:01 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
17947 pts/0    S+     0:00 grep --color=auto nginx
18315 ?        S      0:25 nginx: worker process

Запускаем trace

# strace -p 18315 2>&1 | grep gz
open("/home/admin/web/foobar.com/public_html/uploads/posts/2017-01/1485714800-275451094.jpg.gz", O_RDONLY|O_NONBLOCK|O_LARGEFILE) = 34
open("/home/admin/web/foobar.com/public_html/uploads/posts/2017-01/1485714801-2083693483.jpg.gz", O_RDONLY|O_NONBLOCK|O_LARGEFILE) = 34
open("/home/admin/web/example.com/public_html/uploads/posts/2016-11/thumbs/1480346913_09b7vuxzf2vgwqd.jpg.gz", O_RDONLY|O_NONBLOCK|O_LARGEFILE) = -1 ENOENT (No such file or directory)

monit

https://mmonit.com/wiki/Monit/Nginx

server {
  listen 80;
  server_name monit.domain.com;
  location / {
    proxy_pass 127.0.0.1:2812;
    proxy_set_header Host $host;
  }
}

Много соединений в TIME_WAIT

Apache (backend) nginx (frontend)

В netstat сотни/тысячи коннектов в состоянии TIME_WAIT

Скорее всего это нормально если включён keepalive

Применять с осторожностью

echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

Или добавить в /etc/sysctl.conf

net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_fin_timeout=15
net.ipv4.ip_local_port_range = 10240 65000

TCP_CORK/TCP_NOPUSH и TCP_NODELAY

Игорь Сысоев / http://sysoev.ru

Да, в Линкусе TCP_CORK (tcp_nopush) и TCP_NODELAY взаимоисключающие, но nginx проявляет недюженный интеллект, пытаясь совместить преимущества обеих опций.

"tcp_nopush on" полезно для sendfile(), он в этом случае выводит данные полными пакетами. После того, как весь запрос обработан, TCP_CORK/TCP_NOPUSH выключается, что приводит в сбросу последнего неполного пакета.

"tcp_nodelay on" полезно для keep-alive. nginx включает TCP_NODELAY только по окончании запроса, после которого соединение переходит в состоянии keep-alive. До этого nginx выводит данные вызовами writev() достаточно большими порциями для заполнения пакета ("postpone_output 1460"), поэтому данные должны уходить без задержек и TCP_NODELAY не нужен. А вот с последним неполным пакетом может случится небольшая задержка, если соединение не закрывается. Для этого и нужно включить TCP_NODELAY.

В Линуксе обработка этих двух опций

 
     tcp_nopush       on;
     tcp_nodelay      on;

такова:

1) если данные будут выводить комбинацией writev(заголовок)/sendfile(), то проверяется, не было ли уже включен TCP_NODELAY. Если было, то TCP_NODELAY выключается и включается TCP_CORK. По окончании передачи TCP_CORK выключается. Включать TCP_NODELAY не нужно, так как выключание TCP_CORK сбрасывает данные.

2) если при переходе в keep-alive TCP_CORK не была включена, то включается TCP_NODELAY, чтобы сбросить неполный пакет.

Кстати, возможно, для "proxy_buffering off" имеет смысл включать TCP_NODELAY до отдачи ответа.

Как определить количество рабочих процессов, задаваемых параметром worker_processes?

via http://www.httpd.kiev.ua/tips/nginx/number-of-worker-processes/

Ответ автора nginx Игоря Сысоева:

Если весь сайт помещается в память сервера, к диску обращений нет, и это выделенный сервер для nginx, то 1. Не будет лишних переключений контекста. Если нужно ходить на диск, то 5-10 - это позволит обрабатывать соединения процессами, незаблокироваными на диске.

Кроме этого необходимо понаблюдать за состоянием процессов nginx в работе в часы пик. Командой ps посмотреть состояние рабочих процессов (worker process):

# ps ax -o %cpu,vsz,wchan,command | grep "nginx\|PID"

%CPU   VSZ WCHAN  COMMAND
0,0  1428 pause  nginx: master process /usr/local/nginx/sbin/nginx
0,0  2284 -      nginx: worker process (nginx)
0,0  2128 kqread nginx: worker process (nginx)

Если один из рабочих процессов находится в состоянии ожидания "kqread" в колонке "WCHAN", то значит их количество достаточно. Ну а если уж все они постоянно находятся в этом состоянии, то их количество можно сократить до одного.

И не забывайте контролировать логи ошибок nginx, если количество соединений превысит значение, которое в может обслужить nginx текущим количеством процессов, то в логах это будет соответствующее сообщение.

Правильная отдача заголовков при технических работах на сайте

(via http://www.zagirov.name/correct-return-header-on-service)

Есть ситуация: проводятся какие-то технические работы на сайте и нужно сайт правильно закрыть. Это нужно чтобы поисковики знали, что сайт не доступен, а не добавляли страницы в индекс или помечали страницы как удалённые.

server {
    listen 80 default;
    server_name _;
    root /var/www/default/www;
    charset utf-8;
    error_page 404 403 =503 /503.html;
    location = /503.html {
        add_header Retry-After "Sun, 27 Feb 2011 23:59:59";
    }
}

Строка error_page 404 403 =503 /503.html означает, что перенаправляем все запросы с ошибками 404 и 403 на файл 503.html, попутно меняя код ответа на 503. И при запросе файла 503.html отдаём заголовок Retry-After, чтобы поисковики знали, когда можно опять запросить страницу. Вместо даты можно указать количество секунд перед следующей попыткой. В файле 503.html можно написать что-нибудь осмысленное для пользователей и даже встроить флэш-игру, чтобы не было скучно.

Схема frontend-backend

Кэширование

Разное

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies

Discussion

Enter your comment. Wiki syntax is allowed:
 
linux/nginx/nginx_tnt.txt · Последнее изменение: 2020/12/18 03:23 (внешнее изменение)