4

I'm trying to achieve following thing. I've main website under domain root directory. It's working fine. i.e PHP files are executed. After some time I've added "auth" directory with basic HTTP authentication. Next, I uploaded PHP program into "auth" directory, but PHP files are downloading instead of executing.

  • domain.name/test.php -> executing
  • domain.name/sub/file.php -> executing
  • domain.name/auth/protected.php -> downloading instead of executing

Here is sites-available conf

server {
    charset utf-8;

    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;
    server_name xxx.com;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        # try_files $uri $uri/ =404;
        try_files $uri $uri/ /index.php?$args;
    }

    location ^~ /auth {
        auth_basic "Restricted Content";
        auth_basic_user_file /var/www/html/auth/.htpasswd;
    }

    location ^~ /protected {
        deny all;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;

        # With php5-fpm:
        fastcgi_pass unix:/var/run/php5-fpm.sock;
    }

    location ~ /\.(ht|git|svn) {
        deny all;
    }
}

Currently I've following solution, but I believe it's not a right way.

    location ^~ /auth {
        auth_basic "Restricted Content";
        auth_basic_user_file /var/www/html/auth/.htpasswd;
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;

            # With php5-fpm:
            fastcgi_pass unix:/var/run/php5-fpm.sock;
        }
    }

Following solution doesn't work

        location ^~ /auth {
                auth_basic "Restricted Content";
                auth_basic_user_file /var/www/html/auth/.htpasswd;
                try_files $uri @php-fpm;
        }

        location @php-fpm {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
        }
  • 1
    What did you do to solve this? – gxx May 03 '16 at 14:48
  • 1
    Currenty solution is to add sub location: location ^~ /auth { auth_basic "Restricted Content"; auth_basic_user_file /var/www/html/auth/.htpasswd; location ~ \.php$ { include snippets/fastcgi-php.conf; # With php5-fpm: fastcgi_pass unix:/var/run/php5-fpm.sock; } } – Andrey Andreevsky May 03 '16 at 15:02
  • Why do you think this is not the right way? (Besides: Maybe use `try_files` as you did in `/` ...) – gxx May 03 '16 at 15:19
  • 1
    Not working. `try_files $uri $uri/ =404;` – Andrey Andreevsky May 03 '16 at 16:02
  • Actually do you know what the code you wrote above does, or are you just doing copy / paste? Hint 1: Try `try_files $uri @php-fpm-backend;`. Hint 2: Set up a location named `@php-fpm-backend { ... }` and put your `fastcgi_pass` inside there. – gxx May 03 '16 at 16:46
  • I updated my question. Still doesn't work. – Andrey Andreevsky May 04 '16 at 07:39

1 Answers1

6

Had the same issue!

Found the answer here, http://www.ceus-now.com/nginx-password-protect-directory-downloads-source-code/

Because we are adding ^~ we are leaving behind some other settings (not sure why we need to add this but it was the only way to get it to actually pull up the authentication :( )

include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/lib/php5-fpm/web11.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;

I tried various combinations to see what was/not needed and each line is needed. I wish I understood these things better.

UPDATE: July 27th 2016:

So I did some reading and finally understand why we have this issue.

In short when we install FastCGI and php-fpm it creates a directive in the nginx server files (which file depends on your server install).

So in mine I have the following...

        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
    #
    #       # With php7.0-cgi alone:
    #       fastcgi_pass 127.0.0.1:9000;
    #       # With php7.0-fpm:
            fastcgi_pass unix:/run/php/php7.0-fpm.sock;

As you will notice these directives are in location / and not in the global settings. Since we want to secure a particular folder these directives are not inherited. Therefore, we need to declare it again.

If we wanted to follow the DRY ("Don't Repeat Yourself") principle, then we would declare the PHP-fpm and FastCGI in the global settings. We can do this by moving it to below (example, but it just needs to be outside of location directive). Here is an example.

root /var/www/html;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;

Hope this helps. I realized the above by reading https://www.digitalocean.com/community/tutorials/understanding-and-implementing-fastcgi-proxying-in-nginx

Disclaimer: I am no pro so if you see mistakes be nice and just let me know and I will hopefully update.

Kalman
  • 71
  • 1
  • 4