How to Log HTTP/HTTPS Scheme in Apache Like Nginx’s $scheme Variable


2 views

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