diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c index 28e01df..19fe22b 100644 --- a/modules/metadata/mod_remoteip.c +++ b/modules/metadata/mod_remoteip.c @@ -44,6 +44,12 @@ typedef struct { * from the proxy-via IP header value list) */ const char *proxies_header_name; + /** A header that may indicate user is using a + * HTTPS connection to the reverse-proxy, and + * the value that it must match for it to do so. + */ + const char *secure_header_name; + const char *secure_header_value; /** A list of trusted proxies, ideally configured * with the most commonly encountered listed first */ @@ -85,6 +91,12 @@ static void *merge_remoteip_server_config(apr_pool_t *p, void *globalv, config->proxymatch_ip = server->proxymatch_ip ? server->proxymatch_ip : global->proxymatch_ip; + config->secure_header_name = server->secure_header_name + ? server->secure_header_name + : global->secure_header_name; + config->secure_header_value = server->secure_header_value + ? server->secure_header_value + : global->secure_header_value; return config; } @@ -106,6 +118,16 @@ static const char *proxies_header_name_set(cmd_parms *cmd, void *dummy, return NULL; } +static const char *secure_header_set(cmd_parms *cmd, void *dummy, + const char *name, const char *value) +{ + remoteip_config_t *config = ap_get_module_config(cmd->server->module_config, + &remoteip_module); + config->secure_header_name = name; + config->secure_header_value = value; + return NULL; +} + /* Would be quite nice if APR exported this */ /* apr:network_io/unix/sockaddr.c */ static int looks_like_ip(const char *ipstr) @@ -229,6 +251,7 @@ static int remoteip_modify_request(request_rec *r) char *proxy_ips = NULL; char *parse_remote; char *eos; + char *secure = NULL; unsigned char *addrbyte; /* If no RemoteIPInternalProxy, RemoteIPInternalProxyList, RemoteIPTrustedProxy @@ -394,6 +417,22 @@ static int remoteip_modify_request(request_rec *r) return OK; } + if (config->secure_header_name) { + secure = (char *) apr_table_get(r->headers_in, config->secure_header_name); + } + + if (secure) { + if (!strcmp(secure, config->secure_header_value)) { + apr_table_setn(r->subprocess_env, "HTTPS", "on"); + apr_table_setn(r->subprocess_env, "SERVER_PORT", "443"); + } + /* Header is available. Unset even if no match. */ + apr_table_unset(r->headers_in, config->secure_header_name); + } + else { + secure = NULL; + } + req->proxied_remote = remote; req->proxy_ips = proxy_ips; @@ -417,9 +456,10 @@ static int remoteip_modify_request(request_rec *r) ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, req->proxy_ips - ? "Using %s as client's IP by proxies %s" - : "Using %s as client's IP by internal proxies%s", + ? "Using %s as client's IP by %s proxies %s via" + : "Using %s as client's IP by %s internal proxies %s", req->useragent_ip, + secure ? "HTTPS" : "HTTP", (req->proxy_ips ? req->proxy_ips : "")); return OK; } @@ -447,6 +487,9 @@ static const command_rec remoteip_cmds[] = RSRC_CONF | EXEC_ON_READ, "The filename to read the list of internal proxies, " "see the RemoteIPInternalProxy directive"), + AP_INIT_TAKE2("SecureIndicatorHeader", secure_header_set, NULL, RSRC_CONF, + "Specifies a request header and value that indicates a secure connection, " + "e.g. \"X-Forwarded-Proto https\" or \"X-Secure-Connection on\""), { NULL } };