Примеры настройки перенаправлений на nginx

Знай свой конфиг

Красота Ingress-контроллера том, что вы можете положиться на эту замечательную программу в вопросе генерации и перезагрузки конфигурации прокси-сервера и больше по этому поводу не беспокоиться. Вам даже не обязательно быть знакомым с нижележащей технологией (NGINX в данном случае). Правда? Нет!

Если вы этого еще не сделали, обязательно посмотрите на сгенерированную для вас конфигурацию. Для NGINX Ingress-контроллера можно получить содержимое с помощью .

Теперь попробуйте найти что-нибудь несовместимое с вашей установкой. Хотите пример? Давайте начнем с ;

Первая проблема: в настоящий момент (будет ли это когда-либо исправлено?) NGINX ничего не знает о cgroups, а значит, в случае будет использовано значение количества хоста, а не количества «виртуальных» процессоров, как определено в Kubernetes resource requests/limits.

Проведем эксперимент. Что будет, если мы попробуем загрузить следующий файл конфигурации NGINX на двухъядерном сервере в контейнере, ограниченном только одним CPU? Сколько рабочих процессов будет запущено?

Таким образом, если вы планируете ограничить ресурсы процессора, которые доступны NGINX Ingress, не стоит позволять nginx создавать большое количество рабочих процессов в одном контейнере. Лучше всего явно указать их необходимое количество с помощью директивы .

Теперь рассмотрим директиву . Значение параметра явно не указано и по умолчанию для Linux равно . Если параметр ядра равен, скажем, , то нужно присвоить соответствующее значение. Другими словами, убедитесь в том, что конфигурация nginx настроена с учетом параметров ядра.

Но на этом не останавливайтесь. Такое упражнение необходимо провести для каждой строчки сгенерированного файла конфигурации. Только посмотрите на все те параметры, которые позволяет поменять Ingress-контроллер. Исправляйте без колебаний все, что не подходит для вашего случая. Большинство параметров NGINX могут быть настроены с помощью записей и/или аннотаций .

Параметры ядра

С Ingress или без него, всегда проверяйте и настраивайте параметры нод в соответствии с ожидаемой нагрузкой.

Это достаточно сложная тема, поэтому я не планирую здесь подробно ее раскрывать. Дополнительные материалы по этом вопросу можно найти в разделе .

Kube-Proxy: Таблица Conntrack

Тем, кто использует Kubernetes, думаю, не нужно объяснять, что такое Сервисы и для чего они предназначены. Однако полезно будет рассмотреть некоторые особенности их работы.

Другими словами, отправленные на IP сервиса пакеты направляются (напрямую или через балансировщик) на соответствующий (пары подов, которые соответствуют label selector сервиса) с помощью правил iptables, управляемых kube-proxy. Соединения с IP-адресами сервиса отслеживаются ядром с помощью модуля , и эта информация хранится в RAM.

Поскольку различные параметры conntrack должны быть согласованы друг с другом (например, и ), kube-proxy, начиная работу, устанавливает разумные значения по умолчанию.

Это неплохой вариант, но вам может потребоваться увеличить значения этих параметров, если мониторинг показывает, что у вас заканчивается место, выделенное для conntrack. Однако необходимо помнить, что увеличение значений этих параметров ведет к повышенному потреблению памяти, так что поаккуратнее там.

Мониторинг использования conntrack

Сжатие GZIP

Один из самых эффективных методов ускорить ответ от вашего веб-сервера nginx — это включить GZIP сжатие.

включает сжатие.

устанавливает минимальную длину ответов, для которых будет применяться сжатие. По умолчанию 20, но имеет смысл поставить больше, так как постоянное сжатие приведет к повышению нагрузки на процессоры сервера и клиента.

перечисляет параметры проксированных запросов, для которых будет разрешено сжатие.

по умолчанию включено сжатие для ответов типа текст. В данном параметре можно перечислить все необходимые типы ответов.

запрещает для перечисленных параметров заголовка User-Agent сжатие. В данном примере для Internet Explorer 6 сжатие применяться не будет, так как данный браузер не умеет принимать сжатые ответы.

Rewrite Break Flag в локальном контексте

В этом примере, мы поместили условие перезаписи внутри директивы location.

В этом примере директива location /data/, также совпадает с $ 1 в строке замены, приведенной ниже.

location /data/ {
 rewrite ^(/data/.*)/andreyex/(\w+)\.?.*$ $1/linux/$2.html break;
 return 403;
}

