1

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
    # ------------------------------------------------------------------------
}

4 Answers 4

1

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;
}
1
  • 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. Sep 28, 2011 at 14:04
1

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;
    }
  }
}
0

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;
    }

}
8
  • ok, now I am getting infinite redirect errors. I will make some edits above Sep 28, 2011 at 3:37
  • Put the domain.com into a separate server context.
    – quanta
    Sep 28, 2011 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? Sep 28, 2011 at 3:43
  • ok, i just added the full code sample, thoughts? Sep 28, 2011 at 3:49
  • i found the solution, but will have to wait 6 hours to post it Sep 28, 2011 at 4:46
0

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;
    }
  }
}
9
  • 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, 2011 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. Sep 29, 2011 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, 2011 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, 2011 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. Sep 29, 2011 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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