php directives in .htaccess? - apache

I have attempted to make a few changes to php via .htaccess, yet none have yielded any results. For example:
php_value memory_limit 256M within will not activate.
Attempting to set SetEnv PHPRC /home/username/public_html/php.ini or any similar incantation, such as SetEnv PHPRC /home/username/some_path, will not work yield any difference in phpinfo. I DO see that _SERVER["PHPRC"] is indeed set, but no values are overwritten such as that noted above.
My phpinfo is as follows:
https://gist.github.com/ylluminate/08efd9a2844723631214
I'm wondering if I'm missing an apache module that's not allowing this to work as expected for a custom php.ini or phprc. Further This is an Apache 2.4.4 installation on a VPS over which I have 100% control (Linode) and using WHM + cPanel.

Since PHP 5.3 you can use .user.ini files, given that PHP is setup to run via the CGI/FastCGI SAPI.
http://php.net/configuration.file.per-user
It's a simple extension of the main php.ini and allows specifying options equivalently:
memory_limit = 256M
upload_tmp_dir = /tmp
Usually you can place one of these in the DOCUMENT_ROOT. But every directory may contain one, so options may vary per script/folder. It's meant as full alternative to Apaches/mod_php .htaccess setting directives.

Related

Use alternative to .htaccess file if it exists?

Background: I used to use an environment variable to enable me to differentiate between my dev and production server, using this in .htaccess: -
<IfDefine DEV_SERVER>
# dev server specific stuff here
</IfDefine>
<IfDefine !DEV_SERVER>
# production server specific stuff here
</IfDefine>
The environment variable "DEV_SERVER" was only ever set on my dev server, and never on production, obviously.
This approach worked a treat until my production server host installed Litespeed as a replacement for Apache. Litespeed doesn't like the above, and ignores everything.
I tried having different versions of .htaccess files for dev and production, but that's messy and dangerous, I like to be able to interchange all files at any time between the two.
My dev server runs Apache 2.4 and I have no plans to change this. I read that you can specify a different filename for .htaccess by putting this in httpd.conf: -
AccessFileName .htaccess.dev
Which is half way there - now I can have a .htaccess.dev file which only my dev server will use in place of .htaccess. But ideally I would like the dev server to: -
use .htaccess if that's all there is
use .htaccess.dev if that's all there is
use .htaccess.dev if there are both .htaccess and .htaccess.dev present
It does (2) and (3), but unfortunately not (1).
Is there any solution? Any help greatly appreciated, as always!
You can specify multiple files in AccessFileName so you can do: AccessFileName .htaccess.dev .htaccess
What this will do is to prefer .htaccess.dev over .htaccess if it exists, and will use .htaccess if .htaccess.dev doesn't exist.
However, in my opinion you're doing something wrong, if you have to customize your .htaccess per environment :)
Update with working example:
If you put AccessFileName .htaccess.dev .htaccess in your Apache configuration (Such as the vhost it will work as it should):
# curl -sI http://example.com/test.html | grep "x-htaccess"
x-htaccess: dev
# mv .htaccess.dev htaccess.dev
# curl -sI http://example.com/test.html | grep "x-htaccess"
x-htaccess: default
The content of .htaccess is Header set x-htaccess default and the content of .htaccess.dev is Header set x-htaccess dev.

Unable to set php_value 'soap.wsdl_cache_dir'