Это то, что случилось бы, если бы вы использовали флаг «last»:

  • Так что, если у вас был флаг «last», после первоначальной перезаписи URL, Nginx как правило, ищет следующую директиву rewrite для нового URL.
  • В этом случае, Nginx будет держать перенаправление на одни и те же данные о местоположении и продолжать обработку тех же правил перезаписи максимум 10 раз, и, потом, он возвратит код 500 ошибок.

Так как мы не хотим описанное выше поведение, мы использовали «break» в качестве флага, который просто остановит обработку перезаписи блоков.

Почему возникает ошибка 404 в Nginx

Давайте сначала разберёмся, как обрабатываются URL в Nginx. Когда веб-сервер определил, к какому блоку server (сайту) нужно передать запрос пользователя, просматриваются все префиксные блоки location и выбирается тот, который подходит лучше всего. Например, рассмотрим стандартную конфигурацию для WordPress. Здесь префиксные location отмечены зелёным, а с регулярным выражением — оранжевым:

location / {index index.html index.php;}location /favicon.ico {access_log off;}location ~* \.(gif|jpg|png)$ {expires 30d;}location ~ \.php$ {fastcgi_pass localhost:9000;fastcgi_param SCRIPT_FILENAME$document_root$fastcgi_script_name;include fastcgi_params;}

Префиксные локейшены всегда начинаются с символа /. Регулярные же содержат символы регулярных выражений: ~ $ ^ * и так далее. Если пользователь запрашивает favicon.ico, то будет выбран второй location, так как он лучше всего соответствует запросу, при любом другом запросе будет выбран location /, так как он соответствует всем запросам, а других префиксных location у нас нет. Это просто, а дальше начинается магия. После того, как был найден нужный location, Nginx начинает проверять все регулярные выражения в порядке их следования в конфигурационном файле.

При первом же совпадении Nginx останавливает поиск и передаёт управление этому location. Или, если совпадений не было найдено, используется ранее обнаруженный префиксный location. Например, если запрос заканчивается на .php, то первый location будет проигнорирован, а управление передастся четвёртому (~ \.php$)

Таким образом, любое неверно составленное регулярное выражение в любой части конфигурационного файла может полностью всё сломать. Поэтому разработчики рекомендуют по минимум использовать регулярные выражения. Что касается вложенных location, то обрабатываются они так же как и основные, только уже после передачи управления в нужный location. Путём чтения конфигурационного файла понять, какой location вызывает 404 сложно, поэтому, чтобы исправить ошибку, нам понадобиться режим отладки Nginx.

Основные ошибки nginx и их устранение

502 Bad Gateway

Ошибка означает, что NGINX не может получить ответ от одного из сервисов на сервере. Довольно часто эта ошибка появляется, когда NGINX работает в связке с Apache, Varnish, Memcached или иным сервисом, а также обрабатывает запросы PHP-FPM.
Как правило, проблема возникает из-за отключенного сервиса (в этом случае нужно проверить состояние напарника и при необходимости перезапустить его) либо, если они находятся на разных серверах, проверить пинг между ними, так как, возможно, отсутствует связь между ними.
Также, для PHP-FPM нужно проверить права доступа к сокету.
Для этого убедитесь, что в прописаны правильные права

listen = /tmp/php5-fpm.sock 
listen.group = www-data
listen.owner = www-data

504 Gateway Time-out

Ошибка означает, что nginx долгое время не может получить ответ от какого-то сервиса. Такое происходит, если Apache, с которым NGINX работает в связке, отдаёт ответ слишком медленно.
Проблему можно устранить с помощью увеличения времени таймаута.
При работе в связке NGINX+Apache в конфигурационный файл можно внести изменения:

server { 
... 
   send_timeout 800;
   proxy_send_timeout 800;
   proxy_connect_timeout 800;  
   proxy_read_timeout 800;  
... 
}

Тут мы выставили ожидание таймаута в 800 секунд.

Upstream timed out (110: Connection timed out) while reading response header from upstream

Причиной может быть сложная и потому долгая обработка php в работе PHP-FPM.
Здесь тоже можно увеличить время ожидания таймаута

location ~ \.php$ { 
   include fastcgi_params;
   fastcgi_index index.php; 
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
   fastcgi_pass unix:/tmp/php5-fpm.sock;  
   fastcgi_read_timeout 800;
}

800 секунд на ожидание ответа от бекенда.

413 Request Entity Too Large

