Compare commits

...

No commits in common. "master" and "pristine-tar" have entirely different histories.

32 changed files with 3 additions and 1523 deletions

4
.gitignore vendored
View File

@ -1,4 +0,0 @@
.libs
mod_proxy_protocol.la
mod_proxy_protocol.lo
mod_proxy_protocol.slo

View File

@ -1,38 +0,0 @@
stages:
- build
- deploy
rpmbuild:
stage: build
image: gitlab-registry.cern.ch/cloud/ciadm
except:
- tags
script:
- if [ -z "$CI_BUILD_TAG" ]; then export CI_BUILD_TAG=$CI_DEFAULT_BUILD_TAG; fi
- export parser=(${CI_BUILD_TAG//-/ })
- sed -i s/CERN_VERSION_PLACEHOLDER/${parser[0]}/g mod_proxy_protocol.spec
- sed -i s/CERN_RELEASE_PLACEHOLDER/${parser[1]}/g mod_proxy_protocol.spec
- curl https://gitlab.cern.ch/cloud-infrastructure/cloud-dev/raw/master/gitlab/rpmbuild.sh | bash
kojicheck:
stage: build
image: gitlab-registry.cern.ch/cloud/ciadm
script:
- if [ -z "$CI_BUILD_TAG" ]; then export CI_BUILD_TAG=$CI_DEFAULT_BUILD_TAG; fi
- export parser=(${CI_BUILD_TAG//-/ })
- sed -i s/CERN_VERSION_PLACEHOLDER/${parser[0]}/g mod_proxy_protocol.spec
- sed -i s/CERN_RELEASE_PLACEHOLDER/${parser[1]}/g mod_proxy_protocol.spec
- curl https://gitlab.cern.ch/cloud-infrastructure/cloud-dev/raw/master/gitlab/kojicheck.sh | bash
kojibuild:
stage: deploy
image: gitlab-registry.cern.ch/cloud/ciadm
only:
- tags
script:
- export DIST='.el7.cern'
- if [ -z "$CI_BUILD_TAG" ]; then export CI_BUILD_TAG=$CI_DEFAULT_BUILD_TAG; fi
- export parser=(${CI_BUILD_TAG//-/ })
- sed -i s/CERN_VERSION_PLACEHOLDER/${parser[0]}/g mod_proxy_protocol.spec
- sed -i s/CERN_RELEASE_PLACEHOLDER/${parser[1]}/g mod_proxy_protocol.spec
- curl https://gitlab.cern.ch/cloud-infrastructure/cloud-dev/raw/master/gitlab/kojibuild.sh | bash

202
LICENSE
View File

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@ -1,33 +0,0 @@
##
## Makefile -- Build procedure for sample proxy_protocol Apache module
## Autogenerated via ``apxs -n proxy_protocol -g''.
##
# the used tools
APXS=apxs
XSLT=xsltproc
# the default target
all: .libs/mod_proxy_protocol.so
# build the so in the current directory
.libs/mod_proxy_protocol.so: mod_proxy_protocol.c
$(APXS) -c -Wc,-Wall mod_proxy_protocol.c
# install the so - usually needs root access
install: .libs/mod_proxy_protocol.so
$(APXS) -i mod_proxy_protocol.la
# generate the html doc
docs: mod_proxy_protocol.html
mod_proxy_protocol.html: mod_proxy_protocol.xml mod_proxy_protocol.xml.meta
$(XSLT) -o $@ $<
# generate packages
dpkg:
debuild --no-tgz-check -uc -us
# cleanup
clean:
-rm -rf mod_proxy_protocol.o mod_proxy_protocol.lo mod_proxy_protocol.slo mod_proxy_protocol.la .libs mod_proxy_protocol.html

View File

@ -1,52 +0,0 @@
# Apache Proxy Protocol Module
This is an [Apache](http://httpd.apache.org/) module that implements the
server side of HAProxy's
[Proxy Protocol](http://blog.haproxy.com/haproxy/proxy-protocol/).
Note: as of Apache 2.4.30 this code has been merged into
[mod_remoteip](https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html),
with the `ProxyProtocol` directive renamed to `RemoteIPProxyProtocol`.
## Build and Install
You'll need the apache development packages installed (typically something
like `apache-devel` or `apache2-dev`). Then simply running `make` will
create the shared library in `.libs/mod_proxy_protocol.so`; `make install`
will attempt to install it in your current apache installation (you'll
probably need to be root for this).
## Configuration
Add the following directive to your apache config to load the module
LoadModule proxy_protocol_module <path-to-module>/mod_proxy_protocol.so
or try running
apxs -a mod_proxy_protocol.c
For configuration details see the
[module docs](http://roadrunner2.github.io/mod-proxy-protocol/mod_proxy_protocol.html)
## Amazon EC2 Notes
To properly secure Apache when using this on EC2 behind an ELB you'll probably
want to do something like the following to ensure that only the ELB can
provide the proxy protocol header while still being able to access the site
directly (not via the ELB):
1. In Apache create a copy of virtual host with a new port, and add the
'ProxyProtocol On' directive to this new virtual host.
2. Add an entry to the security group for the server that only allows access
to this new port from the ELB (specify the source as `amazon-elb/amazon-elb-sg`)
3. Point the ELB listener at this new port (and of course
[enable](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html)
the proxy protocol for that)
## TODO
* Add access-control (see commented out `ProxyProtocolTrustedProxies` in
`mod_proxy_protocol.xml`)
* Add support for outgoing connections (`mod_proxy`)

View File

@ -1,5 +0,0 @@
## To activate mod_proxy_protocol, do:
a2enmod proxy_protocol && /etc/init.d/apache2 force-reload
## And then enable ProxyProtocol for the desired hosts.

3
debian/apache2 vendored
View File

@ -1,3 +0,0 @@
mod .libs/mod_proxy_protocol.so
mod debian/proxy_protocol.load
mod debian/proxy_protocol.conf

17
debian/changelog vendored
View File

@ -1,17 +0,0 @@
mod-proxy-protocol (0.2-3) UNRELEASED; urgency=medium
* Add patch for CVE-2019-10097
-- Mario Fetka <mario.fetka@gmail.com> Wed, 12 Feb 2020 11:54:28 +0100
mod-proxy-protocol (0.2-1) xenial; urgency=low
* Merged patch to fix http/2 issues.
-- Roadrunner2 <roadrunner2@github.com> Tue, 20 Mar 2018 02:11:49 -0700
mod-proxy-protocol (0.1-1) trusty; urgency=low
* Initial release
-- Roadrunner2 <roadrunner2@github.com> Thu, 30 Oct 2014 16:46:21 -0700

1
debian/compat vendored
View File

@ -1 +0,0 @@
9

17
debian/control vendored
View File

@ -1,17 +0,0 @@
Source: mod-proxy-protocol
Section: web
Priority: optional
Maintainer: Roadrunner2 <roadrunner2@github.com>
Build-Depends: debhelper (>= 7.0.50~), apache2-dev (>= 2.4.0), xsltproc
Standards-Version: 3.8.4
Homepage: https://github.com/roadrunner2/mod-proxy-protocol
Package: libapache2-mod-proxy-protocol
Architecture: amd64
Depends: ${shlibs:Depends}, ${misc:Depends}, apache2-api-20120211
Description: Apache module for proxy protocol
The proxy protocol is a way for upstream proxies and load-balancers to
for the ip-address of the client to the server. This package contains
an Apache module that implements the server-side of this protocol, thereby
allowing other modules to see and use actual client's ip-address instead
of that of the upstream proxy/load-balancer.

13
debian/copyright vendored
View File

@ -1,13 +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.

1
debian/dirs vendored
View File

@ -1 +0,0 @@
usr/lib/apache2/modules

4
debian/docs vendored
View File

@ -1,4 +0,0 @@
README.md
mod_proxy_protocol.xml
mod_proxy_protocol.xml.meta
debian/README.Debian

View File

@ -1,2 +0,0 @@
libapache2-mod-proxy-protocol: apache2-module-depends-on-real-apache2-package
libapache2-mod-proxy-protocol: copyright-should-refer-to-common-license-file-for-apache-2

View File

@ -1,3 +0,0 @@
<IfModule mod_proxy_protocol.c>
#ProxyProtocol On
</IfModule>

View File

@ -1 +0,0 @@
LoadModule proxy_protocol_module /usr/lib/apache2/modules/mod_proxy_protocol.so

43
debian/rules vendored
View File

@ -1,43 +0,0 @@
#!/usr/bin/make -f
# debian rules file for mod_proxy_protocol
build:
dh_testdir
make all # docs
clean:
dh_testdir
dh_testroot
make clean
dh_clean
install: build
dh_testdir
dh_testroot
dh_prep
dh_installdirs
dh_install
dh_apache2 -e
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installdocs
dh_installchangelogs
dh_link
dh_strip
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
# Build architecture-independent files here.
binary-indep: build install
binary: binary-arch binary-indep
.PHONY: build clean binary-indep binary-arch binary install configure

View File

@ -1 +0,0 @@
1.0

Binary file not shown.

View File

@ -0,0 +1 @@
6744e24b7ed53084e7fc92d93da0da787cc58add

Binary file not shown.

View File

@ -0,0 +1 @@
ee435efb975034684c4e6e5e9a5be6f33340c8d7

Binary file not shown.

View File

@ -0,0 +1 @@
6744e24b7ed53084e7fc92d93da0da787cc58add

View File

@ -1,755 +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"
#include "apr_version.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_VERSION_AT_LEAST(1,5,0))
apr_sockaddr_t addr0;
static const char inaddr_any[ sizeof(struct in_addr) ] = {0};
#endif
if (apr_sockaddr_equal(addr1, addr2) &&
(addr1->port == addr2->port || addr1->port == 0 || addr2->port == 0)) {
return 1;
}
#if APR_VERSION_AT_LEAST(1,5,0)
/* test address wildcards */
if (apr_sockaddr_is_wildcard(addr1) &&
(addr1->port == 0 || addr1->port == addr2->port)) {
#else
addr0.ipaddr_ptr = &inaddr_any;
addr0.ipaddr_len = addr1->ipaddr_len;
if (apr_sockaddr_equal(&addr0, addr1) &&
(addr1->port == 0 || addr1->port == addr2->port)) {
#endif
return 1;
}
#if APR_VERSION_AT_LEAST (1,5,0)
if (apr_sockaddr_is_wildcard(addr2) &&
(addr2->port == 0 || addr2->port == addr1->port)) {
#else
addr0.ipaddr_len = addr2->ipaddr_len;
if (apr_sockaddr_equal(&addr0, addr2) &&
(addr2->port == 0 || addr2->port == addr1->port)) {
#endif
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 */
};

View File

@ -1,72 +0,0 @@
%{!?_httpd_apxs: %{expand: %%global _httpd_apxs %%{_sbindir}/apxs}}
%{!?_httpd_mmn: %{expand: %%global _httpd_mmn %%(cat %{_includedir}/httpd/.mmn || echo missing-httpd-devel)}}
%{!?_httpd_confdir: %{expand: %%global _httpd_confdir %%{_sysconfdir}/httpd/conf.d}}
# /etc/httpd/conf.d with httpd < 2.4 and defined as /etc/httpd/conf.modules.d with httpd >= 2.4
%{!?_httpd_modconfdir: %{expand: %%global _httpd_modconfdir %%{_sysconfdir}/httpd/conf.d}}
%{!?_httpd_moddir: %{expand: %%global _httpd_moddir %%{_libdir}/httpd/modules}}
%global cern_version CERN_VERSION_PLACEHOLDER
%global cern_release CERN_RELEASE_PLACEHOLDER
Name: mod_proxy_protocol
Summary: Apache module that implements the downstream server side of HAProxy's Proxy Protocol.
Version: %{cern_version}
Release: %{cern_release}%{?dist}
License: ASL 2.0
Group: System Environment/Daemons
Source0: %{name}-%{version}.tar.gz
BuildRequires: httpd-devel
BuildRequires: gcc
BuildRequires: libtool
Requires: httpd
Requires: httpd-mmn = %{_httpd_mmn}
# Suppress auto-provides for module DSO per
# https://fedoraproject.org/wiki/Packaging:AutoProvidesAndRequiresFiltering#Summary
%{?filter_provides_in: %filter_provides_in %{_libdir}/httpd/modules/.*\.so$}
%{?filter_setup}
%description
HAProxy's Proxy Protocol is a way for upstream proxies and load balancers to
report the IP address of the original remote client to the downstream server,
without having to modify things like HTTP headers in the actual payload.
This package contains an Apache module that implements the downstream (i.e. the
receiving) server side of this protocol, thereby allowing other modules to see
and use the actual client's IP address instead of that of the upstream proxy or
load balancer.
%prep
#%setup -q -n mod_proxy_protocol-%{version}
%setup -q -n %{name}-%{version}
%build
%{_httpd_apxs} -c mod_proxy_protocol.c
%install
rm -rf $RPM_BUILD_ROOT
install -Dm 755 .libs/mod_proxy_protocol.so $RPM_BUILD_ROOT%{_httpd_moddir}/mod_proxy_protocol.so
%if "%{_httpd_modconfdir}" == "%{_httpd_confdir}"
# httpd <= 2.2.x
cat redhat/proxy_protocol.module > unified.conf
echo >> unified.conf
cat redhat/proxy_protocol.conf >> unified.conf
touch -c -r redhat/proxy_protocol.conf unified.conf
install -Dp -m 644 unified.conf $RPM_BUILD_ROOT%{_httpd_confdir}/proxy_protocol.conf
%else
# httpd >= 2.4.x
install -Dp -m 644 redhat/proxy_protocol.module $RPM_BUILD_ROOT%{_httpd_modconfdir}/10-proxy_protocol.conf
install -Dp -m 644 redhat/proxy_protocol.conf $RPM_BUILD_ROOT%{_httpd_confdir}/proxy_protocol.conf
%endif
%files
%doc README.md LICENSE
%if "%{_httpd_modconfdir}" != "%{_httpd_confdir}"
%config(noreplace) %{_httpd_modconfdir}/10-proxy_protocol.conf
%endif
%config(noreplace) %{_httpd_confdir}/proxy_protocol.conf
%{_httpd_moddir}/*.so
%changelog
* Fri Dec 09 2016 Jose Castro Leon <jose.castro.leon@cern.ch> 0.1-1
- First package release.

View File

@ -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"?>
<!--
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>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<metafile reference="mod_proxy_protocol.xml">
<basename>mod_proxy_protocol</basename>
<path>/mod/</path>
<relpath>https://httpd.apache.org/docs/2.4</relpath>
</metafile>

View File

@ -1,48 +0,0 @@
--- mod_proxy_protocol.c-orig 2016-05-19 12:58:26.902187400 +0000
+++ mod_proxy_protocol.c 2016-05-19 13:24:25.417638197 +0000
@@ -44,6 +44,7 @@
#include "ap_config.h"
#include "ap_listen.h"
#include "apr_strings.h"
+#include "apr_version.h"
module AP_MODULE_DECLARE_DATA proxy_protocol_module;
@@ -91,19 +92,37 @@
static int pp_sockaddr_compat(apr_sockaddr_t *addr1, apr_sockaddr_t *addr2)
{
/* test exact address equality */
+#if !(APR_VERSION_AT_LEAST(1,5,0))
+ apr_sockaddr_t addr0;
+ static const char inaddr_any[ sizeof(struct in_addr) ] = {0};
+#endif
+
if (apr_sockaddr_equal(addr1, addr2) &&
(addr1->port == addr2->port || addr1->port == 0 || addr2->port == 0)) {
return 1;
}
+#if APR_VERSION_AT_LEAST(1,5,0)
/* test address wildcards */
if (apr_sockaddr_is_wildcard(addr1) &&
(addr1->port == 0 || addr1->port == addr2->port)) {
+#else
+ addr0.ipaddr_ptr = &inaddr_any;
+ addr0.ipaddr_len = addr1->ipaddr_len;
+ if (apr_sockaddr_equal(&addr0, addr1) &&
+ (addr1->port == 0 || addr1->port == addr2->port)) {
+#endif
return 1;
}
+#if APR_VERSION_AT_LEAST (1,5,0)
if (apr_sockaddr_is_wildcard(addr2) &&
(addr2->port == 0 || addr2->port == addr1->port)) {
+#else
+ addr0.ipaddr_len = addr2->ipaddr_len;
+ if (apr_sockaddr_equal(&addr0, addr2) &&
+ (addr2->port == 0 || addr2->port == addr1->port)) {
+#endif
return 1;
}

View File

@ -1,71 +0,0 @@
%{!?_httpd_mmn: %{expand: %%global _httpd_mmn %%(cat %{_includedir}/httpd/.mmn || echo 0-0)}}
%{!?_httpd_apxs: %{expand: %%global _httpd_apxs %%{_sbindir}/apxs}}
%{!?_httpd_confdir: %{expand: %%global _httpd_confdir %%{_sysconfdir}/httpd/conf.d}}
# /etc/httpd/conf.d with httpd < 2.4 and defined as /etc/httpd/conf.modules.d with httpd >= 2.4
%{!?_httpd_modconfdir: %{expand: %%global _httpd_modconfdir %%{_sysconfdir}/httpd/conf.d}}
%{!?_httpd_moddir: %{expand: %%global _httpd_moddir %%{_libdir}/httpd/modules}}
Name: mod_proxy_protocol
Summary: Apache module that implements the downstream server side of HAProxy's Proxy Protocol.
Version: 0.1
Release: 1.20141031git62d2df6%{?dist}
License: ASL 2.0
Group: System Environment/Daemons
Source0: https://github.com/roadrunner2/mod-proxy-protocol/archive/62d2df6c94eb0a18605e47f6236c08130d7e120d.tar.gz
Source1: proxy_protocol.module
Source2: proxy_protocol.conf
Patch0: mod_proxy_protocol.c-fix-apr14-compat.patch
BuildRequires: httpd-devel
Requires: httpd
URL: https://github.com/roadrunner2/mod-proxy-protocol
# Suppress auto-provides for module DSO per
# https://fedoraproject.org/wiki/Packaging:AutoProvidesAndRequiresFiltering#Summary
%{?filter_provides_in: %filter_provides_in %{_libdir}/httpd/modules/.*\.so$}
%{?filter_setup}
%description
HAProxy's Proxy Protocol is a way for upstream proxies and load balancers to
report the IP address of the original remote client to the downstream server,
without having to modify things like HTTP headers in the actual payload.
This package contains an Apache module that implements the downstream (i.e. the
receiving) server side of this protocol, thereby allowing other modules to see
and use the actual client's IP address instead of that of the upstream proxy or
load balancer.
%prep
#%setup -q -n mod_proxy_protocol-%{version}
%setup -q -n mod-proxy-protocol-62d2df6c94eb0a18605e47f6236c08130d7e120d
%patch0 -p0 -F1
%build
%{_httpd_apxs} -c mod_proxy_protocol.c
%install
rm -rf $RPM_BUILD_ROOT
install -Dm 755 .libs/mod_proxy_protocol.so $RPM_BUILD_ROOT%{_httpd_moddir}/mod_proxy_protocol.so
%if "%{_httpd_modconfdir}" == "%{_httpd_confdir}"
# httpd <= 2.2.x
cat %{SOURCE1} > unified.conf
echo >> unified.conf
cat %{SOURCE2} >> unified.conf
touch -c -r %{SOURCE1} unified.conf
install -Dp -m 644 unified.conf $RPM_BUILD_ROOT%{_httpd_confdir}/proxy_protocol.conf
%else
# httpd >= 2.4.x
install -Dp -m 644 %{SOURCE1} $RPM_BUILD_ROOT%{_httpd_modconfdir}/10-proxy_protocol.conf
install -Dp -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_httpd_confdir}/proxy_protocol.conf
%endif
%files
%doc README.md LICENSE
%if "%{_httpd_modconfdir}" != "%{_httpd_confdir}"
%config(noreplace) %{_httpd_modconfdir}/10-proxy_protocol.conf
%endif
%config(noreplace) %{_httpd_confdir}/proxy_protocol.conf
%{_httpd_moddir}/*.so
%changelog
* Fri May 20 2016 earsdown <earsdown@github.com> 0.1-1.20141031git62d2df6
- First package release. Includes mamanguy patch to fix APR 1.4.x compatibility.

View File

@ -1,3 +0,0 @@
<IfModule mod_proxy_protocol.c>
#ProxyProtocol On
</IfModule>

View File

@ -1 +0,0 @@
LoadModule proxy_protocol_module modules/mod_proxy_protocol.so