diff --git a/docs/manual/mod/mod_remoteip.xml b/docs/manual/mod/mod_remoteip.xml index 0699e8fea9d..7c5f5f3f583 100644 --- a/docs/manual/mod/mod_remoteip.xml +++ b/docs/manual/mod/mod_remoteip.xml @@ -237,7 +237,10 @@ RemoteIPProxiesHeader X-Forwarded-By send the header every time it opens a connection or the connection will be aborted unless it is in the list of disabled hosts provided by the RemoteIPProxyProtocolExceptions - directive.

+ directive. Alternatively, if the + RemoteIPProxyProtocolOnly + directive is used, a PROXY protocol header will only be required from + the specified clients.

While this directive may be specified in any virtual host, it is important to understand that because the PROXY protocol is connection @@ -293,6 +296,27 @@ Listen 8080 + +RemoteIPProxyProtocolOnly +Enable processing of PROXY header for only certain hosts or networks +RemoteIPProxyProtocolOnly host|range [host|range] [host|range] +server configvirtual host + +RemoteIPProxyProtocolOnly is only available in httpd UNRELEASED and newer + + +

The RemoteIPProxyProtocolOnly directive enables or + disables the reading and handling of the PROXY protocol connection header. + Only clients configured with this directive (and not excluded with + RemoteIPProxyProtocolExceptions) + will be required to provide a PROXY protocol header. + This configuration can be desirable if a set of proxy hosts connect to the + server, but other clients also connect directly to the server bypassing the + proxy. In this case you could configure the server to only accept PROXY + protocol from the IP addresses of the proxy servers.

+ + + RemoteIPTrustedProxy Restrict client IP addresses trusted to present the RemoteIPHeader value diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c index e88c9c9ee6e..64008cc08b2 100644 --- a/modules/metadata/mod_remoteip.c +++ b/modules/metadata/mod_remoteip.c @@ -65,6 +65,7 @@ typedef struct { remoteip_addr_info *proxy_protocol_disabled; apr_array_header_t *disabled_subnets; + apr_array_header_t *only_subnets; apr_pool_t *pool; } remoteip_config_t; @@ -153,6 +154,7 @@ static void *create_remoteip_server_config(apr_pool_t *p, server_rec *s) { remoteip_config_t *config = apr_pcalloc(p, sizeof(*config)); config->disabled_subnets = apr_array_make(p, 1, sizeof(apr_ipsubnet_t *)); + config->only_subnets = apr_array_make(p, 1, sizeof(apr_ipsubnet_t *)); /* config->header_name = NULL; * config->proxies_header_name = NULL; * config->proxy_protocol_enabled = NULL; @@ -453,8 +455,8 @@ static const char *remoteip_enable_proxy_protocol(cmd_parms *cmd, void *config, return NULL; } -static const char *remoteip_disable_networks(cmd_parms *cmd, void *d, - int argc, char *const argv[]) +static const char *remoteip_proxyproto_networks(cmd_parms *cmd, void *d, + int argc, char *const argv[]) { int i; apr_pool_t *ptemp = cmd->temp_pool; @@ -486,7 +488,7 @@ static const char *remoteip_disable_networks(cmd_parms *cmd, void *d, addr, &rv); } - *(apr_ipsubnet_t**)apr_array_push(conf->disabled_subnets) = *ip; + *(apr_ipsubnet_t**)apr_array_push(cmd->info ? conf->only_subnets : conf->disabled_subnets) = *ip; } return NULL; @@ -908,6 +910,20 @@ static int remoteip_hook_pre_connection(conn_rec *c, void *csd) return DECLINED; } + /* check if we're enabled for this host (all hosts by default) */ + if (conf->only_subnets->nelts != 0) { + for (i = 0; i < conf->only_subnets->nelts; i++) { + apr_ipsubnet_t *ip = ((apr_ipsubnet_t**)conf->only_subnets->elts)[i]; + + if (ip && apr_ipsubnet_test(ip, c->client_addr)) { + break; + } + } + if (i == conf->only_subnets->nelts) { + return DECLINED; + } + } + /* mod_proxy creates outgoing connections - we don't want those */ if (!remoteip_is_server_port(c->local_addr->port)) { return DECLINED; @@ -1241,7 +1257,10 @@ static const command_rec remoteip_cmds[] = AP_INIT_FLAG("RemoteIPProxyProtocol", remoteip_enable_proxy_protocol, NULL, RSRC_CONF, "Enable PROXY protocol handling ('on', 'off')"), AP_INIT_TAKE_ARGV("RemoteIPProxyProtocolExceptions", - remoteip_disable_networks, NULL, RSRC_CONF, "Disable PROXY " + remoteip_proxyproto_networks, 0, RSRC_CONF, "Disable PROXY " + "protocol handling for this list of networks in CIDR format"), + AP_INIT_TAKE_ARGV("RemoteIPProxyProtocolOnly", + remoteip_proxyproto_networks, (void*)1, RSRC_CONF, "Only enable PROXY " "protocol handling for this list of networks in CIDR format"), { NULL } };