Ошибка означает, что вы пытались загрузить слишком большой файл. В настройках nginx по умолчанию стоит ограничение в 1Mb.
Для устранения ошибки в nginx.conf нужно найти строку

client_max_body_size 1m;

и заменить значение на нужное. Например, мы увеличим размер загружаемых файлов до

client_max_body_size 100m;

Также, можно отключить проверку размера тела ответа полностью значением ноль:

client_max_body_size 0;

304 Not Modified не устанавливается

Если возникает проблема с правильным отображением ответного заголовка сервера , то проблема, скорее всего, в пунктах:

  • В секции конкретного сайта включен (). По умолчанию, ssi отключен, но некоторые хостеры и ISPManager любят его прописывать в дефолтную конфигурацию сайта включенным. Его нужно обязательно отключить, закомментировав или удалив эту строку;
  • установить в , то есть на уровне или конкретного прописать:

Как перезагрузить nginx

Для перезагрузки NGINX используйте или .
Команда в консоли:

service nginx reload

либо

/etc/init.d/nginx reload

либо

nginx -s reload

Эти команды остановят и перезапустят сервер NGINX.

Перезагрузить конфигурационный файл без перезагрузки NGINX можно так:

nginx -s reload

Проверить правильность конфигурации можно командой

nginx -t 

В чём разница между reload и restart

Как происходит перезагрузка в NGINX:

  1. Команда посылается серверу
  2. Сервер анализирует конфигурационный файл
  3. Если конфигурация не содержит ошибок, новые процессы открываются с новой конфигурацией сервера, а старые плавно прекращают свою работу
  4. Если конфигурация содержит ошибки, то при использовании
    1. процесс перезагрузки сервера прерывается, сервер не запускается
    2. сервер откатывается назад к старой конфигурации, работа продолжается

Короче говоря, обрывает работу резко, делает это плавно. рекомендуется использовать, только когда внесены глобальные изменения, например, заменено ядро сервера, либо нужно увидеть результат внесённых изменений прямо здесь и сейчас. В остальных случаях используйте reload.

Ещё лучше, если вы будете предварительно проверять правильность конфигурации командой , например:

nginx -t && service nginx reload

или

nginx -t && nginx -s reload

Отличия между 301 и 302 редиректами:

В чем принципиальная разница между ответом с кодом 301 и 302? Для обычного посетителя сайта разницы нет. А вот для поискового робота разница огромная.

301-й редирект говорит о склеивании страниц. Это означает для поисковика то, что старая и новая страницы — это одно и тоже. Таким образом результаты ранжирования необходимо сохранить для новой страницы.

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

P.S. Не забывайте, что внесение любых изменений в конфигурации сервера могут привести к тому, что самостоятельно вы можете и не восстановить. Поэтому не забывайте делать бекапы!

Делиться (не) значит заботиться

До недавнего времени у нас был только один экземпляр NGINX Ingress, ответственный за проксирование запросов ко всем приложениям во всех окружениях (dev, staging, production). Я убедился на собственном опыте, что это плохая идея. Не складывайте все яйца в одну корзину.

Думаю, то же самое может быть сказано и по поводу использования одного кластера для всех окружений, однако мы выяснили, что такой подход приводит к более эффективному расходованию ресурсов. Мы запускали dev/staging-поды на уровне QoS с негарантированной доставкой (best-effort QoS tier), используя таким образом ресурсы, оставшиеся от production-приложений.

Обратной стороной медали здесь является то, что мы оказываемся ограничены в действиях, которые можно выполнять по отношению к кластеру. Например, если нам потребуется провести нагрузочное тестирование staging-сервиса, придется быть очень осторожными, чтобы не повлиять на боевые сервисы, запущенные в этом же кластере.

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

Одна установка Ingress на каждое окружение

Мы уже говорили о том, что нет причин, по которым не стоит использовать по одному Ingress-контроллеру на каждое окружение. Это дает дополнительный уровень защиты на тот случай, если с сервисами в dev и/или staging начнутся проблемы.

Некоторые преимущества этого подхода:

  • Появляется возможность использовать различные настройки для разных окружений.
  • Позволяет тестировать обновления Ingress перед применением их в production.
  • Можно избежать раздувания конфигурации NGINX записями множества вышестоящих серверов и сервисов, связанных с эфемерными и/или нестабильными окружениями.
  • Ускоряются перезагрузки конфигурации и сокращается количество этих событий в течение дня (позже мы обсудим, почему нужно стремиться к минимизации количества перезагрузок).

Ingress-классы в помощь

