Наткнуться на подводные камни в конфигурации и работе веб-сервера очень легко. Но трудно понять причину некорректной или не всегда корректной/ошибочной работы, если все правила соблюдаются.
Нет ничего плохого в размещении root-директории внутри location. Но если location не соответствует, то у нее не будет доступа к корневому каталогу. Правильнее делать так:
server { server_name www.somesite.com; root /var/www/nginx-default/; location / { # [...] } location /foo { # [...] } location /bar { # [...] } }
# Указание root внутри секции server
Не нужно плодить большое количество директив index. Пропишите ее один раз в блоке http
:
http { index index.php index.htm index.html; server { server_name www.somesite.com; location / { # [...] } } server { server_name somesite.com; location / { # [...] } location /foo { # [...] } } }
#Index будет автоматически наследоваться в всех секциях
Вы же в курсе, что if = зло? При использовании директивы нужно быть осторожным, ошибиться несложно. Так что по возможности избегайте использования if.
Предположим, ваш сайт лежит на домене somesite.com и вы перенаправляете на него пользователей, которые идут на www.somesite.com:
server { server_name somesite.com *.somesite.com; if ($host ~* ^www\.(.+)) { set $raw_domain $1; rewrite ^/(.*)$ $raw_domain/$1 permanent; } # [...] } }
# Проверяет и перенаправляет хост
Здесь несколько проблем. Главная – if. Вне зависимости от запроса хоста (с www или без), Nginx все равно проверяет if. Для каждого запроса. Взамен можно сделать так:
server { server_name www.somesite.com; return 301 $scheme://somesite.com$request_uri; } server { server_name somesite.com; # [...] }
# Используется $scheme, которая подходит для http и https
Не используйте if для проверки наличия файла:
server { root /var/www/somesite.com; location / { if (!-f $request_filename) { break; } } }
# Подход как минимум не эффективен
Взамен у Nginx есть директива try_files
:
server { root /var/www/somesite.com; location / { try_files $uri $uri/ /index.html; } }
# Проверка последовательности на наличие файла, если не существует, то отправляет на index.html
Примечательно, что директиву также можно использовать для защиты веб-сервера от несанкционированного доступа.
Если Nginx перенаправляет все запросы, заканчивающиеся на .php
, напрямую на интерпретатор PHP, то для злоумышленников открываются возможности для выполнения стороннего кода. PHP по умолчанию пытается догадаться, куда должен вести неправильный запрос. Так что в первую очередь необходимо подправить php.ini
, указав:
cgi.fix_pathinfo=0
#Интерпретатор будет обрабатывать только корректные запросы
Обратите внимание на правильную конфигурацию Nginx:
# Перенаправляет запросы только для указанных файлов location ~* (file_a|file_b|file_c)\.php$ { fastcgi_pass backend; # [...] } # Отключить выполнение скриптов в пользовательских загрузках location /uploaddir { location ~ \.php$ {return 403;} # [...] } # Фильтрация при помощи try_files location ~* \.php$ { try_files $uri =404; fastcgi_pass backend; # [...] } # Использует вложенное расположение для фильтрации location ~* \.php$ { location ~ \..*/.*\.php$ {return 404;} fastcgi_pass backend; # [...] }
# Параметры можно комбинировать
Неправильное указание путей размещения скриптов FastCGI часть приводит к ошибке “Primary script unknown”, которая легко решается.
Используйте переменную $request_uri
для изменения URI запроса:
rewrite ^ http://somesite.com$request_uri? permanent; # Или так return 301 http://somesite.com$request_uri;
# Перенаправляет на страницу 301
Добавить отсутствующий http://
очень просто:
rewrite ^ http://somesite.com permanent;
# Автоматически дополняет запрос
Не перенаправляйте все запросы на PHP в таком виде:
server { server_name _; root /var/www/site; location / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; } }
# Передает все на phpcgi.socket
Используйте все те же директиву try_files
:
server { server_name _; root /var/www/site; location / { try_files $uri $uri/ @proxy; } location @proxy { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; } }
# Передает только нужные запросы на proxy
Или так:
server { server_name _; root /var/www/site; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; } }
# Если Nginx не может обработать запрашиваемый URI самостоятельно, то проверяет директории на наличие, затем передает на proxy
Основная причина ошибочной работы системы (не только Nginx) — бездумный копипаст. Проверяйте конфиги, тестируйте приложение перед выкаткой, читайте документацию.
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…