When setting up Apache as a reverse proxy to forward HTTPS requests to an HTTP backend (thirdparty.com in this case), you might encounter unexpected 301 redirects. This typically happens when:
- The backend server responds with absolute URLs containing its own domain
- Apache's proxy modules aren't properly configured to rewrite URLs
- SSLProxyEngine directives are missing or misconfigured
Here's the corrected VirtualHost configuration that handles HTTPS-to-HTTP proxying without 301 redirects:
<VirtualHost *:443>
ServerName mydomain.com
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
SSLProxyEngine On
ProxyRequests Off
ProxyPreserveHost Off
RequestHeader set X-Forwarded-Proto "https"
# Important for URL rewriting
SetOutputFilter proxy-html
ProxyHTMLExtended On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /proxy/ http://thirdparty.com/app/ nocanon
ProxyPassReverse /proxy/ http://thirdparty.com/app/
<Location /proxy/>
ProxyHTMLEnable On
ProxyHTMLURLMap http://thirdparty.com/app/ /proxy/
ProxyHTMLURLMap / /proxy/
ProxyHTMLURLMap https://thirdparty.com/app/ /proxy/
RequestHeader unset Accept-Encoding
</Location>
</VirtualHost>
nocanon: Prevents Apache from canonicalizing URLs which could trigger redirects
ProxyPreserveHost Off: Ensures the Host header is set to the backend server's domain
RequestHeader set X-Forwarded-Proto: Informs the backend about the original HTTPS request
Multiple ProxyHTMLURLMap: Handles all possible URL variations from the backend
If you still experience issues:
- Enable verbose logging:
- Test with curl to examine headers:
- Check backend responses directly:
LogLevel debug
ErrorLog /var/log/apache2/proxy_error.log
CustomLog /var/log/apache2/proxy_access.log combined
curl -v -k -H "Host: mydomain.com" https://mydomain.com/proxy/
curl -v http://thirdparty.com/app/
For complex scenarios, consider these additions:
# Handle WebSocket connections
ProxyPass /proxy/ws/ ws://thirdparty.com/app/ws/
ProxyPassReverse /proxy/ws/ ws://thirdparty.com/app/ws/
# Cookie path rewriting
ProxyPassReverseCookiePath /app/ /proxy/
When trying to set up Apache as a reverse proxy to forward HTTPS traffic from https://mydomain.com/proxy/
to an HTTP backend at http://thirdparty.com/app/
, you might encounter an infinite 301 redirect loop. This happens because the backend server tries to redirect HTTP requests, while Apache is already handling HTTPS.
Here's the proper VirtualHost configuration that solves this issue:
<VirtualHost *:443>
ServerName mydomain.com
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
SSLProxyEngine On
ProxyRequests Off
ProxyPreserveHost On
# Fix for 301 redirects
ProxyPass /proxy/ http://thirdparty.com/app/ nocanon
ProxyPassReverse /proxy/ http://thirdparty.com/app/
# HTML content rewriting
SetOutputFilter proxy-html
ProxyHTMLExtended On
<Location /proxy/>
ProxyHTMLEnable On
ProxyHTMLURLMap http://thirdparty.com/app/ /proxy/
ProxyHTMLURLMap / /proxy/
RequestHeader unset Accept-Encoding
</Location>
</VirtualHost>
The critical elements that make this work:
nocanon
parameter prevents URL canonicalization that could cause redirectsProxyPreserveHost On
maintains the original host headerRequestHeader unset Accept-Encoding
prevents gzip encoding issues- Proper SSL configuration for the frontend
After implementing these changes, test with curl to verify no redirects occur:
curl -vk https://mydomain.com/proxy/
Look for these indicators of success:
- HTTP 200 response code
- No Location header in the response
- Content from the backend server appears correctly
If you still encounter problems:
- Check Apache error logs:
tail -f /var/log/httpd/error_log
- Verify mod_proxy and mod_proxy_html are loaded:
httpd -M | grep proxy
- Test backend connectivity:
curl -v http://thirdparty.com/app/
- Ensure SELinux isn't blocking connections:
setsebool -P httpd_can_network_connect 1