Как перенаправить на 404, когда url указывает на существующую папку (без косой черты). Связанный HAproxy или mod-rewrite

Я использую прослушивание HAProxy на 80 для отправки запросов на сервер node (порт: 3000) или php-сервер (4000); У меня также есть CSF, у которых есть порты 3000 и 80.

Он работает нормально, когда я просматриваю страницу в http://example.com/forum/1/page.php, но иногда, когда я случайно вхожу example.com/forum/1 (без конечной косой черты), он продолжает загружать и в конечном итоге приводит к странице ошибок ERR_CONNECTION_TIMED_OUT. Адресная строка показывает, что она перенаправлена ​​на http://example.com:4000/forum/1/.

Так как у меня нет открытого порта 4000, когда я несколько раз перехожу к example.com/forum/1, он будет генерировать блок CSF. Мой вопрос: могу ли я перенаправить все запросы, указывающие на фактическую папку example.com/forum/1 (без конечной косой черты) на страницу 404? Я попытался добавить правило перезаписи для добавления конечной косой черты к каждому запросу, но это сломало бы все мои относительные пути (см. Мою проблему в этой статье).

Итак, что я хочу знать, почему я был перенаправлен на http://example.com:4000/forum/1/ из http://example.com/forum/1? Это вызвано HAproxy?

Некоторая конфигурация HAproxy:

frontend all 0.0.0.0:80
    timeout client 1h
    # use apache2 as default webserver for incoming traffic
    default_backend apache2

backend apache2
    balance roundrobin

    option forwardfor
    server apache2 myIpAddress:4000 weight 1 maxconn 1024 check 

    # server must be contacted within 5 seconds
    timeout connect 5s
    # all headers must arrive within 3 seconds
    timeout http-request 3s
    # server must respond within 25 seconds. should equal client timeout
    timeout server 25s

Здесь мои правила перезаписи:

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]

RewriteCond %{REQUEST_URI} !^.*\.(jpg|css|js|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]

RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^([^\.]+)$ $1.php [NC,L]

Ответ 1

Так как /forum/1 является действительным физическим каталогом, вы перенаправляетесь на /forum/1/ из-за этого параметра:

DirectorySlash On

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

Вы можете, конечно, отключить этот флаг, используя:

DirectorySlash Off

но знать о последствиях безопасности.

Чтобы быть более безопасным, вам также необходимо:

Options -Indexes

чтобы отключить список каталогов.

Предупреждение о безопасности (скопировано из связанного руководства)

Отключение перенаправления трейлинг-косой черты может привести к раскрытию информации. Рассмотрим ситуацию, в которой mod_autoindex активен (Options +Indexes), а DirectoryIndex установлен на допустимый ресурс (скажем, index.html), и для этого URL нет другого специального обработчика. В этом случае запрос с завершающей косой чертой отобразит файл index.html. Но запрос без косой черты перечислил содержимое каталога.


Обновление: Чтобы ответить на эту часть вопроса:

Мой вопрос: могу ли я перенаправить все запросы, указывающие на фактическую папку example.com/forum/1 (без конечной косой черты) на страницу 404?

Вы можете использовать этот код в /forum/1/.htaccess:

DirectorySlash On
RewriteEngine On

RewriteRule ^$ - [L,R=404]

Это заставит конечную косую черту, чтобы правило перезаписи могло использоваться для отправки ошибки 404.

Ответ 2

В вашем файле .htaccess добавьте следующий код. Замените /404.php любым файлом, который вы хотите.

ErrorDocument 404 /404.php

Ответ 3

Поместите это вверху вашего .htaccess

DirectorySlash Off
RewriteOptions AllowNoSlash
RewriteEngine On
RewriteCond ${REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ - [L,R=404]

DirectorySlash Off сделает каталоги доступными без косой черты без перенаправления.

Но проблема не слэш-версия просто перечислит содержимое каталога. Я стараюсь избегать этого, добавляется RewriteOptions AllownoSlash.

Теперь, когда папка запрашивается без косой черты, возникает ошибка 404.