С двумя правилами перезаписи для разных каталогов работает только одно

#apache #.htaccess #redirect #mod-rewrite

#apache #.htaccess #перенаправление #мод-перезапись

Вопрос:

Предыстория

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

Это новое правило, которое я создаю, приводит к нарушению исходного правила (например, не работает… Я не получаю никаких ошибок). Будет выполняться только одно или другое правило.

Это легче объяснить, показав код…

Код

Правило №1:

 # Redirect hits from non-existent page to link shortener
<Directory /var/www/html/lnf>
Options  FollowSymLinks
RewriteEngine On

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

RewriteRule ^/?([^/] )/?$ link/link.php?a=$1 [L]
</Directory>
 

Правило #2:

 # Deny disallowed user agents (when adding this, it causes the first one to break)
<Directory ~ "/var/www/html/*">
Options  FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} "(netscape|.ru)" [nocase]
RewriteRule ^.*$ – [forbidden,last]
</Directory>
 

Вопрос

Почему это происходит и как мне это исправить?

PS: Извините за мою неосведомленность, я все еще чувствую себя новичком, когда дело доходит до Apache.

Обновить

У меня есть 4 vhosts для HTTP и 4 для HTTPS.

Четыре в обоих /etc/apache2/sites-enabled/000-default.conf и /default-ssl.conf являются:

1. Универсальный для запрета всех обращений к общедоступным IP-адресам, которые обычно являются ботами (это находится в верхней части файла vhosts, чтобы перехватить, если ничего другого не происходит):

 <VirtualHost *:80 (and 443 in ssl)>
    ServerName catchall
    <Location />
        Require all denied
    </Location>
</VirtualHost>
 

2. 3 разных vhosts для 3 разных доменов

 <VirtualHost _default_:80 (and 443 in ssl)>
ServerName (my domain)

### REDIRECT HTTP TO HTTPS (this is only in the 000-default.conf)
RewriteEngine On
RewriteCond %{HTTPS} off
#only change when using [mydomain.com] domain (the only public domain)
RewriteCond %{HTTP_HOST} ^mydomain.com
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

# doc roots, error logs, ssl certificates (I omitted this to save space)
</VirtualHost>
 

Ответ №1:

Пусть будет так:

 # default rule applied to all locations
<Location />
    RewriteEngine On
    RewriteCond %{HTTP_USER_AGENT} "(netscape|.ru)" [NC]
    RewriteRule ^ – [F,L]
</Location>

# catch all virtual host
<VirtualHost _default_:*>
    DocumentRoot "/var/www/html"
    ServerName catchall
    <Location />
        Require all denied
    </Location>
</VirtualHost>

# rules specific to mydomain.com placed here
<VirtualHost _default_:80>
    DocumentRoot "/var/www/html/lnf"
    ServerName mydomain.com
    DirectoryIndex index.php

    ### REDIRECT HTTP TO HTTPS (this is only in the 000-default.conf)
    Options  FollowSymLinks
    RewriteEngine On

    RewriteCond %{HTTPS} off
    #only change when using [mydomain.com] domain (the only public domain)
    RewriteCond %{HTTP_HOST} ^mydomain.com$
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

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

    RewriteRule ^/?([^/] )/?$ /link/link.php?a=$1 [L,QSA]
</VirtualHost>
 

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

1. Упс… Я вижу. Я изменил регулярное выражение на то, что вы сказали, и оно работает, но проблема не в этом… При использовании этого правила перед ним «Перенаправление обращений с несуществующей страницы на средство сокращения ссылок» не работает… Вместо этого я получаю стандартный 404 not found…

2. Я попробую, но я не имею в виду правило, которое вы написали… Предполагается, что указанное выше перенаправляет несуществующие каталоги в php-скрипт с каталогом в качестве параметра… Это просто приводит к 404, когда правило под ним (то, которое вы изменили) помещается в файл…

3. DocRoot: /var/www/html/lnf/ полный путь: /var/www/html/lnf/link/link.php … Я попытался изменить порядок правил, как указано в моем вопросе, в обратном порядке, но произошло то же самое… Правило сокращения ссылок не работает, когда существует другое правило…

4. Я пронумеровал правила для наглядности… Я ставлю правило № 2 выше правила № 1, но правило № 1 работает только в том случае, если правила № 2 там нет…

5. Спасибо, это работает правильно, за исключением того, что правило № 2 должно работать на всех доменах, которые я размещаю… Возможно, есть способ сделать это? (Вот для чего было регулярное выражение …)