Apache Reverse Proxy – Fixing 404 Errors

apache-2.4jettyreverse-proxy

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 pieros.tzamas@spectrum.com.cy
 # 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>

Best Answer

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>