Is it safe to source system-wide environment variables in apache envvars? - php

I am trying to set an environment variable on Linux which should be available in shell as well as Apache.
I added the variable to /etc/environment, so the file looks something like this:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
MY_VAR="foo"
To have MY_VAR available in apache, this is what I added in /etc/apache2/envvars:
. /etc/environment
export MY_VAR=$MY_VAR
After doing a lot of research, this is the only way I was able to get the same environment variable work system-wide and in Apache without having to declare them twice.
Are there any security concerns with this approach?

In general, you don't need to use the keyword export when sourcing scripts.
Therefore the extra script (i.e. my_apacheenv.sh) should have this format:
VARIABLE_A="some hardcoded value"
VARIABLE_B="${DYNAMIC_ONE}"
VARIABLE_C="${APACHE_HOSTNAME}"
and be sure it is marked as executable (chmod +x /path/to/my_apacheenv.sh).
The file /etc/apache2/envvars should contain:
. /path/to/my_apacheenv.sh
Then you can define the value of DYNAMIC_ONE or APACHE_HOSTNAME in any usual way, either in the session or as environment variable.
For me, it works pretty well when used in combination of a docker-compose file:
version: "3"
services:
single-apache-php:
build: ./../cicd/apache
environment:
APACHE_HOSTNAME: "my.dynamic.hostname.com"

I was able to solve my own problem. I removed MY_VAR from /etc/environment and created a separate file /etc/profile.d/apache.sh which looks like this:
export MY_VAR="foo"
Then I sourced this file in /etc/apache2/envvars like so:
. /etc/profile.d/apache.sh
Any variable set in apache.sh is available system-wide as well as in Apache
Because apache.sh is a script, unlike /etc/environment, the variables do not have to be "export"ed again in envvars
There is no security risk because no unwanted variables are passed magically to Apache
Whatever variables you want to be available system-wide as well as Apache, you add it to apache.sh and if you want it only in Apache then you add it in envvars

Related

Is there a way to access Apache2's SetEnv variables through PHP CLI?

