Set Apache directive based on external environment variable with default - apache

I would like to do something like this with my Apache configuration:
<VirtualHost *:443>
DocumentRoot /var/www
TimeOut ${APACHE_TIME_OUT}
...
</VirtualHost>
where APACHE_TIME_OUT is an environment variable set in the OS before Apache starts. However, I would like Apache to use a suitable default if the environment variable APACHE_TIME_OUT is not defined.
I tried this without success:
<If "-n env('APACHE_TIME_OUT')" >
TimeOut ${APACHE_TIME_OUT}
</If>
The above generated the complaint "Config variable ${APACHE_TIME_OUT} is not defined".
This could be solved by always being sure that APACHE_TIME_OUT is defined before starting Apache, but I want to handle the case where APACHE_TIME_OUT might not be defined.

Related

Apache httpd.conf using defined variable in if statement

I try to make a universal httpd.conf using an if statement to decide which port is used.
# In HOME the path of the home directory of the apache user is set
PassEnv HOME
Define HTTPServerPath "${HOME}/HTTPServer"
<If "%{HTTPServerPath} -strcmatch '*something*'">
Define ListenPort 1080
</If>
<Else>
Define ListenPort 1180
</Else>
This does not work, as the variable from the Define line seems not available. How can I implement such an universal config file?
I found no solution for that. The workaround is now to start the service with a different parameter.
Start of service:
httpd start -Dsomething
#httpd start -DsomethingElse.
httpd.conf
<IfDefine something>
...
</IfDefine>
<IfDefine somethingElse>
...
</IfDefine>

Can you use Apache's <If> to conditionally set the Document Root (without using mod_rewrite)?

I need to set Apache's DocumentRoot directive inside a <VirtualHost> according to whether a particular remote IP address is calling it. I could use mod_rewrite for this but once I've "made the switch" I subsequently have a very complicated .htaccess file in the two destination folders themselves. I figure I need to do this inside httpd.conf. Is there a way to conditionally switch the entire Virtual Host directory based on my IP?
I am close with the following code, but it doesn't change based on my IP.
<VirtualHost _default_:443>
<If "-R '1.2.3.4'">
Define mydocumentroot "/var/www/just_for_me"
</If>
<Else>
Define mydocumentroot "/var/www/everyone_else"
</Else>
DocumentRoot ${mydocumentroot}
</VirtualHost>
The DocumentRoot variable correctly gets set to the mydocumentroot variable, but this always evaluates to the <Else> clause, no matter what I try.
Thanks!
After endless experiments and research it seems that doing any kind of switching in httpd.conf or .htaccess is slow and unnecessarily taxing for the server. I ended up working it out using a combination of mod_rewrite and soft links.

Apache VirtualHost conditional based on an environment variable

I'm trying to include a config file inside an Apache 2.4 <VirtualHost> based on the presence of an environment variable.
Inside the VirtualHost declaration, I set the VIEWMODE environment variable as such:
Define virtualhost_config "${virtualhost_path}/conf/virtualhost.conf"
<VirtualHost *:80>
SetEnv VIEWMODE demo
Include "${virtualhost_config}"
</VirtualHost>
Inside the included config file, I now have this conditional inside the <Directory> block:
<If "env('VIEWMODE') == 'demo'">
RewriteRule (.*) http://www.apple.com/ [L,R=302]
</If>
However, I can't seem to get this to work. The conditional RewriteRule is ignored.
What am I missing?
See the documentation for SetEnv:
The internal environment variables set by this directive are set after most early request processing directives are run, such as access control and URI-to-filename mapping. If the environment variable you're setting is meant as input into this early phase of processing such as the RewriteRule directive, you should instead set the environment variable with SetEnvIf.
And the note about environment variables within the functions section of the Apache Expresions documentation is also of interest:
Environment variable ordering
When environment variables are looked up within an <If> condition, it's important to consider how extremely early in request processing that this resolution occurs. As a guideline, any directive defined outside of virtual host context (directory, location, htaccess) is not likely to have yet had a chance to execute. SetEnvIf in virtual host scope is one directive that runs prior to this resolution
When reqenv is used outside of <If>, the resolution will generally occur later, but the exact timing depends on the directive the expression has been used within.
So you need to use SetEnvIf because SetEnv is not processed soon enough, and that fixed it for me when I tested here. Something like:
Define virtualhost_config "${virtualhost_path}/conf/virtualhost.conf"
<VirtualHost *:80>
SetEnvIf Request_URI ^ VIEWMODE=demo
Include "${virtualhost_config}"
</VirtualHost>
I solved this by setting an Apache variable, which then fed both the SetEnv directive as well as the <If> block. Unfortunately, the <If> block itself seemed to cause issues with the processing order of directives inside it (e.g. ServerAlias not allowed here), but <IfDefine> did not have this problem (using <IfDefine> only worked for me because VIEWMODE was binary). The final solution looked something like this:
Define environment production
Define viewmode demo
<VirtualHost *:80>
SetEnv ENVIRONMENT ${environment}
<IfDefine viewmode>
SetEnv VIEWMODE ${viewmode}
Include "${virtualhost_path}/conf/demo-configuration.conf"
</IfDefine>
</VirtualHost>
UnDefine environment
UnDefine viewmode
An important caveat is that Apache variables are global, so if the same variables might be used in subsequent Virtual Hosts, make sure to UnDefine them at the end of each config.

Debug Environment Variables in Apache VirtualHost

I'm using ProxyPass while attempting to set a request header in my vhost w/:
<VirtualHost *:443>
...
RequestHeader set X-REMOTE-USER "%{REMOTE_USER}s"
ProxyPass / http://127.0.0.1:9292/
ProxyPassReverse / http://127.0.0.1:9292/
...
</VirtualHost>
However when inspecting the headers that are getting sent to my application running on port 9292 I see:
"HTTP_X_REMOTE_USER"=>"(null)"
Does this mean that REMOTE_USER is not set or am I using RequestHeader incorrectly? Is there a way to debug what environment variables I have available to me within the vhost?
The problem is that, those variables are available for mod_rewrite but not to mod_headers.
Here you can found a complete answer to a similar problem:
REMOTE_USER through Apache reverse proxy
To get a list of all available enviroment variables you can use printenv command in the server, or browse this list of common enviroment variables.

Apache upgrade 2.2 -> 2.4 issue

I have got a problem with an update of Apache (from 2.2 to 2.4). I keep getting the same message while trying to access 'localhost'
.htaccess: RewriteEngine not allowed here
Also the result that I get from browser is 500 Internal Server Error.
I have completely change old authorization tags from Allow from all to Require all granted, still the same. Tried to load mod_access_compat - still the same.
Any ideas? My httpd.conf is almost a default one at the moment, the only changes are DocumentRoot and Directory.
I got confused while editing my old httpd.conf - it had configured DocumentRoot as follows:
DocumentRoot "web/"
#
# This should be changed to whatever you set DocumentRoot to.
#
<Directory "web/">
...
With this configuration, new Apache would not like to work. I changed Directory to "/" and it worked.
It is also neccessary to load mod_rewrite module and setup AllowOverride to All (or FileInfo).