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 am trying to rerwrite any sub domains outside of an approved list i.e. (dev,test,home).domain.com

here is what I am working with now:

#rewrite all sub domains
 if ($host ~* "^([^.]+(\.[^.]+)*)\.domain.com$"){
        rewrite ^(.*)$ http://domain.com$1 permanent;
        break;
    }

the problem is it rewrites all sub domains. I have a solution in apache but I am having issues converting it. apache version:

RewriteCond %{HTTP_HOST} !^(dev|test|local\.blog)\.domain\.me$ [NC]

Updates:

server {
    listen 80;
  server_name *.domain.com domain.com;
  root /srv/www/www.domain.com;
  access_log /srv/logs/www_domain.com.access;
  error_log /srv/logs/www_domain.com.error error;

  error_page 400 401 402 403 404 500 502 503 504 /error.htm;
  location  /error.htm {
    internal;
  }
  # ------------------------------------------------------------------------  
  # remove all sub domains and www
  if ($host !~* (dev|test|prod)\.domain\.com) {
            rewrite ^ http://domain.com$request_uri permanent;
    }
  # ------------------------------------------------------------------------
  location / {
    index index.html index.php index.htm;
    location ~* ^.*\.php$ {
      include        fastcgi_params;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
      }
  }
  # ------------------------------------------------------------------------
  # serve favicon
  location = /favicon.ico { 
    log_not_found off;
    access_log off;
  }
    # ------------------------------------------------------------------------
  # process robots.txt
  location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
  }
    # ------------------------------------------------------------------------
  # serve static files directly
  location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
    access_log off;
    expires max;
  }
    # ------------------------------------------------------------------------
  # block access to .ht files
  location ~ /\.ht {
    deny  all;
  }
  # ------------------------------------------------------------------------
    # short cuts
    if ($uri ~* "/login") {
        rewrite ^/login(/.*)? /wp-admin$1;
    }
    # ------------------------------------------------------------------------
    # BEGIN W3TC Browser Cache
    gzip on;
    gzip_types text/css application/x-javascript text/richtext image/svg+xml text/plain    text/xsd text/xsl text/xml image/x-icon;
    location ~ \.(css|js)$ {
            expires 31536000s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
            add_header X-Powered-By "W3 Total Cache/0.9.2.3";
    }
    location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
            expires 180s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=180, public, must-revalidate, proxy-revalidate";
            add_header X-Powered-By "W3 Total Cache/0.9.2.3";
    }
    location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ {
            expires 31536000s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
            add_header X-Powered-By "W3 Total Cache/0.9.2.3";
    }
    # END W3TC Browser Cache
    # BEGIN W3TC Skip 404 error handling by WordPress for static files
    if (-f $request_filename) {
            break;
    }
    if (-d $request_filename) {
            break;
    }
    if ($request_uri ~ "(robots\.txt|sitemap(_index|[0-9]+)?\.xml(\.gz)?)") {
            break;
    }
    if ($request_uri ~* \.(css|js|html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$) {
            return 404;
    }
    # END W3TC Skip 404 error handling by WordPress for static files
    # ------------------------------------------------------------------------
}
share|improve this question

4 Answers 4

Looks like you must use negative look-behind:

server {
    listen 80;
    server_name *.domain.com;
    ...

    if ($host ~* (?<!(dev|test|local))\.domain\.com) {
        rewrite ^ http://domain.com$request_uri permanent;
    }

}
share|improve this answer
    
ok, now I am getting infinite redirect errors. I will make some edits above –  chrishough Sep 28 '11 at 3:37
    
Put the domain.com into a separate server context. –  quanta Sep 28 '11 at 3:41
    
hmmmm...not sure if I can do that, I have an entire grouping of other rules nested inside of the same server command, i would have to duplicate all of those right? –  chrishough Sep 28 '11 at 3:43
    
ok, i just added the full code sample, thoughts? –  chrishough Sep 28 '11 at 3:49
    
i found the solution, but will have to wait 6 hours to post it –  chrishough Sep 28 '11 at 4:46

Check nginx documentation how to convert apache rewrite rules to nginx.

server {
  listen 80;
  server_name domain.com ~(dev|test|local)\.domain\.com$;

  # ... your rules here ... 

}

server {
  listen 80 default_server;
  server_name *.domain.com;
  rewrite ^ http://domain.com$request_uri? permanent;
}
share|improve this answer
    
