Не удается настроить Apache для перенаправления клиентов с использованием 308 вместо 301.

Вопрос или проблема

У меня есть экземпляр 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, правильная настройка которых чуть более детализирована. В вашем случае есть несколько моментов, которые следует проверить и исправить.

  1. Проверьте настройки модуля mod_rewrite:

    Убедитесь, что модуль mod_rewrite включён. Вы можете сделать это, выполнив команду:

    sudo a2enmod rewrite

    После этого перезапустите Apache:

    sudo systemctl restart apache2
  2. Правильное использование правил перенаправления:

    Ваша конфигурация должна выглядеть следующим образом для успешного перенаправления на 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>. Это важно, чтобы правила применялись к запросам.

  3. Проверка наличия конфликта:

    Если у вас есть другие файлы конфигурации или правила, убедитесь, что в них нет конфликтующих или предшествующих правил, которые могут указывать на перенаправление до вашего. Проверьте другие конфигурационные файлы Apache или используемые вами виртуальные хосты.

  4. Обновление и перезапуск Apache:

    После изменения конфигурационного файла не забудьте перезапустить сервер Apache, чтобы изменения вступили в силу:

    sudo systemctl restart apache2
  5. Тестирование:

    Теперь протестируйте перенаправление с помощью 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) на предмет возможных ошибок или конфликтов, которые могли бы повлиять на поведение перенаправления.

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

Капча загружается...