≡ Menu

nginx: Send HTTP User Agent Requests To Specific Backend Server

I've tons of images, css and javascript hosted at backend server IP 192.168.1.5 and 192.168.1.6. How do I make sure nginx reverse proxy load balancer always send all http_user_agent requests coming from "Mozilla" to server 192.168.1.5 and MSIE to server 192.168.1.6 only?

Nginx web server does support if conditional which can redirect and/or select configuration depending on variables. In this case you need to use the variable called $http_user_agent which can be used to retrieve information about the users browser, version and operating system. The syntax is as follows:

if ( condition ){
  do_something
}
if ( $http_user_agent = "wget" ){
   do_something
}
if ( $http_user_agent ~ MSIE ){
   return 403;
}
 

The if directive is used to checks the truth of a condition. If the condition evaluates to true, then the code indicated in the curly braces is carried out and the request is processed in accordance with the configuration within the following block. Configuration inside directive if is inherited from the previous level. You can use the name of variable or any string starting with "0" in condition. Also,

  1. The comparison of variable with the line with using the = and != operators;
  2. Pattern matching with regular expressions using the symbols ~* and ~:
  3. ~ is case-sensitive match
  4. ~* specifies a case-insensitive match (firefox matches FireFox)
  5. !~ and !~* mean the opposite, "doesn't match"
  6. checking for the existence of a file using the -f and !-f operators;
  7. checking existence of a directory using the -d and !-d operators;
  8. checking existence of a file, directory or symbolic link using the -e and !-e operators;
  9. checking whether a file is executable using the -x and !-x operators.
  10. Parts of the regular expressions can be in parentheses, whose value can then later be accessed in the $1 to $9 variables.

Examples

Edit /usr/local/nginx/conf/nginx.conf, enter:
# vi /usr/local/nginx/conf/nginx.conf
Setup upstream servers:

 
upstream myproxybackend  {
       server 192.168.1.1;
       server 192.168.1.2;
       server 192.168.1.3;
       server 192.168.1.4;
}
 
upstream msiebackend  {
       server 192.168.1.6;
}
 
upstream mozillabackend  {
       server 192.168.1.5;
}
 

Update config as follows:

 
server {
      access_log  logs/access.log;
      error_log   logs/error.log;
      index       index.html;
      listen      202.54.1.5:80 default;
      root        /usr/local/nginx/html;
      server_name example.com www.example.com 0.example.com;
 
 
     ## PROXY - Web
      location / {
        proxy_pass  http://myproxybackend;
        if ($http_user_agent ~ MSIE ) {
              proxy_pass  http://msiebackend;
        }
        if ($http_user_agent ~ Mozilla ) {
              proxy_pass  http://mozillabackend;
        }
 
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
 
        ...
         ..
}
 

Finally restart / reload new changes:
# /usr/local/nginx/sbin/nginx -s reload

Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 2 comments… add one }

  • GuTi November 16, 2010, 7:43 am

    Maybe it shout be the follow configuration?
    ## PROXY – Web
    location / {
    if ($http_user_agent ~ MSIE ) {
    proxy_pass http://msiebackend;
    }
    if ($http_user_agent ~ Mozilla ) {
    proxy_pass http://mozillabackend;
    }
    proxy_pass http://myproxybackend;
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;


    ..
    }

  • Glenn June 21, 2011, 1:33 pm

    Quite an interesting way to go about this using this nginx approach. I wonder does the frontend server cache the requests PER upstream server or doesn’t it cache anything at all. Short but nice to get inspired.

Leave a Comment