We have a HAProxy server acting as a loadbalancer for our website.
The loadbalancer sends the client request to 3 backend servers which are running Apache 2.2. SSL is configured in all the 3 Apache servers. HAProxy acts as a loadbalancer in SSLPassthrough mode.
Now we want to capture the Client IP in the backend apache servers.
Is it possible in passthrough mode, if so how?
For SSLPassthrough mode, HAProxy is configured to use TCP protocol rather than HTTP and therefore looses the ability to use the X-Forwarded-* headers.
The solution to this problem is to make use of PROXY Protocol. You need to enable PROXY protocol by using send-proxy keyword in your HAProxy backend configuration.
For your Apache to be able to receive the IP through proxy protocol connection header, you would have to use the “mod-proxy-protocol” Apache module. Below is the link for the Apache module:
You would need to clone the above repository and then build the module to generate mod_proxy_protocol.so file.
yum install apache2-dev git
git clone https://github.com/roadrunner2/mod-proxy-protocol.git
cd mod-proxy-protocol
make
cp .libs/mod_proxy_protocol.so /usr/lib/apache2/modules/
Once the mod_proxy_protocol.so is generated then add the below LoadModule directive to your apache.conf file to use this module:
I have tried your solution but facing the following errors.
OS Detail
[root@access mod-proxy-protocol]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.6 (Maipo)
Httpd version
[root@access mod-proxy-protocol]# httpd -v
Server version: Apache/2.4.6 (Red Hat Enterprise Linux)
Server built: Mar 15 2019 07:18:12
[root@access mod-proxy-protocol]#
After downloading/cloning mod-proxy-protocol from git and trying to execute make the following errors are being received.
[root@access opt]# cd mod-proxy-protocol/
[root@access mod-proxy-protocol]# ll
total 64
drwxr-xr-x. 3 root root 4096 Jul 27 09:24 debian
-rw-r–r–. 1 root root 11358 Jul 27 09:24 LICENSE
-rw-r–r–. 1 root root 839 Jul 27 09:24 Makefile
-rw-r–r–. 1 root root 25537 Jul 27 09:24 mod_proxy_protocol.c
-rw-r–r–. 1 root root 5580 Jul 27 09:24 mod_proxy_protocol.xml
-rw-r–r–. 1 root root 217 Jul 27 09:24 mod_proxy_protocol.xml.meta
-rw-r–r–. 1 root root 2021 Jul 27 09:24 README.md
[root@access mod-proxy-protocol]# make
apxs -c -Wc,-Wall mod_proxy_protocol.c
/usr/lib64/apr-1/build/libtool --silent --mode=compile gcc -std=gnu99 -prefer-pic -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -DLINUX -D_REENTRANT -D_GNU_SOURCE -pthread -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/apr-1 -Wall -c -o mod_proxy_protocol.lo mod_proxy_protocol.c && touch mod_proxy_protocol.slo
mod_proxy_protocol.c: In function ‘pp_hook_pre_connection’:
mod_proxy_protocol.c:338:10: error: ‘conn_rec’ has no member named ‘master’
if (c->master != NULL) {
^
In file included from mod_proxy_protocol.c:39:0:
mod_proxy_protocol.c:339:43: error: ‘conn_rec’ has no member named ‘master’
conn_conf = ap_get_module_config(c->master->conn_config,
^
/usr/include/httpd/http_config.h:508:17: note: in definition of macro ‘ap_get_module_config’
(((void **)(v))[(m)->module_index])
^
apxs:Error: Command failed with rc=65536
.
make: *** [.libs/mod_proxy_protocol.so] Error 1
Googled and found the following link Sign in to CERN
cloned and successfully executed make.
Copied the .so file in the desired location, restarted the httpd
Still no success.
Dear Shivharsh,
Cannot enable apache to accept proxy-protocol.
[root@access mod-proxy-protocol]# apachectl -M | grep proxy
[Sat Jul 27 11:13:05.874907 2019] [so:warn] [pid 30335] AH01574: module remoteip_module is already loaded, skipping
AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/httpd/conf/httpd.conf:47
proxy_module (shared)
proxy_ajp_module (shared)
proxy_balancer_module (shared)
proxy_connect_module (shared)
proxy_express_module (shared)
proxy_fcgi_module (shared)
proxy_fdpass_module (shared)
proxy_ftp_module (shared)
proxy_http_module (shared)
proxy_scgi_module (shared)
proxy_wstunnel_module (shared)
proxy_protocol_module (shared)
[root@access mod-proxy-protocol]#
[root@access mod-proxy-protocol]# apachectl -t
[Sat Jul 27 10:31:18.472109 2019] [so:warn] [pid 27485] AH01574: module remoteip_module is already loaded, skipping
AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/httpd/conf/httpd.conf:47
AH00526: Syntax error on line 26 of /etc/httpd/conf.d/vhosts.conf:
Invalid command ‘RemoteIPProxyProtocol’, perhaps misspelled or defined by a module not included in the server configuration
Whenever I am enabling proxy-protocol through send-proxy, apache is unable to send response.
Hi Shivharsh,
Thanks for your support, you have showed us the way.
Ultimately it worked for version 2.4.
Instead of RemoteIpProxyProtocol we have to write ProxyProtocol On.
As far as i am aware, mod-proxy-protocol supports httpd 2.2.15 as well. You should probably investigate the Apache end for issues as HAProxy end seems to be working just fine (since you mentioned that it worked for version 2.4).
Only if you are using Apache 2.4.31 and above then you may have to use mod_remoteip module in place of mod-proxy-protocol as it has been merged into the former.
Dear Shivharsh,
Thanks for your support.
I have successfully impleted the mod-proxy-protocol in the 2.2.15 version.
For this I used the mod_myfixip module.
Compile the module using the below command.
/usr/sbin/apxs -a -i -c mod_myfixip.c
In the ssl.conf module we have to write
RewriteIPResetHeader on
The following link can be reffered
In the httpd.conf file we have to write the following
RewriteIPResetHeader off
RewriteIPAllow 10.40.4.42
Apache has added a directive that worked for me without having to compile the my_fixip.c myself.
In my virtualhosts file I added:RemoteIPProxyProtocol On
– code snippet –
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
RemoteIPProxyProtocol On
DocumentRoot /var/www/html
– code snippet –
In my haproxy.cfg I added:
backend xyz
... more stuff
server s-xyz xyz.mydomain:443 send-proxy-v2
This is for an SSLPassthrough proxy configuration It now reverse proxies the outside SSL requests, uses SNI to pick the right backend, and the backend can retreive and log the requesting client’s ip that is out on the internet somewhere.