From 26784728169754e5dd4d69cb8e807a91aac9234e Mon Sep 17 00:00:00 2001 From: Theo Buehler Date: Fri, 3 May 2019 17:16:28 +0000 Subject: Add a "forwarded" log format that extends the "combined" log format by including the contents of the X-Forwarded-For and X-Forwarded-Port headers. If httpd(8) runs behind a proxy like relayd(8), this allows tracking the origin of the requests. The format is compatible with log analyzers such as GoAccess and Webalizer. Patch from Bruno Flueckiger ok benno, reyk --- usr.sbin/httpd/httpd.conf.5 | 15 ++++++++++++--- usr.sbin/httpd/httpd.h | 5 +++-- usr.sbin/httpd/parse.y | 10 ++++++++-- usr.sbin/httpd/server_http.c | 46 +++++++++++++++++++++++++++++++++++++++----- 4 files changed, 64 insertions(+), 12 deletions(-) (limited to 'usr.sbin') diff --git a/usr.sbin/httpd/httpd.conf.5 b/usr.sbin/httpd/httpd.conf.5 index 0b221d0fa4a..3290048e36c 100644 --- a/usr.sbin/httpd/httpd.conf.5 +++ b/usr.sbin/httpd/httpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: httpd.conf.5,v 1.105 2019/04/16 20:52:47 jmc Exp $ +.\" $OpenBSD: httpd.conf.5,v 1.106 2019/05/03 17:16:27 tb Exp $ .\" .\" Copyright (c) 2014, 2015 Reyk Floeter .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: April 16 2019 $ +.Dd $Mdocdate: May 3 2019 $ .Dt HTTPD.CONF 5 .Os .Sh NAME @@ -453,7 +453,8 @@ The .Ar style can be .Cm common , -.Cm combined +.Cm combined , +.Cm forwarded or .Cm connection . The styles @@ -463,6 +464,14 @@ and write a log entry after each request similar to the standard Apache and nginx access log formats. The style +.Cm forwarded +extends the style +.Cm combined +by appending two fields containing the values of the headers +.Ar X-Forwarded-For +and +.Ar X-Forwarded-Port . +The style .Cm connection writes a summarized log entry after each connection, that can have multiple requests, diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h index 52d41b3d158..e599e88c56c 100644 --- a/usr.sbin/httpd/httpd.h +++ b/usr.sbin/httpd/httpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.h,v 1.143 2019/02/19 11:37:26 pirofti Exp $ */ +/* $OpenBSD: httpd.h,v 1.144 2019/05/03 17:16:27 tb Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter @@ -437,7 +437,8 @@ SPLAY_HEAD(client_tree, client); enum log_format { LOG_FORMAT_COMMON, LOG_FORMAT_COMBINED, - LOG_FORMAT_CONNECTION + LOG_FORMAT_CONNECTION, + LOG_FORMAT_FORWARDED }; struct log_file { diff --git a/usr.sbin/httpd/parse.y b/usr.sbin/httpd/parse.y index c6cb1ac32f7..84b9d601f43 100644 --- a/usr.sbin/httpd/parse.y +++ b/usr.sbin/httpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.110 2019/02/19 11:37:26 pirofti Exp $ */ +/* $OpenBSD: parse.y,v 1.111 2019/05/03 17:16:27 tb Exp $ */ /* * Copyright (c) 2007 - 2015 Reyk Floeter @@ -140,7 +140,7 @@ typedef struct { %token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET %token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST %token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE -%token CA CLIENT CRL OPTIONAL PARAM +%token CA CLIENT CRL OPTIONAL PARAM FORWARDED %token STRING %token NUMBER %type port @@ -1024,6 +1024,11 @@ logstyle : COMMON { srv_conf->flags |= SRVFLAG_LOG; srv_conf->logformat = LOG_FORMAT_CONNECTION; } + | FORWARDED { + srv_conf->flags &= ~SRVFLAG_NO_LOG; + srv_conf->flags |= SRVFLAG_LOG; + srv_conf->logformat = LOG_FORMAT_FORWARDED; + } ; filter : block RETURN NUMBER optstring { @@ -1295,6 +1300,7 @@ lookup(char *s) { "ecdhe", ECDHE }, { "error", ERR }, { "fastcgi", FCGI }, + { "forwarded", FORWARDED }, { "hsts", HSTS }, { "include", INCLUDE }, { "index", INDEX }, diff --git a/usr.sbin/httpd/server_http.c b/usr.sbin/httpd/server_http.c index 6c8549d2b41..ef45d884fc0 100644 --- a/usr.sbin/httpd/server_http.c +++ b/usr.sbin/httpd/server_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_http.c,v 1.129 2019/02/10 13:41:27 benno Exp $ */ +/* $OpenBSD: server_http.c,v 1.130 2019/05/03 17:16:27 tb Exp $ */ /* * Copyright (c) 2006 - 2018 Reyk Floeter @@ -1632,7 +1632,7 @@ server_log_http(struct client *clt, unsigned int code, size_t len) static char tstamp[64]; static char ip[INET6_ADDRSTRLEN]; time_t t; - struct kv key, *agent, *referrer; + struct kv key, *agent, *referrer, *xff, *xfp; struct tm *tm; struct server_config *srv_conf; struct http_descriptor *desc; @@ -1642,6 +1642,8 @@ server_log_http(struct client *clt, unsigned int code, size_t len) char *version = NULL; char *referrer_v = NULL; char *agent_v = NULL; + char *xff_v = NULL; + char *xfp_v = NULL; if ((srv_conf = clt->clt_srv_conf) == NULL) return (-1); @@ -1698,6 +1700,7 @@ server_log_http(struct client *clt, unsigned int code, size_t len) break; case LOG_FORMAT_COMBINED: + case LOG_FORMAT_FORWARDED: key.kv_key = "Referer"; /* sic */ if ((referrer = kv_find(&desc->http_headers, &key)) != NULL && referrer->kv_value == NULL) @@ -1734,9 +1737,9 @@ server_log_http(struct client *clt, unsigned int code, size_t len) (referrer_v = url_encode(referrer->kv_value)) == NULL) goto done; - ret = evbuffer_add_printf(clt->clt_log, + if ((ret = evbuffer_add_printf(clt->clt_log, "%s %s - %s [%s] \"%s %s%s%s%s%s\"" - " %03d %zu \"%s\" \"%s\"\n", + " %03d %zu \"%s\" \"%s\"", srv_conf->name, ip, user == NULL ? "-" : user, tstamp, server_httpmethod_byid(desc->http_method), @@ -1747,7 +1750,38 @@ server_log_http(struct client *clt, unsigned int code, size_t len) desc->http_version == NULL ? "" : version, code, len, referrer == NULL ? "" : referrer_v, - agent == NULL ? "" : agent_v); + agent == NULL ? "" : agent_v)) == -1) + break; + + if (srv_conf->logformat == LOG_FORMAT_COMBINED) + goto finish; + + xff = xfp = NULL; + + key.kv_key = "X-Forwarded-For"; + if ((xff = kv_find(&desc->http_headers, &key)) != NULL + && xff->kv_value == NULL) + xff = NULL; + + if (xff && + stravis(&xff_v, xff->kv_value, HTTPD_LOGVIS) == -1) + goto finish; + + key.kv_key = "X-Forwarded-Port"; + if ((xfp = kv_find(&desc->http_headers, &key)) != NULL + && xfp->kv_value == NULL) + xfp = NULL; + + if (xfp && + stravis(&xfp_v, xfp->kv_value, HTTPD_LOGVIS) == -1) + goto finish; + + if ((ret = evbuffer_add_printf(clt->clt_log, " %s %s", + xff == NULL ? "-" : xff_v, + xfp == NULL ? "-" : xfp_v)) == -1) + break; +finish: + ret = evbuffer_add_printf(clt->clt_log, "\n"); break; @@ -1769,6 +1803,8 @@ done: free(version); free(referrer_v); free(agent_v); + free(xff_v); + free(xfp_v); return (ret); } -- cgit v1.2.3