SetEnv not updating my environment variable (noob warning) - apache

I am still an Apache noob, and I am trying to set an environment variable that will be used by my Rails application.
I've read https://httpd.apache.org/docs/2.4/mod/mod_env.html#setenv and done some google and SO searches. I have at least determined that the value to be assigned must be in quotes. However, when I run sudo service apache2 restart, the value of SECRET_KEY_BASE is still not correct (viewed via printenv). I don't know what I don't know. Is there some step i'm missing?
In my apache configuration I have:
SetEnv SECRET_KEY_BASE "e10e721..."
# Tell Apache and Passenger where your app's 'public' directory is
DocumentRoot /var/www/some_path
Please let me know what other information I might need to share. Thanks for looking.

There are a few subtle pitfalls here.
First: You can't check it in the terminal you ran that command from. "SetEnv" sets a per-request internal variable that will be copied to CGI-like processes that the server subsequently executes.
Secondly, even if you set a real native environment variable (in e.g. /etc/apache2/envvars) you should not do a restart operation since that will not necessarily reload that particular file. You should do a stop and a start. You still won't see the variable in the command you start the server from, since it was only in the webserver process.
If you want to see the environment of a running process, you can write a basic CGI to dump the environment that was passed down to the CGI script. If you're a PHP user, a basic script with phpinfo() will dump it.
Or, you can determine Apache's process ID with ps and then check /proc/$thepid/env (on Linux).

Related

Dynamically disabling/omitting Apache configuration directives (DRY)

I am working on a product that runs Apache, and i'm trying to make the configuration more DRY — right now there are many different vhost configs that get loaded in different situations but are 90% identical, and this is very tedious to deal with when a change needs made. I don't think Apache is really designed with this kind of dynamic environment in mind, but w/e, here i am anyway.
So i've first turned to environment variables — i have a small boot-strap script that determines the necessary configuration and dumps variables into /etc/apache2/envvars (which is loaded by apache2ctl and similar on Ubuntu). This allows me to do things like this:
envvars:
export MYKEY='/path/to/mykey'
export MYCERT='/path/to/mycert'
export MYBUNDLE='/path/to/mybundle'
vhost config:
SSLCertificateKeyFile ${MYKEY}
SSLCertificateFile ${MYCERT}
SSLCACertificateFile ${MYBUNDLE}
This works fine, but only as long as MYKEY, &al., are non-empty variables referencing non-empty files. In some configurations, for example, no CA bundle is required, so i tried just pointing MYBUNDLE to /dev/null. Apache considers this a 'syntax error' because /dev/null is an empty file, and refuses to start.
My question: Is there any way i can dynamically disable/omit configuration directives in the Apache config (based on environment variables or a similar mechanism) without having to maintain separate files for each possible scenario?
Alternative question: Is there any way i can provide an empty value/certificate to this particular directive (SSLCACertificateFile) in a manner that Apache won't consider invalid?
Ubuntu 12.04.5
Apache 2.2.22
Looks like what you want is a management tool for your configuration.
Now I'm not sure how often you deploy but you probably could make a script that generates your templates for you?
If you have a greater need, maybe consider automation software and use some kind of template? I'm thinking something like chef (https://www.chef.io/) or puppet (http://puppetlabs.com/) or ... They all support template and you can provide value based on environment / server / moods for the different values.

propagate operating system variable in apache server

I'm trying to read the operating system variable HOMEPATH from apache but the getenv() doesn't work in the browser but works in command line.
I have read several articles and they say it's a permission issue. But is there a way to propagate the operating system variable to be an apache env variable when apache starts?
I'm assuming you are on linux, and if you aren't I'm just posting this here for record (my search was fruitless, I'm on CentOS 6.5)
From what I understand, there's no way to provide apache any direct access to the environment variables including variables from the environment of the user that started the apache process and global environment variables you've specified within /etc/profile.d startup scripts.
Since I'm using bash, I have a variables.bashrc file that I source from my ~/.bashrc. This variables.bashrc declares my user environment variables. Within my apache startup script (/etc/init.d/httpd) I have added a line
. /path/to/variables.bashrc
that sources the same variables as my user has access to. This makes these environment variables available to apache.
Apache may receive the variables but it can also block the variables unless you explicitly say to pass them on to your scripts. This uses mod_env so you must ensure this module is loaded So you'll have to add
PassEnv VARIABLE_NAME
to the directory/virtual host you are configuring. For example...
<Directory "/path/to/cgi/scripts/">
AllowOverride None
Options None
Order allow,deny
Allow from all
PassEnv VARIABLE_NAME
</Directory>
This will make it available to your CGI scripts, or whatever script may be trying to access environment variables.
I'm not sure if this is the most elegant way to solve this, so I would be interested to see what other people have done to solve this issue... perhaps some automated way (mod_something) to make these variables visible.
Thanks.

Can I execute a shell script when restarting (starting) apache webserver

