Search code examples
httphttpssonarqubereverse-proxyhaproxy

SonarQube - HAProxy HTTPs Invalid Header


I have all of my development systems stood up behind haproxy (everything dockerized) and I can access my Jenkins / Gitlab / and Sonar but not Nexus. After looking at the docker logs for the nexus container, I can see it is getting the requests, however it is saying the forward header is invalid. My goal is to have haproxy use https and the apps behind haproxy only use http. That way the apps have https by the proxy but don't need the configurations themselves.

Here is the log message:

nexus_1     | 2018-03-23 17:35:08,874-0500 WARN  [qtp1790585161-43] *SYSTEM 
org.sonatype.nexus.internal.web.HeaderPatternFilter - rejecting request 
from 98.192.146.97 due to invalid header 'X-Forwarded-Proto: \http'

Here is my haproxy config for nexus:

frontend www-https
    bind *:443 ssl crt /etc/haproxy/certs/server.pem
    reqadd X-Forwarded-Proto:\http
    acl jenkins hdr_beg(host) -i jenkins.
    acl nexus hdr_beg(host) -i nexus.
    acl git hdr_beg(host) -i git.
    acl sonar hdr_beg(host) -i sonar.

    use_backend jenkins if jenkins
    use_backend nexus if nexus
    use_backend git if git
    use_backend sonar if sonar

backend nexus
    mode http
    balance roundrobin
    option forwardfor
    http-request set-header X-Forwarded-Port %[dst_port]
    server nexus1 nexus:8081 check

I had this line in originally which exists in all my other apps:

    http-request add-header X-Forwarded-Proto https if { ssl_fc }

But when that is enabled Sonar throws this error:

nexus_1     | 2018-03-23 23:54:38,132-0500 WARN  [qtp1790585161-43] 
*SYSTEM org.sonatype.nexus.internal.web.HeaderPatternFilter - rejecting 
request from 98.192.146.97 due to invalid header 'X-Forwarded-Proto: 
\http,https'

Is there something special nexus requires to work with haproxy?

EDIT: I have confirmed that if "docker-compose exec haproxy sh" I can curl "nexus:8081" and it gives me the index.html. So I know the container can correctly communicate with the nexus container.


Solution

  • http-request add-header X-Forwarded-Proto https if { ssl_fc }
    

    This is essentially wrong in most cases. Wherever you are using it, you may need to change it, because you don't want to add this header -- you want to set it. You need your version to overwrite anything that may be in the incoming request.

    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    

    Adding a header preserves previous values, including the one you are adding incorrectly with this line:

    reqadd X-Forwarded-Proto:\http
    

    You either need a space after that \ or you need to remove the \ entirely... but really, this would optimally be done with http-request set-header since this is operationally preferred over req* actions.

    But it really doesn't make obvious sense to have that line, anyway, because your frontend uses bind *:443 ssl, so ssl_fc is always true in this frontend. Hence, your frontend could simply set the correct header.

    http-request set-header X-Forwarded-Proto https