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 haven't been able to find a question that matches my particular scenario so, hopefully this isn't a duplicate, if so I apologize.

I have 4 web servers behind a load balancer. I want only www.mydomain.com, 123.123.123.123 (my server's public IP address) and 456.456.456.456 (my server's internal network IP address) to work, anything else should redirect to www.mydomain.com.

Why: I need to send everything to www.mydomain.com because we have had people setting up other domains (www.otherdomain.com) pointing to our IP address, so it acts like a mirror of our site. We don't know why they do this but Google starts crawling their site as if it was a different site entirely and it causes trouble. I need to allow the server's IP addresses through because we use that for internal server chatter via a custom API, to get around the load balancer.

The only solutions I've been able to find either redirect everything INCLUDING the IP addresses to www.mydomain.com, or they end up redirecting nothing.

Here is my current config (truncated for simplicity):

server {
    listen 80;
    server_name www.mydomain.com 123.123.123.123 456.456.456.456;
}

server {
    listen 80 default;
    server_name _;
    rewrite ^ http://www.mydomain.com$request_uri?;
}

Expected: Requests to the correct domain, or either IP address, match the first rule. All other requests match second rule and get redirected. Actual: Nothing gets redirected at all, I'm assuming because NGINX is just matching the IP address regardless of domain to the first rule. It could also possibly be that the load balancer is messing it up? I am using a Rackspace cloud load balancer, if that helps.

I've also tried this config:

server {
    listen 80 default;
    server_name www.mydomain.com;
}

server {
    listen 80;
    server_name _;
    rewrite ^ http://www.mydomain.com$request_uri?;
}

This has the same results as the previous. Nothing seems to get redirected.

Any ideas how I can fix this?

Thanks for your help!

share|improve this question
add comment

2 Answers 2

up vote 1 down vote accepted

I got it working. Sameer was close but I'm not sure he understood my exact question. This is the solution to my problem;

server {
    listen 80;
    server_name www.mydomain.com 123.123.123.123 456.456.456.456;
}

server {
    listen 80 default_server;
    server_name _;
    rewrite ^ http://www.mydomain.com$request_uri?;
}

With the above, you can load the site via www.mydomain.com, or the direct internal and public IP addresses, but if you try to load it any other way you get redirected.

Oddly enough... This is the first example I tried above. I don't know why it didn't work then and it working now. Perhaps because the "listen 80 default" has been deprecated in favor of "listen 80 default_server". Or perhaps I confused things will testing across all 4 nodes. Either way, it seems to be working right now with this definition!

share|improve this answer
add comment
server {
    listen 456.456.456.456:80;
    server_name mydomain.com;
    # I am more lenient with internal and this will bypass the LB
}

server {
    listen 80 default;
    server_name _;
    if ($host != www.mydomain.com){
        rewrite ^ http://www.mydomain.com$request_uri?;
    }
}

If the internal and external are not different then you can do away with the first server section. Ideally you should be only concerned about the $host header, which is a standard HTTP header. With HTTP loadbalancer you should be using the IP of the load balancer and not the public IP of your machine because that will bypass the LB.

share|improve this answer
    
This config is going on a web node, not on the load balancer. The load balancer is separate, my need for accessing the site via internal IPs is strictly for passing information around among the four web nodes internally via an http api. What I was hoping was that the "listen 456.456.456.456:80" part would be part of the www.mydomain.com definition. Perhaps I can do this? server { listen 80 default; server_name _; if ($host != www.mydomain.com && $host != 456.456.456.456 ){ rewrite ^ mydomain.com$request_uri?; } } –  Matt Dec 27 '12 at 9:41
    
You can go with the rewrite rule. In nginx you can't have AND in IF. To achieve this functionality following instruction from this blog. rosslawley.co.uk/2010/01/nginx-how-to-multiple-if-statements –  Sameer Dec 29 '12 at 11:13
add comment

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.