Как стать автором
Обновить

Комментарии 129

Толково вроде. А почему не кэшируете сгенерированные страницы или у Вас для каждого посетителя свои плюшки имеюются?
Для этого проще php-apc накатить пакет.
это далеко не одно и то же
Для человека, которому необходим этот мануал лезть в кеширование nginx'ом мягко говоря не резонно. Поэтому тем, кто его читает, лучше все же сделать aptitude install php5-apc php-apc и не мучаться до прочтения всего мануала по кешированию у Сысоева.
APC, eAccelerator или XCache необходимы в любом случае, но они не имеют ни малейшего отношения к кешированию контента. APC кеширует сам opcode в памяти, чтобы ускорить загрузку скриптов, а fastcgi_cache_* кеширует генерированные страницы, позволяя для обслуживания части запросов вообще не обращаться к php.
APC etc позволяют не только кэшировать опкод, но и имеют API для кэшиования данных, типа memcashed
НЛО прилетело и опубликовало эту надпись здесь
Про это я в курсе, но мне просто глаз резануло «они не имеют ни малейшего отношения к кешированию контента».
Тут рецепт настройки сервера. Каким боком к администраторской работе относится API для пользовательской программы? Какое отношение это имеет к кешированию контента, кроме косвенного (через него тоже можно кешировать)? Так и через Mongo можно кешировать и через файлы и через memcached, но это требует уже программирования, а не администрирования.
Самое непосредственное отношение имеет. Например:

set $memcached_key "$host$uri";
memcached_pass 127.0.0.1:11211;
error_page 404 500 502 503 504 = @fallback;

Это все равно к админу, а не к программеру.
Где здесь про APC?
да вроде не особо сложно-то.
Я пробовал — не понял как инвалидировать кэш при изменении данных, не из php же скрипта удалять файлы из кэша?
Инвалидировать при добавлении контента? Не ставьте слишком большое время кэша.
При изменении, скажем так. Вряд ли стоит ожидать от одного пользователя (зарегистрированного) запросы чаще чем раз в секунду (если это не (D)DOS), а большее время вызовет неудовольствие.
Ну зарегистрированным пользователям можно кэш и отключить. Хотя вот с комментариями анонимусов проблема, да.
если поставить систему комментирования на ajax, вроде disqus.com, то этой проблемы не будет на при каком кэше.
Если у вас сайт с высокой оперативностью (например новостной, как у меня), то инвалидировать кеш nginx можно удаляя файл, имя и путь к которому легко расчитать через md5, как это делает сам nginx. Если позволит производительность, то кеш на ключевых страницах, вроде главной и фидов, можно отключить или снизить время его жизни до 1 минуты (предпочтительнее всех остальных вариантов). Если сайт вроде блога, то кеш на пол часа и не надо париться с инвалидизацией — самые прыткие найдут новый контент через rss и twitter.
«но это требует уже программирования, а не администрирования» ;)
Конечно. А у вас есть сомнения, что правила выборочной инвалидизации данных, подчиненных архитектуре конкретной системы относятся к компетенции разработчика, а не админа?
Так я про это сразу написал, только про APC
Только к текущему топику это не относится. А fastcgi_cache_* в nginx относится напрямую.
В начале треда сразу было отвечено, что проще установить APC, который будет хотя бы опкоды кэшировать, чем заморачиваться с fastcgi_cache_*. И в том, и в другом случае будем теоретически иметь прирост производительности, но в первом не будет значимых для типичных приложений побочных эффектов, а во втором будут, если не изменять код скриптов. Самsй оптимальный, вариант, конечно, использовать и то, и другое — APC для кэширования опкодов и данных, fastcgi_cache_* для уже сгенерированных страниц. Главное инвалидацию реализовать правильно и для данных в кэше APC, и для страниц в кэше nginx.

Закончим на этом? :)
Давайте я уточню свое мнение и больше не буду претендовать.

1. Заморачиваться с fastcgi_cache_* в рамках этой статьи логично и не выходит за них, чего не скажешь про APC. Все заморачивание с fastcgi_cache_* состоит из дополнительных 5-10 строк к уже написанному конфигу nginx. говорить, что установка APC проще в данном контексте просто нелепо.