I have VPS server (CentOS 6.5) running Apache 2.2.4 and PHP-FPM (FastCGI Process Manager). Looking in php-fpm error_log I've noticed error with every spawn php-fpm child process:
WARNING: [pool www] child 24086 said into stderr: "ERROR: Unable to set php_value 'soap.wsdl_cache_dir'"
I couldn't find any info on this warning googling. Is anybody aware what does this mean and how to get rid of this warning?
UPDATE 1:
fastcgi.conf for apache:
User apache
Group apache
LoadModule fastcgi_module modules/mod_fastcgi.so
<IfModule mod_fastcgi.c>
DirectoryIndex index.php index.html index.shtml index.cgi
AddHandler php5-fcgi .php
# For monitoring status with e.g. Munin
<LocationMatch "/(ping|status)">
SetHandler php5-fcgi-virt
Action php5-fcgi-virt /php5-fcgi virtual
</LocationMatch>
Action php5-fcgi /php5-fcgi
Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /tmp/php5-fpm.sock -pass-header Authorization
</IfModule>
# global FastCgiConfig can be overridden by FastCgiServer options in vhost config
FastCgiConfig -idle-timeout 20 -maxClassProcesses 1
And here is the php-fpm.conf and pool configuration for php:
pid = /var/run/php-fpm/php-fpm.pid
daemonize = yes
; Start a new pool named 'www'.
[www]
listen = /tmp/php5-fpm.sock
group = apache
pm = dynamic
pm.max_children = 8
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.status_path = /status
ping.path = /ping
catch_workers_output = yes
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
Everything else is on defaults.
UPDATE 2:
After manually creating /var/lib/php/wsdlcache directory as suggested and setting permissions to 770 and owner to root:apache, I hoped that I won't see the error again, but unfortunately after restarting php-fpm process the error is there again and this becomes something really very strange.
P.S. Maybe this question is more appropriate for serverfault, but generally there are more experts in php and apache configuration on stackoverflow.
I hate so trivial solutions. Finally I've found the problem and solution by myself. Leaving it here for reference for others with some pre-history.
FastCGI configuration files were taken from internet when first configuring FastCGI as I haven't used it before. Tutorials showing FastCGI configuration contained the line php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache. I became really interested what is SOAP as I don't use it on the websites that I run on this server and this curiosity brought me the solution. Actually I don't need SOAP and simply removing that line would fix the problem I guess, but I've decided to leave it there and found out that I needed simply to install php-soap.
yum install php-soap
For RHEL/CentOS
After restarting php-fpm I don't get the error on respawning fpm processes.
You're getting that message if the directory /var/lib/php/wsdlcache specified in your pool configuration doesn't exist and cannot created by the PHP worker either. Note that the PHP worker is not running as root, but as user apache (which is great for security and should be kept that way!), therefore it most likely doesn't have write permissions in /var/lib. Kepp also in mind that workers can be chrooted (your config doesn't look like you're doing it, but one can) - in that case, the directory has, of course, be inside the chroot jail.
Create that directory and modifiy the access rights so that apacheis able to read and write into it and everything should be fine.
Pretty sure you can't use php_value with (fast) CGI. You might want to look at user.ini files if using a version of PHP newer than 5.3.0 and needing PHP_INI_PERDIR ini settings.
Since PHP 5.3.0, PHP includes support for configuration INI files on a
per-directory basis. These files are processed only by the CGI/FastCGI
SAPI. This functionality obsoletes the PECL htscanner extension. If
you are using Apache, use .htaccess files for the same effect.
UPDATE: Didn't see it was pool www. As Johannes H. observes: "You can use php_value inside the pool-cofiguration of php-fpm...". My original answer only really applies for per directory tweaks. See Johannes comment below.

Change php.ini settings without modifying the original php.ini file or using the htaccess

The default php.ini value on my server for file uploading(upload_max_filesize, post_max_size) is 10M. I wanted to increase it to 40M. How do I do that?
Method 1: I can't use. This method doesn't work in this specific case.
ini_set("upload_max_filesize", "40M");
ini_set("post_max_size", "40M");
Method 2: I can't do it using the htaccess either. Because when I do so my server changes my .htaccess file with the following error
# For security reasons, mod_php is not used on this server. Use a php.ini file for php directives
Method 3: And I don't want to make changes to the default php.ini file because that will change the settings throughout the whole server.
Method 4: I have heard that I can create a php.ini file in my site and define the settings there but it didn't work either. My code for that file. (I kind of have a feeling that I applied this method in a wrong way)
[PHP]
upload_max_filesize =40M
post_max_size =40M
Well, method 4 worked for me as I thought. I just had to do it the right way. Adding this specific line to my .htaccess file reads the newly created php.ini file in that folder.
AddHandler application/x-httpd-php5 .php
On Bluehost cpanel PHP Configuration I selected PHP 5.2
"All files with the extension .php will be handled by the PHP 5.2 engine.
Legacy PHP with security updates. Compatible with most environments. "
To eliminate the "#For security reasons, mod_php is not used on this server. Use a php.ini..." message.

