htaccess if statement - apache

I have the following line in my .htaccess file to select which version of PHP to use:
AddType x-httpd-php53 .php
This works great in the live environment but doesn't apply to the test environment and breaks the site.
Is there a way I can put it in an if statement or something by IP of the server or URL of website or something so that it only comes into effect in the live environment?

With Apache 2.4, it is easy with <If>/<Else> directives (on %{HTTP_HOST}?).
<If "%{HTTP_HOST} == 'foo'">
# configuration for foo
</If>
<Else>
# default configuration
</Else>
For Apache 2.2 and earlier, I would add a parameter to the startup command line of Apache (-D option) in one of the two environments then test if it is present or not via <IfDefine>.
To do this on Windows, with Apache started as a service, modify key registry HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Apache2.<VERSION>\ImagePath
by appending -DFOO. Then, you can write:
<IfDefine FOO>
# configuration for foo
</IfDefine>
<IfDefine !FOO>
# default configuration
</IfDefine>

Another alternative you can do is to change httpd.conf in the test environment to use ".htaccess-test" instead of ".htaccess".
This is simply done by modifying httpd.conf and adding the following line outside of any block:
AccessFileName .htaccess-test
NOTE: You can add AccessFileName inside a <VirtualHost> block if you want to apply it to a specific VirtualHost.
What this means is that the test environment will use .htaccess-test while the production environment will use .htaccess. Hence, you get the freedom of configuring each environment separately.
Then create a file named .htaccess-test adjacent to .htaccess.
Modify .htaccess-test with your test configuration, then finally restart Apache Web server in the test environment server.

Related

Apache .htaccess <FilesMatch> // Setting as forbidden subfolder files

