Apache reverse proxy not working and generates a 404 error
I have an installation of Shiboleth that runs on Jetty 9. Through Apache I have a reverse proxy to the 8080 port of Jetty which serves the Shiboleth instance.
When I curl http://localhost:8080/idp/shibboleth in the console, the instance responce is generated correctly.
However when I do the same on my browser https://idp.example.com/idp/shibboleth I get a 404 error.
This is some indication that the reverse proxy is not working correctly?
This is my apache conf
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
# Disallow embedding your IdP's login page within an iframe and
# Enable HTTP Strict Transport Security with a 2 year duration
<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 or GEANT_OV_RSA_CA_4 (For users who use 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 or GEANT_OV_RSA_CA_4 (For users who use 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>
I have simplified my conf file in order to remove https. The configuration below works fine but with http only. I will investigate why the https configuration generates 404 error.
<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>
# This virtualhost is only here to handle administrative commands
for Shibboleth, executed from 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>
Solution 1:
It's supposed to be
ProxyPass /idp/ http://localhost:8080/idp/
Note the trailing slash in the ProxyPass
command's first argument. Always align the trailing slashes in both arguments.
My VirtualHost
declarations are pretty basic and only contain the bare minimum to work:
<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>
Here's my IDP's /etc/httpd/conf.d/idp.conf
:
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>
Solution 2:
Try removing the port from the ServerName
directive. I.e.,
ServerName idp.spectrum.com.cy
Per https://httpd.apache.org/docs/2.4/mod/core.html#servername the port is optional and allowed, but the following mention in the documentation sounds like it may be the reason why that VirtualHost
configuration is not picking up (browsers do not sent the port number in the Host:
header).
If you are using name-based virtual hosts, the
ServerName
inside a<VirtualHost>
section specifies what hostname must appear in the request'sHost:
header to match this virtual host.