summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Ruggeri <druggeri@apache.org>2017-04-01 13:51:44 +0000
committerDaniel Ruggeri <druggeri@apache.org>2017-04-01 13:51:44 +0000
commit485f90e445382a3cfc69448b6eb90cc8551114f4 (patch)
tree8adfd70c197abe3c13c3e82dfb1d847207b8a39d
parent045142819a3835586f51e0164ef2c6c34d346606 (diff)
downloadhttpd-485f90e445382a3cfc69448b6eb90cc8551114f4.tar.gz
Update PROXY handling by removing Optional processing
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1789800 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--docs/manual/mod/mod_remoteip.xml53
-rw-r--r--modules/metadata/mod_remoteip.c272
2 files changed, 128 insertions, 197 deletions
diff --git a/docs/manual/mod/mod_remoteip.xml b/docs/manual/mod/mod_remoteip.xml
index 81c4c683e3..fba09fa608 100644
--- a/docs/manual/mod/mod_remoteip.xml
+++ b/docs/manual/mod/mod_remoteip.xml
@@ -223,19 +223,19 @@ RemoteIPProxiesHeader X-Forwarded-By
<directivesynopsis>
<name>RemoteIPProxyProtocol</name>
-<description>Enable, optionally enable or disable the PROXY protocol handling</description>
-<syntax>RemoteIPProxyProtocol On|Optional|Off</syntax>
+<description>Enable or disable PROXY protocol handling</description>
+<syntax>RemoteIPProxyProtocol On|Off</syntax>
<contextlist><context>server config</context><context>virtual host</context>
</contextlist>
<compatibility>RemoteIPProxyProtocol is only available in httpd 2.4.26 and newer</compatibility>
<usage>
- <p>The <directive>RemoteIPProxyProtocol</directive> enables or
+ <p>The <directive>RemoteIPProxyProtocol</directive> directive enables or
disables the reading and handling of the PROXY protocol connection header.
If enabled with the <code>On</code> flag, the upstream client <em>must</em>
send the header every time it opens a connection or the connection will
- be aborted. If enabled with the <code>Optional</code> flag, the upstream
- client <em>may</em> send the header.</p>
+ be aborted unless it is in the list of disabled hosts provided by <directive
+ module="mod_remoteip">RemoteIPProxyProtocolDisableHosts</directive> directive.
<p>While this directive may be specified in any virtual host, it is
important to understand that because the PROXY protocol is connection
@@ -247,46 +247,53 @@ RemoteIPProxiesHeader X-Forwarded-By
in the other, that won't work; in such a case the last one wins and a
notice will be logged indicating which setting was being overridden.</p>
- <note type="hint">When multiple virtual hosts on the same IP and port are
- configured with a combination of <code>On</code> and <code>Optional</code>
- flags, connections will not be aborted if the header is not sent.
- Instead, enforcement will happen after the request is read so virtual
- hosts configured with <code>On</code> will return a 400 Bad Request.
- Virtual hosts configured with <code>Optional</code> will continue as
- usual but without replacing the client IP information</note>
-
<highlight language="config">
Listen 80
&lt;VirtualHost *:80&gt;
ServerName www.example.com
- RemoteIPProxyProtocol Optional
-
- #Requests to this virtual host may optionally not have
- # a PROXY protocol header provided
-&lt;/VirtualHost&gt;
-
-&lt;VirtualHost *:80&gt;
- ServerName www.example.com
RemoteIPProxyProtocol On
#Requests to this virtual host must have a PROXY protocol
- # header provided. If it is missing, a 400 will result
+ # header provided. If it is missing, the connection will
+ # be aborted
&lt;/VirtualHost&gt;
Listen 8080
&lt;VirtualHost *:8080&gt;
ServerName www.example.com
RemoteIPProxyProtocol On
+ RemoteIPProxyProtocolDisableHosts 127.0.0.1 10.0.0.0/8
#Requests to this virtual host must have a PROXY protocol
# header provided. If it is missing, the connection will
- # be aborted
+ # be aborted except when coming from localhost or the
+ # 10.x.x.x RFC1918 range
&lt;/VirtualHost&gt;
</highlight>
</usage>
</directivesynopsis>
<directivesynopsis>
+<name>RemoteIPProxyProtocolDisableHosts</name>
+<description>Disable processing of PROXY header for certain hosts or networks</description>
+<syntax>RemoteIPProxyProtocolDisableHosts host|range [host|range] [host|range]</syntax>
+<contextlist><context>server config</context><context>virtual host</context>
+</contextlist>
+<compatibility>RemoteIPProxyProtocolDisableHosts is only available in httpd 2.4.26 and newer</compatibility>
+
+<usage>
+ <p>The <directive>RemoteIPProxyProtocol</directive> directive enables or
+ disables the reading and handling of the PROXY protocol connection header.
+ Sometimes it is desirable to require clients to provide the PROXY header, but
+ permit other clients to connect without it. This directive allows a server
+ administrator to configure a single host or CIDR range of hosts that may do
+ so. This is generally useful for useful for monitoring and administrative
+ traffic to a virtual host direct to the server behind the upstream load
+ balancer.</p>
+</usage>
+</directivesynopsis>
+
+<directivesynopsis>
<name>RemoteIPTrustedProxy</name>
<description>Restrict client IP addresses trusted to present the RemoteIPHeader value</description>
<syntax>RemoteIPTrustedProxy <var>proxy-ip</var>|<var>proxy-ip/subnet</var>|<var>hostname</var> ...</syntax>
diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c
index ca985913fa..573adadbb2 100644
--- a/modules/metadata/mod_remoteip.c
+++ b/modules/metadata/mod_remoteip.c
@@ -61,14 +61,9 @@ typedef struct {
apr_array_header_t *proxymatch_ip;
remoteip_addr_info *proxy_protocol_enabled;
- remoteip_addr_info *proxy_protocol_optional;
remoteip_addr_info *proxy_protocol_disabled;
- /** A flag indicating whether or not proxyprotocol
- * is optoinal for this specific server
- */
- int pp_optional;
-
+ apr_array_header_t *disabled_subnets;
apr_pool_t *pool;
} remoteip_config_t;
@@ -150,22 +145,18 @@ typedef struct {
apr_sockaddr_t *client_addr;
/** Character representation of the client */
char *client_ip;
- /** Flag indicating that the PROXY header may be omitted on this
- connection (do not abort if it is missing). */
- int proxy_protocol_optional;
} remoteip_conn_config_t;
-typedef enum { HDR_DONE, HDR_ERROR, HDR_MISSING, HDR_NEED_MORE } remoteip_parse_status_t;
+typedef enum { HDR_DONE, HDR_ERROR, HDR_NEED_MORE } remoteip_parse_status_t;
static void *create_remoteip_server_config(apr_pool_t *p, server_rec *s)
{
- remoteip_config_t *config = apr_pcalloc(p, sizeof *config);
+ remoteip_config_t *config = apr_pcalloc(p, sizeof(*config));
+ config->disabled_subnets = apr_array_make(p, 1, sizeof(apr_ipsubnet_t *));
/* config->header_name = NULL;
* config->proxies_header_name = NULL;
* config->proxy_protocol_enabled = NULL;
- * config->proxy_protocol_optional = NULL;
* config->proxy_protocol_disabled = NULL;
- * config->pp_optional = 0;
*/
config->pool = p;
return config;
@@ -188,9 +179,6 @@ 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->pp_optional = server->pp_optional
- ? server->pp_optional
- : global->pp_optional;
return config;
}
@@ -363,7 +351,7 @@ static int remoteip_addr_in_list(remoteip_addr_info *list, apr_sockaddr_t *addr)
return 0;
}
-static void remoteip_warn_enable_conflict(remoteip_addr_info *prev, server_rec *new, const char* arg)
+static void remoteip_warn_enable_conflict(remoteip_addr_info *prev, server_rec *new, int flag)
{
char buf[INET6_ADDRSTRLEN];
@@ -376,62 +364,43 @@ static void remoteip_warn_enable_conflict(remoteip_addr_info *prev, server_rec *
buf, prev->addr->port, prev->source->server_hostname,
prev->source->addrs->host_port, prev->source->defn_name,
new->server_hostname, new->addrs->host_port, new->defn_name,
- arg);
+ flag ? "On" : "Off");
}
static const char *remoteip_enable_proxy_protocol(cmd_parms *cmd, void *config,
- const char *arg)
+ int flag)
{
- remoteip_config_t *global_conf;
- remoteip_config_t *server_conf;
+ remoteip_config_t *conf;
server_addr_rec *addr;
remoteip_addr_info **add;
- int list_len = 2;
- remoteip_addr_info **rem_list[list_len];
+ remoteip_addr_info **rem;
remoteip_addr_info *list;
- int i;
- global_conf = ap_get_module_config(ap_server_conf->module_config,
- &remoteip_module);
- server_conf = ap_get_module_config(cmd->server->module_config,
+ conf = ap_get_module_config(ap_server_conf->module_config,
&remoteip_module);
- if (strcasecmp(arg, "On") == 0) {
- add = &global_conf->proxy_protocol_enabled;
- rem_list[0] = &global_conf->proxy_protocol_optional;
- rem_list[1] = &global_conf->proxy_protocol_disabled;
- }
- else if (strcasecmp(arg, "Optional") == 0) {
- add = &global_conf->proxy_protocol_optional;
- rem_list[0] = &global_conf->proxy_protocol_enabled;
- rem_list[1] = &global_conf->proxy_protocol_disabled;
- server_conf->pp_optional = 1;
- }
- else if (strcasecmp(arg, "Off") == 0 ) {
- add = &global_conf->proxy_protocol_disabled;
- rem_list[0] = &global_conf->proxy_protocol_enabled;
- rem_list[1] = &global_conf->proxy_protocol_optional;
+ if (flag) {
+ add = &conf->proxy_protocol_enabled;
+ rem = &conf->proxy_protocol_disabled;
}
else {
- return apr_pstrcat(cmd->pool, "Unrecognized option for %s `%s'", cmd->cmd->name, arg, NULL);
+ add = &conf->proxy_protocol_disabled;
+ rem = &conf->proxy_protocol_enabled;
}
for (addr = cmd->server->addrs; addr; addr = addr->next) {
- /* remove address from other lists */
- for (i = 0; i < list_len ; i++) {
- remoteip_addr_info **rem = rem_list[i];
- if (*rem) {
- if (remoteip_sockaddr_equal((*rem)->addr, addr->host_addr)) {
- remoteip_warn_enable_conflict(*rem, cmd->server, arg);
- *rem = (*rem)->next;
- }
- else {
- for (list = *rem; list->next; list = list->next) {
- if (remoteip_sockaddr_equal(list->next->addr, addr->host_addr)) {
- remoteip_warn_enable_conflict(list->next, cmd->server, arg);
- list->next = list->next->next;
- break;
- }
+ /* remove address from opposite list */
+ if (*rem) {
+ if (remoteip_sockaddr_equal((*rem)->addr, addr->host_addr)) {
+ remoteip_warn_enable_conflict(*rem, cmd->server, flag);
+ *rem = (*rem)->next;
+ }
+ else {
+ for (list = *rem; list->next; list = list->next) {
+ if (remoteip_sockaddr_equal(list->next->addr, addr->host_addr)) {
+ remoteip_warn_enable_conflict(list->next, cmd->server, flag);
+ list->next = list->next->next;
+ break;
}
}
}
@@ -439,7 +408,7 @@ static const char *remoteip_enable_proxy_protocol(cmd_parms *cmd, void *config,
/* add address to desired list */
if (!remoteip_addr_in_list(*add, addr->host_addr)) {
- remoteip_addr_info *info = apr_palloc(global_conf->pool, sizeof(*info));
+ remoteip_addr_info *info = apr_palloc(conf->pool, sizeof(*info));
info->addr = addr->host_addr;
info->source = cmd->server;
info->next = *add;
@@ -450,6 +419,45 @@ 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[])
+{
+ int i;
+ apr_pool_t *ptemp = cmd->temp_pool;
+ apr_pool_t *p = cmd->pool;
+ remoteip_config_t *conf = ap_get_module_config(ap_server_conf->module_config,
+ &remoteip_module);
+
+ if (argc == 0)
+ return "RemoteIPProxyProtocolDisableNetworks requires an argument";
+
+
+ for (i=0; i<argc; i++) {
+ char *addr = apr_pstrdup(ptemp, argv[i]);
+ char *mask;
+ apr_status_t rv;
+ apr_ipsubnet_t **ip = apr_pcalloc(p, sizeof(apr_ipsubnet_t *));
+
+ if ((mask = ap_strchr(addr, '/')))
+ *mask++ = '\0';
+
+ rv = apr_ipsubnet_create(ip, addr, mask, p);
+
+ if(APR_STATUS_IS_EINVAL(rv)) {
+ /* looked nothing like an IP address */
+ return apr_psprintf(p, "ip address '%s' appears to be invalid", addr);
+ }
+ else if (rv != APR_SUCCESS) {
+ return apr_psprintf(p, "ip address '%s' appears to be invalid: %pm",
+ addr, &rv);
+ }
+
+ *(apr_ipsubnet_t**)apr_array_push(conf->disabled_subnets) = *ip;
+ }
+
+ return NULL;
+}
+
static int remoteip_hook_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp)
{
@@ -476,11 +484,6 @@ static int remoteip_hook_post_config(apr_pool_t *pconf, apr_pool_t *plog,
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(03492)
"RemoteIPProxyProtocol: enabled on %s:%hu", buf, info->addr->port);
}
- for (info = conf->proxy_protocol_optional; info; info = info->next) {
- apr_sockaddr_ip_getbuf(buf, sizeof(buf), info->addr);
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(03493)
- "RemoteIPProxyProtocol: optional on %s:%hu", buf, info->addr->port);
- }
for (info = conf->proxy_protocol_disabled; info; info = info->next) {
apr_sockaddr_ip_getbuf(buf, sizeof(buf), info->addr);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(03494)
@@ -523,18 +526,10 @@ static int remoteip_modify_request(request_rec *r)
protocol handling allowing it to take precedence and return
*/
if (conn_config) {
- /* We may have gotten here if processing was optional - check for that */
if (!conn_config->client_addr) {
- if (config->pp_optional) {
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03495)
- "RemoteIPProxyProtocol data is missing, but was optional. Allowing request.");
- return OK;
- }
- else {
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03496)
- "RemoteIPProxyProtocol data is missing, but required! Aborting request.");
- return HTTP_BAD_REQUEST;
- }
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03496)
+ "RemoteIPProxyProtocol data is missing, but required! Aborting request.");
+ return HTTP_BAD_REQUEST;
}
r->useragent_addr = conn_config->client_addr;
@@ -860,7 +855,7 @@ static int remoteip_hook_pre_connection(conn_rec *c, void *csd)
{
remoteip_config_t *conf;
remoteip_conn_config_t *conn_conf;
- int optional;
+ int i;
/* Do not attempt to manipulate slave connections */
if (c->master != NULL) {
@@ -870,16 +865,22 @@ static int remoteip_hook_pre_connection(conn_rec *c, void *csd)
conf = ap_get_module_config(ap_server_conf->module_config,
&remoteip_module);
- /* Used twice - do the check only once */
- optional = remoteip_addr_in_list(conf->proxy_protocol_optional, c->local_addr);
-
/* check if we're enabled for this connection */
- if ((!remoteip_addr_in_list(conf->proxy_protocol_enabled, c->local_addr)
- && !optional )
+ if (!remoteip_addr_in_list(conf->proxy_protocol_enabled, c->local_addr)
|| remoteip_addr_in_list(conf->proxy_protocol_disabled, c->local_addr)) {
+
return DECLINED;
}
+ /* We are enabled for this IP/port, but check that we aren't
+ explicitly disabled */
+ for (i = 0; i < conf->disabled_subnets->nelts; i++) {
+ apr_ipsubnet_t *ip = ((apr_ipsubnet_t**)conf->disabled_subnets->elts)[i];
+
+ if (ip && apr_ipsubnet_test(ip, c->client_addr))
+ return DECLINED;
+ }
+
/* mod_proxy creates outgoing connections - we don't want those */
if (!remoteip_is_server_port(c->local_addr->port)) {
return DECLINED;
@@ -898,12 +899,6 @@ static int remoteip_hook_pre_connection(conn_rec *c, void *csd)
/* this holds the resolved proxy info for this connection */
conn_conf = apr_pcalloc(c->pool, sizeof(*conn_conf));
- /* Propagate the optional flag so the connection handler knows not to
- abort if the header is mising. NOTE: This means we must check after
- we read the request that the header was NOT optional, too.
- */
- conn_conf->proxy_protocol_optional = optional;
-
ap_set_module_config(c->conn_config, &remoteip_module, conn_conf);
return OK;
@@ -1036,31 +1031,20 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
remoteip_parse_status_t psts = HDR_NEED_MORE;
const char *ptr;
apr_size_t len;
- apr_size_t this_read = 0; /* Track bytes read in each brigade */
- apr_size_t prev_read = 0;
if (f->c->aborted) {
return APR_ECONNABORTED;
}
- conn_conf = ap_get_module_config(f->c->conn_config, &remoteip_module);
-
/* allocate/retrieve the context that holds our header */
if (!ctx) {
ctx = f->ctx = apr_palloc(f->c->pool, sizeof(*ctx));
ctx->rcvd = 0;
ctx->need = MIN_HDR_LEN;
ctx->version = 0;
+ ctx->mode = AP_MODE_READBYTES;
ctx->bb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
ctx->done = 0;
- if (conn_conf->proxy_protocol_optional) {
- ctx->mode = AP_MODE_SPECULATIVE;
- ctx->peeking = 1;
- }
- else {
- ctx->mode = AP_MODE_READBYTES;
- ctx->peeking = 0;
- }
}
if (ctx->done) {
@@ -1071,6 +1055,8 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
return ap_get_brigade(f->next, bb_out, mode, block, readbytes);
}
+ conn_conf = ap_get_module_config(f->c->conn_config, &remoteip_module);
+
/* try to read a header's worth of data */
while (!ctx->done) {
if (APR_BRIGADE_EMPTY(ctx->bb)) {
@@ -1084,23 +1070,9 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
return block == APR_NONBLOCK_READ ? APR_SUCCESS : APR_EOF;
}
- if (ctx->peeking) {
- ctx->rcvd = 0;
- ctx->need = MIN_HDR_LEN;
- }
-
while (!ctx->done && !APR_BRIGADE_EMPTY(ctx->bb)) {
b = APR_BRIGADE_FIRST(ctx->bb);
- if (ctx->peeking && APR_BUCKET_IS_EOS(b)) {
- /* Shortcut - we know no header was found yet and an
- EOS indicates we never will */
- apr_brigade_destroy(ctx->bb);
- ctx->bb = NULL;
- ctx->done = 1;
- return APR_SUCCESS;
- }
-
ret = apr_bucket_read(b, &ptr, &len, block);
if (APR_STATUS_IS_EAGAIN(ret) && block == APR_NONBLOCK_READ) {
return APR_SUCCESS;
@@ -1112,10 +1084,6 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
memcpy(ctx->header + ctx->rcvd, ptr, len);
ctx->rcvd += len;
- if (ctx->peeking && block == APR_NONBLOCK_READ) {
- this_read += len;
- }
-
apr_bucket_delete(b);
psts = HDR_NEED_MORE;
@@ -1123,45 +1091,15 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
/* reading initial chunk */
if (ctx->rcvd >= MIN_HDR_LEN) {
ctx->version = remoteip_determine_version(f->c, ctx->header);
-
- /* We've read enough to know that a header is present. In peek mode
- we purge the bb and can decide to step aside or switch to
- non-speculative read to consume the data */
- if (ctx->peeking) {
- if (ctx->version < 0) {
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, APLOGNO(03512)
- "RemoteIPProxyProtocol: PROXY header is missing from "
- "request. Stepping aside.");
- apr_brigade_destroy(ctx->bb);
- ctx->bb = NULL;
- ctx->done = 1;
- return ap_get_brigade(f->next, bb_out, mode, block, readbytes);
- }
- else {
- /* Rest ctx to initial values */
- ctx->rcvd = 0;
- ctx->need = MIN_HDR_LEN;
- ctx->version = 0;
- ctx->done = 0;
- ctx->mode = AP_MODE_READBYTES;
- ctx->peeking = 0;
- apr_brigade_cleanup(ctx->bb);
-
- ap_get_brigade(f->next, ctx->bb, ctx->mode, block,
- ctx->need - ctx->rcvd);
- }
+ if (ctx->version < 0) {
+ psts = HDR_ERROR;
}
- else {
- if (ctx->version < 0) {
- psts = HDR_MISSING;
- }
- else if (ctx->version == 1) {
- ctx->mode = AP_MODE_GETLINE;
- ctx->need = sizeof(proxy_v1);
- }
- else if (ctx->version == 2) {
- ctx->need = MIN_V2_HDR_LEN;
- }
+ else if (ctx->version == 1) {
+ ctx->mode = AP_MODE_GETLINE;
+ ctx->need = sizeof(proxy_v1);
+ }
+ else if (ctx->version == 2) {
+ ctx->need = MIN_V2_HDR_LEN;
}
}
}
@@ -1174,7 +1112,6 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
if (ctx->rcvd >= MIN_V2_HDR_LEN) {
ctx->need = MIN_V2_HDR_LEN +
remoteip_get_v2_len((proxy_header *) ctx->header);
-
}
if (ctx->rcvd >= ctx->need) {
psts = remoteip_process_v2_header(f->c, conn_conf,
@@ -1191,10 +1128,6 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
}
switch (psts) {
- case HDR_MISSING:
- ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(03510)
- "RemoteIPProxyProtocol: no valid PROXY header found");
- /* fall through to error case */
case HDR_ERROR:
f->c->aborted = 1;
apr_brigade_destroy(ctx->bb);
@@ -1208,18 +1141,6 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
break;
}
}
-
- /* In SPECULATIVE mode, upstream will return all data on each brigade get - even data
- we've seen. For non blocking read, make sure we got new data or return early when
- we haven't */
- if (ctx->peeking && block == APR_NONBLOCK_READ) {
- if (this_read == prev_read) {
- return APR_SUCCESS;
- }
- else {
- prev_read = this_read;
- }
- }
}
/* we only get here when done == 1 */
@@ -1268,8 +1189,11 @@ 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_TAKE1("RemoteIPProxyProtocol", remoteip_enable_proxy_protocol, NULL,
- RSRC_CONF, "Enable PROXY protocol handling (`on', `off', `optional')"),
+ AP_INIT_FLAG("RemoteIPProxyProtocol", remoteip_enable_proxy_protocol, NULL,
+ RSRC_CONF, "Enable PROXY protocol handling (`on', `off')"),
+ AP_INIT_TAKE_ARGV("RemoteIPProxyProtocolDisableHosts",
+ remoteip_disable_networks, NULL, RSRC_CONF, "Disable PROXY "
+ "protocol handling for this list of networks in CIDR format"),
{ NULL }
};