diff options
author | Daniel Ruggeri <druggeri@apache.org> | 2016-12-30 20:06:55 +0100 |
---|---|---|
committer | Daniel Ruggeri <druggeri@apache.org> | 2016-12-30 20:06:55 +0100 |
commit | 3e4041649d121653f2b43922b3b584d9408c1100 (patch) | |
tree | 8f23f9dc664731f59e50e1abbe16ab09d28f3c2a | |
parent | Documentation rebuild for mod_remoteip (diff) | |
download | apache2-3e4041649d121653f2b43922b3b584d9408c1100.tar.xz apache2-3e4041649d121653f2b43922b3b584d9408c1100.zip |
Shorten RemoteIPProxyProtocolEnable to RemoteIPProxyProtocol and correct references in docs
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1776624 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | docs/manual/mod/mod_proxy_protocol.html | 5 | ||||
-rw-r--r-- | docs/manual/mod/mod_proxy_protocol.html.en | 123 | ||||
-rw-r--r-- | docs/manual/mod/mod_proxy_protocol.xml | 126 | ||||
-rw-r--r-- | docs/manual/mod/mod_proxy_protocol.xml.meta | 12 | ||||
-rw-r--r-- | docs/manual/mod/mod_remoteip.xml | 28 | ||||
-rw-r--r-- | modules/filters/mod_proxy_protocol.c | 736 | ||||
-rw-r--r-- | modules/metadata/mod_remoteip.c | 8 |
7 files changed, 18 insertions, 1020 deletions
diff --git a/docs/manual/mod/mod_proxy_protocol.html b/docs/manual/mod/mod_proxy_protocol.html deleted file mode 100644 index 88388fe8f2..0000000000 --- a/docs/manual/mod/mod_proxy_protocol.html +++ /dev/null @@ -1,5 +0,0 @@ -# GENERATED FROM XML -- DO NOT EDIT - -URI: mod_proxy_protocol.html.en -Content-Language: en -Content-type: text/html; charset=ISO-8859-1 diff --git a/docs/manual/mod/mod_proxy_protocol.html.en b/docs/manual/mod/mod_proxy_protocol.html.en deleted file mode 100644 index 09ee146fc8..0000000000 --- a/docs/manual/mod/mod_proxy_protocol.html.en +++ /dev/null @@ -1,123 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head> -<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" /> -<!-- - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - This file is generated from xml source: DO NOT EDIT - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - --> -<title>mod_proxy_protocol - Apache HTTP Server Version 2.5</title> -<link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" /> -<link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" /> -<link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" /> -<script src="../style/scripts/prettify.min.js" type="text/javascript"> -</script> - -<link href="../images/favicon.ico" rel="shortcut icon" /></head> -<body> -<div id="page-header"> -<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p> -<p class="apache">Apache HTTP Server Version 2.5</p> -<img alt="" src="../images/feather.png" /></div> -<div class="up"><a href="./"><img title="<-" alt="<-" src="../images/left.gif" /></a></div> -<div id="path"> -<a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">HTTP Server</a> > <a href="http://httpd.apache.org/docs/">Documentation</a> > <a href="../">Version 2.5</a> > <a href="./">Modules</a></div> -<div id="page-content"> -<div id="preamble"><h1>Apache Module mod_proxy_protocol</h1> -<div class="toplang"> -<p><span>Available Languages: </span><a href="../en/mod/mod_proxy_protocol.html" title="English"> en </a></p> -</div> -<table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Implements the server side of the proxy protocol.</td></tr> -<tr><th><a href="module-dict.html#Status">Status:</a></th><td>Extension</td></tr> -<tr><th><a href="module-dict.html#ModuleIdentifier">Module Identifier:</a></th><td>proxy_protocol_module</td></tr> -<tr><th><a href="module-dict.html#SourceFile">Source File:</a></th><td>mod_proxy_protocol.c</td></tr></table> -<h3>Summary</h3> - - <p><code class="module"><a href="../mod/mod_proxy_protocol.html">mod_proxy_protocol</a></code> implements the server side of - HAProxy's - <a href="http://blog.haproxy.com/haproxy/proxy-protocol/">Proxy Protocol</a>.</p> - - <p>The module overrides the client IP address for the connection - with the information supplied by the upstream proxy in the proxy - protocol (connection) header.</p> - - <p>This overridden useragent IP address is then used for the - <code class="module"><a href="../mod/mod_authz_host.html">mod_authz_host</a></code> - <code class="directive"><a href="../mod/mod_authz_core.html#require">Require ip</a></code> - feature, is reported by <code class="module"><a href="../mod/mod_status.html">mod_status</a></code>, and is recorded by - <code class="module"><a href="../mod/mod_log_config.html">mod_log_config</a></code> <code>%a</code> and <code class="module"><a href="../mod/core.html">core</a></code> - <code>%a</code> format strings. The underlying client IP of the connection - is available in the <code>%{c}a</code> format string.</p> - - <div class="warning">It is critical to only enable this behavior from - intermediate proxies which are trusted by this server, since it is trivial - for the remote client to impersonate another client. Currently this must - be done by external means (such as a firewall) as this module does not - (yet) implement access controls.</div> -</div> -<div id="quickview"><h3 class="directives">Directives</h3> -<ul id="toc"> -<li><img alt="" src="../images/down.gif" /> <a href="#proxyprotocolfilter ">ProxyProtocolFilter </a></li> -</ul> -<h3>Bugfix checklist</h3><ul class="seealso"><li><a href="https://www.apache.org/dist/httpd/CHANGES_2.4">httpd changelog</a></li><li><a href="https://bz.apache.org/bugzilla/buglist.cgi?bug_status=__open__&list_id=144532&product=Apache%20httpd-2&query_format=specific&order=changeddate%20DESC%2Cpriority%2Cbug_severity&component=mod_proxy_protocol">Known issues</a></li><li><a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2&component=mod_proxy_protocol">Report a bug</a></li></ul><h3>See also</h3> -<ul class="seealso"> -<li><a href="http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt">Proxy Protocol Spec</a></li> -<li><a href="#comments_section">Comments</a></li></ul></div> - -<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> -<div class="directive-section"><h2><a name="ProxyProtocolFilter " id="ProxyProtocolFilter ">ProxyProtocolFilter </a> <a name="proxyprotocolfilter " id="proxyprotocolfilter ">Directive</a></h2> -<table class="directive"> -<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Enable or disable the proxy protocol handling</td></tr> -<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>ProxyProtocolFilter On|Off</code></td></tr> -<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr> -<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr> -<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_proxy_protocol</td></tr> -</table> - <p>The <code class="directive">ProxyProtocolFilter</code> enables or disables the - reading and handling of the proxy protocol connection header. If enabled - the upstream client <em>must</em> send the header every time it opens a - connection or the connection will get aborted.</p> - - <p>While this directive may be specified in any virtual host, it is - important to understand that because the proxy protocol is connection - based and protocol agnostic, the enabling and disabling is actually based - on ip-address and port. This means that if you have multiple name-based - virtual hosts for the same host and port, and you enable it any one of - them, then it is enabled for all them (with that host and port). It also - means that if you attempt to enable the proxy protocol in one and disable - 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> - - <pre class="prettyprint lang-config">ProxyProtocolFilter On</pre> - - -</div> -</div> -<div class="bottomlang"> -<p><span>Available Languages: </span><a href="../en/mod/mod_proxy_protocol.html" title="English"> en </a></p> -</div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our <a href="http://httpd.apache.org/lists.html">mailing lists</a>.</div> -<script type="text/javascript"><!--//--><![CDATA[//><!-- -var comments_shortname = 'httpd'; -var comments_identifier = 'http://httpd.apache.org/docs/trunk/mod/mod_proxy_protocol.html'; -(function(w, d) { - if (w.location.hostname.toLowerCase() == "httpd.apache.org") { - d.write('<div id="comments_thread"><\/div>'); - var s = d.createElement('script'); - s.type = 'text/javascript'; - s.async = true; - s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier; - (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s); - } - else { - d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>'); - } -})(window, document); -//--><!]]></script></div><div id="footer"> -<p class="apache">Copyright 2016 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p> -<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!-- -if (typeof(prettyPrint) !== 'undefined') { - prettyPrint(); -} -//--><!]]></script> -</body></html>
\ No newline at end of file diff --git a/docs/manual/mod/mod_proxy_protocol.xml b/docs/manual/mod/mod_proxy_protocol.xml deleted file mode 100644 index 1fcea758e1..0000000000 --- a/docs/manual/mod/mod_proxy_protocol.xml +++ /dev/null @@ -1,126 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE modulesynopsis SYSTEM "http://httpd.apache.org/docs/2.4/style/modulesynopsis.dtd"> -<?xml-stylesheet type="text/xsl" href="http://httpd.apache.org/docs/2.4/style/manual.en.xsl"?> - -<!-- - Orig Copyright 2014 Cloudzilla Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<modulesynopsis metafile="mod_proxy_protocol.xml.meta"> - -<name>mod_proxy_protocol</name> -<description>Implements the server side of the proxy protocol.</description> -<status>Extension</status> -<sourcefile>mod_proxy_protocol.c</sourcefile> -<identifier>proxy_protocol_module</identifier> - -<summary> - <p><module>mod_proxy_protocol</module> implements the server side of - HAProxy's - <a href="http://blog.haproxy.com/haproxy/proxy-protocol/">Proxy Protocol</a>.</p> - - <p>The module overrides the client IP address for the connection - with the information supplied by the upstream proxy in the proxy - protocol (connection) header.</p> - - <p>This overridden useragent IP address is then used for the - <module>mod_authz_host</module> - <directive module="mod_authz_core" name="require">Require ip</directive> - feature, is reported by <module>mod_status</module>, and is recorded by - <module>mod_log_config</module> <code>%a</code> and <module>core</module> - <code>%a</code> format strings. The underlying client IP of the connection - is available in the <code>%{c}a</code> format string.</p> - - <note type="warning">It is critical to only enable this behavior from - intermediate proxies which are trusted by this server, since it is trivial - for the remote client to impersonate another client. Currently this must - be done by external means (such as a firewall) as this module does not - (yet) implement access controls.</note> -</summary> -<seealso><a href="http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt">Proxy Protocol Spec</a></seealso> - -<directivesynopsis> -<name>ProxyProtocol </name> -<description>Enable or disable the proxy protocol handling</description> -<syntax>ProxyProtocol On|Off</syntax> -<contextlist><context>server config</context><context>virtual host</context> -</contextlist> - -<usage> - <p>The <directive>ProxyProtocol</directive> enables or disables the - reading and handling of the proxy protocol connection header. If enabled - the upstream client <em>must</em> send the header every time it opens a - connection or the connection will get aborted.</p> - - <p>While this directive may be specified in any virtual host, it is - important to understand that because the proxy protocol is connection - based and protocol agnostic, the enabling and disabling is actually based - on ip-address and port. This means that if you have multiple name-based - virtual hosts for the same host and port, and you enable it any one of - them, then it is enabled for all them (with that host and port). It also - means that if you attempt to enable the proxy protocol in one and disable - 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> - - <highlight language="config"> - ProxyProtocol On - </highlight> -</usage> -</directivesynopsis> - -<!-- -<directivesynopsis> -<name>ProxyProtocolTrustedProxies</name> -<description>A listed of clients that are trusted to provide the proxy -protocol header.</description> -<syntax>ProxyProtocolTrustedProxies <var>levels</var></syntax> -<syntax>ProxyProtocolTrustedProxies all|<var>host</var> [<var>host</var>] ...</syntax> -<default>ProxyProtocolTrustedProxies all</default> -<contextlist><context>server config</context><context>virtual host</context> -</contextlist> - -<usage> - <p>The <directive>ProxyProtocolTrustedProxies</directive> directive limits - which clients are trusted to use the proxy protocol. What happens when a - client is not trusted is controlled by the - <directive module="mod_proxy_protocol">ProxyProtocolRejectUntrusted</directive> - directive.</p> -</usage> -</directivesynopsis> - -<directivesynopsis> -<name>ProxyProtocolRejectUntrusted</name> -<description>The number of characters in subdirectory names</description> -<syntax>ProxyProtocolRejectUntrusted On|Off</syntax> -<default>ProxyProtocolRejectUntrusted On</default> -<contextlist><context>server config</context><context>virtual host</context> -</contextlist> - -<usage> - <p>The <directive>ProxyProtocolRejectUntrusted</directive> directive - controls the behavior when a connection is received from an untrusted - client (as configured by the - <directive module="mod_proxy_protocol">ProxyProtocolTrustedProxies</directive> - directive) on a host and port for which the proxy protocol has been enabled. - If set to On (the default) then the connection is aborted; if set to Off - then the connection is allowed, and client must send a valid proxy protocol - header, but the contents of the header are ignored and the client IP for - the connection left untouched (i.e. will be that of the immediate client). - </p> -</usage> -</directivesynopsis> ---> - -</modulesynopsis> diff --git a/docs/manual/mod/mod_proxy_protocol.xml.meta b/docs/manual/mod/mod_proxy_protocol.xml.meta deleted file mode 100644 index 975b0cf763..0000000000 --- a/docs/manual/mod/mod_proxy_protocol.xml.meta +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!-- GENERATED FROM XML: DO NOT EDIT --> - -<metafile reference="mod_proxy_protocol.xml"> - <basename>mod_proxy_protocol</basename> - <path>/mod/</path> - <relpath>..</relpath> - - <variants> - <variant>en</variant> - </variants> -</metafile> diff --git a/docs/manual/mod/mod_remoteip.xml b/docs/manual/mod/mod_remoteip.xml index fe9d8f48db..cd396e748a 100644 --- a/docs/manual/mod/mod_remoteip.xml +++ b/docs/manual/mod/mod_remoteip.xml @@ -44,8 +44,8 @@ via the request headers. <p>Additionally, this module implements the server side of HAProxy's - <a href="http://blog.haproxy.com/haproxy/proxy-protocol/">Proxy Protocol</a> when - using the <directive module="mod_remoteip">RemoteIPProxyProtocolEnable</directive> + <a href="http://blog.haproxy.com/haproxy/proxy-protocol/">PROXY Protocol</a> when + using the <directive module="mod_remoteip">RemoteIPProxyProtocol</directive> directive.</p> <p>Once replaced as instructed, this overridden useragent IP address is @@ -223,26 +223,26 @@ RemoteIPProxiesHeader X-Forwarded-By <directivesynopsis> <name>RemoteIPProxyProtocol</name> -<description>Enable, optionally enable or disable the proxy protocol handling</description> -<syntax>ProxyProtocol On|Optional|Off</syntax> +<description>Enable, optionally enable or disable the PROXY protocol handling</description> +<syntax>RemoteIPProxyProtocol On|Optional|Off</syntax> <contextlist><context>server config</context><context>virtual host</context> </contextlist> <usage> - <p>The <directive>RemoteIPProxyProtocolEnable</directive> enables or - disables the reading and handling of the proxy protocol connection header. + <p>The <directive>RemoteIPProxyProtocol</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> <p>While this directive may be specified in any virtual host, it is - important to understand that because the proxy protocol is connection + important to understand that because the PROXY protocol is connection based and protocol agnostic, the enabling and disabling is actually based on ip-address and port. This means that if you have multiple name-based virtual hosts for the same host and port, and you enable it any one of them, then it is enabled for all them (with that host and port). It also - means that if you attempt to enable the proxy protocol in one and disable + means that if you attempt to enable the PROXY protocol in one and disable 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> @@ -258,26 +258,26 @@ RemoteIPProxiesHeader X-Forwarded-By Listen 80 <VirtualHost *:80> ServerName www.example.com - RemoteIPProxyProtocolEnable Optional + RemoteIPProxyProtocol Optional #Requests to this virtual host may optionally not have - # a proxy protocol header provided + # a PROXY protocol header provided </VirtualHost> <VirtualHost *:80> ServerName www.example.com - RemoteIPProxyProtocolEnable On + RemoteIPProxyProtocol On - #Requests to this virtual host must have a proxy protocol + #Requests to this virtual host must have a PROXY protocol # header provided. If it is missing, a 400 will result </VirtualHost> Listen 8080 <VirtualHost *:8080> ServerName www.example.com - RemoteIPProxyProtocolEnable On + RemoteIPProxyProtocol On - #Requests to this virtual host must have a proxy protocol + #Requests to this virtual host must have a PROXY protocol # header provided. If it is missing, the connection will # be aborted </VirtualHost> diff --git a/modules/filters/mod_proxy_protocol.c b/modules/filters/mod_proxy_protocol.c deleted file mode 100644 index 0aee5967f3..0000000000 --- a/modules/filters/mod_proxy_protocol.c +++ /dev/null @@ -1,736 +0,0 @@ -/* - * Copyright 2014 Cloudzilla Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * mod_proxy_protocol.c -- Apache proxy_protocol module - * - * This implements the server side of the proxy protocol decribed in - * http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt . It works - * by installing itself (where enabled) as a connection filter (ahead of - * mod_ssl) to parse and remove the proxy protocol header, and by then - * modifying the useragent_* fields in the requests accordingly. - * - * TODO: - * * add the following configs: - * ProxyProtocolTrustedProxies "all"|ip-addr|host [ip-addr|host] ... (default all) - * ProxyProtocolRejectUntrusted Yes|No (default Yes) - * What to do if a connection is received from an untrusted proxy: - * yes = abort the connection - * no = allow connection and remove header, but ignore header - * * add support for sending the header on outgoing connections (mod_proxy), - * and config for choosing which hosts to enable it for - * (ProxyProtocolDownstreamHosts?) - */ - -#include "httpd.h" -#include "http_config.h" -#include "http_protocol.h" -#include "http_connection.h" -#include "http_main.h" -#include "http_log.h" -#include "ap_config.h" -#include "ap_listen.h" -#include "apr_strings.h" - -module AP_MODULE_DECLARE_DATA proxy_protocol_module; - -/* - * Module configuration - */ - -typedef struct pp_addr_info { - struct pp_addr_info *next; - apr_sockaddr_t *addr; - server_rec *source; -} pp_addr_info; - -typedef struct { - pp_addr_info *enabled; - pp_addr_info *disabled; - apr_pool_t *pool; -} pp_config; - -static int pp_hook_pre_config(apr_pool_t *pconf, apr_pool_t *plog, - apr_pool_t *ptemp) -{ - pp_config *conf; - - conf = (pp_config *) apr_palloc(pconf, sizeof(pp_config)); - conf->enabled = NULL; - conf->disabled = NULL; - conf->pool = pconf; - - ap_set_module_config(ap_server_conf->module_config, &proxy_protocol_module, - conf); - - return OK; -} - -/* Similar apr_sockaddr_equal, except that it compares ports too. */ -static int pp_sockaddr_equal(apr_sockaddr_t *addr1, apr_sockaddr_t *addr2) -{ - return (addr1->port == addr2->port && apr_sockaddr_equal(addr1, addr2)); -} - -/* Similar pp_sockaddr_equal, except that it handles wildcard addresses - * and ports too. - */ -static int pp_sockaddr_compat(apr_sockaddr_t *addr1, apr_sockaddr_t *addr2) -{ - /* test exact address equality */ - if (apr_sockaddr_equal(addr1, addr2) && - (addr1->port == addr2->port || addr1->port == 0 || addr2->port == 0)) { - return 1; - } - - /* test address wildcards */ - if (apr_sockaddr_is_wildcard(addr1) && - (addr1->port == 0 || addr1->port == addr2->port)) { - return 1; - } - - if (apr_sockaddr_is_wildcard(addr2) && - (addr2->port == 0 || addr2->port == addr1->port)) { - return 1; - } - - return 0; -} - -static int pp_addr_in_list(pp_addr_info *list, apr_sockaddr_t *addr) -{ - for (; list; list = list->next) { - if (pp_sockaddr_compat(list->addr, addr)) { - return 1; - } - } - - return 0; -} - -static void pp_warn_enable_conflict(pp_addr_info *prev, server_rec *new, int on) -{ - char buf[INET6_ADDRSTRLEN]; - - apr_sockaddr_ip_getbuf(buf, sizeof(buf), prev->addr); - - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, new, - "ProxyProtocol: previous setting for %s:%hu from virtual " - "host {%s:%hu in %s} is being overriden by virtual host " - "{%s:%hu in %s}; new setting is '%s'", - 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, - on ? "On" : "Off"); -} - -static const char *pp_enable_proxy_protocol(cmd_parms *cmd, void *config, - int flag) -{ - pp_config *conf; - server_addr_rec *addr; - pp_addr_info **add; - pp_addr_info **rem; - pp_addr_info *list; - - conf = ap_get_module_config(ap_server_conf->module_config, - &proxy_protocol_module); - - if (flag) { - add = &conf->enabled; - rem = &conf->disabled; - } - else { - add = &conf->disabled; - rem = &conf->enabled; - } - - for (addr = cmd->server->addrs; addr; addr = addr->next) { - /* remove address from opposite list */ - if (*rem) { - if (pp_sockaddr_equal((*rem)->addr, addr->host_addr)) { - pp_warn_enable_conflict(*rem, cmd->server, flag); - *rem = (*rem)->next; - } - else { - for (list = *rem; list->next; list = list->next) { - if (pp_sockaddr_equal(list->next->addr, addr->host_addr)) { - pp_warn_enable_conflict(list->next, cmd->server, flag); - list->next = list->next->next; - break; - } - } - } - } - - /* add address to desired list */ - if (!pp_addr_in_list(*add, addr->host_addr)) { - pp_addr_info *info = apr_palloc(conf->pool, sizeof(*info)); - info->addr = addr->host_addr; - info->source = cmd->server; - info->next = *add; - *add = info; - } - } - - return NULL; -} - -static int pp_hook_post_config(apr_pool_t *pconf, apr_pool_t *plog, - apr_pool_t *ptemp, server_rec *s) -{ - pp_config *conf; - pp_addr_info *info; - char buf[INET6_ADDRSTRLEN]; - - conf = ap_get_module_config(ap_server_conf->module_config, - &proxy_protocol_module); - - for (info = conf->enabled; info; info = info->next) { - apr_sockaddr_ip_getbuf(buf, sizeof(buf), info->addr); - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, - "ProxyProtocol: enabled on %s:%hu", buf, info->addr->port); - } - for (info = conf->disabled; info; info = info->next) { - apr_sockaddr_ip_getbuf(buf, sizeof(buf), info->addr); - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, - "ProxyProtocol: disabled on %s:%hu", buf, info->addr->port); - } - - return OK; -} - -static const command_rec proxy_protocol_cmds[] = { - AP_INIT_FLAG("ProxyProtocol", pp_enable_proxy_protocol, NULL, RSRC_CONF, - "Enable proxy-protocol handling (`on', `off')"), - { NULL } -}; - -/* - * Proxy-protocol implementation - */ - -static const char *pp_inp_filter = "ProxyProtocol Filter"; - -typedef struct { - char line[108]; -} proxy_v1; - -typedef union { - struct { /* for TCP/UDP over IPv4, len = 12 */ - uint32_t src_addr; - uint32_t dst_addr; - uint16_t src_port; - uint16_t dst_port; - } ip4; - struct { /* for TCP/UDP over IPv6, len = 36 */ - uint8_t src_addr[16]; - uint8_t dst_addr[16]; - uint16_t src_port; - uint16_t dst_port; - } ip6; - struct { /* for AF_UNIX sockets, len = 216 */ - uint8_t src_addr[108]; - uint8_t dst_addr[108]; - } unx; -} proxy_v2_addr; - -typedef struct { - uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */ - uint8_t ver_cmd; /* protocol version and command */ - uint8_t fam; /* protocol family and address */ - uint16_t len; /* number of following bytes part of the header */ - proxy_v2_addr addr; -} proxy_v2; - -typedef union { - proxy_v1 v1; - proxy_v2 v2; -} proxy_header; - -static const char v2sig[12] = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"; -#define MIN_V1_HDR_LEN 15 -#define MIN_V2_HDR_LEN 16 -#define MIN_HDR_LEN MIN_V1_HDR_LEN - -typedef struct { - char header[sizeof(proxy_header)]; - apr_size_t rcvd; - apr_size_t need; - int version; - ap_input_mode_t mode; - apr_bucket_brigade *bb; - int done; -} pp_filter_context; - -typedef struct { - apr_sockaddr_t *client_addr; - char *client_ip; -} pp_conn_config; - -static int pp_is_server_port(apr_port_t port) -{ - ap_listen_rec *lr; - - for (lr = ap_listeners; lr; lr = lr->next) { - if (lr->bind_addr && lr->bind_addr->port == port) { - return 1; - } - } - - return 0; -} - -/* Add our filter to the connection. - */ -static int pp_hook_pre_connection(conn_rec *c, void *csd) -{ - pp_config *conf; - pp_conn_config *conn_conf; - - /* check if we're enabled for this connection */ - conf = ap_get_module_config(ap_server_conf->module_config, - &proxy_protocol_module); - - if (!pp_addr_in_list(conf->enabled, c->local_addr) || - pp_addr_in_list(conf->disabled, c->local_addr)) { - return DECLINED; - } - - /* mod_proxy creates outgoing connections - we don't want those */ - if (!pp_is_server_port(c->local_addr->port)) { - return DECLINED; - } - - /* add our filter */ - if (!ap_add_input_filter(pp_inp_filter, NULL, NULL, c)) { - return DECLINED; - } - - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, - "ProxyProtocol: enabled on connection to %s:%hu", - c->local_ip, c->local_addr->port); - - /* this holds the resolved proxy info for this connection */ - conn_conf = apr_pcalloc(c->pool, sizeof(*conn_conf)); - ap_set_module_config(c->conn_config, &proxy_protocol_module, conn_conf); - - return OK; -} - -/* Set the request's useragent fields to our client info. - */ -static int pp_hook_post_read_request(request_rec *r) -{ - pp_conn_config *conn_conf; - - conn_conf = ap_get_module_config(r->connection->conn_config, - &proxy_protocol_module); - if (!conn_conf || !conn_conf->client_addr) { - return DECLINED; - } - - r->useragent_addr = conn_conf->client_addr; - r->useragent_ip = conn_conf->client_ip; - - return OK; -} - -typedef enum { HDR_DONE, HDR_ERROR, HDR_NEED_MORE } pp_parse_status_t; - -/* - * Human readable format: - * PROXY {TCP4|TCP6|UNKNOWN} <client-ip-addr> <dest-ip-addr> <client-port> <dest-port><CR><LF> - */ -static pp_parse_status_t pp_process_v1_header(conn_rec *c, - pp_conn_config *conn_conf, - proxy_header *hdr, apr_size_t len, - apr_size_t *hdr_len) -{ - char *end, *next, *word, *host, *valid_addr_chars, *saveptr; - char buf[sizeof(hdr->v1.line)]; - apr_port_t port; - apr_status_t ret; - apr_int32_t family; - -#define GET_NEXT_WORD(field) \ - word = apr_strtok(NULL, " ", &saveptr); \ - if (!word) { \ - ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, \ - "ProxyProtocol: no " field " found in header '%s'", \ - hdr->v1.line); \ - return HDR_ERROR; \ - } - - end = memchr(hdr->v1.line, '\r', len - 1); - if (!end || end[1] != '\n') { - return HDR_NEED_MORE; /* partial or invalid header */ - } - - *end = '\0'; - *hdr_len = end + 2 - hdr->v1.line; /* skip header + CRLF */ - - /* parse in separate buffer so have the original for error messages */ - strcpy(buf, hdr->v1.line); - - apr_strtok(buf, " ", &saveptr); - - /* parse family */ - GET_NEXT_WORD("family") - if (strcmp(word, "UNKNOWN") == 0) { - conn_conf->client_addr = c->client_addr; - conn_conf->client_ip = c->client_ip; - return HDR_DONE; - } - else if (strcmp(word, "TCP4") == 0) { - family = APR_INET; - valid_addr_chars = "0123456789."; - } - else if (strcmp(word, "TCP6") == 0) { - family = APR_INET6; - valid_addr_chars = "0123456789abcdefABCDEF:"; - } - else { - ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, - "ProxyProtocol: unknown family '%s' in header '%s'", - word, hdr->v1.line); - return HDR_ERROR; - } - - /* parse client-addr */ - GET_NEXT_WORD("client-address") - - if (strspn(word, valid_addr_chars) != strlen(word)) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, - "ProxyProtocol: invalid client-address '%s' found in " - "header '%s'", word, hdr->v1.line); - return HDR_ERROR; - } - - host = word; - - /* parse dest-addr */ - GET_NEXT_WORD("destination-address") - - /* parse client-port */ - GET_NEXT_WORD("client-port") - if (sscanf(word, "%hu", &port) != 1) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, - "ProxyProtocol: error parsing port '%s' in header '%s'", - word, hdr->v1.line); - return HDR_ERROR; - } - - /* parse dest-port */ - /* GET_NEXT_WORD("destination-port") - no-op since we don't care about it */ - - /* create a socketaddr from the info */ - ret = apr_sockaddr_info_get(&conn_conf->client_addr, host, family, port, 0, - c->pool); - if (ret != APR_SUCCESS) { - conn_conf->client_addr = NULL; - ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, - "ProxyProtocol: error converting family '%d', host '%s'," - " and port '%hu' to sockaddr; header was '%s'", - family, host, port, hdr->v1.line); - return HDR_ERROR; - } - - conn_conf->client_ip = apr_pstrdup(c->pool, host); - - return HDR_DONE; -} - -/* Binary format: - * <sig><cmd><proto><addr-len><addr> - * sig = \x0D \x0A \x0D \x0A \x00 \x0D \x0A \x51 \x55 \x49 \x54 \x0A - * cmd = <4-bits-version><4-bits-command> - * 4-bits-version = \x02 - * 4-bits-command = {\x00|\x01} (\x00 = LOCAL: discard con info; \x01 = PROXY) - * proto = <4-bits-family><4-bits-protocol> - * 4-bits-family = {\x00|\x01|\x02|\x03} (AF_UNSPEC, AF_INET, AF_INET6, AF_UNIX) - * 4-bits-protocol = {\x00|\x01|\x02} (UNSPEC, STREAM, DGRAM) - */ -static pp_parse_status_t pp_process_v2_header(conn_rec *c, - pp_conn_config *conn_conf, - proxy_header *hdr) -{ - apr_status_t ret; - struct in_addr *in_addr; - struct in6_addr *in6_addr; - - switch (hdr->v2.ver_cmd & 0xF) { - case 0x01: /* PROXY command */ - switch (hdr->v2.fam) { - case 0x11: /* TCPv4 */ - ret = apr_sockaddr_info_get(&conn_conf->client_addr, NULL, - APR_INET, - ntohs(hdr->v2.addr.ip4.src_port), - 0, c->pool); - if (ret != APR_SUCCESS) { - conn_conf->client_addr = NULL; - ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, - "ProxyProtocol: error creating sockaddr"); - return HDR_ERROR; - } - - conn_conf->client_addr->sa.sin.sin_addr.s_addr = - hdr->v2.addr.ip4.src_addr; - break; - - case 0x21: /* TCPv6 */ - ret = apr_sockaddr_info_get(&conn_conf->client_addr, NULL, - APR_INET6, - ntohs(hdr->v2.addr.ip6.src_port), - 0, c->pool); - if (ret != APR_SUCCESS) { - conn_conf->client_addr = NULL; - ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, - "ProxyProtocol: error creating sockaddr"); - return HDR_ERROR; - } - - memcpy(&conn_conf->client_addr->sa.sin6.sin6_addr.s6_addr, - hdr->v2.addr.ip6.src_addr, 16); - break; - - default: - /* unsupported protocol, keep local connection address */ - return HDR_DONE; - } - break; /* we got a sockaddr now */ - - case 0x00: /* LOCAL command */ - /* keep local connection address for LOCAL */ - return HDR_DONE; - - default: - /* not a supported command */ - ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, - "ProxyProtocol: unsupported command %.2hx", - hdr->v2.ver_cmd); - return HDR_ERROR; - } - - /* got address - compute the client_ip from it */ - ret = apr_sockaddr_ip_get(&conn_conf->client_ip, conn_conf->client_addr); - if (ret != APR_SUCCESS) { - conn_conf->client_addr = NULL; - ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, - "ProxyProtocol: error converting address to string"); - return HDR_ERROR; - } - - return HDR_DONE; -} - -/* Determine if this is a v1 or v2 header. - */ -static int pp_determine_version(conn_rec *c, const char *ptr) -{ - proxy_header *hdr = (proxy_header *) ptr; - - /* assert len >= 14 */ - - if (memcmp(&hdr->v2, v2sig, sizeof(v2sig)) == 0 && - (hdr->v2.ver_cmd & 0xF0) == 0x20) { - return 2; - } - else if (memcmp(hdr->v1.line, "PROXY ", 6) == 0) { - return 1; - } - else { - ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, - "ProxyProtocol: no valid header found"); - return -1; - } -} - -/* Capture the first bytes on the protocol and parse the proxy protocol header. - * Removes itself when the header is complete. - */ -static apr_status_t pp_input_filter(ap_filter_t *f, - apr_bucket_brigade *bb_out, - ap_input_mode_t mode, - apr_read_type_e block, - apr_off_t readbytes) -{ - apr_status_t ret; - pp_filter_context *ctx = f->ctx; - pp_conn_config *conn_conf; - apr_bucket *b; - pp_parse_status_t psts; - const char *ptr; - apr_size_t len; - - if (f->c->aborted) { - return APR_ECONNABORTED; - } - - /* 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 (ctx->done) { - /* Note: because we're a connection filter we can't remove ourselves - * when we're done, so we have to stay in the chain and just go into - * passthrough mode. - */ - return ap_get_brigade(f->next, bb_out, mode, block, readbytes); - } - - conn_conf = ap_get_module_config(f->c->conn_config, &proxy_protocol_module); - - /* try to read a header's worth of data */ - while (!ctx->done) { - if (APR_BRIGADE_EMPTY(ctx->bb)) { - ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block, - ctx->need - ctx->rcvd); - if (ret != APR_SUCCESS) { - return ret; - } - } - if (APR_BRIGADE_EMPTY(ctx->bb)) { - return APR_EOF; - } - - while (!ctx->done && !APR_BRIGADE_EMPTY(ctx->bb)) { - b = APR_BRIGADE_FIRST(ctx->bb); - - ret = apr_bucket_read(b, &ptr, &len, block); - if (APR_STATUS_IS_EAGAIN(ret) && block == APR_NONBLOCK_READ) { - return APR_SUCCESS; - } - if (ret != APR_SUCCESS) { - return ret; - } - - memcpy(ctx->header + ctx->rcvd, ptr, len); - ctx->rcvd += len; - - apr_bucket_delete(b); - psts = HDR_NEED_MORE; - - if (ctx->version == 0) { - /* reading initial chunk */ - if (ctx->rcvd >= MIN_HDR_LEN) { - ctx->version = pp_determine_version(f->c, ctx->header); - if (ctx->version < 0) { - psts = HDR_ERROR; - } - 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) { - psts = pp_process_v1_header(f->c, conn_conf, - (proxy_header *) ctx->header, - ctx->rcvd, &ctx->need); - } - else if (ctx->version == 2) { - if (ctx->rcvd >= MIN_V2_HDR_LEN) { - ctx->need = MIN_V2_HDR_LEN + - ntohs(((proxy_header *) ctx->header)->v2.len); - } - if (ctx->rcvd >= ctx->need) { - psts = pp_process_v2_header(f->c, conn_conf, - (proxy_header *) ctx->header); - } - } - else { - ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, - "ProxyProtocol: internal error: unknown version " - "%d", ctx->version); - f->c->aborted = 1; - apr_brigade_destroy(ctx->bb); - return APR_ECONNABORTED; - } - - switch (psts) { - case HDR_ERROR: - f->c->aborted = 1; - apr_brigade_destroy(ctx->bb); - return APR_ECONNABORTED; - - case HDR_DONE: - ctx->done = 1; - break; - - case HDR_NEED_MORE: - break; - } - } - } - - /* we only get here when done == 1 */ - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, - "ProxyProtocol: received valid header: %s:%hu", - conn_conf->client_ip, conn_conf->client_addr->port); - - if (ctx->rcvd > ctx->need || !APR_BRIGADE_EMPTY(ctx->bb)) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, - "ProxyProtocol: internal error: have data left over; " - " need=%lu, rcvd=%lu, brigade-empty=%d", ctx->need, - ctx->rcvd, APR_BRIGADE_EMPTY(ctx->bb)); - f->c->aborted = 1; - apr_brigade_destroy(ctx->bb); - return APR_ECONNABORTED; - } - - /* clean up */ - apr_brigade_destroy(ctx->bb); - ctx->bb = NULL; - - /* now do the real read for the upper layer */ - return ap_get_brigade(f->next, bb_out, mode, block, readbytes); -} - -static void proxy_protocol_register_hooks(apr_pool_t *p) -{ - /* mod_ssl is CONNECTION + 5, so we want something higher (earlier); - * mod_reqtimeout is CONNECTION + 8, so we want something lower (later) */ - ap_register_input_filter(pp_inp_filter, pp_input_filter, NULL, - AP_FTYPE_CONNECTION + 7); - - ap_hook_pre_config(pp_hook_pre_config, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_post_config(pp_hook_post_config, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_pre_connection(pp_hook_pre_connection, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_post_read_request(pp_hook_post_read_request, NULL, NULL, - APR_HOOK_REALLY_FIRST); -} - -/* Dispatch list for API hooks */ -AP_DECLARE_MODULE(proxy_protocol) = { - STANDARD20_MODULE_STUFF, - NULL, /* create per-dir config structures */ - NULL, /* merge per-dir config structures */ - NULL, /* create per-server config structures */ - NULL, /* merge per-server config structures */ - proxy_protocol_cmds, /* table of config file commands */ - proxy_protocol_register_hooks /* register hooks */ -}; diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c index a47ccbbacd..8abfff73f4 100644 --- a/modules/metadata/mod_remoteip.c +++ b/modules/metadata/mod_remoteip.c @@ -369,7 +369,7 @@ static void remoteip_warn_enable_conflict(remoteip_addr_info *prev, server_rec * apr_sockaddr_ip_getbuf(buf, sizeof(buf), prev->addr); ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, new, APLOGNO(03491) - "RemoteIPProxyProtocolEnable: previous setting for %s:%hu from virtual " + "RemoteIPProxyProtocol: previous setting for %s:%hu from virtual " "host {%s:%hu in %s} is being overriden by virtual host " "{%s:%hu in %s}; new setting is '%s'", buf, prev->addr->port, prev->source->server_hostname, @@ -412,7 +412,7 @@ static const char *remoteip_enable_proxy_protocol(cmd_parms *cmd, void *config, rem_list[1] = &global_conf->proxy_protocol_optional; } else { - return apr_pstrcat(cmd->pool, "Unrecognized option for ProxyProtocolEnable `%s'", arg, NULL); + return apr_pstrcat(cmd->pool, "Unrecognized option for RemoteIPProxyProtocol `%s'", arg, NULL); } for (addr = cmd->server->addrs; addr; addr = addr->next) { @@ -1008,7 +1008,7 @@ static int remoteip_determine_version(conn_rec *c, const char *ptr) } } -/* Capture the first bytes on the protocol and parse the proxy protocol header. +/* Capture the first bytes on the protocol and parse the PROXY protocol header. * Removes itself when the header is complete. */ static apr_status_t remoteip_input_filter(ap_filter_t *f, @@ -1211,7 +1211,7 @@ 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("RemoteIPProxyProtocolEnable", remoteip_enable_proxy_protocol, NULL, + AP_INIT_TAKE1("RemoteIPProxyProtocol", remoteip_enable_proxy_protocol, NULL, RSRC_CONF, "Enable proxy-protocol handling (`on', `off')"), { NULL } }; |