I am running Apache 2.2 with FastCGI and php-fpm. I am trying to duplicate the following logic:
<FilesMatch "^(admin|api|app)?(_dev)?$">
#ForceType application/x-httpd-php
SetHandler php-fcgi
</FilesMatch>
Which allows me to symlink admin.php as admin, so I can remove the .php extension. It seems the only way to do this with php-fpm is to set the security.limit_extension of the www.conf file to empty, however, as the comments indicate, this is a pretty big security hole, in that php code can now be executed from within any file, regardless of extension.
What would be the preferred way to accomplish the above, but still maintain some semblance of security?
Looks like the best solution so far is to manually add the known symlinks to the list (located in /etc/php-fpm.d/www.conf):
security.limit_extension php admin admin_dev api api_dev app app_dev
Not sure if security.limit_extension directive can even take a regex, doesn't look like it, so this is about as good as it gets. As mentioned in the OP, you will still have to maintain the filesmatch directive in the vhost config as well:
<FilesMatch "^(admin|api|app)?(_dev)?$">
SetHandler php-fcgi
</FilesMatch>
-- Update --
Per the comments by tftd, adding current rewrite directive:
RewriteBase /
# we skip all files with .something
RewriteCond %{REQUEST_URI} \..+$
RewriteCond %{REQUEST_URI} !\.html$
RewriteRule .* - [L]
# we check if the .html version is here (caching)
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]
#Mike, based on your updated answer, something similar to this .htaccess file should be able to handle what you're trying to do:
# Enable the rewrite engine
RewriteEngine on
# Set the rewrite base path (i.e. if this .htaccess will be running at root context "/" or a subdir "/path")
RewriteBase /
# If the file exists, process as usual.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .* - [NC,L]
# If the dir exists, process as usual (if you don't need this, just comment/remove the next two lines).
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [NC,L]
# If (requested_file_name).html exists, rewrite to that file instead.
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [QSA,L]
# If (requested file name).php exists, rewrite to that file instead.
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.html [QSA,L]
# If none of the above rules were triggered, fallback to index.php.
RewriteRule ^(.*)$ index.php [QSA,L]
With a bit of tweaking this should be able to do the job without the need of having to dive into httpd.conf and the <VirtualHost> nor <FilesMatch> directives. Hope this helps.
Related
I have a vue.js app which consists of 2 entry points (2 SPA's). one of them is index.html, which serves the client website and the other is for the platform (platform.html)
Following the Vue CLI documentation, I am using the following in my .htacess file
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
this only works if I only have index.html and when I type in myUrl.com/platform it doesn't change to the platform.
I have tried the following and can't make it work
<IfModule mod_rewrite.c>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^platform(.*)$ platform.html [L]
RewriteRule ^(.*)$ index.html [L]
</IfModule>
</IfModule>
Assuming that any URL prefixed with platform should be sent to platform.html and everything else to index.html then you could do something like the following in your root .htaccess file:
DirectoryIndex index.html
RewriteEngine On
# Optimisation - prevent rewritten requests for the front-controller being reprocessed
RewriteRule ^index\.html$ - [L]
RewriteRule ^platform\.html$ - [L]
# Prevent static resources being routed through the app
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Any URLs that start "/platform" (whole path segment only) are sent to "/platform.html"
RewriteRule ^platform($|/) platform.html [L]
# All other URLs are sent to "/index.html"
RewriteRule . index.html [L]
The RewriteBase directive is not required here.
You do not need the <IfModule> wrappers, unless these directives are optional (they are not). (It doesn't make sense to nest these wrappers in this way.) See my answer to the following question on the Webmasters stack for more discussion on this: Is Checking For mod_write Really Necessary?
Note that requests for the document root are not actually rewritten by the directives above, but are instead sent to index.html by the DirectoryIndex directive - this is often already configured on the server, so the directive may not be required here.
UPDATE: Since your URLs are like /platform/<subroute>, rather than /platform<something>, the regex in the above rule would be better as ^platform($|/), rather than simply ^platform, in order to match the whole path segment only and to avoid potentially matching too much, such as /platformsomething. (I've updated the code above.)
^platform($|/) matches platform or platform/something, but not platformsomething.
I am using a subdomain URL for my test server. Something like:
http://dev.mysite.com
I have the following in my .htaccess file:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1
RewriteRule ^about/(.*)$ /about.php?request=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
The above works well on the production (non-subdomain) set of URLs. But it doesn't quite make the cut on my dev box. For example, if I type in
http://dev.mysite.com/about
I get a 404 error. But the following with the appended .php extension works.
http://dev.mysite.com/about.php
I am guessing this has something to do with the first rewrite condition that deals with the www subdomain. How would I modify my .htaccess file to account for the dev subdomain?
It appears that your .htaccess is not enabled.
Verify whether your .htaccess is enabled or not, by putting same garbage text on top of your .htaccess and see if it generates 500 (internal server) error or not?
To enable .htaccess your httpd.conf file will need this line:
AllowOverride All
You need at least AllowOverride All or AllowOverride FileInfo in order for the htaccess file to work in your server/vhost config. FileInfo is for things like mod_rewrite.
Additionally, make sure you have mod_rewrite loaded.
You'll also want to change this condition:
RewriteCond %{REQUEST_FILENAME}.php -f
to:
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
because mod_rewrite will recognize that about has a php file and make it so /about/something passes the -f test, resulting in /about/something.php.
I need to check the requested URL, and serve different options depending on whether the request is for a file or a directory.
My URLs would look like:
http://www.example.com/Services/Service-1 (directory, serve /pages/Services/Service1/index.php)
http://www.example.com/Services/Service-1/Feature-1/Sub-Feature (an actual file, serve /pages/Services/Service-1/Feature-1/Sub-Feature.php)
Because of my lack of understanding of .htaccess (would this need a RewriteCondition?), I am currently stuck enumerating out each and every folder of my directory structure as follows:
RewriteRule ^Services/Service-1/(.*)$ /pages/Services/Service-1/$1.php
RewriteRule ^Services/Service-1 /pages/Services/Service-1/index.php
RewriteRule ^Services/Service-2/(.*)$ /pages/Services/Service-2/$1.php
RewriteRule ^Services/Service-2 /pages/Services/Service-2/index.php
RewriteRule ^Services/(.*)$ /pages/Services/$1.php
RewriteRule ^Services /pages/Services/index.php
RewriteRule ^Testimonials/(.*)$ /pages/Testimonials/$1.php
RewriteRule ^Testimonials /pages/Testimonials/index.php
Needless to say, this is a real pain - any time I add folders of content, I have to mess with .htaccess.
I know there must be a better way, but my google and stackoverflow searches haven't turned up anything that works when I try it.
you guessed it right, a rewriteCond can be used to verify if the requested uri is a file or a directory:
# f for a file, d for a directory
RewriteCond %{REQUEST_FILENAME} -f
you .htaccess would be:
Options -MultiViews
RewriteEngine ON
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.+) /$1/index.php [QSA,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.+) /$1.php [QSA,L]
EDIT:
if your files reside in the page sub directory , you have to use the following code:
Options -MultiViews
RewriteEngine ON
RewriteCond %{DOCUMENT_ROOT}/pages/$1 -d
RewriteRule (.+) /pages/$1/index.php [QSA,L]
RewriteCond %{DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule (.+) /pages/$1.php [QSA,L]
By far the easiest if mod negotiation is enabled (it usually is):
Options MultiViews
MultiviewsMatch Any
DirectoryIndex index.php
Won't force the .php though, if you have somefile.html as well as somefile.php the .html file is usually selected.
So I am using Kohana which is useful if you know it, but not needed to assist me.
I have the following mod_rewrite rules:
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/store/.*$
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php [L]
So I am trying to rewrite all requests for files and directories that do not exist to index.php.
However, I want any request sent to mydomain.com/store/* to go through as there is another htaccess file in the store directory that does work there. That does not seem to be working at the moment. Any ideas?
Full htaccess:
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /
#ErrorDocument 404 http://www.mydomain.com/404Page.html
#Options +FollowSymlinks
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
RewriteCond %{REMOTE_ADDR} !^myip
RewriteCond %{REQUEST_URI} !^/maintenance\.html$
RewriteRule ^(.*)$ http://www.mydomain.com/maintenance.html [R=307,L]
##301 Redirect Rules##
#some 301 redirects i did not include here
##Kohana Redirect Rules##
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system|kohana|vendors)\b.* http://www.mydomain.com/ [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/?store/
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php [L]
Try this condition:
RewriteCond %{REQUEST_URI} !^/?store/
There is no need to check the characters after the directory. I made the first slash optional if I remeber correctly is the first slash only visible if your server configuration does not contain a tailing slash.
The issue turned out to be in the .htaccess file in the store directory not the one in the webroot. Thanks all, and sorry for my stupidity. IF anyone wants to leave comments on how to debug something of this nature for future users that would be awesome.
Currently I have these rules in my .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*).css style.php?u=$1 [QSA]
RewriteRule ^(.*).xml rss.php?u=$1 [QSA]
</IfModule>
This will rewrite the following URLs:
http://domain.com/user.css
http://domain.com/user.xml
But when I'm trying to grab a file from a subdirectory: http://domain.com/css/style.css it gets rewritten as well.
My goal is rewrite only for current directory and avoid sub-directories, since all real CSS files on sub-directories will be rewritten.
How I can avoid this?
You need to make your pattern more restrictive: this ^(.*).css will match ANYTHING with .css in it while this pattern ^([^/]+)\.css$ will be restricted to something.css (styles\something.css will not match it).
<IfModule mod_rewrite.c>
RewriteEngine On
# do not do anything to real files or folders
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
RewriteRule ^([^/]+)\.css$ style.php?u=$1 [QSA,L]
RewriteRule ^([^/]+)\.xml$ rss.php?u=$1 [QSA,L]
</IfModule>
The easiest way is to tell mod_rewrite to avoid rewriting if the file is a real file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*).css style.php?u=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*).xml rss.php?u=$1 [L,QSA]
I've added a [L] tag (end) because once a rule is applied you certainly doesn't need the next rule to be checked.
Now if the files really exists but you really want to handle them with a php script if no 'css' subdirectory is present on the url... let's try that:
<Location "/css">
RewriteEngine off
</Location>