Одним из способов заставить разные -контроллеры управлять разными Ingress-ресурсами является использование разных имен классов ingress для каждой отдельной установки ingress, а затем аннотирование -ресурсов с целью указать, кто кем должен управлять.

Настройка перенаправлений

Настройки необходимо вносить в файлах конфигураций виртуальных доменов. В Linux на основе RPM (CentOS, Red Hat), как правило, они расположены в директории /etc/nginx/conf.d/. В Linux на основе Deb (Ubuntu, Debian) — в директории /etc/nginx/sites-enabled/. Во FreeBSD все в одном файле — /usr/local/etc/nginx/nginx.conf.

Саму настройку на перенаправление в NGINX можно прописать несколькими способами.

1. Первый:

rewrite ^ https://$host$request_uri? <флаг>;

* $host — имя хоста из запроса, если отсутствует — имя в поле «Host» заголовка, если тоже отсутствует — имя сервера; $request_uri — первоначальный запрос с аргументами (все, что идет после доменного имени).
** где флаги могут быть следующие:

  • permanent — перенаправление с кодом 301.
  • redirect — перенаправить с кодом 302.
  • last — закончить обработку с переходом в новый location.
  • break — закончить обработку и остаться в текущем location.

2. Второй: 

return <код> https://$host$request_uri;

* где коды могут использоваться любые, но чаще всего — 301, 302, 404.

Есть различные мнения, какой из методов лучше и безопаснее, поэтому каким воспользоваться — решать по ситуации. В данных примерах используются оба варианта.

После внесения изменений, необходимо проверить их корректность:

nginx -t

И для их применения перезапустить веб-сервер:

systemctl restart nginx

service nginx restart

* в первом примере перезапуск выполняется на новых системах Linux. Второй пример — на устаревших или FreeBSD.

Проверяя редиректы в браузере, следует учесть, что настройки могут кэшироваться. Для обновления кэша используйте комбинацию Ctrl + F5. Если и это не помогает, закрывайте вкладку и открывайте новую.

Безопасность

Помимо уменьшения времени отклика веб-сервера, необходимо позаботиться о безопасности. Разберем основные http заголовки, которые могут представлять угрозу.

X-XSS-Protection

Заголовок может предотвратить некоторые XSS-атаки.

Вы можете реализовать защиту XSS, используя три варианта в зависимости от конкретной потребности.

  • Это полностью отключит фильтр
  • Это включает фильтр, но очищает только потенциально вредоносные скрипты
  • Это включает фильтр и полностью блокирует страницу.

X-Frame-Options

Заголовок позволяет снизить уязвимость вашего сайта для clickjacking-атак. Этот заголовок служит инструкцией для браузера не загружать вашу страницу в frame/iframe. Не все браузеры поддерживают этот вариант.

Настроить X-Frame-Options можно тремя способами:

  • : это полностью отключит функции iframe.
  • : iframe может использоваться только кем-то из того же источника.
  • : Это позволит размещать страницы в окнах iframe только с определенных URL-адресов.

X-Permitted-Cross-Domain-Policies

Аналогично механизму браузеров блокировки стороннего контента Adobe Flash имеет свой. Он регулируется файлами crossdomain.xml сайта, начиная с корневого каталога. Проблема с механизмом в том, что на любом уровне вложенности корневой регулирующий файл (политика безопасности) может быть переопределен. Чтобы избежать таких ситуаций, необходимо задать этот HTTP-заголовок.

Доступно несколько вариантов настройки:

  • — никакая политика не допускается
  • — разрешить только главную политику
  • — все позволено
  • — Разрешить только определенный тип контента. Пример — XML
  • — применимо только для FTP-сервера

Strict-Transport-Security

Заголовок Strict-Transport-Security запрещает использование незащищенного HTTP соединения на сайте, если есть защищенное HTTPS.

X-Content-Type-Options

Рейтинг наиболее опасных к использованию возможностей браузера возглавляет возможность Internet Explorer «угадывать» тип файла, игнорируя его MIME-тип.

При передаче от сервера к браузеру все файлы имеют тот или иной тип, который прямо указывает на суть содержимого файла. Однако, Internet Explorer имеет встроенный механизм, который позволяет по-содержимому файла переопределить его тип.

Таким образом, обычные текстовые файлы могут быть интерпретированы как JavaScript со всеми вытекающими последствиями. Например, если у вас на сайте запрещена загрузка текстовых файлов с расширениями .js пользователями, то они могут загрузить в виде картинок текстовый файл, содержащий JavaScript-код, который может быть исполнен браузером.