check out the answer I just posted which works correctly, do you have any recommendations to perfect it further? thank you for your help bro. –  chrishough Sep 28 '11 at 14:04

after locating a killer tool : http://www.anilcetin.com/convert-apache-htaccess-to-nginx/ I was able to rebuild my nginx vhost config to work correctly, however, I am open to suggestions , modifications. This is a multi host server, and individual host file in sites-available for each host

server {
  listen 80;
  server_name *.domain.com domain.com;
  root /srv/www/www.domain.com;
  access_log /srv/logs/www_domain.com.access;
  error_log /srv/logs/www_domain.com.error error;

  error_page 400 401 402 403 404 500 502 503 504 /error.htm;
  location  /error.htm {
    internal;
  }
  # ------------------------------------------------------------------------
  #RewriteCond %{HTTP_HOST} !^(dev|test|prod)\.domain\.com$ [NC]
  #RewriteCond %{HTTP_HOST} ^([^.]+)\.domain\.com$
  #RewriteRule ^(.*)$ http://domain.com/$1 [R=301,L]
  # all sub domains and www
    if ($http_host !~* "^(dev|test|prod)\.domain\.com$"){
        set $rule_0 1$rule_0;
    }
    if ($http_host ~ "^([^.]+)\.domain\.com$"){
        set $rule_0 2$rule_0;
    }
    if ($rule_0 = "21"){
        rewrite ^/(.*)$ http://domain.com/$1 permanent;
        break;
    }
  # ------------------------------------------------------------------------
  location / {
    index index.html index.php index.htm;
    location ~* ^.*\.php$ {
      include        fastcgi_params;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
      }
  }
  # ------------------------------------------------------------------------
  # serve favicon
  location = /favicon.ico { 
    log_not_found off;
    access_log off;
  }
    # ------------------------------------------------------------------------
  # process robots.txt
  location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
  }
    # ------------------------------------------------------------------------
  # serve static files directly
  location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
    access_log off;
    expires max;
  }
    # ------------------------------------------------------------------------
  # block access to .ht files
  location ~ /\.ht {
    deny  all;
  }
  # ------------------------------------------------------------------------
    # short cuts
    if ($uri ~* "/login") {
        rewrite ^/login(/.*)? /wp-admin$1;
    }
    # ------------------------------------------------------------------------
    # BEGIN W3TC Browser Cache
    gzip on;
    gzip_types text/css application/x-javascript text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
    location ~ \.(css|js)$ {
            expires 31536000s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
            add_header X-Powered-By "W3 Total Cache/0.9.2.3";
    }
    location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
            expires 180s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=180, public, must-revalidate, proxy-revalidate";
            add_header X-Powered-By "W3 Total Cache/0.9.2.3";
    }
    location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ {
            expires 31536000s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
            add_header X-Powered-By "W3 Total Cache/0.9.2.3";
    }
    # END W3TC Browser Cache
    # BEGIN W3TC Skip 404 error handling by WordPress for static files
    if (-f $request_filename) {
            break;
    }
    if (-d $request_filename) {
            break;
    }
    if ($request_uri ~ "(robots\.txt|sitemap(_index|[0-9]+)?\.xml(\.gz)?)") {
            break;
    }
    if ($request_uri ~* \.(css|js|html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$) {
            return 404;
    }
    # END W3TC Skip 404 error handling by WordPress for static files
    # ------------------------------------------------------------------------
}

default server configuration:

server {
  listen 80 default;
  server_name localhost;
  root /srv/www/www.default.site;
  access_log /srv/logs/localhost.access;
  error_log /srv/logs/localhost.error error;

  error_page 400 401 402 403 404 500 502 503 504 /error.htm;
  location  /error.htm {
    internal;
  }

  location / {
    index index.html index.php index.htm;
    location ~* ^.*\.php$ {
        if (!-f $document_root/$fastcgi_script_name){
            return 404;
      }
      include        fastcgi_params;
      fastcgi_pass   127.0.0.1:9000;
      fastcgi_index  index.php;
      fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
      fastcgi_intercept_errors on;
    }
  }
}
share|improve this answer
    
Please check link to nginx documentation I provided above. Using if's to select http_host "is a wrong, cumbersome, and ineffective way" (quote from documentation). Also check wiki.nginx.org/IfIsEvil –  AlexD Sep 28 '11 at 15:40
    