2. Разница в ускорении работы сайта при fastcgi_cache_* и при простом opcode-cache настолько существенная, что про APC вообще можно было не вспоминать. это как сравнить для автомобиля прирост скорости от установки в 10 раз более мощного двигателя и изменение аэродинамики кузова на 0.1 Это решения разных порядков эффективности.

3. Для большинства сайтов вопрос инвалидизации кеша стоит не сильнее, чем установка допустимого времени задержки обновления. 10 минут можно считать идеальным для подавляющего большинства часто обновляемых сайтов. А для редко обновляемых можно кешировать и на час. Только новостные сайты требуют более оперативного обновления, но там в механизме инвалидизации кеша нет надобности из-за очень короткого кеширования основных страниц и фидов.
Не могу не возразить :)
1. Установка APC — одна строчка в консоли
2. При условии, что есть попадания в кэш
3. Простой пример неновостного часто обновляемого сайта: браузерная ((M)M)OG. Ещё пример: соцсети (а предыдущий пункт может быть и в них), ещё — веб-морды к, например, мылу. Не знаю как в абсолютном количестве сайтов, но по количеству хитов, имхо, сайты, кэш страниц которых не может быть инвалидирован только по времени без нарушения ожидаемой пользователем функциональности, сейчас составляют большинство. Почему-то придумалось выражение «Users's Content Driven Behavior of User» :) (sorry for my English)
1. Если по сценарию, приведенному здесь, то не одна. Если по принципу «меньше эффекта, за то меньше строчек», то я не могу разделить таких оснований для гордости. В любом случае APC и eAccelerator полезные вещи, но не повод отказываться от статического кеширования на популярном сайте.

2. Без этого условия сайту не нужна оптимизация средствами системного администрирования.

3. Такие сайты относятся к подавляющему меньшинству. При этом как раз в широко популярных социальных сетях статическое кеширование определенных частей контента выполняется наиболее часто, поскольку это самый дешевый метод повышения производительности. Конечно оно не применяется для частей, требующих мгновенной реакции, но, повторяю — статическое кеширование применимо на подавляющем большинстве сайтов. Если ваш сайт не имеет возможности пользоваться статическим кешированием, отдавая 100% пользовательской нагрузки на движок, то для такого проекта появляется слишком много ограничений. php с его cgi-архитектурой обнуления состояний между запросами, mysql c его нелинейной регрессией производительности при увеличении объемов данных в реляционных соединениях и блокировками делают производительность измеряемой десятками запросов в секунду. И это на фоне производительности в тысячи запросов в секунду для fastcgi_cache_*

Всё, что я хочу сказать, что те 5-10 строчек конфига nginx, которые отвечают за кеширование являются важной частью для большого числа сайтов, к которым относится эта статья и вы зря от них отмахнулись.
Если речь о WordPress, то я сделал так.

За валидность кеша отвечает WP Super Cache. Если файл есть, то nginx берет его прямо в кеше, если нет, то отправляет запрос PHP.

Если в админке поменять пост, то его файл с кешем стирается и при следующем заходе генерируется новый файл.
А nginx представленный в офф. репозитариях debian'а (версии 0.6.32) о нём еще не догадывается :)
Пардон:
— вместо «debian'а» следует читать lenny;
— вместо «о нём» следует читать «о кешировании».
А есть маньяки ставящие nginx из репозитария? o_O
А что, сейчас снова модно собирать из сорцов?
А что, сейчас модно ставить старые версии nginx из репозитория?
Срезал)
Чуть не перешло в танец в такидатую дуэль =)
Есть два решения, и оба через жопу неудобны:
— ставить из неофициального репа
— из сорцов
Есть третье решение, самое православное — собрать пакет и поставить.
А можно не использовать дефолтные репы.
В CentALT лежит версия 0.9.4
0.8.54 в sid у debian (в статье lenny-backports — 0.7.63 там)
А что, алтернативные репозитории уже отменили?
а что там собирать? за то можно приточить к процессору и собрать epoll или aio на выбор.
В статье как раз такой путь описан :)
У меня тоже, но по статьям годовалой давности тупой копи-пастой уже ничего не поставишь, а новичкам полезно будет)

