Passing variables to httpd

Latest response

I have installed RHEL 7.1 and Apache 2.4 on a server and I am able to serve up a web page. Now I am trying to configure Apache. From what I can see when I start apache using "systemctl start httpd.service" the script /usr/sbin/apachectl gets executed and sources in the contents from /etc/sysconfig/httpd.

I am not sure where RHEL's ownership ends and where Apache's ownership begins in this process. I have been told that the distro owns /etc/sysconfig/httpd and Apache owns /usr/sbin/apachectl but there does not appear to be any documentation on what is allowed in /etc/sysconfig/httpd.

What I want to do is pass variables to the httpd.conf file to drive some of the configuration and create more generic configuration files that can be shared between servers.

The following in supposed to be the correct syntax but that generates an error message.
export HTTPD_VAR1="devl"
Jun 10 06:24:56 server02 systemd[1]: Ignoring invalid environment 'export HTTPD_VAR1=devl': /etc/sysconfig/httpd

However if I split the line with the variable assignment first and the export second there is no error message and the variable is available in httpd.conf. Then I wanted to be a little more creative and assign a dynamic value to the variable with HTTPD_VAR2=hostname and HTTPD_VAR3=$(hostname). This however did not work. What I got in the httpd.conf file was variables with values "hostname" and "$(hostname)."

Looking on the web I found the following example to leads me to believe that what I want to do is something that is allowed.
export IPADDR_ETH0=$(ifconfig ens192 | grep inet | grep -v inet4 | awk '{print $2}' | sed -e s/addr://g)

So does anybody know what is allowed and what is not allowed in /etc/sysconfig/httpd? Any insight into this would be greatly appreciated.

Responses

Good question!

You aren't supposed to pass dynamic configuration parameters or shell expansions within init. One of the purposes of an init daemon is to sanitize all environment variables away so they don't interfere with the starting of services.

You can however pass environment variables with systemd using Environment= in the systemd unit file, see man systemd.exec for more info about this.

I don't know if you can perform shell expansions like $(hostname) in there, but I wouldn't expect so. Putting the correct hostname/IP into httpd.conf is really a host-based configuration problem to be solved with a configuration management tool (like Puppet).

Also maybe I am too fussy but various incantations of ifconfig | grep and ip addr | grep really grind my gears, they can be unreliable across Linuxes, are non-portable across Unixes, and the older tools like ifconfig/route/arp are considered deprecated in favor of the iproute2 utils.

The moreutils collection includes ifdata so you can run ifdata -pa ethX and get JUST strings containing the IPs on the interface. moreutils is packaged in EPEL, and depends on some things in the Optional channel on RHEL7.

Facter is available from the RHEL 7 repo and provides what you want:

facter ipaddress_eth0
10.0.0.5

Just don't look under the covers for how it's doing it.. will likely grind your gears.

Well I just had to look after you said that :) oh dear...

Jamie,

Thanks for the information. We only have a couple of apache servers each with a httpd.conf that has an include of either test.conf or prod.conf. The two include files contain all the virtual host configurations. What I was hoping to do was have identical httpd.conf files on all servers with a directive with a regular expression as our server names have test or prod in the name.

As I am only now getting into the system side of things I guess I need to get working on my system knowledge.

Ah, I understand!

I don't believe there's a way to set a variable in the httpd conf based on system hostname.

One easy way to achieve your aims could be to only deploy /etc/httpd/conf.d/prod.conf to the prod hosts, and only deploy /etc/httpd/conf.d/test.conf config to the test hosts.

You could also write a small script which modifies the httpd.conf outside of init or the webserver, and you run the script whenever you deploy or re-purpose a system. For example:

#!/bin/bash
if [[ $(hostname) == *"prod"* ]]; then
  sed -ibak \
    -e 's%^Include test.conf%#Include test.conf%' \
    -e 's%^#Include prod.conf%Include prod.conf%' \
    /etc/httpd/conf/httpd.conf
  logger -t ddevos "httpd configured with prod config"
elif [[ $(hostname) == *"test"* ]]; then
  sed -ibak \
    -e 's%^Include prod.conf%#Include prod.conf%' \
    -e 's%^#Include test.conf%Include test.conf%' \
    /etc/httpd/conf/httpd.conf
  logger -t ddevos "httpd configured with test config"
fi

At least that would let you put the same files on all servers, and just needs you as sysadmin to manually run the script at least once.

Close

Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.