Решение проблемы nginx directory index of is forbidden с помощью strace
После некоторых изменений шаблонов конфигов nginx один из сайтов открывался с ошибкой 403 Forbidden. Логи nginx показывали очень скудную информацию. Можно конечно включить отладку, но я пошёл другим путём - воспользовался замечательной утилитой strace.
В error.log ошибка была такого вида:
2020/10/23 04:39:04 [error] 32741#32741: *79182 directory index of "/home/012447/data/www/my-site.ru/" is forbidden, client: 31.xx.xx.202, server: my-site.ru, request: "GET / HTTP/1.1", host: "my-site.ru"
И тут на помощь пришла утилита strace. strace — утилита для Linux, которая позволяет отследить выполнение системных вызовов (system call) и сигналов к ядру системы.
Если в системе нет strace, то:
yum install -y strace
Анализ поведения nginx с помощью strace
Сначала узнаем PIDы nginx:
# pidof nginx
23581 831
Теперь запускаем strace:
strace -p 23581 -p 831 -e trace=file -f
strace: Process 23581 attached
strace: Process 19579 attached
Пробуем открыть сайт и видим в консоли такую картину:
strace -p 23581 -p 19579 -e trace=file -f
strace: Process 23581 attached
strace: Process 19579 attached
[pid 19579] open("/home/012447/data/www/my-site.ru", O_RDONLY|O_NONBLOCK|O_PATH|O_DIRECTORY) = 71
[pid 19579] openat(71, ".", O_RDONLY|O_NONBLOCK) = 72
[pid 19579] open("/home/012447/data/www/my-site.ru", O_RDONLY|O_NONBLOCK|O_PATH|O_DIRECTORY) = 71
[pid 19579] openat(71, ".", O_RDONLY|O_NONBLOCK) = 72
[pid 19579] open("/home/012447/data/www/my-site.ru", O_RDONLY|O_NONBLOCK|O_PATH|O_DIRECTORY) = 71
[pid 19579] openat(71, "index.php,", O_RDONLY|O_NONBLOCK) = -1 ENOENT (No such file or directory)
[pid 19579] stat("/home/012447/data/www/my-site.ru", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
[pid 19579] open("/home/012447/data/www/my-site.ru", O_RDONLY|O_NONBLOCK|O_PATH|O_DIRECTORY) = 71
[pid 19579] openat(71, "index.html", O_RDONLY|O_NONBLOCK) = -1 ENOENT (No such file or directory)
^Cstrace: Process 23581 detached
strace: Process 19579 detached
В моём случае nginx не мог найти файл index.php (на index.html не обращайте внимания я его не использую), потому что была опечатка в виде запятой "index.php,".
В конфиге сайта в контексте server директива index выглядела так:
server {
server_name my-site.ru www.my-site.ru;
charset UTF-8;
index index.php, index.html;
...
При этом, в том же контексте location выглядит так:
...
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
location ~ [^/]\.ph(p\d*|tml)$ {
try_files /does_not_exists @php;
}
}
...
Как вы уже поняли - достаточно было убрать запятую.
Получилось так:
server {
server_name my-site.ru www.my-site.ru;
charset UTF-8;
index index.php index.html;
...
Делаем nginx -s reload и проверяем сайт, попутно запустив strace:
# pidof nginx
23581 831
# strace -p 23581 -p 831 -e trace=file -f
strace: Process 23581 attached
strace: Process 831 attached
[pid 831] open("/home/012447/data/www/my-site.ru", O_RDONLY|O_NONBLOCK|O_PATH|O_DIRECTORY) = 10
[pid 831] openat(10, ".", O_RDONLY|O_NONBLOCK) = 15
[pid 831] open("/home/012447/data/www/my-site.ru", O_RDONLY|O_NONBLOCK|O_PATH|O_DIRECTORY) = 10
[pid 831] openat(10, ".", O_RDONLY|O_NONBLOCK) = 15
[pid 831] open("/home/012447/data/www/my-site.ru", O_RDONLY|O_NONBLOCK|O_PATH|O_DIRECTORY) = 10
[pid 831] openat(10, "index.php", O_RDONLY|O_NONBLOCK) = 15
[pid 831] newfstatat(10, "index.php", {st_mode=S_IFREG|0644, st_size=420, ...}, AT_SYMLINK_NOFOLLOW) = 0
[pid 831] open("/home/012447/data/www/my-site.ru", O_RDONLY|O_NONBLOCK|O_PATH|O_DIRECTORY) = 10
...
На самом деле причин ошибки 403 множество. Я лишь хотел показать как с помощью strace можно быстро разобраться в причине.
Комментариев 1