*единственное негативное дежавю — «все комманды под рутом»)
А это не с тобой мы последние пару дней чинили chroot? )
Мы, добавил в пост :)
Если статья для установки копи-пастой, то логичнее было бы оформить всё в скрипт.
Только php-frm поменять на php-fpm еще бы по тексту и в теге
готово
Кто-нибудь из многочисленных копипастеров конфигов nginx может объяснить зачем нужны gzip_disable «msie6» и аналоги? Да, этот браузер не поддерживает gzip, и честно об этом сообщает, не передавая заголовок Accept-Encoding.
Вы еще не встречали ситуацию когда на экран вместо страницы выпадает абракадабра?
Какой информативный ответ.
Какая разница, встречал ли я, я же не пользователь ие6. При каких условиях появляется абракадабра? Почему она появляется? Почему вы считаете, что именно эта строчку поможет от нее избавится?
Я уже имел опыт появления этой ошибки в IE на довольно популярном ресурсе. Исправил этой строчкой. Уже полтора года никто не заявляет, что у него сломана страница. Если вам этого мало, то поищите ответов в документации nginx и на форуме разработчика.
Вы разбирались в чем была проблема? IE действительно посылал заголовок Accept-Encoding: gzip?

В документации сказано, что есть такой фильтр по юзерагенту, и то у него есть некоторое значение. Там не сказано, почему вдруг может понадобиться его использовать. Еще сказано, что данный параметр was introduced in Nginx 0.6.23. А до этой версии как жили?
Разбирался, IE слал заголовки, но не всегда понимал Encoding в ответе. Эта строчка устранила проблему, копать глубже не стало нужды.
Кандидат на причину данного явления: support.microsoft.com/kb/837251
«some compressed files were not parsed correctly over a Security Sockets Layer (SSL) connection while the Do not save encrypted pages to a disk security option in Internet Explorer was selected
APPLIES TO
Microsoft Internet Explorer 6.0 Service Pack 1»

Т.е. при загрузке контента по ssl (который не используется на 95% сайтов) в одной конкретной версии браузера при включении выключенной по-умолчанию (я проверил) настройки происходил глюк. И из-за этого большинство копипастеров предлагается резать gzip в проблемной версии и ниже для всех типов соединения, а не только для проблемного.

Ну в общем, как-то примерно так я и предполагал, да.
Когда я исследовал этот вопрос, я находил целый сонм глюков в IE6 (до версии SP2), так что проще выключить gzip там, чем «лечить».
Отрицаю. Абракадабра была на обычном http и не устойчиво — то нормально показывает, то ломает.
MSIE 6 не выдаёт gzip в Accept-Encoding? Вы ошибаетесь, выдаёт (с четвёртой версии браузера). Я специально исследовал этот вопрос для книги «Реактивные веб-сайты». Брал «чистую Windows XP» без SP, смотрел под IE6.

Под IE6SP2 проблемы исправлены (именно я посоветовал Сысоеву добавить исключение SV1, который является флагом, что в IE6 есть SP2).
Заинтриговал, пойду тоже поставлю.
Если этот так, возникает еще больше вопросов:
Зачем же он слал, если не поддерживал?
А как же было возможно использовать gzip в nginx до версии 0.6.23, в которой этот gzip_disable и был добавлен?
Если проблема действительно имеет место быть, почему это не зашитая в nginx логика, а отдельная опция, да еще и не включенная по-умолчанию?
Нет, он поддерживал. Просто глючил.
> А как же было возможно использовать gzip в nginx до версии 0.6.23, в которой этот gzip_disable и был добавлен?
Потому что глюки проявлялись в разных условиях. Где-то IE не «расшифровывал» gzip, если прокси отсылал ответ HTTP/1.0, где-то не кешировал такие ответы и так далее.

Я не знаю почему опция появилась не сразу (тем более, что IE6 не единственный браузер, у которого глюки), может Игорь не сразу узнал о проблемах.

> Если проблема действительно имеет место быть, почему это не зашитая в nginx логика, а отдельная опция, да еще и не включенная по-умолчанию?
Проблема имеет место, опция не включена по-умолчанию, потому что, вообще-то, помимо msie6 там ещё должны быть значения, не дело автору веб-сервера заморачиваться с исследованием на эту тему.
Спасибо за развернутый ответ.
Вот только с последним пунктом, прости, я не согласен :) Помоему как раз логично одному человеку разобраться в вопросе досконально и сделать затычку «по-умолчанию», чем предлагать сделать то же самое тысячам людей, использующим nginx.
На мой взгляд nginx имеет набор средств программирования, позволяющий организовать исключение для отдельного браузера и без опции gzip_disable. То что она вообще появилась я относил на счет оптимизации производительности столь необходимого функционала. Ну и большое спасибо автору за отключаемость этой опции на случай последующего уменьшения доли ie6
Ерудненюшка-то в том, что браузеры появляются, появляются новые глюки. Не все могут позволить себе обновлять nginx на каждый чих, но каждый может сменить конфигурацию.

