Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have Nginx setup as a reverse proxy behind 2 different load balancers. My application server backend expects the header CF-Visitor: {"scheme":"https"} when the visitor connects over SSL. In both cases, SSL termination happens at the load balancers, which then proxy the traffic to Nginx over port 80.

Load Balancer A sends that header and everything works as expected. Load Balancer B sends the header X-Forwarded-Proto: https.

I'm trying to configure Nginx to set the CF-Visitor header to the correct value regardless of the load balancer that the traffic comes through.

Ideally, I would be able to conditionally set the header in my Nginx location block. However, I've read about the evils of if and so far the only thing I've been able to come up with is using the map directive.

http block

# set the value of $x_scheme based on $http_cf_visitor
# default to #http_x_forwarded_proto if the header isn't set
map $http_cf_visitor $x_scheme {
    '{"scheme":"http"}'     http;
    '{"scheme":"https"}'    https;
    default $http_x_forwarded_proto;
}

# using the value set above in $x_scheme, normalize into a variable
map $x_scheme $x_scheme_json {
    http    '{"scheme":"http"}';
    https   '{"scheme":"https"}';
    default      "NO-MATCH";
}

location block

proxy_set_header       CF_VISITOR $x_scheme_json;

This seems to work for traffic from Load Balancer B. However traffic from Load Balancer A ends up with a comma seperated header being passed to the backend app servers.

HTTP_CF_VISITOR: "{"scheme":"http"},{"scheme":"http"}"
# What I need is HTTP_CF_VISITOR: "{"scheme":"http"}"

How can I make Nginx set the value/overwrite the existing header value instead of appending the string?

Also -- is this the correct/ideal way to configure this behavior? It feels a little clunky. It would be nice to have all this logic contained in a single server or location block instead of in the http block.

NOTE: Part of my inspiration for this approach was from this forum post: http://forum.nginx.org/read.php?2,198861,198949

share|improve this question
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.