I have an application with some cacheing backend and I want to clear the cacheing whenever the webserver is been restarted.
Is there a apache configuration directive or any other way to execute a shell script upon webserver (re)start?
Thanks,
Phil
Adding some more information, as asked by some answers already:
Base system is ofc linux based, in this exact situation: CentOs
Modifying the startup script is unfortunately no option as pointed out by one of the comments already, due to it beeing not configuration file within the respective RPM packages and therefor beeing replaced by updates. Also I think modifying the startup script would be a bad thing in general
I see, that actually linking both "restarting the webserver" and "clearing my app cache" is not exactly what should be tied together. I will consider other alternatives
My situation is as follows: I can define how the virtual host config looks like, but I can not define how the rest of the servers configuration looks like.
The application is actually PHP based (and runs on the symfony framework). Symfony pre-compiles alot of stuff into dynamic php files from what it finds in the static configuration files. We deploy our apps via RPM and after deployment, an webserver restart is actually initiated already, so I thought it might make sense to tie the cache-cleanup to it. But I think after getting all your feedback, it looks like it is better to put the cache cleanup process into the installation process itself.
You haven't provided a lot of detail here, so it's hard to give a concrete answer, but I would suggest that your best option is to write a script which handles restarting apache, and clearing your cache. It would look something like this:
#!/bin/sh
# restart apache
/etc/init.d/httpd graceful
# whatever needs to be done to clear cache
rm -rf /my/cache/dir
Ramy suggests modifying the system startup script for Apache -- this is a bad idea! If and when you update Apache on your server, there is a good chance that your change will be lost.
Dirk suggests that what you are trying to do is probably misguided, and I think he's right. You haven't told us what platform you are running, but I can think of few situations where restarting your webserver and clearing a cache actually need to happen together.
You can modify Startup script for the Apache Web Server in /etc/init.d/httpd and write your own syntax inside it.
chattr +i /etc/init.d/httpd
If you have (root) access to the server you could do this by shell scripts but I would consider if it is the best way of cache management to rely on apache restarts.

Is there a way to check if a directory exists in Apache configuration files?

Is there a way to include configuration settings in Apache based on if a directory exists? Basically I have a portable hard drive that I transport between work and home that has some stuff I'm developing on it. I only want the Apache config to load a particular virtual host if the folder exists.
Since Apache 2.4.34 you can now use <IfFile>...</IfFile> which will check to see if a file exists. There's more details on the <IfFile> page.
No, there seems to be no direct way to do this.
The only thing that might be a solution is the IfDefine directive. You can define defines using the -d parameter to when the server is started.
The parameter-name argument is a define as given on the httpd command line via -Dparameter-, at the time the server was started.
You might be able to check for the existence of a directory in a batch or bash file, and set the -d parameter accordingly.
Whether that is an option, will depend on how your server is started from the portable hard drive.
I've come up with a solution that seems to work for Linux and OS X, and it hinges on "mountpoints". It might be possible to emulate it within Windows, as well, but you would probably have to get creative with FUSE and/or Cygwin.
If you create an empty folder in your home directory, such as "/Users/username/ExtraVhosts", you can add an apache directive to "Include /Users/username/ExtraVhosts/*".
Then, when you insert your thumb drive, you can mount somewhere and then use mountpoint "binding" to cross-link the ExtraVhosts folder to a folder on the mobile device.
An OS X example:
I have a thumb drive called 'Cherrybomb'
When I insert it, it always gets mounted to /Volumes/Cherrybomb
I can then use bindfs (sudo port install bindfs) to mount a subfolder of it, like so:
sudo bindfs /Volumes/Cherrybomb/Projects/vhosts /Users/username/ExtraVhosts
Then I can restart apache to read in the updated configuration:
sudo /opt/local/apache2/bin/apachectl restart
At that point, it's just a matter of adding entries in /etc/hosts for server aliases to get picked up.
The linux equivalent would be using the "--bind" parameter of the mount command.
One caveat: This makes it difficult to quickly unmount the USB drive, since it is always marked as "in use" by apache. Here's a removal procedure:
Close all open files and terminal sessions that are using the drive (the present-working-directory in terminal can cause unmount issues)
Stop apache: sudo /opt/local/apache2/bin/apachectl stop
umount /Users/username/ExtraVhosts
Then you can either unmount it graphically or manually (umount /Volumes/Cherrybomb).
If your work and home machines mount the drive to different locations, you could have multiple vhosts folders - home_vhost, work_vhost, etc - and use that in the binding step.
I hope this helps someone out :)
If you point apache to the mountpoint only there shouldn't be an issue. Just don't point Directory directives to directories within the drive.
eg, if you mount /dev/somedisk /mnt/somevhost, the
/mnt/somevhost directory will be there whether or not you have the drive mounted and apache will start. Apache doesn't care if the directory is empty so a <Directory "/mnt/somevhost"/> won't cause server to not start if the drive isn't mounted.
Work with UNIX not against it :-p This solution should be sufficient for development.

Getting Apache to execute command on every page view

Is there any way to get Apache to run a command/program every time a web page is requested? I know I could scan the logs for new entries every minute or so, but can I get Apache to directly call the command? There might be an option like this in one of the configuration files, but if there is I don't know what it is. My server is running Ubuntu 9.04.
You can use the CustomLog directive to pipe the access log to a script or program, which could be useful in your situation. All you would have to do is set up a while loop (or similar structure) on STDIN in the language of your choice and then execute your command from there.
http://httpd.apache.org/docs/2.2/logs.html#piped