#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 должно работать на всех доменах, которые я размещаю… Возможно, есть способ сделать это? (Вот для чего было регулярное выражение …)