I'm going mad over Apache .htaccess
I'm trying to setting as protected my subfolders using relative address, but it seems impossible.
The path of Apache folder is structured like this:
/var/www/apachedir
now I want to protect
/var/www/apachedir/subfolder/*
What I tryied is putting in /var/www/apachedir/ an .htaccess file like this
<FilesMatch "subfolder\/.*">
Order Allow,Deny
Deny from all
</FilesMatch>
but it seems not woking good.
I don't want to use ModRewrite and I want to make this .htaccess reusable.
So, listen, if I put the site over an other server that has a direcory structure like /var/www/zzz it has to protect files in /var/www/zzz/subfolder/*.
Also the file .htaccess has to stay in the root folder /var/www/apachedir.
There's a way to do it?
Edit:
I don't want to use ModRewrite but also I don't want to use Redirectmatch.
I want to know if there's a way to set it up with FilesMatch without ModRewrite or Redirectmatch.
I don't want to use ModRewrite.
You can use RedirectMatch to block access to a known path:
Redirectmatch 403 ^/subfolder/
I want to know if there's a way to set it up with FilesMatch
No, because the FilesMatch (and the non-regex Files) directive(s) literally match against files only, not directories. eg. <Files "*.jpg"> matches all .jpg files in any subdirectory.
There are various methods to block access to that subdirectory...
Use a <Directory> section in the server config
If you have access to the server (virtual host) config then you can use the <Directory> (and <DirectoryMatch>) directive(s) to target specific directories. But this is not permitted in .htaccess. For example:
<Directory "/var/www/apachedir/subfolder">
Require all denied
</Directory>
Create an additional .htaccess file in that subdirectory
The equivalent userland .htaccess way of doing this is to create an additional .htaccess file in that subdirectory (ie. at /subfolder/.htaccess) with a single Require all denied directive. The .htaccess file itself is equivalent to the <Directory> directive in the server config.
Aside: Order, Deny and Allow are Apache 2.2 directives and formerly deprecated on Apache 2.4 (which you are far more likely to be using). You should be using the equivalent Require (mod_authz_core) directives instead, as used above.
Use Redirect 403 (mod_alias) - not a "redirect"
I don't want to use ModRewrite but also I don't want to use Redirectmatch
RedirectMatch (and Redirect) are part of mod_alias - this is a base module and compiled into Apache by default (unlike mod_rewrite), so using the prefix-matching Redirect directive (no need for the regex variant RedirectMatch) is a reasonable solution as #anubhava suggests in his answer, depending on the scenario and existing directives. For example:
Redirect 403 /subfolder/
Despite the use of the Redirect directive, this is not an external (HTTP) redirect. The 403 response is served via an internal subrequest.
Set an environment variable and check with mod_authz_....
Alternatively, you can set an environment variable when the /subfolder is requested (using SetEnvIf) and check for this using the Require directive. This allows you to keep the condition separate from the directives that actually permit access. For example (using Apache 2.4 mod_authz_core):
SetEnvIf Request_URI "^/subfolder/" BLOCK_ACCESS
<RequireAll>
Require all granted
Require not env BLOCK_ACCESS
</RequireAll>
NB: If you are doing any URL-rewriting with mod_rewrite then you might need to check for REDIRECT_BLOCK_ACCESS instead in the above Require directive.
<If> expression (Apache 2.4)
On Apache 2.4 you can also use an <If> expression to target that specific subfolder with a containing mod_authz_core directive. For example:
<If "%{REQUEST_URI} =~ m#^/subfolder/#">
Require all denied
</If>
Although, strictly speaking, these methods target the URL-path, not the file-path.

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.

Use an external rewrite engine with apache

I want to run a rewrite engine on my frontend servers (apache).
I have added this configuration
<If "-f 'PATH_TO_MY_LUA_SCRIPT'">
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteMap cust "prg:PATH_TO_MY_LUA_SCRIPT"
RewriteRule ^(.*)$ ${cust:%{REQUEST_URI}}" [QSA,L]
</IfModule>
</If>
But Apache says that RewriteMap not allowed here
PS : Of course PATH_TO_MY_LUA_SCRIPT is replaced by the full path (and my script is executable)
Has anyone used an external rewrite lua scriupt with Apache 2.4 ?
Of course, I forget to precise.
This conf is not in my .htaccess but in the main vhost config
See RewriteMap documentation
Context: server config, virtual host
And Context means
Context
This indicates where in the server's configuration files the directive is legal. It's a comma-separated list of one or more of the following values:
server config ...
virtual host ...
directory ...
.htaccess ...
The directive is only allowed within the designated context; if you try to use it elsewhere, you'll get a configuration error that will either prevent the server from handling requests in that context correctly, or will keep the server from operating at all -- i.e., the server won't even start.
So you cannot use RewriteMap in an .htaccess file, only in the main or in a virtual host configuration.
In this case If is causing the failure, because
Only directives that support the directory context can be used within this configuration section.
But RewriteMap may not be used in a directory context. So even if you have it in the main or virtual host configuration, you must not use it inside an If directive.

Is there a way for Apache to silently ignore unrecognized .htaccess directives?

I'm in the unfortunate position of having an Apache staging server combined with a Zeus web server. (Not my choice).
I'd like to be able to include a Zeus-specific directive in the .htaccess file (e.g. ContentCompressionEnabled) and, if possible, include the Apache equivalent (AddOutputFilterByType DEFLATE) in the same file too.
Is there a way of doing this which doesn't involve separate .htaccess files for Zeus and Apache?
Only in 2.4, where there is an Nonfatal option to AllowOverride.
If I understood correctly, you can use httpd.conf file do this configuration for all requests. .htaccess file configurations effect only requests to where the file located.
You could put any Apache only directives into either Apache's main httpd.conf file, or the sites vhost config file - along with AllowOverride None.
This would mean that Apache would get all it's config info from there and ignore any .htaccess files completely.
You could then place anything you wanted in the .htaccess files, including all the Zeus config you need - and Zeus would be configured only from there - thus separating the two configs.

identify Apache config directive

My website has a file: www.mydomain.com/contact.php
If I request any of the following (which do not exist), apache serves the contact.php page.
www.mydomain.com/contact
www.mydomain.com/contact/
www.mydomain.com/contact/anything/else/here
How can I determine what part of the apache config to change to disallow this?
The apache server is running on a CentOS 5 box if that makes any difference.
This is called MultiViews.
A .htaccess file or modifying your httpd.conf with Options -MultiViews should do the trick.