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

2
  • Where is the rewrite rule for proxying the requests located? Jul 9, 2014 at 0:16
  • rewrite rule for proxying is located in main apache site config. The users cannot change it. It is used for dynamic directory and port mapping for apache and fcgi.
    – user229874
    Jul 9, 2014 at 1:38

5 Answers 5

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.

1
  • Dr. Fu, I'm not familiar with all the intricacies of the mod_proxy machinery, but I have 2.4.10, and this config (I forgot why I had to use unix sockets...): <Proxy "unix:/var/run/my.socket|fcgi://php-fpm"> ProxySet disablereuse=off </Proxy> <FilesMatch \.php$> SetHandler proxy:fcgi://php-fpm </FilesMatch>. It's very similar to yours (apart from the socket), but HTTP Basic Auth does fall through to PHP if I press Cancel on the passwd. prompt. How should this work properly?
    – Sz.
    Nov 24, 2018 at 21:48
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

1
  • Unfortunately "RewriteOptions InheritBefore" does not work as expected when combined with RewriteRule mapping shared hosting configuration (similar to this httpd.apache.org/docs/2.4/rewrite/vhosts.html). What happens in this case is that whatever rules it tries to apply from .htacces it does it against already rewritten rules, thus the URI contains full file path.
    – user229874
    Apr 7, 2015 at 6:01
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.

1
  • I am completely aware what is going on. I am after workaround. I would rather avoid mod_php if I could. I use rewrite rule to map user directory and php-fpm port, this way I can update config dynamically without changing apache configuration (by using RewriteMap).
    – user229874
    Jul 9, 2014 at 1:43
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>
-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.

1
  • Unfortunately after a few apache updates the -U workaround stopped working. Looking at re-factoring config so it works with InheritBefore but without affecting the URI, not sure if it is possible...
    – user229874
    Apr 7, 2015 at 6:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .