When working with web servers, logging the protocol scheme (http or https) is crucial for security analysis, traffic monitoring, and debugging. While Nginx provides the convenient $scheme
variable, Apache requires a different approach.
Apache's mod_log_config provides several useful variables, but none directly equivalent to Nginx's $scheme
:
%{SCHEME}e - Environment variable (not reliable)
%H - Protocol version (HTTP/1.1, etc.)
%r - First line of request
The most reliable method is to use mod_rewrite to set an environment variable based on the scheme:
RewriteEngine On
RewriteCond %{HTTPS} =on
RewriteRule ^ - [E=REQUEST_SCHEME:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^ - [E=REQUEST_SCHEME:http]
Add this to your httpd.conf or virtual host configuration:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{REQUEST_SCHEME}e" combined_with_scheme
CustomLog /var/log/apache2/access_log combined_with_scheme
For reverse proxy setups, you might use:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{X-Forwarded-Proto}i\"" proxy_scheme
After restarting Apache, your logs will now contain the scheme information:
192.168.1.1 - - [10/Oct/2023:12:34:56 +0000] "GET / HTTP/1.1" 200 1234 "-" "Mozilla/5.0" https
The mod_rewrite solution adds minimal overhead as the rules are processed very early in the request cycle. For high-traffic servers, the impact is negligible compared to the logging benefits.
When analyzing web server logs, knowing whether requests were made via HTTP or HTTPS is crucial for:
- Security auditing and compliance monitoring
- Migration from HTTP to HTTPS tracking
- Mixed content troubleshooting
- Traffic analysis by protocol
While Apache doesn't have an exact equivalent to Nginx's $scheme
, we can leverage these variables:
%{SSL} # Returns "on" for HTTPS, empty for HTTP
%{HTTPS} # Same as above but more widely supported
%{SERVER_PORT} # Shows port number (80/443)
%{REQUEST_SCHEME} # Available in Apache 2.4+
For Apache 2.4 and newer, use this in your httpd.conf or virtual host:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{REQUEST_SCHEME}" combined_scheme
CustomLog logs/access-scheme.log combined_scheme
For older versions, create a conditional log format:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{HTTPS}" combined_conditional
CustomLog logs/access-conditional.log combined_conditional
When you need more sophisticated logging, consider these approaches:
1. Using SetEnvIf:
SetEnvIf X-Forwarded-Proto "^https$" HTTPS=on
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{ENV:HTTPS}" proxy_scheme
2. Rewriting Logs with ModSecurity:
SecRule REQUEST_SCHEME "@rx ^(https?)$" \
"phase:5,id:1000,nolog,pass,setenv:request_scheme=%{matched_var}"
Sample log entries from different configurations:
Apache 2.4+ output:
192.168.1.1 - - [10/Oct/2023:12:34:56 +0000] "GET /test HTTP/1.1" 200 1234 "-" "Mozilla/5.0" https
Legacy conditional output:
192.168.1.1 - - [10/Oct/2023:12:34:56 +0000] "GET /test HTTP/1.1" 200 1234 "-" "Mozilla/5.0" on
After configuration, verify with:
apachectl configtest
tail -f /var/log/apache2/access-scheme.log
Use this curl command to test both protocols:
curl -k http://yoursite.com
curl -k https://yoursite.com