Кроме того, перебрать все версии браузеров на всех платформах — это огромный труд. Пусть лучше nginx улучшает :)
Поставил, посмотрел трафик. Действительно шлет заголовок и действительно есть какие-то проблемы с недогрузкой css на одном сайте, которые исчезли сразу как включил gzip_disable.
Теперь не могу понять, откуда у меня был твердая уверенность что до второго сервиспака IE вообще не поддерживал gzip. Видимо, так говорили люди, имевшие ввиду, что он настолько глючит, что gzip ему все равно никто не отдает.
Если честно, то после массовых жалоб реальных пользователей эксперименты на сферической теории не вдохновляют. Но вы, конечно, развлекайтесь. Сделайте экспериментальную выборку побольше — глюк с непониманием заголовка сжатия, если я правильно помню, проявлялся где-то в 10-15% по отношению к случайным страницам. У меня в тот момент было всего 4000-5000 хитов из которых на IE6 приходилось где-то 60% Это давало 20-30 писем и 10-15 звонков с жалобами на поломку страницы.
Для резолвинга лучше, имхо, не копировать файлы, а делать симлинки. Уж на библиотеку точно, чтобы при обновлении не использовалась старая. На hosts и resolv.conf — тоже, если не нужны разные конфигурации.

По самой установке ничего нового не узнал, но вот конфиг nginx интересен, спасибо :)
Симлинки из chroot? Ну-ну…
Да, про симлинки прогнал что-то, забыл, что я ставил хардлинки. Для hosts и resolf.conf они пойдут, для библиотеки, увы, нет :(
И для библиотеки должны пойти, если etc, lib и www находятся на одном разделе. А это крайне нежелательно с точи зрения стабильности системы, почему во многих рецептах и советуют копировать, а не линковать.
Для библиотеки, по-моему, не пойдёт, т. к. после обновления физически это будет уже другой файл
И как это противоречит цели держать два файла синхронизированными?
Хардлинк нужно будет обновлять или ручками, или писать скрипт, запускающий создание хардлинка после apt-get upgrade
Можете указать цитату в мануале, где это написано?
Нет, общее представление о работе ФС (ext*), хардлинков на ней и процесса обновления:
— запись файла в каталоге ссылается на какой-то инод
— хардлинк ссылается на тот же инод
— при обновлении создаётся временный файл, оригинал сначала переименовывается во что-то временное, временный файл с новой версией переименовывается в оригинал (то есть файл библиотеки ссылается уже на другой инод), переименованный оригинал удаляется.

Если не прав — поправьте, пожалуйста, одним заблуждением будет у меня меньше.
Только что проверил.

~$ echo "this is 1" > file1
~$ ln ./file1 file2
~$ cat file2
this is 1
~$ echo "this is 3" > file3
~$ mv file3 file1
~$ cat file2
this is 1
~$ cat file1
this is 3

Вы правы. Спасибо. Век живи, век учись, дураком помрешь.
Не убедили, что я прав :) Из трёх пунктов для меня самый сомнительный последний — утилит для Linux типа FileMon (логирование операций с файлами) не знаю, в исходниках apt-get вряд ли разберусь. Если разработчики ставили целью обновление и хардлинков на обновляемые файлы, то, исходя из тех же первых двух общих соображений, могли это реализовать. Прямо сейчас проверить не могу — недавно обновился.
А вот за cgi.fix_pathinfo=0 спасибо, не знал.
Тоже не знал, одно время начали вылавливать в user-uploads файлах всякие интересности в виде картинок с php-кодом внутри, долго думали, как они исполняются, в итоге завернули все запросы на index.php.
Только вчера этим занимался :) Спасибо за статью! Ловите плюсик.
Пытался настроить nginx на работу с несколькими сайтами, и столкнулся с проблемой: как предотвратить доступ одного сайта к другому? Т.е. если при Apache используют php open_basedir, то при nginx, это вроде бесполезно. Существуют ли решения этой проблемы, или в этих конфигах уже есть таковое?
Знаю что можно для PHP-fpm каждый процесс PHP запускать от разных юзеров (но на практике не сталкивался).
Надо запускать php-fpm с разными конфиг файлами, где указаны разные php.ini с разными пользователями и разными chroot. Это решение не для массового применения и на мой взгляд — только лишняя трата ресурсов.
разный chroot не обязательно, можно папкам пользователей просто права доступа поставить построже типа rwx r-- ---
Да, конечно. А можно даже спрятать чужие папки sticky-битом. Тут действительно много вариантов. А ключевое выше.
Во, WST извне хабра попросил добавить альтернативный вариант open_basedir для php-fpm

