Forum: NGINX drupal+nginx: this works => using try_files

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mark A. (Guest)
on 2009-03-17 11:47
(Received via mailing list)
The following has been tested in Nginx  0.7.42 + Drupal 6.10 + Ubuntu
8.10.

M.


The tests included calls to:
# http://clinica.0/index.php    # ok
# http://clinica.0      # ok
# http://www.clinica.0      # ok
# http://clinica.0/user/password  # ok
# http://clinica.0/test      # Page not found
# http://nonexistant.clinica.0/    # Address Not Found
# http://clear.clinica.0/    # redirect to [clear.]clinica.0
#
# http://clinica.0/scripts/drupal.sh    # 403 Forbidden
# http://clinica.0/scripts/code-style.pl  # 403 Forbidden
# http://clinica.0/sites/default/settings.php  # 403 Forbidden
# http://clinica.0/sites/all/README.txt    # show README.txt
# http://clinica.0/sites/default/files/README.txt # show (*1)
# http://clinica.0/nice ports,/Trinity.txt.bak  # Page not found
#
# http://www.clinica.0/benchtest.php  # show a timed phpinfo (*2)
# http://www.clinica.0/somefile.php  # No input file specified.
# http://127.0.0.1/      # redirect to clinica.0
#
#(*1) this README.txt is a copy made from sites/all/README.txt
#(*2) see at the end of this email how benchtest.php was created

The file bellow does not fully take care of:
   ^/system/test/(.*)$ => /index.php?q=system/test/$1,
   ^/([^.?]*)\?(.*)$ => /index.php?q=$1&$2,
   ^/([^.?]*)$ => /index.php?q=$1
   ^/search/node/(.*)$" => /index.php?q=search/node/$1


### drupal-cgm file follows:
# --- cut here ---
# nginx - /etc/nginx/sites-available/drupal-cgm
#
server {
  listen 80 default;
  server_name _; # non defined server
  return 444; # silently drop request
}
server {
  listen clinica.0:80;
  server_name www.clinica.0;
  rewrite ^(.*) http://clinica.0$1 permanent;
}
server {
  listen clinica.0:80;
  server_name clinica.0;

  access_log /var/log/nginx/drupal-cgm.access.log;
  error_log /var/log/nginx/drupal-cgm.error.log;

  root /var/www/drupal-cgm;

  # restrict request methods to: GET|HEAD|POST
  if ( $request_method !~ ^(GET|HEAD|POST)$ ) {
    return 444;
    break;
  }

  # hide drupal system files
  location ~*
((cron\.php|settings\.php)|\.(htaccess|engine|inc|info|install|module|profile|pl|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(Entries.*|Repository|Root|Tag|Template))$
{
    deny all;
  }

#  # rewrite domain name without the leading www.
#  if ($host ~* ^www\.(.*)) {
#    set $host_without_www $1;
#    # bellow $1 contains '/foo', not 'www.mydomain.com/foo'
#    rewrite ^(.*)$ http://$host_without_www$1 permanent;
#  }

  location / {
    index index.php index.html;
    try_files $uri $uri/ @drupal;
  }

  location @drupal {
    # clean url rewrite for Drupal
    rewrite ^/(.*)$ /index.php?q=$1 last;
    #rewrite ^/(\w*)/(.*)$ /$1/index.php?q=$2 last;
  }

  location ~ \.php$ {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass unix:/tmp/php-fastcgi.socket;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }
}
# --- cut here ---


### benchtest.php file follows:
# --- cut here ---
sudo tee /var/www/drupal-cgm/benchtest.php <<-\EOA
<?php
// /var/www/drupal-cgm/benchtest.php
$start = microtime(true);
ob_start(); //Turn on output buffering
phpinfo();
$info = ob_get_clean();
echo "phpinfo() run time:  ";
printf("%0.1f ms\n", (microtime(true)-$start)*1000);
echo $info;
ob_end_flush();
?>
EOA
# --- cut here ---
mike (Guest)
on 2009-03-17 19:23
(Received via mailing list)
2009/3/17 Mark A. <removed_email_address@domain.invalid>:
> The following has been tested in Nginx  0.7.42 + Drupal 6.10 + Ubuntu 8.10.
>
> M.
>

Seems to me that

a) drupal should not include scripts/etc. that should not be ran via
the web -in- the webroot, or
b) they should be localized to only one directory

