Вопрос или проблема
У меня есть экземпляр Apache, работающий на Ubuntu Server 22.04:
% lsb_release -a
Нет доступных модулей LSB.
Идентификатор дистрибьютора: Ubuntu
Описание: Ubuntu 22.04.5 LTS
Версия: 22.04
Кодовое имя: jammy
% apache2 -v
Версия сервера: Apache/2.4.52 (Ubuntu)
Сервер собран: 2024-07-17T18:57:26
Этот экземпляр обслуживает один виртуальный хост (“foo”).
Мне сложно заставить Apache перенаправлять клиентов, обращающихся к /admin
, на HTTPS-версию хоста с использованием 308 вместо 301.
Вот содержание foo.conf
:
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName dev-server.lan
DocumentRoot /var/www/html/vhosts/foo
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/var/www/html/vhosts/foo">
Require all granted
AllowOverride All
</Directory>
<Directory "/var/www/html/vhosts/foo/admin">
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}/admin/$1 [R=308,L]
</Directory>
</VirtualHost>
Вот что происходит:
% curl -v 'http://dev-server.lan/admin'
* Пытаюсь 192.168.1.253:80...
* Подключено к dev-server.lan (192.168.1.253) порт 80 (#0)
> GET /admin HTTP/1.1
> Host: dev-server.lan
> User-Agent: curl/7.81.0
> Accept: */*
>
* Пометить пакет как не поддерживающий многопользовательское использование
< HTTP/1.1 301 Moved Permanently
< Date: Sat, 28 Sep 2024 09:50:35 GMT
< Server: Apache/2.4.52 (Ubuntu)
< Location: http://dev-server.lan/admin/
< Content-Length: 316
< Content-Type: text/html; charset=iso-8859-1
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>Документ был перемещен <a href="http://dev-server.lan/admin/">сюда</a>.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Сервер на dev-server.lan Порт 80</address>
</body></html>
* Соединение #0 с хостом dev-server.lan осталось нетронутым
Что я пробовал:
-
[R=307,L]
: ничего не меняет; -
Искал надоедливые
.htaccess
файлы; под/var/www/html/vhosts/foo
нет вообще.htaccess
файлов, кроме нескольких, вложенных под/var/www/html/vhosts/foo/tickets
(которые, кстати, не определяют никакого перенаправления):% find /var/www/html/vhosts/foo -name '.htaccess' /var/www/html/vhosts/foo/tickets/.htaccess /var/www/html/vhosts/foo/tickets/pdfs/.htaccess
-
Искал надоедливые
RewriteRule
; в любом.conf
файле под/etc/apache2
нет определенныхRewriteRule
, кроме одной, определенной вfoo.conf
:% find /etc/apache2 -type f -name '*.conf' -exec grep 'RewriteRule' {} + /etc/apache2/sites-available/foo.conf: RewriteRule ^(.*)$ https://%{HTTP_HOST}/admin/$1 [R=308,L]
Что я упускаю?
Ответ или решение
Чтобы настроить перенаправление с использованием кода состояния 308 в вашем экземпляре Apache, актуальным кажется использование конфигураций Apache, правильная настройка которых чуть более детализирована. В вашем случае есть несколько моментов, которые следует проверить и исправить.
-
Проверьте настройки модуля
mod_rewrite
:Убедитесь, что модуль
mod_rewrite
включён. Вы можете сделать это, выполнив команду:sudo a2enmod rewrite
После этого перезапустите Apache:
sudo systemctl restart apache2
-
Правильное использование правил перенаправления:
Ваша конфигурация должна выглядеть следующим образом для успешного перенаправления на HTTPS с использованием кода 308:
<VirtualHost *:80> ServerAdmin [email protected] ServerName dev-server.lan DocumentRoot /var/www/html/vhosts/foo ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined RewriteEngine On RewriteCond %{REQUEST_URI} ^/admin$ RewriteRule ^(.*)$ https://%{HTTP_HOST}/admin/$1 [R=308,L] <Directory "/var/www/html/vhosts/foo"> Require all granted AllowOverride All </Directory> </VirtualHost>
Обратите внимание, что
RewriteEngine On
иRewriteCond
находятся на одном уровне сRewriteRule
, а не внутри блока<Directory>
. Это важно, чтобы правила применялись к запросам. -
Проверка наличия конфликта:
Если у вас есть другие файлы конфигурации или правила, убедитесь, что в них нет конфликтующих или предшествующих правил, которые могут указывать на перенаправление до вашего. Проверьте другие конфигурационные файлы Apache или используемые вами виртуальные хосты.
-
Обновление и перезапуск Apache:
После изменения конфигурационного файла не забудьте перезапустить сервер Apache, чтобы изменения вступили в силу:
sudo systemctl restart apache2
-
Тестирование:
Теперь протестируйте перенаправление с помощью
curl
:curl -v 'http://dev-server.lan/admin'
Если вы все сделали правильно, вы должны увидеть ответ с кодом 308, указывающий, что запрос должен быть выполнен с использованием метода HTTP, который был использован (в случае, если вы выполняете POST-запрос, он будет также оставаться POST).
Если после всех этих изменений проблема не решена и вы по-прежнему получаете 301 вместо 308, проверьте логи Apache (/var/log/apache2/error.log
и /var/log/apache2/access.log
) на предмет возможных ошибок или конфликтов, которые могли бы повлиять на поведение перенаправления.