How to Fix “Reverse Proxy Setup Broken” Error in Jenkins with Apache SSL Configuration


12 views

When setting up Jenkins behind an Apache reverse proxy with SSL, you might encounter this frustrating warning despite apparently working configuration:

It appears that your reverse proxy set up is broken.
404 http://server.domain.com/jenkins/manage vs. https://server.domain.com/jenkins/manage

Jenkins performs strict header validation through its ReverseProxySetupMonitor. The key issues in your current setup are:

  • Missing proper header rewriting for HTTPS
  • Incomplete proxy configuration for Jenkins context path
  • Self-signed certificate complications (though not the primary issue)

Here's the corrected configuration that resolves the Jenkins warning while maintaining SonarQube access:

<VirtualHost *:80>
  ServerName server.domain.com
  Redirect permanent / https://server.domain.com/
</VirtualHost>

<VirtualHost *:443>
  ServerName server.domain.com

  SSLEngine on
  SSLCertificateFile /etc/ssl/certs/server.crt
  SSLCertificateKeyFile /etc/ssl/private/server.key

  # Jenkins Configuration
  ProxyPass /jenkins http://localhost:8080/jenkins nocanon
  ProxyPassReverse /jenkins http://localhost:8080/jenkins
  ProxyPreserveHost On

  # Critical headers for Jenkins
  RequestHeader set X-Forwarded-Proto "https"
  RequestHeader set X-Forwarded-Port "443"
  RequestHeader set X-Forwarded-Host "server.domain.com"

  # SonarQube Configuration
  ProxyPass /sonar http://localhost:9000/sonar nocanon
  ProxyPassReverse /sonar http://localhost:9000/sonar

  # General proxy settings
  AllowEncodedSlashes NoDecode
  ProxyRequests Off
</VirtualHost>

For optimal performance and security, consider adding these to your configuration:

# Timeout settings
Timeout 300
ProxyTimeout 300

# Security headers
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"

# HTTP/2 support
Protocols h2 http/1.1

Don't forget to configure Jenkins itself:

  1. Go to Manage JenkinsConfigure System
  2. Under Jenkins Location, set:
    • Jenkins URL: https://server.domain.com/jenkins

Run these commands to verify your setup:

# Test Jenkins proxy
curl -vk https://server.domain.com/jenkins

# Test SonarQube proxy
curl -vk https://server.domain.com/sonar

# Check headers
curl -I https://server.domain.com/jenkins
  • Missing nocanon flag in ProxyPass directives
  • Forgetting to set X-Forwarded-Proto header
  • Incorrect context paths in Jenkins/SonarQube configuration
  • Firewall blocking internal communication between Apache and services

For high-traffic installations, consider these optimizations:

# Keepalive settings
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

# Compression
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript

After setting up SSL on my Apache server hosting both Jenkins (8080) and SonarQube (9000), Jenkins started throwing the dreaded "reverse proxy setup is broken" warning. The issue manifests specifically when the ReverseProxySetupMonitor detects URL scheme mismatches:

404 http://server.domain.com/jenkins/manage vs. https://server.domain.com/jenkins/manage

The core issue lies in how Apache handles header rewriting for HTTPS proxied connections. Jenkins expects all URLs to maintain HTTPS scheme consistency, but the current configuration doesn't properly rewrite:

  • Location headers
  • Content-Location headers
  • HTML base tags

Here's the corrected Apache configuration with key improvements:


  ServerName server.domain.com
  
  SSLEngine on
  SSLCertificateFile /etc/ssl/certs/server.crt
  SSLCertificateKeyFile /etc/ssl/private/server.key

  # Jenkins Proxy Configuration
  ProxyPass /jenkins http://localhost:8080/jenkins nocanon
  ProxyPassReverse /jenkins http://localhost:8080/jenkins
  
  # Critical fixes for HTTPS headers
  ProxyPassReverse /jenkins https://server.domain.com/jenkins
  RequestHeader set X-Forwarded-Proto "https"
  RequestHeader set X-Forwarded-Port "443"
  
  # SonarQube Configuration  
  ProxyPass /sonar http://localhost:9000/sonar nocanon
  ProxyPassReverse /sonar http://localhost:9000/sonar
  ProxyPassReverse /sonar https://server.domain.com/sonar
  
  # Additional security hardening
  AllowEncodedSlashes NoDecode
  ProxyRequests Off
  ProxyPreserveHost On
  
    Require all granted
  
  
  # Required for Jenkins URL rewriting
  Header edit Location ^http://server.domain.com https://server.domain.com

1. Header Rewriting: The Header edit directive ensures all Location headers get proper HTTPS conversion.

2. Forwarded Protocol Headers: Setting X-Forwarded-Proto explicitly tells Jenkins about the HTTPS connection.

3. Modern Access Control: Replaced deprecated Order/Allow syntax with Apache 2.4 Require directives.

After applying changes:

sudo apachectl configtest
sudo systemctl reload apache2

Test with:

curl -vk https://server.domain.com/jenkins
curl -vk https://server.domain.com/sonar

For production environments, consider:

# Enable HSTS
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

# Modern SSL configuration
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5