>        # hide drupal system files
>        location ~*
> 
((cron\.php|settings\.php)|\.(htaccess|engine|inc|info|install|module|profile|pl|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(Entries.*|Repository|Root|Tag|Template))$
> {
>                deny all;
>        }

That is ugly as sin to me, and could change at any given time. Is
there a true need to protect all of these? Is it only a specific
folder?You could always use location /folder { internal; } then too.

you can add these to fastcgi_params, no need for repetition:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;

I'm just trying to approach this from a purely KISS perspective. I
hate seeing denormalized/excessive configs. Especially since I host a
drupal instance I want the cleanest possible ;)

and actually, since drupal has nothing really specific besides a
single line, you could get away with:

try_files $uri $uri/ /index.php?q=$request_uri;            ($uri might
work too - might warrant testing the two, I'm trying to find the
difference between the two on the wiki)

I also have an open question to the list about using try_files with
multiple prefixes... i.e.:

location /drupal {
 try_files $uri $uri/ /drupal/index.php?q=$request_uri
}

# wordpress, for example
location /blog {
 try_files $uri $uri/ /blog/index.php?q=$request_uri
}

I don't really like the current wiki examples either. It's got a mix
of parsing php and try_files and other wacky stuff that will just lead
to confusion.
mike (Guest)
on 2009-03-17 19:46
(Received via mailing list)
On Tue, Mar 17, 2009 at 10:15 AM, mike <removed_email_address@domain.invalid> 
wrote:


> try_files $uri $uri/ /index.php?q=$request_uri;            ($uri might
> work too - might warrant testing the two, I'm trying to find the
> difference between the two on the wiki)

found it.

http://wiki.nginx.org/NginxHttpCoreModule

$document_uri
The same as $uri.

$uri
This variable is equal to current URI in the request, it can differ
from initial, for example by internal redirects, or with the use of
index it is file with internal redirects.

So it is the same. Could just keep it $uri then for simplicity. $uri
$uri/ /index.php?q=$uri
Mark A. (Guest)
on 2009-03-17 22:05
(Received via mailing list)
mike wrote:
> a) drupal should not include scripts/etc. that should not be ran via
> the web -in- the webroot, or
> b) they should be localized to only one directory

Those were/are options of the Drupal Development Team.

>> 
((cron\.php|settings\.php)|\.(htaccess|engine|inc|info|install|module|profile|pl|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(Entries.*|Repository|Root|Tag|Template))$
> That is ugly as sin to me, and could change at any given time. Is
> there a true need to protect all of these?

Yes

> Is it only a specific folder?

No.

> You could always use location /folder { internal; } then too.

That is an interesting idea, but the level of complexity would be quite
the same.

> you can add these to fastcgi_params, no need for repetition:
> fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
> fastcgi_index index.php;

In what way would that contribute to reduce complexity, or better
document the procedure?

> and actually, since drupal has nothing really specific besides a
> single line,

On the contrary, it has.

> you could get away with:
> try_files $uri $uri/ /index.php?q=$request_uri;

That does not work. You could at least have tried it...

> I don't really like the current wiki examples either. It's got a mix
> of parsing php and try_files and other wacky stuff that will just lead
> to confusion.

I am sure that you will provide a couple of cleaner examples to help us
all.


M.
mike (Guest)
on 2009-03-18 00:30
(Received via mailing list)
On Tue, Mar 17, 2009 at 12:57 PM, Mark A. <removed_email_address@domain.invalid>
wrote:
> mike wrote:
>>
>> a) drupal should not include scripts/etc. that should not be ran via
>> the web -in- the webroot, or
>> b) they should be localized to only one directory
>
> Those were/are options of the Drupal Development Team.

I've got a bone to pick ...

> That is an interesting idea, but the level of complexity would be quite the
> same.

Ideally it would be

location /drupal {
 try_files $uri $uri/ /drupal/index.php?q=$uri;
}

location /drupal/protected {
 internal;
}

pretty simple (ideally)

> In what way would that contribute to reduce complexity, or better document
> the procedure?

Both. Why have duplication in configuration files (especially common
things such as that) if unnecessary?

> On the contrary, it has.

location @drupal just has the rewrite to /index.php?q=$uri

This was what I meant. The other "block these scripts" stuff... I
would like to pick a bone with the drupal folks for not localizing
those into at least a single directory.

>> you could get away with:
>> try_files $uri $uri/ /index.php?q=$request_uri;
>
> That does not work. You could at least have tried it...

I swear Igor said it should work.

> I am sure that you will provide a couple of cleaner examples to help us all.

This sounds kind of sarcastic; but yes, I would like to. A lot of
people's nginx configurations they post when they have questions are
littered with extra stuff which just leads to confusion or
confliction.
This topic is locked and can not be replied to.