I am trying to port a PHP application from Windows IIS to Linux (Debian) with Apache web server (v2.4). I successfully changed my Document Root to /code/wwwroot, and am using the config file /etc/apache2/sites-available/000-default.conf instead of .htaccess for my configuration (in the Apache 2.4 docs it says to use the config files in /etc/apache2/sites-available if you have access to server configuration files, which I do). This is what I am using for my configuration:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /code/wwwroot
<Directory /code/wwwroot>
Options Indexes FollowSymLinks
AllowOverride None
FallbackResource /start.php
</Directory>
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
This works almost exactly how I would expect. When files found in /code/wwwroot/ are requested, they are served. If the file/path requested does not exist, start.php is run and returned. For example, if my request is localhost/gadgasd.html, etc, it internally redirects to start.php. However, for files with .php extensions that do not exist in Document Root, I am getting 404's. For example, if the request is localhost/gadgasd.php, I get a 404 directly from Apache (I was hoping to handle 404's in my code rather than Apache). This behavior is strictly limited to files with .php extensions that do not exist in Document Root. I am very confused about this behavior. I have setup the correct packages for using php with apache (apt-get install -y php libapache2-mod-php) and the FallbackResource rule works for all other file extensions. What am I doing wrong? Thanks in advance!
This appears to be a bug in Apache and has an open issue tracker here. There is also a workaround provided.
EDIT: In case the link ever dies, the workaround is to use the old mod_rewrite approach as follows:
RewriteEngine On
RewriteCond /var/www/%{REQUEST_FILENAME} !-f
RewriteCond /var/www/%{REQUEST_FILENAME} !-d
RewriteRule (.*) start.php
The problem comes from the fact that the default mod_php configuration (/etc/apache2/mods-enabled/phpX.conf) doesn't appear to check if the file exists before passing the request to the PHP handler. This can easily be added by changing:
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
to
<FilesMatch ".+\.ph(ar|p|tml)$">
<If "-f %{REQUEST_FILENAME}">
SetHandler application/x-httpd-php
</If>
</FilesMatch>
<FilesMatch/> doesn't appear to check if the file exists like you might expect, this means all requests that end with .php, .phtml and .phar are blindly passed to the php handler.
It's worth noting that this might have a performance impact as Apache must have to check on disk if the file is there but I would speculate that the difference would be negligible in almost all cases.
Related
I am trying to use mod_rewrite module of Apache24 server, but I am not being able to load it. I know there have been many questions asked regarding this topic and I have gone through all of them but nothing seem to work. These are the steps that I have followed until now---
CHANGED httpd.conf file made these changes--
a. Uncommented LoadModule rewrite_module modules/mod_rewrite.so
b. Changed AllowOverride None to AllowOverride All
Restarted apache server
Checked loaded modules using command prompt command httpd -M. I can see there that the mod_rewrite module has loaded. I am attaching the image below.
But after performing all these steps I can't see mod_rewrite as loaded module in phpinfo.
As it can be seen in the above pic there is no mod_rewrite loaded module.
Also as a wild hack I even tried rewriting URLs using .htaccess file but this is not working. Apache seems to ignore .htaccess file although I have put that file inside my root directory.
Note: I am running `PHP` as an apache module
Using `WAMP` stack
Using `localhost` as server
I need this module badly for URL rewriting purposes. Can you guys suggest some other way to load this module?
I am cracking my head for the past two days. Do you think a re-installation is needed or has it got something to do with path dependencies. Any suggestion will be appreciated.
EDIT
I have tried to rewrite URL from virtual host as the answer suggests that the module is loaded and it does not depend neither on .htaccess nor on info.php.But stil it is not redirecting. I am adding the Virtual host setup below---
<VirtualHost *:80>
<Directory "/Apache24/htdocs">
Options FollowSymLinks
AllowOverride All
DirectoryIndex index.html index.php
</Directory>
ServerName localhost
DocumentRoot "/Apache24/htdocs"
ErrorLog "/Apache24/logs/error.log"
CustomLog "/Apache24/logs/access.log" combined
<directory "/Apache24/htdocs">
<IfModule rewrite_module>
Options +FollowSymlinks
RewriteEngine On
</IfModule>
<IfModule rewrite_module>
RewriteRule ^working.php fun.html
</IfModule>
</directory>
# Rewrite Rules #####################
RewriteEngine On
RewriteRule ^working.php fun.html
# end Rewrite Rules #################
</VirtualHost>
The above code does not redirect it to working.php when I try to run fun.html. It simply says the requested URL /working.php was not found on this server..
Thanks in advance!
If apachectl -M or httpd -M says the module is loaded, it is loaded. phpinfo is an external thing ran by a php script, why should you trust it over httpd own software?
If you really need to use mod_rewrite, just make sure to add RewriteEngine on before your other rewrite directives.
Note: I would really make sure I need mod_rewrite knowing what I have to configure next, in many cases it is not necessary and overused.
Very important: To configure your server, if it is your server you do not need .htaccess, and mod_rewrite does not depend on it either
in my apache sites-available/default file i had change the config to folowing:
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All //originally was AllowOverride None
FallbackResource rewrite.php //i added this line, too
Order allow,deny
allow from all
</Directory>
i wanted to handle all url calls in my own rewrite.php file. this works, when i visit my site at http://192.168.1.104:4567/web/knxzkcha but doesnt work when i go for http://192.168.1.104:4567/web/. i got this problem in firefox : The connection to the server was reset while the page was loading.
the index site http://192.168.1.104:4567/web/index.php works flawlessly and shows me my index.php file. all i want is to let me show the index file when visiting the root directory, too. /var/www points to the /web directory. i have some ubuntu 12.04 server 64 LTS edition
when i rewert the config lines, the root gives me the index file by default.
You do not need to add AllowOverride All, telling apache to avoid IO by checking existence of .htaccess files in current directory and all parents directories with AllowOverride None is a good recipe for speed. Avoid .htaccess files if you can edit Apache configuration.
Now FallbackResource is a quite new feature and may have some bugs. Did you check the ErrorLog for details? Could you try that with LogLevel debug?
It seems you problems is with directories, maybe you could fix it by enforcing usage of your fallback when a Directory is requested, try to add:
DirectoryIndex rewrite.php
all. So I'm running Apache 2.2. I have a single VirtualHost that's used for a Django application (by way of mod_wsgi) as well as a PHP one that lives in a subdirectory. Normally, this is no problem. You can just Alias /subdir /path/to/phpapp followed by WSGIScriptAlias / /path/to/django.wsgi.
But, the complication is that this PHP application uses mod_rewrite to implement "Fancy URLs," which just means that '/subdir/foo/bar' will get rewritten to something like '/subdir/index.php?path=foo/bar'.
Here's my configuration:
<VirtualHost *:80>
ServerName [snip]
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
Alias /phpapp/ /home/ubuntu/phpapp/
<Directory /home/ubuntu/phpapp>
Order allow,deny
Allow from all
RewriteEngine on
RewriteCond $1 !^(index\.php|img|bin)
RewriteRule ^(.*)$ index.php?__dingo_page=$1 [PT]
</Directory>
WSGIDaemonProcess foo user=ubuntu
WSGIProcessGroup foo
WSGIScriptAlias / /home/ubuntu/djangoapp/apache/django.wsgi
<Directory /home/ubuntu/djangoapp/apache>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
The problem is that whenever a rewrite takes place (e.g., I try to go to /phpapp or /phpapp/foo) the request gets handled by WSGI and I see my Django site's 404 page. If the address passes through (e.g., I go to /phpapp/index.php) then it is handled by PHP and works normally. I thought maybe that adding the [PT] flag to my RewriteRule would fix this problem, but it doesn't seem to have any effect on which handler is chosen. I've also tried SetHandler application/x-httpd-php in the Directory section for the PHP app.
I need the Django application to continue to handle any URLs that aren't specifically aliased to something else. There must be a way to make this work! Thanks.
Using /phpapp wouldn't ever work because you have a trailing slash on that path for the Alias directive. Use:
Alias /phpapp /home/ubuntu/phpapp
By rights that Alias directive should then take precedence over WSGIScriptAlias for the sub URL.
I would suggest you enable logging by mod_rewrite and verify what the URL is being written to. So long as the rewritten URL still sits below /phpapp, it should be fine.
The alternative is to not use WSGIScriptAlias, but use the scheme as outline towards the end of:
http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#The_Apache_Alias_Directive
That allows you to set things up so that the Python web application will only be used as a fallback if no static resource, including PHP, could be mapped.
I have an apache web server. Let's say this server's domain is example.com.
When I access example.com, then the index.php file is correctly displayed in the browser.
However, when I access e.g. example.com/~user, then the index.php file of /home/user/public_html/index.php file is downloaded rather than displayed.
How do I fix this problem? I changed "expose_php = Off" in php.ini, but nothing has changed.
If you are on Debian/Ubuntu take a look at this file /etc/apache2/mods-available/php5.conf
mine looks like this and you can see I had to comment some line to get PHP working in the user dir
<IfModule mod_php5.c>
<FilesMatch "\.ph(p3?|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
# To re-enable php in user directories comment the following lines
# (from <IfModule ...> to </IfModule>.) Do NOT set it to On as it
# prevents .htaccess files from disabling it.
#<IfModule mod_userdir.c>
# <Directory /home/*/public_html>
# php_admin_value engine Off
# </Directory>
#</IfModule>
</IfModule>
Please note that after editing the file you would have to restart apache for the modifications to take effect, the command to restart apache on a debian based system is: /etc/init.d/apache2 restart
Hope this saves someone else the headache. I know this question is old, but it still comes up when searching for this problem.
I'm not sure if this works across all installations of apache2, but I am running apache2 on ubuntu and had the problem of my web browser downloading files instead of displaying the correct index file.
The problem lies in the file /etc/apache2/mods-enabled/dir.conf
The default document setting here was overriding what I had set in /etc/apache2/httpd.conf
So just open up /etc/apache2/mods-enabled/dir.conf and change the order of the files listed.
:)
I've had a similar experience - some php files working OK, but others seem to have the raw php code downloaded.
In my case, it was due to the broken files using the short tag format of <? and ?>. This is not recommended, and you may find the default php.ini has this support forced off. With support off, the php code is sent down to the browser as if it was HTML.
If you can't avoid short tags (as in my case - a whole legacy codebase using short tags), then you can set it to be allowed in php.ini:
short_open_tag = On
I'm making a website which allows people to upload files, html pages, etc... Now I'm having a problem. I have a directory structure like this:
-/USERS
-/DEMO1
-/DEMO2
-/DEMO3
-/etc... (every user has his own direcory here)
-index.php
-control_panel.php
-.htaccess
Now I want to disable PHP, but enable Server-side includes in the direcories and subdirectories inside /USERS
Can this be done (and if so, how)?
I use WAMP server
Try to disable the engine option in your .htaccess file:
php_flag engine off
To disable all access to sub dirs (safest) use:
<Directory full-path-to/USERS>
Order Deny,Allow
Deny from All
</Directory>
If you want to block only PHP files from being served directly, then do:
1 - Make sure you know what file extensions the server recognizes as PHP (and dont' allow people to override in htaccess). One of my servers is set to:
# Example of existing recognized extenstions:
AddType application/x-httpd-php .php .phtml .php3
2 - Based on the extensions add a Regular Expression to FilesMatch (or LocationMatch)
<Directory full-path-to/USERS>
<FilesMatch "(?i)\.(php|php3?|phtml)$">
Order Deny,Allow
Deny from All
</FilesMatch>
</Directory>
Or use Location to match php files (I prefer the above files approach)
<LocationMatch "/USERS/.*(?i)\.(php3?|phtml)$">
Order Deny,Allow
Deny from All
</LocationMatch>
If you're using mod_php, you could put (either in a .htaccess in /USERS or in your httpd.conf for the USERS directory)
RemoveHandler .php
or
RemoveType .php
(depending on whether PHP is enabled using AddHandler or AddType)
PHP files run from another directory will be still able to include files in /USERS (assuming that there is no open_basedir restriction), because this does not go through Apache. If a php file is accessed using apache it will be serverd as plain text.
Edit
Lance Rushing's solution of just denying access to the files is probably better
<Directory /your/directorypath/>
php_admin_value engine Off
</Directory>
This will display the source code instead of executing it:
<VirtualHost *>
ServerName sourcecode.testserver.me
DocumentRoot /var/www/example
AddType text/plain php
</VirtualHost>
I used it once to enable other co-worker to have read access to the source code from the local network (just a quick and dirty alternative).
WARNING !:
As Dan pointed it out sometime ago, this method should never be used in production. Please follow the accepted answer as it blocks any attempt to execute or display php files.
If you want users to share php files (and let others to display the source code), there are better ways to do it, like git, wiki, etc.
This method should be avoided! (you have been warned. Left it here for educational purposes)
None of those answers are working for me (either generating a 500 error or doing nothing). That is probably due to the fact that I'm working on a hosted server where I can't have access to Apache configuration.
But this worked for me :
RewriteRule ^.*\.php$ - [F,L]
This line will generate a 403 Forbidden error for any URL that ends with .php and ends up in this subdirectory.
#Oussama lead me to the right direction here, thanks to him.
If you use php-fpm, the php_admin_value will NOT work and gives an Internal Server Error.
Instead use this in your .htaccess. It disables the parser in that folder and all subfolders:
<FilesMatch ".+\.*$">
SetHandler !
</FilesMatch>
This might be overkill - but be careful doing anything which relies on the extension of PHP files being .php - what if someone comes along later and adds handlers for .php4 or even .html so they're handled by PHP. You might be better off serving files out of those directories from a different instance of Apache or something, which only serves static content.
On production I prefer to redirect the requests to .php files under the directories where PHP processing should be disabled to a home page or to 404 page. This won't reveal any source code (why search engines should index uploaded malicious code?) and will look more friendly for visitors and even for evil hackers trying to exploit the stuff.
Also it can be implemented in mostly in any context - vhost or .htaccess.
Something like this:
<DirectoryMatch "^${docroot}/(image|cache|upload)/">
<FilesMatch "\.php$">
# use one of the redirections
#RedirectMatch temp "(.*)" "http://${servername}/404/"
RedirectMatch temp "(.*)" "http://${servername}"
</FilesMatch>
</DirectoryMatch>
Adjust the directives as you need.
I use in Centos 6.10 for multiple folders in virtual host .conf definitioin file:
<DirectoryMatch ^/var/www/mysite/htdocs/(nophpexecutefolder1|nophpexecutefolder2)>
php_admin_value engine Off
</DirectoryMatch>
However, even though it doesn't parse php code the usual way it still outputs from a .php things such as variable declarations and text when doing echo e.g.
<?php
echo "<strong>PHP CODE EXECUTED!!";
$a=1;
$b=2;
echo $a+$b;
The above produces in web browser?
PHP CODE EXECUTED!!"; $a=1; $b=2; echo $a+$b;
This could potentially expose some code to users which isn't ideal.
Therefore, it's probably best to use the above in combination with the following in .htaccess:
<FilesMatch ".*.(php|php3|php4|php5|php6|php7|php8|phps|pl|py|pyc|pyo|jsp|asp|htm|html|shtml|phtml|sh|cgi)$">
Order Deny,Allow
Deny from all
#IPs to allow access to the above extensions in current folder
# Allow from XXX.XXX.XXX.XXX/32 XXX.XXX.XXX.XXX/32
</FilesMatch>
The above will prevent access to any of the above file extensions but will allow other extensions such as images, css etc. to be accessed the usual way. The error when accessing .php:
Forbidden
You don't have permission to access /nophpexecutefolder1/somefile.php on this server.
<Files *.php>
Order deny,Allow
Deny from all
</Files>