Hi
When I run httpd(8) behind relayd(8) the access log of httpd contains
the IP address of relayd, but not the IP address of the client. I've
tried to match the logs of relayd(8) and httpd(8) using some scripting
and failed.
So I've written a patch for httpd(8). It stores the content of the
X-Forwarded-For header in the third field of the log entry:
www.example.com 192.0.2.99 192.0.2.134 - [11/Nov/2018:09:28:48 ...
Cheers,
Bruno
Index: usr.sbin/httpd/server_http.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.127
diff -u -p -r1.127 server_http.c
--- usr.sbin/httpd/server_http.c 4 Nov 2018 05:56:45 -0000 1.127
+++ usr.sbin/httpd/server_http.c 11 Nov 2018 08:41:18 -0000
@@ -1632,7 +1632,7 @@ server_log_http(struct client *clt, unsi
static char tstamp[64];
static char ip[INET6_ADDRSTRLEN];
time_t t;
- struct kv key, *agent, *referrer;
+ struct kv key, *agent, *referrer, *xff;
struct tm *tm;
struct server_config *srv_conf;
struct http_descriptor *desc;
@@ -1642,6 +1642,7 @@ server_log_http(struct client *clt, unsi
char *version = NULL;
char *referrer_v = NULL;
char *agent_v = NULL;
+ char *xff_v = NULL;
if ((srv_conf = clt->clt_srv_conf) == NULL)
return (-1);
@@ -1666,7 +1667,7 @@ server_log_http(struct client *clt, unsi
*
* httpd's format is similar to these Apache LogFormats:
* "%v %h %l %u %t \"%r\" %>s %B"
- * "%v %h %l %u %t \"%r\" %>s %B \"%{Referer}i\" \"%{User-agent}i\""
+ * "%v %h %a %u %t \"%r\" %>s %B \"%{Referer}i\" \"%{User-agent}i\""
*/
switch (srv_conf->logformat) {
case LOG_FORMAT_COMMON:
@@ -1708,6 +1709,11 @@ server_log_http(struct client *clt, unsi
agent->kv_value == NULL)
agent = NULL;
+ key.kv_key = "X-Forwarded-For";
+ if ((xff = kv_find(&desc->http_headers, &key)) != NULL &&
+ xff->kv_value == NULL)
+ xff = NULL;
+
/* Use vis to encode input values from the header */
if (clt->clt_remote_user &&
stravis(&user, clt->clt_remote_user, HTTPD_LOGVIS) == -1)
@@ -1718,6 +1724,9 @@ server_log_http(struct client *clt, unsi
if (agent &&
stravis(&agent_v, agent->kv_value, HTTPD_LOGVIS) == -1)
goto done;
+ if (xff &&
+ stravis(&xff_v, xff->kv_value, HTTPD_LOGVIS) == -1)
+ goto done;
/* The following should be URL-encoded */
if (desc->http_path &&
@@ -1728,10 +1737,10 @@ server_log_http(struct client *clt, unsi
goto done;
ret = evbuffer_add_printf(clt->clt_log,
- "%s %s - %s [%s] \"%s %s%s%s%s%s\""
+ "%s %s %s %s [%s] \"%s %s%s%s%s%s\""
" %03d %zu \"%s\" \"%s\"\n",
- srv_conf->name, ip, clt->clt_remote_user == NULL ? "-" :
- user, tstamp,
+ srv_conf->name, ip, xff == NULL ? "-" : xff_v,
+ clt->clt_remote_user == NULL ? "-" : user, tstamp,
server_httpmethod_byid(desc->http_method),
desc->http_path == NULL ? "" : path,
desc->http_query == NULL ? "" : "?",
@@ -1762,6 +1771,7 @@ done:
free(version);
free(referrer_v);
free(agent_v);
+ free(xff_v);
return (ret);
}