Создание файла контроллера с помощью Nginx Rewrite

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

Следующий пример Rewrite объясняет это.

rewrite ^/linux/(.*)$ /linux.php?distro=$1 last;

В приведенном выше примере, когда вы делаете запрос к URL andreyex.ru/linux/centos, он получит переписанный с использованием вышеуказанного правила, и он выдаст страницу с этим переписанным URL: andreyex.ru/linux.php?distro=centos

Как вы видите выше, любой URL, который имеет соответствующий шаблон здесь (т.е. /linux/ в URL) будет выполнять linux.php, но последняя часть в исходном входящем URL будет использоваться в качестве значения для аргумента distro контроллера linux.php.

Таким образом, приведенное выше правило перезаписи преобразует входящий URL, как здесь:

  • linux/centos becomes linux.php?distro=centos
  • linux/debian becomes linux.php?distro=debian
  • linux/redhat becomes linux.php?distro=redhat
  • и т.д.

Как и в предыдущем примере, мы используем $ 1 в замещающей строке, чтобы захватить все, что находится внутри 1-й скобках () в reg-ех. В этом случае, последняя часть оригинального входящего URL.

Мы также используем здесь флаг last, чтобы проинструктировать Nginx, остановить поиск дальнейших директив Rewrite в текущем-блоке и о переходе к следующему месту соответствия для дальнейшего поиска.

Корректный редирект с одного url на другой

Допустим вы корректно настроили стандартные редиректы в nginx. А потом в какой-то момент у вас поменялась структура сайта, или просто нужно было сделать редиректы для отдельных страниц. К примеру, запрос https://site.ru/main/hello/ перенаправить в https://site.ru/main/. По идее ничего сложного. Добавляем редирект:

