3

I am using apache 2.4.7 with mod_proxy_fcgi for purpose of passing through php to php-fpm (this will be used for shared hosting environment). The htaccess works fine for non php files, but once it hit rewrite rule that proxies through the php requests, the htaccess is ignored.

I know why it is happening. The question is: how do I work around it?

The question how do I force apache to treat the request to php file as a request to local file, and then proxy it through?

I have spent substantial time in researching on this problem, and following "answers" were given as solution:

1) "use apache configuration instead of .htaccess" it is valid solution, but not for shared hosting environment (I am not going to give access to apache configuration to shared hosting customers ;)).

2) "don't use .htaccess, as it has performance/security/other issues", well how else would shared hosting customers control access/url rewriting on their site? Besides if the .htaccess was not a requirement I would simply use nginx.

3) "put rewrite rule for proxy inside of " - this is incorrect, and it does not work.

This behaviour appears to be not a bug but a "feature" as per https://issues.apache.org/bugzilla/show_bug.cgi?id=54887

5 Answers5

3

Meanwhile, another option is available since Apache 2.4.10: Proxy via Handler. See the example in the Apache documentation: mod_proxy_fcgi examples

You can also force a request to be handled as a reverse-proxy request, by creating a suitable Handler pass-through. The example configuration below will pass all requests for PHP scripts to the specified FastCGI server using reverse proxy. This feature is available in Apache HTTP Server 2.4.10 and later. For performance reasons, you will want to define a worker representing the same fcgi:// backend. The benefit of this form is that it allows the normal mapping of URI to filename to occur in the server, and the local filesystem result is passed to the backend. When FastCGI is configured this way, the server can calculate the most accurate PATH_INFO.

<Proxy "fcgi://localhost/">
    ProxySet enablereuse=On
</Proxy>
<FilesMatch "\.php$">
    SetHandler "proxy:fcgi://localhost:9000"
</FilesMatch>

This allows RewriteRules and authentication in .htaccess files. After all the rewriting is done, the request is passed to php-fpm.

2

Beware that RewriteCond -U will check if the URI is correct before doing the actual redirect, hence doubling every request! this might have severe impact on performance, especially on heavy loaded websites.

I suggest to check "RewriteOptions InheritBefore" , which seems to solve any problem related to htaccess inheritance, as described here:

Understanding apache 2.4 mod_proxy_fcgi and RewriteRules in htaccess

Cheers, Giorgio

Giorgio
  • 21
1

It appears you pass all your php execution to your fast cgi server which does not know how to use htaccess so that's why it ignores those files. If you need to use htaccess files by Apache, then you need to execute php scripts by Apache (i.e. using mod_php) instead of passing execution to another service which has no idea about htaccess.

You could re-do your rewrite rules, but since these are user-controlled, then you can't do anything much about it.

nochkin
  • 241
0

i guess this is the cleanest method, without any ugly rewrites in apache config:

<VirtualHost IP:80>
    ServerName domain.tld
    ServerAlias www.domain.tld
    DocumentRoot /var/www/project/web

    <FilesMatch \.php$>
        SetHandler proxy:fcgi://127.0.0.1:9000
    </FilesMatch>

    <Directory /var/www/project/web>
        AllowOverride All
    </Directory>
</VirtualHost>
ADM
  • 1,413
-1

EDIT:

The real solution to this problem is not putting rewrite rule for proxy to php-fpm in but to do the following:

RewriteCond %{REQUEST_URI} -U
RewriteRule (.*\.php)$ fcgi://IP:PORT/$1 [P,L]

Outside of the tags and inside of the tags.

As original solution had a problem: if there was "RewriteEngine On" or any "RewriteRule" related rules/conditions it would cause Apache to completely ignore the rewrite rules inside of tags in main config file.

The below is not entirely correct

I found that I was wrong about not working inside of tag.

RewriteMap and standard rewrite lookup of the user dirs goes here

<Directory /PATH_TO_WWW/*>
      Standard directory conf goes here

      RewriteRule ^(.*\.php)$ fcgi://IP_OF_THE_FPM:FPM_PORT/$1 [P,L]

</Directory>

Basically the secret (for me at least) I needed to put rewrite rule that proxies through inside directory tags that are for common directory of the users with *.

so if I have users in /var/www/$username , the directory tag should look like this:

TL;DR: use proxy rewirte rule inside of directory tags for the common users directory.