Set path to php.ini

Is it possible to have just a single php.ini file, for example in the webroot (or even outside of it to prevent people accessing it via GET), and tell PHP quickly and easily where it is?
I know you can set php.ini directives in .htaccess, but is it possible to define a specific php.ini file to be used?
Add this to your server configuration...
<VirtualHost 1.2.3.4:80>
PHPINIDir /path/to/new/php_ini
</VirtualHost>
Make sure to just include the path to the directory, not the entire path to the file.
Then restart Apache.
Check it worked with phpinfo().
Have a look at .user.ini section at the php docs.
Since PHP 5.3.0, PHP includes support for .htaccess-style INI files on
a per-directory basis.
But beside the .unser.ini solution you can place an additional ini file in the "additional .ini files parsed" directory. There you can use one single ini file to overwrite all other settings. Name it with zzz at the beginning and it will be parsed at last. This is also easy for your hoster to deploy without destroying his settings.
Kolink, I suspect that you are on a shared hosting service, in which case your host may be using something called suPHP. In this case -- as you describe -- the PHPINIDir directive doesn't work, in which case there is a suPHP_ConfigPath directive.
In terms of access, I have a standard mod_rewrite in my DOCROOT/.htaccess:
RewriteEngine On
RewriteBase /
# if a forbidden directory or file name (starting with a . or /) then raise 404 Fatal
RewriteRule (^|/)[_.] - [F]
What this does is forbid any request for any filename or directory prefixed by . or _. I have a DOCROOT/_private where I keep this stuff for me:
suPHP_ConfigPath DOCROOT/_private
where you will need to replace DOCROOT by your local setting on your service. Look for DOCUMENT_ROOT in a phpinfo() listing.

PHP - a different open_basedir per each virtual host

I've came across on this problem, I have a sever running apache and php. We have many virtual hosts but we've noticed that a potentially malicious user could use his web space to browse other user's files(via a simple php script) and even system files, this could happens due to the php permissions.
A way to avoid it is to set the open_basedir var in php.ini, yhis is very simple in a single host system, but in case of virtual hosts there would be a basebir per each host.
Ho can I set dis basedir per each user/host? is there a way to let apache hereditate php privileges of the php file that has been requested
E.G.
/home/X_USER/index.php has as owner X_USER, when apache read the file index.php it checks its path and owner, simply I'm looking for a system set php basedir variable to that path.
Thank in advance
Lopoc
It is possible to set open_basedir on a per-directory basis using the php_admin_value Apache directive.
Example from the manual:
<Directory /docroot>
php_admin_value open_basedir /docroot
</Directory>
Re your comment: yes, external commands are not affected by open_basedir - when calling ls / this is done with the rights the user account PHP runs under (often named www or similar). As far as I know, it is not possible to extend open_basedir to external commands.
In that case, I don't think the kind of protection that you're looking for is possible in a normal Apache/PHP setup. The only thing that maybe comes close is running Apache in a chroot jail. I haven't done this myself so I can't say anything about it - you'd have to dig in and maybe ask a question specifically about that.
You can set many php.ini settings using the Apache configuration file.
See these related pages from the PHP manual:
- http://php.net/manual/en/configuration.changes.php
- http://www.php.net/manual/en/ini.core.php#ini.sect.path-directory
- http://www.php.net/manual/en/configuration.changes.modes.php
chroot is a good idea. And now docker is more effective.
and open_basedir with "/docroot" is not security ,you should end with a "/" or PHP can access /docroot1