server {
 listen 443;
........................
 location /main/hello {
  return 301 /main/;
 }
........................

Если делать запросы по https, то все в порядке. Никаких проблем, сработает ровно один 301-й редирект на другой url. А что будет при запросе http://site.ru/main/hello ? Смотрим.

# curl -I -L --insecure http://site.ru/main/hello

HTTP/1.1 301 Moved Permanently
Server: nginx
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://site.ru/main/hello/

HTTP/2 301 
server: nginx
content-type: text/html
content-length: 162
location: https://site.ru/main/

HTTP/2 200 
server: nginx
content-type: text/html; charset=utf-8
vary: Accept-Encoding

Опять два 301-х редиректа. Переделываем на один, не забывая все возможные варианты написания.

server {
    listen 443 ssl http2;
    server_name www.site.ru;

    location ~* ^.+.(js|css|png|jpg|jpeg|gif|webp|ico|woff|txt)$ {
	return 301 https://site.ru$request_uri;
    }
    
    location / {
	rewrite ^/(.*)/$ /$1;
	return 301 https://site.ru$uri/;
    }

    location /main/hello {
	rewrite ^/(.*)/$ /$1;
	return 301 https://site.ru/main/;
    }

}

server {
    listen 80;
    server_name site.ru www.site.ru;

    location ~* ^.+.(js|css|png|jpg|jpeg|gif|webp|ico|woff|txt)$ {
	return 301 https://site.ru$request_uri;
    }
    
    location / {
	rewrite ^/(.*)/$ /$1;
	return 301 https://site.ru$uri/;
    }

    location /main/hello {
	rewrite ^/(.*)/$ /$1;
	return 301 https://site.ru/main/;
    }
}

Ну и так далее. Думаю, идея ясна. Следует следить за всеми редиректами и стараться всегда оставлять только один.

Все стандартные редиректы в nginx

Рассмотрю типовой пример, когда у нас одновременно присутствуют следующие редиректы:

  1. С http на https.
  2. С www на без www для обоих протоколов.
  3. Без слеша на конце на урл со слешем.

Наша цель будет реализовать все преобразования url в одном месте и выдать клиенту только один 301-й редирект.

server {
    listen 443 ssl http2;
    server_name site.ru;
    root /web/sites/site.ru/www/;
    index index.php index.html index.htm;
    access_log /web/sites/site.ru/log/access.log main;
    error_log /web/sites/site.ru/log/error.log;

    ssl_certificate		/etc/letsencrypt/live/site.ru/fullchain.pem;
    ssl_certificate_key		/etc/letsencrypt/live/site.ru/privkey.pem;

    location / {
	rewrite ^(*)$ $1/ permanent;
	try_files $uri/ /index.php?$args;
	}

    location ~* ^.+.(js|css|png|jpg|jpeg|gif|webp|ico|woff|txt)$ {
	access_log off;
	expires max;
	}

    location ~* ^/(\.ht|xmlrpc\.php)$ {
	return 404;
	}

    location ~ \.php$ {
	try_files  $uri =404;
	fastcgi_pass   unix:/var/run/php-fpm/php7-fpm.sock;
	fastcgi_index index.php;
	fastcgi_param DOCUMENT_ROOT /web/sites/site.ru/www/;
	fastcgi_param SCRIPT_FILENAME /web/sites/site.ru/www$fastcgi_script_name;
	fastcgi_param PATH_TRANSLATED /web/sites/site.ru/www$fastcgi_script_name;
	include fastcgi_params;
	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 HTTPS on;
	fastcgi_intercept_errors on;
	}

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

    location = /robots.txt {
	allow all;
	log_not_found off;
	access_log off;
	}
}

server {
    listen 443 ssl http2;
    server_name www.site.ru;

    location ~* ^.+.(js|css|png|jpg|jpeg|gif|webp|ico|woff|txt)$ {
	return 301 https://site.ru$request_uri;
    }
    
    location / {
	rewrite ^/(.*)/$ /$1;
	return 301 https://site.ru$uri/;
    }
}

server {
    listen 80;
    server_name site.ru www.site.ru;

    location ~* ^.+.(js|css|png|jpg|jpeg|gif|webp|ico|woff|txt)$ {
	return 301 https://site.ru$request_uri;
    }
    
    location / {
	rewrite ^/(.*)/$ /$1;
	return 301 https://site.ru$uri/;
    }
}

Получилось примерно так. Призываю не копировать бездумно конфиг, а проверить то, что я предлагаю. Хотя я сам внимательно проверил, как мог, но все равно не застрахован от ошибки. На мой взгляд здесь рассмотрены все основные моменты с редиректами. На выходе всегда один 301 редирект, какой бы запрос мы не сделали. При этом все реализовано средствами самого веб сервера, а значит, будет работать максимально быстро.

Как исправить ошибку на виртуальном хостинге

Данная ошибка возникает при наличии редиректа в файле «.htaccess» и включенном редиректе в ISPmanager. Подробнее о нем можно прочитать в статье «Что такое редирект» нашего блога. Для решения проблемы нужно проверить файл «.htaccess» на наличие редиректов с «http» на «https» с помощью изложенного ниже алгоритма.

  1. Перейти в ISPmanager, в разделе «WWW» выбрать «WWW-домены» и нужный домен. Затем нажать «Каталог» в верхнем меню для перехода к файлам сайта.
  2. Выбрать файл «.htaccess» одним нажатием и кликнуть «Изменить» в верхнем меню.
  3. Проверить файл на наличие редиректов. О возможных вариантах редиректов в «.htaccess» можно узнать.
  4. Проверить включен ли редирект в настройках ISPmanager. В разделе «WWW» нажать «WWW-домены», выбрать нужный домен и кликнуть «Изменить» в верхнем меню.
  5. В появившемся окне проверить — установлена ли галочка на пункте «Перенаправлять HTTP-запросы в HTTPS». Данный пункт будет виден только, если включена галочка на пункте «Защищенное соединение (SSL)».
  6. В разделе «WWW» нажать «WWW-домены», выбрать нужный домен и кликнуть «Редиректы» в верхнем меню. Появится список с редиректами. Если редиректы отсутствуют, то он будет пустым.
  7. Если редирект включен в пунктах 1, 2 и 3, нужно убрать лишние редиректы оставив лишь один из них.

Шаг 6. Установка и настройка access и error logs nginx

Журналы access и error logs nginx включены по умолчанию и расположены соответственно в logs/error.log и logs/access.log. Если вы хотите изменить местоположение, вы можете использовать директиву error_log в файле конфигурации nginx. Вы также можете использовать эту директиву, чтобы указать журналы, которые будут записываться в соответствии с их уровнем безопасности. Например, уровень crit заставит nginx регистрировать критические проблемы и все проблемы, которые имеют более высокий уровень, чем уровень crit. Чтобы установить уровень crit, установите директиву error_log следующим образом:

Вы можете найти полный список уровней error_log в официальной .

Вы также можете изменить директиву access_log в файле конфигурации nginx, указав расположение не по умолчанию для журналов доступа. Наконец, вы можете использовать директиву log_format для настройки формата записываемых сообщений, как описано .

Мой первый сбой в Ingress

Сперва позвольте предупредить: если вы еще не обеспокоены переполнениями очереди приема (accept queue overflows), начинайте беспокоиться.

Не забывайте об очередях

Случилось вот что: стоящее за NGINX приложение начало отвечать с большими задержками, что, в свою очередь, привело к заполнению . Из-за этого NGINX начал сбрасывать соединения, в том числе и те, что пытался установить Kubernetes для проверки работоспособности сервиса (liveness/readiness probes).

А что происходит, когда под не отвечает на такие запросы? Kubernetes думает, что что-то пошло не так, и перезапускает его. Проблема в том, что это одна из тех ситуаций, когда перезапуск пода только усугубляет ситуацию: очередь приема продолжает переполняться, Kubernetes продолжает перезапускать поды, и в итоге их затягивает в водоворот падений и последующих рестартов.

Переполнения очереди TCP listen, согласно netstat

Какие уроки можно извлечь из этой ситуации?

  • Изучите конфигурацию своего NGINX до последней буквы. Выясните, что там должно быть и чего не должно. Не нужно слепо доверять настройкам по умолчанию.
  • Большинство Linux-дистрибутивов из коробки не настроены на работу в качестве высоконагруженных веб-серверов. Перепроверьте значения соответствующих параметров ядра с помощью .
  • Измеряйте задержку своих сервисов и устанавливайте соответствующие таймауты на основе ожидаемого максимального значения + запас на небольшие отклонения.
  • Настраивайте свои приложения таким образом, чтобы в случае перегрузки они начинали отклонять запросы или аккуратно снижать нагрузку. Например, в приложениях на NodeJS увеличения задержек в цикле сообщений могут означать, что сервер уже с трудом справляется с обработкой текущего трафика.
  • Используйте более одного NGINX Ingress-контроллера.

Важность мониторинга

Мой совет №0: не запускайте в production Kubernetes-кластер (или что-то аналогичное), не настроив качественный мониторинг его работы. Сам по себе мониторинг от проблем не избавит, но собранная телеметрия значительно облегчает нахождение первопричин сбоев, что позволяет исправлять их в процессе дальнейшей работы.

Несколько полезных метрик из `nodenetstat`*

Если и вы поддались повальному увлечению Prometheus, для сбора метрик уровня ноды можете воспользоваться node_exporter. Это удобный инструмент, который позволяет выявлять в том числе и только что описанные проблемы.

Некоторые метрики, получаемые с NGINX Ingress-контроллера

NGINX Ingress-контроллер и сам способен генерировать метрики для Prometheus. Не забудьте наладить их сбор.

Оптимизация работы соединений

Настроим несколько основных параметров, которые отвечают за количество обрабатываемых соединений и сроки их поддержания.

— Определяет количество рабочих процессов. Обычно, выставляют равному числу ядер, но в новых версиях его лучше устанавливать в auto. По умолчанию 1

— Устанавливает максимальное количество соединений одного рабочего процесса, то есть nginx будет обрабатывать * , остальные запросы ставить в очередь. Следует выбирать значения от 1024 до 4096. По умолчанию 512.

— Позволяет принимать максимально возможное количество соединений. Иначе, процесс nginx за один раз будет принимать только одно новое соединение. По умолчанию off.

— Отвечает за максимальное время поддержания keepalive-соединения, в случае, если пользователь по нему ничего не запрашивает. Для современных систем, стоит выставить от 30 до 50. В нашем случае 45. По умолчанию 75.

— Если клиент перестал читать страницу, Nginx будет сбрасывать соединение с ним. По умолчанию off.

— Ждет выставленное количество секунд тело запроса от клиента, после чего сбрасывает соединение. По умолчанию 60.

— Если клиент прекратит чтение ответа, Nginx подождет выставленное количество секунд и сбросит соединение. По умолчанию 60.

Шаг 8. Настройте Nginx для включения заголовков безопасности

Чтобы дополнительно защитить свой веб-сервер nginx, вы можете добавить несколько различных заголовков HTTP. Вот некоторые из вариантов, которые мы рекомендуем.

X-Frame-Options

Заголовок HTTP-ответа X-Frame-Options, используется чтобы указать, разрешено ли браузеру отображать страницу в frame или iframe . Это может предотвратить атаки с помощью clickjacking. Поэтому мы рекомендуем вам включить эту опцию для вашего сервера nginx.

Для этого добавьте следующий параметр в файл конфигурации nginx в разделе server:

Strict-Transport-Security

HTTP Strict Transport Security (HSTS) — это метод, используемый веб-сайтами для объявления того, что доступ к ним должен осуществляться только через безопасное соединение (HTTPS). Если веб-сайт объявляет политику HSTS, браузер должен отклонить все HTTP-соединения и запретить пользователям принимать незащищенные SSL-сертификаты. Чтобы добавить заголовок HSTS на ваш сервер nginx, вы можете добавить следующую директиву в ваш раздел сервера:

CSP and X-XSS-Protection

Политика безопасности контента (CSP) защищает ваш веб-сервер от определенных типов атак, включая атаки с использованием Cross-site Scripting (XSS) и атаки с использованием data injection

Вы можете реализовать CSP, добавив следующий пример заголовка Content-Security-Policy (обратите внимание, что фактический заголовок должен быть настроен в соответствии с вашими уникальными требованиями):. Заголовок HTTP X-XSS-Protection поддерживается IE и Safari и не требуется для современных браузеров, если у вас есть строгая политика безопасности содержимого

Однако, чтобы предотвратить XSS в случае более старых браузеров (которые еще не поддерживают CSP), вы можете добавить заголовок X-XSS Protection в раздел вашего сервера:

Заголовок HTTP X-XSS-Protection поддерживается IE и Safari и не требуется для современных браузеров, если у вас есть строгая политика безопасности содержимого. Однако, чтобы предотвратить XSS в случае более старых браузеров (которые еще не поддерживают CSP), вы можете добавить заголовок X-XSS Protection в раздел вашего сервера:

Оптимизация работы с файлами

позволяет использовать более совершенный системный вызов, который обеспечивает прямую передачу файла, то есть без системных вызовов read + write.

включает использование асинхронного обращения к файлам, что избавит от очередей запросов.

позволит передавать заголовок ответа и начало файла в одном пакете.

по умолчанию выключена. Задает настройку для кэширования информации о файлах, с которыми работает nginx. По умолчанию выключено.

задает время, через которое веб-сервер будет проверять актуальность данных. По умолчанию 60 секунд.

задает минимальное число обращений к файлу, чтобы дескриптор файла оставался открытым в кэше.

включает или выключает кэширование ошибок.

Популярные сервисы для отслеживания цепочек редиректов

Netpeak Spider

  • Язык: русский.
  • Платно (с бесплатным пробным периодом).
  • Помимо отслеживания цепочки редиректов, делает полный SEO-аудит сайта, включая выявление ошибок оптимизации.
  • Анализирует крупные контентные сайты (более 100 000 страниц).

Анализ сайта Webmasta

  • Язык: русский.
  • Бесплатно.
  • Отслеживает полную цепочку перенаправлений.
  • Получение IP-адреса сайта и отслеживание всех веб-ресурсов на этом адресе.

Проверка переадресации Website Planet

  • Язык: русский.
  • Бесплатно.
  • Отслеживание всех типов редиректов.
  • Получение полного URL-адреса коротких, рекламных или партнерских ссылок без перехода.

Массовая проверка цепочек редиректов Majento

  • Язык: русский.
  • Бесплатно.
  • Анализирует цепочку редиректов.
  • Получение полного URL-адреса коротких, рекламных или партнерских ссылок без перехода.

SEO-помощник Rookee

  • Язык: русский.
  • Бесплатно (после регистрации).
  • SEO-аудит сайта всех страниц сайта по 70 параметрам.
  • Пошаговые рекомендации по исправлению найденных ошибок.

После того как страницы с кодами редиректов найдены, рекомендуется приступить к правке конфигурационного файла .htaccess.

Заключение

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

В завершении рекомендую мою статью про настройку nginx. Я там частично рассматриваю и эту тему

А вообще там рассказаны все основные моменты, на которые стоит обращать внимание при работе с nginx

Онлайн курс «DevOps практики и инструменты»

Если у вас есть желание научиться строить и поддерживать высокодоступные и надежные системы, научиться непрерывной поставке ПО, мониторингу и логированию web приложений, рекомендую познакомиться с онлайн-курсом «DevOps практики и инструменты» в OTUS. Курс не для новичков, для поступления нужны базовые знания по сетям и установке Linux на виртуалку. Обучение длится 5 месяцев, после чего успешные выпускники курса смогут пройти собеседования у партнеров.

Проверьте себя на вступительном тесте и смотрите программу детальнее по .

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Техноарена
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: