Решение проблемы 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 можно быстро разобраться в причине.

Web

Комментариев 1

  1. Офлайн
    Андрей
    Андрей 16 ноября 2023 10:17
    + +1 -
    К сожалению, проблему не решил - вроде как Апач из корня должен перенаправлять все вызовы в /public (проект на Laravel), но похоже этого не происходит. Ох уж эти сервера...

    Но! Большое спасибо за такой универсальный пост. Очень люблю, когда авторы не просто дают решение (которое может и не подойти), а инструмент для решения проблемы.

Добавить комментарий