From 2df1e61b51b5534664c93c9684ffc06b93af74b5 Mon Sep 17 00:00:00 2001 From: Vladimir Belov Date: Fri, 31 Mar 2017 23:14:39 +0300 Subject: [PATCH 1/3] reqs: Add support for X-Forwarded-For header. --- src/reqs.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/reqs.c b/src/reqs.c index 990152a..a598caa 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -822,6 +822,35 @@ done: return ret; } +/* + * Create a 'X-Forwarded-For' header or append to the existing one. + * It isn't standard, but is a common method for identifying the originating + * IP address of a client. + */ +static int +write_xff_header(int fd, hashmap_t hashofheaders, + char* client_ip_addr) +{ + ssize_t len; + char *data; + int ret; + + len = hashmap_entry_by_key(hashofheaders, "x-forwarded-for", (void **)&data); + if (len > 0) { + ret = write_message(fd, + "X-Forwarded-For: %s, %s\r\n", + data, client_ip_addr); + + hashmap_remove(hashofheaders, "x-forwarded-for"); + } else { + ret = write_message(fd, + "X-Forwarded-For: %s\r\n", + client_ip_addr); + } + + return ret; +} + /* * Number of buckets to use internally in the hashmap. */ @@ -894,6 +923,18 @@ process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders) NULL); goto PULL_CLIENT_DATA; } + /* Send new or appended the 'X-Forwarded-For' header */ + ret = write_xff_header(connptr->server_fd, hashofheaders, + connptr->client_ip_addr); + if (ret < 0) { + indicate_http_error(connptr, 503, + "Could not send data to remote server", + "detail", + "A network error occurred while " + "trying to write data to the remote web server.", + NULL); + goto PULL_CLIENT_DATA; + } /* * Output all the remaining headers to the remote machine. @@ -1055,6 +1096,11 @@ retry: connptr->protocol.minor); if (ret < 0) goto ERROR_EXIT; + /* Send new or appended the 'X-Forwarded-For' header */ + ret = write_xff_header(connptr->client_fd, hashofheaders, + connptr->server_ip_addr); + if (ret < 0) + goto ERROR_EXIT; #ifdef REVERSE_SUPPORT /* Write tracking cookie for the magical reverse proxy path hack */ From 0fc9d1cd3938a1c63108a6585574eb709b183671 Mon Sep 17 00:00:00 2001 From: Vladimir Belov Date: Sat, 1 Apr 2017 14:19:04 +0300 Subject: [PATCH 2/3] Add an option to control the use of X-Forwarded-For header. --- docs/man5/tinyproxy.conf.txt.in | 8 +++++++ etc/tinyproxy.conf.in | 9 ++++++++ src/conf.c | 17 ++++++++++++++- src/conf.h | 2 ++ src/reqs.c | 38 +++++++++++++++++++-------------- 5 files changed, 57 insertions(+), 17 deletions(-) diff --git a/docs/man5/tinyproxy.conf.txt.in b/docs/man5/tinyproxy.conf.txt.in index e40135b..c3f966b 100644 --- a/docs/man5/tinyproxy.conf.txt.in +++ b/docs/man5/tinyproxy.conf.txt.in @@ -246,6 +246,14 @@ AddHeader "X-My-Header" "Powered by Tinyproxy" enabling this option, you break compliance. Don't disable the `Via` header unless you know what you are doing... +*DisableXffHeader*:: + + The 'X-Forwarded-For' header isn't required by the HTTP RFC, + but is a common method for identifying the originating IP address + of a client connecting to a web server through an HTTP proxy or + load balancer. Though, using this is a security concern. + So turn this off only for demand. + *Filter*:: Tinyproxy supports filtering of web sites based on URLs or diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index e24ad4a..a7ebe8d 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -233,6 +233,15 @@ ViaProxyName "tinyproxy" # #DisableViaHeader Yes +# +# DisableXffHeader: The 'X-Forwarded-For' header isn't required by the +# HTTP RFC, but is a common method for identifying the originating +# IP address of a client connecting to a web server through an HTTP +# proxy or load balancer. Though, using this is a security concern. +# So we disable it by default. +# +DisableXffHeader Yes + # # Filter: This allows you to specify the location of the filter file. # diff --git a/src/conf.c b/src/conf.c index c003627..977e1f7 100644 --- a/src/conf.c +++ b/src/conf.c @@ -156,6 +156,7 @@ static HANDLE_FUNC (handle_timeout); static HANDLE_FUNC (handle_user); static HANDLE_FUNC (handle_viaproxyname); static HANDLE_FUNC (handle_disableviaheader); +static HANDLE_FUNC (handle_disablexffheader); static HANDLE_FUNC (handle_xtinyproxy); #ifdef UPSTREAM_SUPPORT @@ -205,11 +206,12 @@ struct { STDCONF ("defaulterrorfile", STR, handle_defaulterrorfile), STDCONF ("statfile", STR, handle_statfile), STDCONF ("stathost", STR, handle_stathost), - STDCONF ("xtinyproxy", BOOL, handle_xtinyproxy), /* boolean arguments */ STDCONF ("syslog", BOOL, handle_syslog), STDCONF ("bindsame", BOOL, handle_bindsame), STDCONF ("disableviaheader", BOOL, handle_disableviaheader), + STDCONF ("disablexffheader", BOOL, handle_disablexffheader), + STDCONF ("xtinyproxy", BOOL, handle_xtinyproxy), /* integer arguments */ STDCONF ("port", INT, handle_port), STDCONF ("maxclients", INT, handle_maxclients), @@ -736,6 +738,19 @@ static HANDLE_FUNC (handle_disableviaheader) return 0; } +static HANDLE_FUNC (handle_disablexffheader) +{ + int r = set_bool_arg (&conf->disable_xffheader, line, &match[2]); + + if (r) { + return r; + } + + log_message (LOG_INFO, + "Disabling transmission of the \"X-Forwarded-For\" header."); + return 0; +} + static HANDLE_FUNC (handle_defaulterrorfile) { return set_string_arg (&conf->errorpage_undef, line, &match[2]); diff --git a/src/conf.h b/src/conf.h index 0fb4226..8a7d27d 100644 --- a/src/conf.h +++ b/src/conf.h @@ -77,6 +77,8 @@ struct config_s { unsigned int disable_viaheader; /* boolean */ + unsigned int disable_xffheader; /* boolean */ + /* * Error page support. Map error numbers to file paths. */ diff --git a/src/reqs.c b/src/reqs.c index a598caa..d7dce81 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -923,17 +923,20 @@ process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders) NULL); goto PULL_CLIENT_DATA; } - /* Send new or appended the 'X-Forwarded-For' header */ - ret = write_xff_header(connptr->server_fd, hashofheaders, - connptr->client_ip_addr); - if (ret < 0) { - indicate_http_error(connptr, 503, - "Could not send data to remote server", - "detail", - "A network error occurred while " - "trying to write data to the remote web server.", - NULL); - goto PULL_CLIENT_DATA; + + if (!config.disable_xffheader) { + /* Send new or appended the 'X-Forwarded-For' header */ + ret = write_xff_header(connptr->server_fd, hashofheaders, + connptr->client_ip_addr); + if (ret < 0) { + indicate_http_error(connptr, 503, + "Could not send data to remote server", + "detail", + "A network error occurred while " + "trying to write data to the remote web server.", + NULL); + goto PULL_CLIENT_DATA; + } } /* @@ -1096,11 +1099,14 @@ retry: connptr->protocol.minor); if (ret < 0) goto ERROR_EXIT; - /* Send new or appended the 'X-Forwarded-For' header */ - ret = write_xff_header(connptr->client_fd, hashofheaders, - connptr->server_ip_addr); - if (ret < 0) - goto ERROR_EXIT; + + if (!config.disable_xffheader) { + /* Send new or appended the 'X-Forwarded-For' header */ + ret = write_xff_header(connptr->client_fd, hashofheaders, + connptr->server_ip_addr); + if (ret < 0) + goto ERROR_EXIT; + } #ifdef REVERSE_SUPPORT /* Write tracking cookie for the magical reverse proxy path hack */ From 5df36151b1f5b3d74177483376cd8ffa3be42305 Mon Sep 17 00:00:00 2001 From: Vladimir Belov Date: Fri, 30 Mar 2018 15:17:10 +0300 Subject: [PATCH 3/3] Rename option DisableXffHeader to EnableXffHeader. --- docs/man5/tinyproxy.conf.txt.in | 4 ++-- etc/tinyproxy.conf.in | 4 ++-- src/conf.c | 16 +++++++++------- src/conf.h | 2 +- src/reqs.c | 4 ++-- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/docs/man5/tinyproxy.conf.txt.in b/docs/man5/tinyproxy.conf.txt.in index c3f966b..143b746 100644 --- a/docs/man5/tinyproxy.conf.txt.in +++ b/docs/man5/tinyproxy.conf.txt.in @@ -246,13 +246,13 @@ AddHeader "X-My-Header" "Powered by Tinyproxy" enabling this option, you break compliance. Don't disable the `Via` header unless you know what you are doing... -*DisableXffHeader*:: +*EnableXffHeader*:: The 'X-Forwarded-For' header isn't required by the HTTP RFC, but is a common method for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer. Though, using this is a security concern. - So turn this off only for demand. + So turn this on only for demand. *Filter*:: diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index a7ebe8d..5fc63f1 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -234,13 +234,13 @@ ViaProxyName "tinyproxy" #DisableViaHeader Yes # -# DisableXffHeader: The 'X-Forwarded-For' header isn't required by the +# EnableXffHeader: The 'X-Forwarded-For' header isn't required by the # HTTP RFC, but is a common method for identifying the originating # IP address of a client connecting to a web server through an HTTP # proxy or load balancer. Though, using this is a security concern. # So we disable it by default. # -DisableXffHeader Yes +#EnableXffHeader No # # Filter: This allows you to specify the location of the filter file. diff --git a/src/conf.c b/src/conf.c index 977e1f7..442c473 100644 --- a/src/conf.c +++ b/src/conf.c @@ -156,7 +156,7 @@ static HANDLE_FUNC (handle_timeout); static HANDLE_FUNC (handle_user); static HANDLE_FUNC (handle_viaproxyname); static HANDLE_FUNC (handle_disableviaheader); -static HANDLE_FUNC (handle_disablexffheader); +static HANDLE_FUNC (handle_enablexffheader); static HANDLE_FUNC (handle_xtinyproxy); #ifdef UPSTREAM_SUPPORT @@ -210,7 +210,7 @@ struct { STDCONF ("syslog", BOOL, handle_syslog), STDCONF ("bindsame", BOOL, handle_bindsame), STDCONF ("disableviaheader", BOOL, handle_disableviaheader), - STDCONF ("disablexffheader", BOOL, handle_disablexffheader), + STDCONF ("enablexffheader", BOOL, handle_enablexffheader), STDCONF ("xtinyproxy", BOOL, handle_xtinyproxy), /* integer arguments */ STDCONF ("port", INT, handle_port), @@ -527,6 +527,8 @@ static void initialize_with_defaults (struct config_s *conf, conf->disable_viaheader = defaults->disable_viaheader; + conf->enable_xffheader = defaults->enable_xffheader; + if (defaults->errorpage_undef) { conf->errorpage_undef = safestrdup (defaults->errorpage_undef); } @@ -738,17 +740,17 @@ static HANDLE_FUNC (handle_disableviaheader) return 0; } -static HANDLE_FUNC (handle_disablexffheader) +static HANDLE_FUNC (handle_enablexffheader) { - int r = set_bool_arg (&conf->disable_xffheader, line, &match[2]); + int r = set_bool_arg (&conf->enable_xffheader, line, &match[2]); - if (r) { + if (!r) { return r; } log_message (LOG_INFO, - "Disabling transmission of the \"X-Forwarded-For\" header."); - return 0; + "Enabling transmission of the \"X-Forwarded-For\" header."); + return r; } static HANDLE_FUNC (handle_defaulterrorfile) diff --git a/src/conf.h b/src/conf.h index 8a7d27d..2d38d03 100644 --- a/src/conf.h +++ b/src/conf.h @@ -77,7 +77,7 @@ struct config_s { unsigned int disable_viaheader; /* boolean */ - unsigned int disable_xffheader; /* boolean */ + unsigned int enable_xffheader; /* boolean */ /* * Error page support. Map error numbers to file paths. diff --git a/src/reqs.c b/src/reqs.c index d7dce81..e4bcf1d 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -924,7 +924,7 @@ process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders) goto PULL_CLIENT_DATA; } - if (!config.disable_xffheader) { + if (config.enable_xffheader) { /* Send new or appended the 'X-Forwarded-For' header */ ret = write_xff_header(connptr->server_fd, hashofheaders, connptr->client_ip_addr); @@ -1100,7 +1100,7 @@ retry: if (ret < 0) goto ERROR_EXIT; - if (!config.disable_xffheader) { + if (config.enable_xffheader) { /* Send new or appended the 'X-Forwarded-For' header */ ret = write_xff_header(connptr->client_fd, hashofheaders, connptr->server_ip_addr);