Суть в том, что запрос передается не пользовательскому скрипту. а скрипту-диспетчеру, который смотрит к какому домену обратились и выставляет соответствующий open_basedir через ini_set, отключает функцию ini_set и инклюдит уже пользовательский скрипт. Вот ссылка: averkov.web.id/articles/admin/nginx/open_basedir/
Интересное решение, хотя и не без изъянов. Спасибо.
перенес в Системное администрирование
правильно ))
> chmod -R 750 /var/www/example.ru
лучше заменить на find /var/www/example.ru -type f -exec chmod 640 {} \; && find /var/www/example.ru -type d -exec chmod 750 {} \;
потому что файлам права на запуск не нужны.
А не проще использовать
chmod u=rwX,g=rX,o= -Rv /var/www/example.ru
он будет учитывать каталоги и файлы отдельно.
chmod соотв. из утилит GNU
Зачем копировать в chroot, если для такого существуют симлинки?
chroot, если вы посмотрите в документацию, по определению не может ходить по симлинкам. Его прямая обязанность оберегать от таких операций.
try_files $uri $uri/ /index.php?q=$uri&$args;

Выделенное — чушь, не несущая смысловой нагрузки в try_files.

В случае с:
location = /favicon.ico {
log_not_found off;
access_log off;
}


Лучше сделать так:
Пардон,
location = /favicon.ico {
empty_gif;
access_log off;
}
Это не то будет, в оригинале:
1) если фавикон есть, то он отдастся, но в лог не запишется
2) фавикона нет — отдастся 404, но в лог тоже не запишется