I need to run a php script to refresh data every 10 minutes, and I'm doing it using cron.
crontab -e configuration is:
*/10 * * * * php my_file.php
In this file, I'm using $_SERVER['my_env_var'] to retrieve the value of the variable, which is an encrypted string (it is set in apache2.conf as SetEnv MY_ENCRYPTED_VALUE something).
Using debug in web browser will correctly output the values (it is being run with apache, so it can read the file and recognize I'm calling the variables set on the server).
However, cron is using the CLI. And when using
<?php
print_r($_SERVER);
?>
my variables are not listed in here.
I do understand they do not share the same .ini files and SAPIs (apache2handler vs cli).
I have seen other posts that say:
"Set them as /etc/environment variables"
but if possible I would prefer not to use that (is it secure?).
But, is there a way to access Apache2's SetEnv variables through PHP CLI?
As #CBroe said, cli has no relationship with PHP in cli mode. And you still need some common environment variable, you can take help from CI CD pipelines. It will keep those secure and at one place.
We are talking about almost same thing, i am saying that env should be written by the pipeline to target system, rather manually maintained by some individual team.
CI CD pipeline give us a way to use env variables for any reason and security is very good candidate to use that.

What cache stores the windows PATH and how do I clear it?

I am using PHP in an HTML5 document in Windows 10, calling shell_exec() which I want to use to call Rscript, ultimately. The problem I have run into is that the environmental %PATH% variable in Windows that shell_exec() is getting from some cache somewhere is yesterday's version, which doesn't include the path to Rscript, so the call fails.
I carefully set both the personal and the system environmental PATH variables in Windows using the Windows tool to include a path to Rscript, and then later to remove another link to PERL to make sure the total path was below 260 characters, then I moved the Rscript path up to the front. No joy.
The following command pulls up a %PATH% from somewhere but I have no idea where If I simply use CMD to go to that directory and issue the commands via that shell, they find the right path, but if I call it via shell_exec() it's the old path. I've tried rebooting and clearing the browser caches so I'm pretty sure this is a PHP cache thing, but I see many references to cahces here to figure out which one I'm facing.
So any help would be appreciated.
This code shows the OLD path, not the current one:
shell_exec("echo %PATH% > outputFilexx.Rout 2> errorFilexx.Rout");
Environment variables are not really cached but simply part of the run-time environment of a process. A new process inherits all environment variables and their values - at that time when it is started - from its parent process.
After that changing the value of an environment variable in one process does not affect other (already running) processes.
How to change an environment variable of a running process depends on the program and may not always be possible. To "reload" environment variables otherwise you need to restart the process - and possibly also their parent processes since otherwise they would inherit the "old" values from them again.
I.e. you not only should restart PHP/Apache but also the WAMP console so %PATH% is inherited from the system environment. To be completely sure you can just reboot the whole machine.
But environment variables may also be change via application depend configurations. So you could change the PATH only for
Apache via SetEnv
PHP via putenv()

How to set global environment variables for PHP

I have read the question/answers here but I don't understand how to set variables in /etc/environment. If I edit the file, do I need to restart my machine or simply log out my current user (or log in a new one?).
I want to set a global variable to denote that websites on my machine are in 'development' or 'testing' mode. I don't want to have to set this for every project (whether it uses PHP, Java/Tomcat, NodeJS, etc). I'm aware that (for Apache) I can set the environment variable in the following ways:
directly from php with putenv() (this seems useless since I want to avoid logic that tries to figure out what server the files are on)
using .htaccess SetEnv ENVIRONMENT 'local' (this would require me to duplicate this file/code for every server, not ideal)
using a Virtual Host directive SetEnv ENVIRONMENT 'local' (if I'm using a virtual host, which in nearly all cases I am, but again requires me to copy/paste code over and over again)
in httpd-conf SetEnv ENVIRONMENT 'local' (this will only apply to apache, and I would like it to apply to NodeJS servers as well)
I'm not saying I can't do #4 (and apply #3 selectively to NodeJS servers). But I'm thinking that this is a good reason to use /etc/environment. As I said above, I have edited the file (after first creating it) and tried the following combinations, none of which seemed to work:
ENVIRONMENT='local'
ENVIRONMENT=local
export ENVIRONMENT='local'
export ENVIRONMENT=local
I say that none of them worked because I did not find the variable in output from:
print_r($_SERVER);
print_r($_ENV);
echo(getenv('ENVIRONMENT'));
What you want to do is use an Apache configuration file. You will need access to a configuration folder and the httpd.conf file (or modified version). You can then configure the httpd.conf to dynamically load configuration files using this approach
Include conf.d/*.conf
Inside the conf.d folder you place your specific environment configuration files.
server-environment-dev.conf example:
SetEnv ENVIRONMENT "local"
server-environment-prod.conf example:
SetEnv ENVIRONMENT "production"
These settings will show up in your php code as available environment variables. This approach allows you to keep your vhost files, .htaccess, and your other configuration files agnostic of the environment.
etc/environment, etc/profile.d, .bash_profile, .profile, etc files are not readable by PHP in Apache due to some process/user limitations. You can bash, smash, crash the variables all you want and see them set in your terminal but they will not show up in phpinfo() unless you set it via one of the Apache configuration files.
For NodeJS you can start the app passing in your environment variable or you can set the NODE_ENV in multiple ways include your .bash_profile and possibly etc/environment file if you want to be user agnostic.
A good read for Node:
http://www.hacksparrow.com/running-express-js-in-production-mode.html
So I would assume you have a global config file somewhere. Why not put a constant in that file that you can change? Would be far easier that trying to set something on the server level.
define('ENVIRONMENT', 'testing');
if(ENVIRONMENT == 'testing') {
echo 'We\'re just testing';
}
If you still can't get your environment variables:
you may need to edit your real httpd.conf in
~/Library/Application Support/appsolute/MAMP PRO/
instead of
/Applications/MAMP/conf/apache/
Also you may need to use getenv() instead of $_ENV

PHP and Apache environment variables

I want to pass an environment variable in linux to apache on start up.
export MYVAR=5
--I define my environment variable on the command line
PassEnv MYVAR
--set apache to import the variable in apache config file
apachectl restart
--when I restart apache I don't get an error message. However I have noticed
that if I do not create the environment variable in my first step, I get a warning message, so must be working here
echo $_SERVER['MYVAR']
--i try to access the environment variable within PHP but it is not defined
I've observed that if I try to PassEnv an environment variable that already exits (one that I havn't created myself) it works fine. The SetEnv directive also works fine.
I'd really like to pass an environment variable to apache on the fly without writing it in a file. Help much appreciated.
I'm using CentOS, PHP5 and Apache2.
Thanks.
update
it seems the environment variable gets passed if i invoke the apache startup directly with httpd and not use apachectl which is a shell script. I would have thought that the "export" would have exported the variable to the shell script no? I am not a linux guru so excuse my lack of knowledge.
If you want the environment variable to be passed to apache, you should make sure that said environment variable is defined for the environment that apache is running in. To do that, the easiest option is to add an export MYVAR=value line to envvars (should be located in /etc/apache2) or the script that starts apache (in /etc/init.d), and add your PassEnv MYVAR where it's wanted in your apache configuration.
Restarting apache should make sure the MYVAR environment variable is passed. AFAIK you won't be able to change the value of this var while apache is running though...
Some relevant info for CentOS : http://php.dzone.com/news/inserting-variable-headers-apa&default=false&zid=159&browser=16&mid=0&refresh=0
You should access environment variables using the superglobal $_ENV:
$_ENV['MYVAR']
http://www.php.net/manual/en/reserved.variables.environment.php
Update
Your variable may actually be under $_SERVER afterall, as per the link below. Worth checking $_ENV though.
As per http://www.php.net/manual/en/reserved.variables.environment.php#97105
To expand on wimvds' answer above; you can change environment variables while Apache is running with the SetEnvIf module. Specifically, the SetEnvIf directive of said module.
e.g.
SetEnvIf Request_URI "^.*\/foobar.*$" FOOBAR="something"
The above example will set the $FOOBAR environment variable to "something" if the regex matches the request URI (in this case, any URI containing the word "foobar"). You can define this in your host's configuration file (usually in /etc/apache2/sites-available/mywebsite.conf or something similar).

reinitialize system wide environment variable in linux

I just want my apache to register some of my predefined environment so that i can retrieve it using getenv function in php. How can i do this? I tried adding /etc/profile.d/foo.sh with export FOO=/bar/baz using root and restarted apache.
Environment variables are inherited by processes in Unix. The files in /etc/profile.d are only executed (in the current shell, not in a subshell) when you log in. Just changing the value there and then restarting a process will not update the environment.
Possible Fixes:
log out/log in, then start apache
source the file: # . /etc/profile.d/foo.sh, then restart apache
source the file in the apache init script
You also need to make sure that /etc/profile.d/ is sourced when Apache is started by init rather than yourself.
The best fix might also depend on the distribution you are using, because they use different schemes for configuration.
You can use SetEnv in your config files (/etc/httpd/conf.d/*.conf, .htaccess ...). Additionally you should be able to define them in /etc/sysconfig/httpd (on RPM-based distribs) and export them (note: not tested).
Note: it wouldn't surprise me if some distributions tried quite hard to hide as much as possible, as far as system config is concerned, from a publically accessible service such as Apache. And if they don't, they might start doing this in a future version. Hence I advise you to do this explicitly. If you need to share such a setting between Apache and your shells, you could try sourcing /etc/profile.d/yourprofile.sh from /etc/sysconfig/httpd
Apache config files allow you to set environment variables on a per site basis.
So if your web server is serving pages from two logical sites you can have the same environment variable set differently for each site and thus get your PHP to react differently.
See the Apache mod_env for details:
If you need env vars for Apache only, what worked for me was editing the /etc/apache2/envvars and restart of Apache. I added these settings:
export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'

Categories