Вопрос или проблема
У меня установлена Shibboleth, которая работает на Jetty 9. Через Apache у меня есть обратный прокси на порт 8080 Jetty, который обслуживает экземпляр Shibboleth.
Когда я выполняю curl http://localhost:8080/idp/shibboleth в консоли, ответ экземпляра генерируется корректно.
Однако, когда я делаю то же самое в своем браузере https://idp.example.com/idp/shibboleth, я получаю ошибку 404.
Это указывает на то, что обратный прокси работает неправильно?
Это моя конфигурация Apache
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
<VirtualHost *:80>
ServerName "idp.spectrum.com.cy"
Redirect permanent "/" "https://idp.spectrum.com.cy/"
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerName idp.spectrum.com.cy:443
ServerAdmin [email protected]
# Debian
CustomLog /var/log/apache2/idp.spectrum.com.cy.log combined
ErrorLog /var/log/apache2/idp.spectrum.com.cy.org-error.log
# Centos
#CustomLog /var/log/httpd/idp.example.org.log combined
#ErrorLog /var/log/httpd/idp.example.org-error.log
DocumentRoot /var/www/html/idp.spectrum.com.cy
SSLEngine On
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"
SSLHonorCipherOrder on
# Запретить встраивание страницы входа вашего IdP в iframe и
# Включить строгую транспортную безопасность HTTP с длительностью 2 года
<IfModule headers_module>
Header set X-Frame-Options DENY
Header set Strict-Transport-Security "max-age=63072000 ; includeSubDomains ; preload"
</IfModule>
# Debian
SSLCertificateFile /etc/ssl/certs/idp.spectrum.com.cy.crt
SSLCertificateKeyFile /etc/ssl/private/idp.spectrum.com.cy.key
# ACME-CA или GEANT_OV_RSA_CA_4 (для пользователей, которые используют GARR TCS/Sectigo RSA Organization Validation Secure Server CA)
#SSLCACertificateFile /etc/ssl/certs/ACME-CA.pem
#SSLCACertificateFile /etc/ssl/certs/GEANT_OV_RSA_CA_4.pem
# Centos
#SSLCertificateFile /etc/pki/tls/certs/idp.example.org.crt
#SSLCertificateKeyFile /etc/pki/tls/private/idp.example.org.key
# ACME-CA или GEANT_OV_RSA_CA_4 (для пользователей, которые используют GARR TCS/Sectigo RSA Organization Validation Secure Server CA)
#SSLCACertificateFile /etc/pki/tls/certs/ACME-CA.pem
#SSLCACertificateFile /etc/pki/tls/certs/GEANT_OV_RSA_CA_4.pem
<IfModule mod_proxy.c>
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
ProxyPass /idp http://localhost:8080/idp/ retry=5
ProxyPassReverse /idp http://localhost:8080/idp/ retry=5
<Location /idp>
Require all granted
</Location>
</IfModule>
</VirtualHost>
</IfModule>
<VirtualHost 127.0.0.1:80>
ProxyPass /idp http://localhost:8080/idp/ retry=5
ProxyPassReverse /idp http://localhost:8080/idp/ retry=5
<Location /idp>
Require all granted
</Location>
</VirtualHost>
Я упростил свой конфигурационный файл, чтобы убрать https. Ниже представленная конфигурация работает нормально, но только с http. Я буду расследовать, почему конфигурация https генерирует ошибку 404.
<VirtualHost *:80>
ServerName idp.spectrum.com.cy
<IfModule mod_proxy.c>
ProxyPreserveHost On
ProxyPass /idp/ http://localhost:8080/idp/ retry=5
ProxyPassReverse /idp/ http://localhost:8080/idp/ retry=5
<Location /idp>
Require all granted
</Location>
</IfModule>
</VirtualHost>
# Этот виртуальный хост создан только для обработки административных команд
для Shibboleth, выполняемых с localhost
<VirtualHost 127.0.0.1:80>
ProxyPass /idp http://localhost:8080/idp/ retry=5
ProxyPassReverse /idp http://localhost:8080/idp/ retry=5
<Location /idp>
Require all granted
</Location>
</VirtualHost>
Обычно это должно быть
ProxyPass /idp/ http://localhost:8080/idp/
Обратите внимание на завершающий слэш в первом аргументе команды ProxyPass
. Всегда согласовывайте завершающие слэш в обоих аргументах.
Мои декларации VirtualHost
довольно просты и содержат только минимально необходимое для работы:
<VirtualHost *:80>
DocumentRoot /var/www/html
ServerName idp.example.com
ServerAlias idp
ErrorLog logs/error_log
CustomLog logs/access_log
</VirtualHost>
<VirtualHost *:443>
DocumentRoot /var/www/html
SSLEngine on
SSLProxyEngine on
SSLCertificateKeyFile /etc/pki/tls/private/idp.example.com.key
SSLCertificateFile /etc/pki/tls/certs/idp.example.com.crt
SSLCertificateChainFile /etc/pki/tls/certs/chain.crt
ServerName idp.example.com
ServerAlias idp
ErrorLog logs/ssl-error_log
CustomLog logs/ssl-access_log combined
</VirtualHost>
Вот мой /etc/httpd/conf.d/idp.conf
для IDP:
ProxyPass /idp/ http://localhost:8080/idp/ retry=5
ProxyPassReverse /idp/ http://localhost:8080/idp/
<Proxy http://localhost:8080>
Require all granted
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Proxied-Https on
RequestHeader set Proxy-ssl-id %{SSL_SESSION_ID}s
</Proxy>
Попробуйте удалить порт из директивы ServerName
. Т.е.,
ServerName idp.spectrum.com.cy
Согласно https://httpd.apache.org/docs/2.4/mod/core.html#servername, порт является необязательным и допускается, но далее в документации упоминается, что это может быть причиной того, что эта конфигурация VirtualHost
не срабатывает (браузеры не отправляют номер порта в заголовке Host:
).
Если вы используете виртуальные хосты на основе имени,
ServerName
внутри секции
<VirtualHost>
указывает, какому имени хоста должно соответствовать содержимое заголовкаHost:
в запросе для совпадения с этим виртуальным хостом.
Ответ или решение
Когда вы сталкиваетесь с проблемой обратного прокси в Apache, который выдает ошибку 404 при попытке доступа к ресурсу, в то время как запрос к тому же ресурсу на порту 8080 работает корректно, важно тщательно проанализировать конфигурацию и детализировать возможные причины проблемы.
Проблема: Ошибка 404 при доступе через Apache Reverse Proxy
-
Проверка конфигурации Apache: Первым делом нужно удостовериться, что конфигурация Apache правильно установлена для обратного прокси. В вашем конфигурационном файле вы используете модули
mod_proxy
иmod_ssl
, что корректно для работы с HTTPS и проксированием.<IfModule mod_proxy.c> ProxyPreserveHost On ProxyPass /idp http://localhost:8080/idp/ retry=5 ProxyPassReverse /idp http://localhost:8080/idp/ retry=5 </IfModule>
Обратите внимание на:
- Трасировка слешей. Вам следует убедиться, что у вас стоит слеш на конце строки. Например, менять
ProxyPass /idp http://localhost:8080/idp/
наProxyPass /idp/ http://localhost:8080/idp/
, а также указыватьProxyPassReverse /idp/ http://localhost:8080/idp/
. - Контекст Location. Убедитесь, что у вас есть блок
<Location>
, позволяющий доступ к/idp
, и что права на доступ установлены корректно.
<Location /idp> Require all granted </Location>
- Трасировка слешей. Вам следует убедиться, что у вас стоит слеш на конце строки. Например, менять
-
Проверка виртуальных хостов: Вы указали несколько блоков
<VirtualHost>
. Чтобы избежать путаницы, рекомендуется проверить, правильно ли вы настраиваете свои виртуальные хосты. Не включайте порт в директивуServerName
, как это указано в документации Apache, так как браузеры обычно не отправляют номер порта в заголовкахHost
.ServerName idp.spectrum.com.cy
-
Проверка логов: Логи ошибок Apache могут дать ценную информацию о том, что происходит. Если вы настроили отдельный лог для этого виртуального хоста:
ErrorLog /var/log/apache2/idp.spectrum.com.cy.org-error.log
Просмотрите логи после попытки доступа к URL, чтобы определить, сообщает ли сервер конкретные причины ошибки 404.
-
Проверка настройки SSL: Поскольку вы используете HTTPS, необходимо убедиться, что SSL настроен правильно, и что Apache может обрабатывать запросы через защищенное соединение. Возможно, стоит отключить проверки сертификатов на начальном этапе для диагностики.
-
Проблемы с кэшированием: Убедитесь, что кэширование не вызывает проблему. Попробуйте очистить кэш браузера или протестировать доступ через режим инкогнито.
-
Firewall и SELinux: Если ваш сервер работает под управлением Linux, проверьте настройки брандмауэра (iptables или firewalld) и SELinux, чтобы удостовериться, что они не блокируют трафик.
Заключение
Для устранения ошибки 404, возникающей при работе обраного прокси с Apache, необходимо внимательно проверить конфигурацию. Убедитесь в правильности слешей в ProxyPass
, настройке виртуальных хостов, доступности логов, а также в корректности SSL-установок. Проверка всех этих аспектов поможет быстрее найти и устранить причину проблемы.
Регулярное ведение логов и их анализ помогут оперативно выявлять и исправлять подобные проблемы в будущем.
Здравствуйте! Судя по вашему описанию, проблема может заключаться в конфигурации Apache при работе с HTTPS и обратным прокси на Jetty. Ошибка 404 при доступе через
https://idp.example.com/idp/shibboleth
указывает на то, что запросы не перенаправляются корректно.Обращаю ваше внимание на несколько моментов, которые могут помочь решить проблему:
Включите SSLProxyEngine: Для проксирования HTTPS-запросов Apache требует явного включения SSLProxyEngine. Добавьте следующую строку внутри вашего блока
<VirtualHost _default_:443>
:SSLProxyEngine On
Удалите номер порта из ServerName: Указание порта в директиве
ServerName
может привести к некорректному сопоставлению виртуального хоста, поскольку браузеры не включают номер порта в заголовкеHost
. Измените:ServerName idp.spectrum.com.cy:443
на
ServerName idp.spectrum.com.cy
Согласуйте завершающие слэши в ProxyPass: Несоответствие в использовании завершающих слэшей может вызывать проблемы с маршрутизацией запросов. Убедитесь, что ваши директивы выглядят так:
ProxyPass /idp/ http://localhost:8080/idp/ retry=5
ProxyPassReverse /idp/ http://localhost:8080/idp/ retry=5
Добавьте необходимые заголовки для проксирования HTTPS: Это поможет Jetty корректно обрабатывать исходные HTTPS-запросы. Внутри блока
<VirtualHost _default_:443>
добавьте:RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Proxied-Https "on"
Проверьте логи Apache: Логи часто содержат подробную информацию о причинах ошибок. Просмотрите файлы логов, указанные в директивах
ErrorLog
иCustomLog
, чтобы найти дополнительные подсказки.Внесение этих изменений должно помочь настроить обратный прокси с поддержкой HTTPS корректно. Если проблема сохранится после применения этих рекомендаций, возможно, стоит проверить настройки Jetty или дополнительные модули Apache, которые могут влиять на обработку запросов.
Удачи в решении проблемы!