thank you for sending me the site, i was there way before posting to this thread. as stated this is a multi host server so your solution will not work as many domains hit this box, in apache it would be 1 vhost per site with .htaccess rules. so... I have to use 1 file from what i can see. can you post an extended solution using what I have provided? is that possible. I read that using "if" is not ideal, but it works correctly. –  chrishough Sep 29 '11 at 2:55
    
Please, read documentation for nginx listen and server_name directives wiki.nginx.org/HttpCoreModule#server_name. My solution will work with same set of domain names as yours: *.domain.com and domain.com. And it uses one configuration file. –  AlexD Sep 29 '11 at 5:28
    
If you want to use multiple 2nd level domains like domain.com, domain2.com etc, all you need is to remove default_server option from listen directive or add another server { } block with listen 80 default_server and server_name _. –  AlexD Sep 29 '11 at 5:34
    
@Alex I added my default host configuration. this box hosts 1-x sites, right now this default captures all domains not enabled. all of the other active domains have their own hosts file like the solution posted. do you think this has been setup correctly? I am new to nginx so this process has really helped me. –  chrishough Sep 29 '11 at 16:35
up vote 0 down vote accepted

based on @AlexD reply I have updated my solution. if you have any other suggestions fellow geeks, let me know.

server {
  listen 80;
  server_name *.noconformity.co;
  rewrite ^ http://noconformity.co$request_uri? permanent;
}
server {
  listen 80;
  server_name noconformity.co ~(sub1|sub2)\.noconformity\.co$;
  root /srv/www/www.noconformity.co;
  access_log /var/log/nginx-hosts/www_noconformity.co.access;
  error_log /var/log/nginx-hosts/www_noconformity.co.error error;

  error_page 400 401 402 403 404 500 502 503 504 /error.htm;
  location  /error.htm {
    internal;
  }
  # ------------------------------------------------------------------------
  location / {
    index index.html index.php index.htm;
    location ~* ^.*\.php$ {
      include        fastcgi_params;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
      }
  }
  # ------------------------------------------------------------------------
  # serve favicon
  location = /favicon.ico { 
    log_not_found off;
    access_log off;
  }
    # ------------------------------------------------------------------------
  # process robots.txt
  location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
  }
    # ------------------------------------------------------------------------
  # serve static files directly
  location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
    access_log off;
    expires max;
  }
    # ------------------------------------------------------------------------
  # block access to .ht files
  location ~ /\.ht {
    deny  all;
  }
  # ------------------------------------------------------------------------
    # short cuts
    if ($uri ~* "/login") {
        rewrite ^/login(/.*)? /wp-admin$1;
    }
    # ------------------------------------------------------------------------
    # BEGIN W3TC Browser Cache
    gzip on;
    gzip_types text/css application/x-javascript text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
    location ~ \.(css|js)$ {
            expires 31536000s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
            add_header X-Powered-By "W3 Total Cache/0.9.2.3";
    }
    location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
            expires 180s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=180, public, must-revalidate, proxy-revalidate";
            add_header X-Powered-By "W3 Total Cache/0.9.2.3";
    }
    location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ {
            expires 31536000s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
            add_header X-Powered-By "W3 Total Cache/0.9.2.3";
    }
    # END W3TC Browser Cache
    # BEGIN W3TC Skip 404 error handling by WordPress for static files
    if (-f $request_filename) {
            break;
    }
    if (-d $request_filename) {
            break;
    }
    if ($request_uri ~ "(robots\.txt|sitemap(_index|[0-9]+)?\.xml(\.gz)?)") {
            break;
    }
    if ($request_uri ~* \.(css|js|html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$) {
            return 404;
    }
    # END W3TC Skip 404 error handling by WordPress for static files
    # ------------------------------------------------------------------------
}

this is the default website:

server {
  listen 80 default_server;
  server_name localhost;
  root /srv/www/www.default.site;
  access_log /var/log/nginx-hosts/default.access;
  error_log /var/log/nginx-hosts/default.error error;

  error_page 400 401 402 403 404 500 502 503 504 /error.htm;
  location  /error.htm {
    internal;
  }

  location / {
    index index.html index.php index.htm;
    location ~* ^.*\.php$ {
        if (!-f $document_root/$fastcgi_script_name){
            return 404;
      }
      include        fastcgi_params;
      fastcgi_pass   127.0.0.1:9000;
      fastcgi_index  index.php;
      fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
      fastcgi_intercept_errors on;
    }
  }
}
share|improve this answer

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.