When configuring Apache HTTP Server (2.4.6+), many administrators need to expose server information through custom headers while maintaining environment variable flexibility. The specific challenge occurs when trying to reference system environment variables like HOSTNAME
in Header set
directives.
The mod_headers
documentation correctly states that environment variables should be referenced with %{VARNAME}e
syntax. However, there are three critical layers where this can fail:
# Common failure pattern:
Header set X-Server-Name %{HOSTNAME}e # Returns literal "%{HOSTNAME}e"
# Working alternatives:
SetEnv MY_HOSTNAME "${HOSTNAME}"
Header set X-Server-Name "%{MY_HOSTNAME}e" # Requires proper variable scoping
Option 1: Using PassEnv (System to Apache)
# In httpd.conf or virtual host:
PassEnv HOSTNAME
Header set X-Server-Name "%{HOSTNAME}e"
Option 2: Variable Chaining
# Capture system env then pass to header:
SetEnvIfExpr "true" APACHE_HOSTNAME=%{ENV:HOSTNAME}
Header set X-Server-Name "%{APACHE_HOSTNAME}e"
Option 3: Direct Shell Reference (For Static Values)
# For values that won't change during runtime:
Header set X-Build-Date "%{TZ}e $(date +%Y-%m-%d)"
- Verify environment variables exist in Apache's context using
%{ENV:VAR}
in ErrorLog - Check
envvars
file for Apache's startup environment - Confirm
LoadModule headers_module
is active - Test with simple values before complex expressions
<IfModule mod_headers.c>
# Combine multiple environment variables
SetEnvIfExpr "true" SERVER_ID="app-%{ENV:HOSTNAME}-%{UNIQUE_ID}e"
Header set X-Server-Identity "%{SERVER_ID}e"
</IfModule>
When working with Apache's mod_headers, many developers encounter issues when trying to inject environment variables into HTTP response headers. The documentation suggests using the %{VARNAME}e
syntax, but in practice, this often results in null values or literal strings being output instead of the expected variable contents.
The primary reasons your attempts aren't working:
# This doesn't work because:
Header Set X-Serv %{HOSTNAME}e
# And this fails because:
SetEnv myvar ${HOSTNAME}
Header set X-Serv %{myvar}e
1. Apache doesn't automatically import system environment variables
2. The ${HOSTNAME} syntax works in shell but not in Apache config
3. The SetEnv directive creates request environment variables, not server ones
Solution 1: Using mod_env to Pass System Variables
# In your httpd.conf or vhost configuration:
PassEnv HOSTNAME
Header set X-Server-Name "%{HOSTNAME}e"
Solution 2: Alternative Using ServerName
# If you just need the server's hostname:
Header set X-Server-Name "%{SERVER_NAME}e"
Solution 3: For Custom Environment Variables
# Set via shell before starting Apache:
export MY_CUSTOM_VAR="production"
# In Apache config:
PassEnv MY_CUSTOM_VAR
Header set X-Environment "%{MY_CUSTOM_VAR}e"
To verify if your variables are available to Apache:
# Create a test PHP file:
<?php phpinfo(INFO_ENVIRONMENT); ?>
# Or for shell access:
sudo -u apache env
For complex scenarios, consider using RewriteMap:
RewriteEngine On
RewriteMap serverinfo "prg:/etc/apache2/get-server-info.sh"
Header set X-Server-Info "${serverinfo}"
Where get-server-info.sh might contain:
#!/bin/sh
echo "Host: $(hostname), IP: $(hostname -I)"
When exposing server information via headers:
- Never expose sensitive data in headers
- Consider using this only in internal networks
- Use custom headers (X- prefix) rather than standard ones