У вас в любом случае отдастся empty.gif
Тогда так:
location = /favicon.ico {
try_files $uri @emptygif;
}
location @emptygif {
internal;
empty_gif;
}
А собственно зачем его отдавать? :)
Чтобы клиент 404 не получал. Не люблю, знаете ли, красные строчки в фаербаге.
На вкус и цвет… Но идеологически правильно, если файла нет отдавать 404
С другой стороны, если почти каждый браузер запрашивает favicon.ico и каждый поисковый бот — robots.txt, то идеологически правильно их создать и предоставить.
robots.txt — да, favicon.ico рисовать надо — я не умею :( но подсовывать вместо него прозрачный пиксель — извращение, по-моему.
favicon generator вам поможет, их много разных сервисов.
Internal в именнованом location не нужен
Почему чушь? Ну ка обоснуй. Неужто все движки сами uri разбирают?
Не путайте try_files и rewrite.
try_files'у насрать на аргументы — он делает то, что и должен делать с таким названием — пробует найти файлы по списку.
В случае, если ни один файл не найден, то делается внутренний редирект на последний параметр.
а теперь ещё раз читаем по приведённой ссылке и прекращаем умничать
Извиняюсь, я ошибался.
Действительно работает.
squeeze на дворе. какой нафиг ленни?
Кстати никто не в курсе когда squeeze уже stable будет? судя по wiki вроде как со дня на день.
5-6 февраля. Завтра.
100500-я статья на эту тему…
А можно всё то же самое, но только под Squeeze?
Можно, разрешаю.
Как показала практика в репах очень старый nginx. deb-файлы нужные тоже найти не просто. Приходится компилить из исходников. А тогда уж лучше последний брать. Спросите, а какая разница? Например, я на домашнем серваке поднимал rtorrent в связке с rutorrent, а ему scgi нужен, который есть в nginx, начиная с 0.8.42. Поднимать апача на машине с 512 метрами оперативы, большую часть которой занимают rtorrent и xbmc — не вариант.
packages.debian.org/sid/nginx — Пакет: nginx (0.8.54-3 и другие)

sysoev.ru/nginx/ — Версию nginx-0.8.54 я рассматриваю как стабильную с точки зрения надёжности.
Если nginx + fpm то где про акселератор загрузки файлов?
При использовании HTTPS в настройки нужно внести некоторые плюшечки:
# SSL Trick
fastcgi_param HTTPS on;


Да, ещё несколько плюшечек нужно внести чтобы корректно работала авторизация…
# for authentication to work
fastcgi_param AUTH_USER $remote_user;
fastcgi_param REMOTE_USER $remote_user;


А ещё не забываем про проблему .svn и .cvs (.git и т.д. — кто на что богат)

ПСы: в отличии от автора использую файловые сокеты… Ну, наверное из-за чисто религиозных соображений.

Собственно, выходит как-то так:
server {
    listen 10.20.30.40:443;
    server_name mail.mylocal.info;
    access_log /web/http/mail.mylocal.info/logs/access.log;
    error_log  /web/http/mail.mylocal.info/logs/error.log;

    # Enable SSL Engine
    ssl                         on;
    ssl_certificate             /etc/nginx/keys/mail.mylocal.info.crt;
    ssl_certificate_key         /etc/nginx/keys/mail.mylocal.info.key;
    ssl_client_certificate      /etc/nginx/keys/ca.crt;

    ssl_session_timeout         5m;
    ssl_verify_client           off;

    ssl_protocols               SSLv3 TLSv1;
    ssl_ciphers                 AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
    ssl_prefer_server_ciphers   on;

    location ~ /.svn/ {
        deny all;
    }

    location ~ /.cvs/ {
        deny all;
    }

    location ~ ^/.*\.php$ {
        root           /web/http/mail.mylocal.info/httpdocs;

        fastcgi_pass    unix:/var/spool/php/mail.sock;
        fastcgi_send_timeout 600;

        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME    /web/http/mail.mylocal.info/httpdocs$fastcgi_script_name;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;
        fastcgi_param  QUERY_STRING       $query_string;
        # for authentication to work
        fastcgi_param  AUTH_USER          $remote_user;
        fastcgi_param  REMOTE_USER        $remote_user;
        #
        include        /etc/nginx/fastcgi_params;
        # Auth
        auth_basic "Restricted Area";
        auth_basic_user_file /web/http/.passwd-mail.mylocal.info;
        # SSL Trick
        fastcgi_param HTTPS on;
    }

    # Root dir
    location / {
        root /web/http/mail.mylocal.info/httpdocs;
        index index.php;

        # Auth
        auth_basic "Restricted Area";
        auth_basic_user_file /web/http/.passwd-mail.mylocal.info;
    }
}



А в чём проблема .svn и .cvs, .git?
Нет слов, как говорится, одни буквы
А в чем надобность делиться ими с посетителями? По-хорошему их на сайт не надо закачивать вообще.
Вот я и удивился, что за проблема — у меня в svn/hg при коммите срабатывает хук, который деплоит на продакшен только то, что нужно (а-ля Капистрано)
проблема не в .svn а в админе.
если админ выложит на сайт password.txt с паролями — то это проблема не текстового редактора
У меня такой вопрос, на сервере крутится nginx+apache2+php+mysql… и еще несколько игровых серверов. Иногда в браузер Opera «как бы долго думает» перед тем как перейти на нажатую ссылку, тут я не знаю на кого грешить или на роутер, или на браузер или на nginx.

Если дописать в конфиг: «worker_priority -5; #Увеличитвваем приоритет», nginx сможет быстрее откликаться когда требуется, или будет как обычно? Или не сыграет роли.

З.Ы. ушел пробовать, но хочу услышать ваше мнение.

З.Ы2. тут есть подобная статья.
Новайсам: не нужно пытаться запускать /usr/share/phpmyadmin прописав chroot /var/www
на тему уязвимости можно попробовать использовать location ~* \w+\.php$ {, nginx стабильно выдает 404.
Не хватает слеша:

Нужно location ~ \.php$ {

Вместо location ~ .php$ {
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории