MAC OS X, Linux, Windows and other IT Tips and Tricks

16 May 17 Hardening the SSL security in Apache, Dovecot and Postfix


After having gotten a report from OpenVAS that my SSL security level of the mail server were medium, I looked for ways to improve this.
I found very good sites which helps me making these improvements:
Based on this site and extending to cover dovecot mail service here is the result:

Hardening Apache:

In /etc/apache2/mods-available/ssl.conf
Change the following parameters as follows:
SSLHonorCipherOrder on

Hardening Dovecot:

Note: you should have openssl >=1.0.0 dovecot >=2.1.x required, better dovecot >=2.2.x because of ECDHE support Dovecot tryies to use PFS by default, so besides the enabled SSL almost no actions are required change the log settings to see the cipher, grep for a login_log_format_elements in dovecot configs and add %k to it
login_log_format_elements = "user=< %u> method=%m rip=%r lip=%l mpid=%e %c %k"
Configure the allowed ciphers. Server side enforcement works only for dovecot >=2.2.6
In /etc/dovecot/conf.d/ssl.conf
Change some parameters as follows:
#only for dovecot >=2.2.6, enforce the server cipher preference
ssl_prefer_server_ciphers = yes
#disable SSLv2 and SSLv3
ssl_protocols = !SSLv2 !SSLv3

Add the following parameter:
ssl_dh_parameters_length = 2048
Delete the file /var/lib/dovecot/ssl-parameters.dat
and restart Dovecot service:
service dovecot restart
Dovecote seeing that the Diffie Hellman parameters are assigned to be 2048 bits long and that its file is just been deleted, will regenerate a new one in the background.

Hardening Postfix

In /etc/postfix/
Change or add the following configuration parameters:
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3

Generate a new Diffie Hellman parameters file as follows:
openssl dhparam -out /etc/ssl/dh2048.pem 2048

19 Jan 17 Installing TeamPass in Debian Jessie

TeamPass is a very good Web application which can store securely Passwords for single person or teams. Here are the steps I used to install it in Debian Jessie. These instructions can also be used with no or minimal changes to install TeamPass in other Debian or Ubuntu systems.
These instruction are partly based on this site:
and these

Create the user that will be used as owner of the TeamPass htdocs and Apache TeamPass requests processes.
useradd -d /opt/teampass/ -s /bin/false passwords
Prepare the teampass home directories
mkdir -p /var/www/teampass/fcgi/tmp
mkdir /var/www/teampass/logs
mkdir /var/www/teampass/auth
cd /var/www/teampass/
#Get the latest released software:
wget --no-check-certificate

Install the required packages:
apt-get install php5-mcrypt php5-mysqlnd php5-gd openssl apache2-suexec-custom apache2-mpm-prefork libapache2-mod-fcgid libapache2-mod-php5 php5-cgi mariadb-server
In order to allow Apache to modify files inside the TeamPass htdocs we use FCGI/suexec Modules.
a2enmod fcgid
a2enmod suexec
a2enmod ssl

Create the fcgi_wrapper script:
touch /var/www/teampass/fcgi/php-fcgi-starter
mcedit /var/www/teampass/fcgi/php-fcgi-starter

export PHPRC=/var/www/teampass/fcgi/
exec /usr/bin/php5-cgi

Make it runnable but not for others:
chmod 750 /var/www/teampass/fcgi/php-fcgi-starter
Copy the php.ini from system to /var/www/teampass/fcgi/
cp /etc/php5/apache2/php.ini /var/www/teampass/fcgi/
Adapt the php.init to the site:
mcedit /var/www/teampass/fcgi/php.ini
Add the following 2 lines at the end:
upload_tmp_dir = /var/www/teampass/fcgi/tmp
session.save_path = /var/www/teampass/fcgi/tmp

And look for the configuration: max_execution_time and change its value from 30 to 60. Eg.
max_execution_time = 60
Create the Apache2 configuration:
Content of config file in /etc/apache2/sites-available/
# ============ ==================
<virtualhost *:443>
DocumentRoot /var/www/teampass/TeamPass-master
SuexecUserGroup passwords passwords
<directory /var/www/teampass/TeamPass-master>
Options -Indexes +FollowSymLinks +ExecCGI
FCGIWrapper /var/www/teampass/fcgi/php-fcgi-starter .php
AddHandler fcgid-script .php
DirectoryIndex index.php
Require 192.168. granted
AuthType Basic
AuthName "Private area"
AuthUserFile /var/www/teampass/auth/web.auth
Require valid-user
Satisfy all
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/
SSLCACertificateFile /etc/letsencrypt/live/
ErrorLog /var/www/teampass/logs/error_log
CustomLog /var/www/teampass/logs/access_log combined

Create the first layer(BASIC) Authentication credentials for first user:
htpasswd -c /var/www/teampass/auth/web.auth username
Give the whole directory ownership to ‘passwords’ user
chown -R passwords: /var/www/teampass/
NOTE: Before you restart your Apache2 service, make sure the Certificate is been issue and installed in the directory: /etc/letsencrypt/live/
You can use the instructions on this link to install LetsEncrypt software:

Enable Apache’s new configuration:
Restart Apache to activate it’s new configuration:
service apache2 restart
Prepare the suexec permissions files
echo "/var/www/teampass" >> /etc/apache2/suexec/www-data
echo "/var/www/teampass" > /etc/apache2/suexec/passwords
echo "TeamPass-master" >> /etc/apache2/suexec/passwords

IMPORTANT: We need to make sure that the cgi-script called by suexec is residing under the Server’s DocumentRoot for suexec to be allowed to run, therefore we installed the site under /var/www/teampass(which is located under the Server’s DocumentRoot(/var/www/) NOT meaning the VirtualHost’s DocumentRoot. A symlink is allowed here.

Preparing the MySQL database:

Create the new Database in MySQL:
Follow theses instructions:
1) Connect to mysql as root:
mysql -p -u root
PW: ******

2) Create the DB, user and user access rights:
flush privileges;

Quit Mysql:
3) Tip: To confirm if the permissions were granted successfully, log into the DB server with the PWDB DB user(pwuser) and run the command below:
SHOW GRANTS FOR 'pwuser'@'localhost';
4) Quit Mysql:
Installing TeamPass via the web interface:
In the browser:
Fill-in the appropriate, paths, MySQL credentials and extra settings and save this configuration.
You are then ready to use TeamPass

20 Dec 16 Upgrading Apache2 from Debian Wheezy to Jessie

As I tried to make a full distribution upgrade from Wheezy to Jessie the upgrade of Apache2 didn’t go well at all: dpkg kept coming up with dependencies errors and post-install scripts errors. Unfortunately I don’t have a sample of these errors here. Since I had to dist-upgrade over 30 servers of the same nature I decide to find a solution and here is what I found:

Remove the packages(but not the configurations) that will create problems during the dist-upgrade.
apt-get remove apache2 apache2-mpm-prefork apache2-suexec apache2-utils apache2.2-bin apache2.2-common libapache-mod-security libapache2-mod-fcgid libapache2-mod-php5 libapache2-modsecurity
Add the following default repositories of Jessie in /etc/apt/sources.list
# Debian Jessie
deb jessie/updates main
deb-src jessie/updates main
deb jessie main contrib non-free
deb-src jessie main contrib non-free

apt-get update && apt-get dist-upgrade
apt-get install apache2 apache2-bin apache2-data apache2-mpm-worker apache2-suexec apache2-suexec-pristine apache2-utils libapache2-mod-fcgid libapache2-mod-security2

NOTE: During this upgrade the version of Apache will go from 2.2 to 2.4. This means that some directives of version 2.2 will no more be valid for version 2.4 example:
Oder deny,allow
Should change:
Allow from All >> Require All granted
Deny from All >> Require All denied

See this special Apache site for more information on upgrading Apache 2.2 to 2.4.

24 Oct 16 Upgrading php from 5.4 to 5.6 in Debian Wheezy

In order to upgrade PHP from 5.4 to 5.6 we need to use the DOTDEB repositories by which many other packages will also be upgraded. Here are the steps.

Edit the file /etc/apt/sources.lst and add the following lines:
deb wheezy all
deb-src wheezy all
deb wheezy-php56-zts all
deb-src wheezy-php56-zts all

Then run the following commands:
Note: Because of a bug in these package’s after-install I added some extra commands that will take care of it:
mkdir -p /etc/apache2/conf-available/
touch /etc/apache2/conf-available/php5-cgi.conf
gpg --keyserver --recv-key E9C74FEEA2098A6E
gpg -a --export E9C74FEEA2098A6E | apt-key add -
apt-get update
apt-get upgrade
apt-get install php5

26 Apr 16 Activating SPDY in Apache 2.4 (Ubuntu 14.04)

SPDY is a new protocol created by Google and given to the Apache Foundation which allows faster Web traffic under SSL. Apache 2.4 is SPDY capable but its module is not included in Ubuntu 14.04 LTS Server. Here are some instructions that allow to get, install and enable SPDY feature foe Apache 2.4 under Ubuntu 14.04.

Get the third party Apache 2.4 module, extract and install it:
cd /usr/local/
tar zxf mod_spdy.tar.gz
cd /usr/lib/apache2/modules
mv /usr/local/mod-spdy/mod-spdy/src/ .
mv /usr/local/mod-spdy/mod-spdy/src/out/Release/
echo "LoadModule spdy_module /usr/lib/apache2/modules/" | sudo tee /etc/apache2/mods-available/spdy.load
echo "SpdyEnabled on" | sudo tee /etc/apache2/mods-available/spdy.conf
a2enmod spdy
service apache2 restart

In case you get the error message in log file eg:
...... [core:notice] [pid 7842:tid 140724740487067] AH00052: child pid 8025 exit signal Segmentation fault (11)
Then that means that you are using a version of the MPM that is not compatible with SPDY module. You might need to change to the thread-stable mpm_prefork as follows:
a2dismod mpm_event
a2enmod mpm_prefork
service apache2 restart

Test your sites for SPDY protocol:

24 Mar 16 Using HTTPS as proxy backend in Apache 2.4

In Apache 2.4 in a Vhost in order to be able to proxy to a backend with HTTPS using either a self-signed or expired certificate on the backend we need to include the following directives:
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off

You also need to enable the required Apache2 modules as follows:
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_connect
service apache2 restart

Example when using Apache 2.4 to proxy to Webmin port 10000:
RewriteEngine On
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
RewriteRule ^/(.*)$1 [P]
ProxyPassReverse /

09 Mar 16 Testing SSL Connections with SSLyze, Nmap or OpenSSL

OpenSSL is a great tool to check SSL connections to servers. The difficulty here is when one want a full scan of all possible SSL Cyphers and protocols used by a server. That is where SSLyze comes in handy. This tool is a Python script which will scan the target host/port for SSL handshake and report what works/support and what not. Unfortunately this lovely tool is not included in the Ubuntu/Debian distributions, and this is where this post comes handy.

IMPORTANT: Besides executing all the tests below one thing very important (as noted in the This link) is to upgrade OpenSSL to the latest version as follows:
OpenSSL 1.0.2 users should upgrade to 1.0.2g
OpenSSL 1.0.1 users should upgrade to 1.0.1s


Installing the dependencies and tool
cd /root/bin
tar fvxz 0.13.4.tar.gz
apt-get install python-pip python-dev
pip install nassl

Using SSLyze
python /root/bin/sslyze-0.13.4/ --regular


Scanning the full server for weaknesses including weak SSL Versions using NMAP.
Note: This operation can take a long time to execute.
apt-get install nmap
nmap -sV -sC

OR better(for checking the HTTPS,SMTPS,IMAPS,POP3S)
nmap --script ssl-cert,ssl-enum-ciphers -p 443,465,993,995


Checking the SSL connection with OpenSSL
echo 'q' | openssl s_client -host -port 443
Note: In this above case since the SSLv2 support is normally disabled for OpenSSL in Debian/Ubuntu distributions, you will not be able to see if the server is supporting it. To overcome this and enable SSLv2 support(for your testing Linux) then follow the instructions in this site:

For more information regarding protection against DROWN(SSLv2) or POODLE(SSLv3) attacks see:,_Insufficient_Transport_Layer_Protection_%28OTG-CRYPST-001%29

17 Dec 15 Issue free and CA signed SSL certificates for web servers from LetsEncrypt

SSL Certificates provide two functions:
1. Authentication
2. Encryption

Encryption can be achieved without authentication but, for some reason, someone decided to join them together in one certificate. It seem to make sense for banks and serious e-commerce sites which need to be properly authenticated. Therefore when the HTTPS protocol got developed it was not possible to encrypt-only the stream of HTTP. This situation made us dependent to Certificate Authentication Authorities to obtain a certificate even if we only wanted encryption. Now some genius group of people at finally created the possibility to obtaining certificates which preform simple authentication verification, by calling the URL and expecting a specific response, and if successful issues a free 90 days valid and CA signed SSL certificate. For system administrators this process of requesting and install such free certificate has therefore become quite simple. Here is one method of doing just this in a Debian/Ubuntu web server.


Installing LetsEncrypt

apt-get update && apt-get install git
cd /usr/local/lib/
git clone
cd letsencrypt
./letsencrypt-auto --email --agree-tos --help
echo "export PATH=$PATH:/usr/local/lib/letsencrypt" >> /root/.bashrc
. /root/.bashrc

NOTE: Make sure your web site you want to add HTTPS to is already configured and live in your web server.
The reason is that during the process of requesting a certificate, LetsEncrypt will create an extra sub-directory({htdocs}/.well-known/acme-challenge/) and a special temporary file in the htdocs of the site (pointed to by DocumentRoot directive in Apache) then call that file on the site from the LetsEncrypt server to authenticate the URL. If the the URL called is invalid it won’t issue the certificate. For this reason your site needs to be live and you need to give the path of the htdocs. After the authentication process, the temporary file will be erased but not the sub directories. They will stay empty.


If you get the following error message then in Debian Wheezy you can solve it by importing SSl into Python. See below.
InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see

Importing Python SSL support:
>>> import ssl
>>> (CTRL-D)

Upgrading LetsEncrypt client program

rm -rf /usr/local/lib/letsencrypt.old &>/dev/null
mv /usr/local/lib/letsencrypt /usr/local/lib/letsencrypt.old
cd /usr/local/lib/
git clone

Requesting the certificate

Eg. for the domain
NOTE: on first time request the script will ask you to give an email address for contact purposes as well as to accept the terme and conditions of using this tool. Afterwards it will not ask you these questions.
letsencrypt-auto certonly --webroot -w /www/clients/ -d
The certificates and key will be stored in /etc/letsencrypt/live/ as:
cert.pem : Certificate
chain.pem : CA Certificate
privkey.pem : Private key
fullchain.pem : Combination of the certificate and the CA Certificate

Instead of moving the certificate, just configure Apache or other web server to point to the certs files where they are.
This way a cron job can be created to regularly renew the certificate automatically without manual intervention.
The certificate will be valid for 90 Days only; no exceptions.
This means that the same above command will need to be run every 3 months or earlier with the addition of the option –renew-by-default.
The limit of certificates you can ask for a certain domain is: currently 5 certificates / 7 days.

Renewing single certificate:

In order to renew the certificate automatically it is suggested to use a cron job and adding the option –renew-by-default in the command eg. as follows:
letsencrypt-auto certonly --renew-by-default --webroot -w /www/clients/ -d

Renewing all installed Letsencrypt certificates:

letsencrypt-auto renew
Note: It is recommended to send the output of the command by email to verify if the process was successful.

Extra Info

The certificates of LetsEncrypt are stored in /etc/letsencrypt/ directories in different ways. It is simply NOT recommended to delete any of the certificates, files or symlinks in these directories because the files in the ‘keys’ and ‘csr’ directories are not identified to refer to a specific certificate. So just deleting some files but not others related to the same cert might confuse the client command and you then can’t request any more certificates. The error message from the client program is something like:
letsencrypt TypeError: coercing to Unicode: need string or buffer, NoneType found
If you ever get to that non-return point then just delete all directories: archive, csr, keys, live and renewal BUT not accounts. Then re-issue certificates requests for already existing sites. The certificates will then be renewed and you can then also request new ones.

For more information of the subject see:

Comfortable script

If you want to be able to issue a certificate and you want it to self-renew after 80 days, this script might be of some use.
# Purpose: Issue or renew a certificate from LetsEncrypt
# It will also issue an 'at'command which will be responsible to automatically renew the certificate automatically
# This script also issues a new at comand which will do the same in around 3 Months days depending on the settings here
# Changes: 30.12.2015 First implementation of the script
# 10.01.2016 Took out the read of wpinstall.cfg config file. Added checks for the letsencrypt and at programs
. /root/.bashrc
# Absolute path to this script.
SCRIPT=$(readlink -f $0)
# Absolute path this script is in.
scriptdir=$(dirname $SCRIPT)

# Check the syntax
function usage () {
echo "Usage: -s SITE_NAME -d SITE_HTDOCS"
echo "-s SITE_NAME Full web site address WITHOUT the 'http://' eg.:"
echo "-d SITE_HTDOCS The absolute path where WordPress will be installed. eg. /www/sites/"
exit 1

if [ $# -ne 4 ]; then
echo "ERROR: Wrong number of given argunents."

# Make sure the letsencrypt client prgm is installed
if ! [ -e $encryptprgm ] ; then
echo "ERROR: the letsencrypt program isn not installed. Install it and retry."
echo "See instructions at: //"
exit 1

# Make sure the at is installed
if ! [ -e $atprgm ] ; then
echo "ERROR: the 'AT' program isn not installed. Install it and retry."
echo "apt-get install at"
exit 1

# Everything look good so far. Lets start.

# get the command options
while getopts "s:d:" OPTION
case $OPTION in
echo "ERROR: argument(s) unknown."

echo "Requesting certificate at LetsEncrypt"
# Does it exist already, then renew only, otherwise request renewing the cert
if [ -d $CERTS_DIR/${SITE_NAME} ] ; then
echo "The certificate already exists. Requesting a renewal"

if ($encryptprgm certonly $RENEW --webroot -w $SITE_HTDOCS -d ${SITE_NAME} &>/dev/null); then
# Enable the Apache SSL configuration and restart Apache
(echo "Certificate request successful."
echo "Issuing a renewal of the certificate in 80 days using 'at' command"
service apache2 restart
echo "$SCRIPT -s $SITE_NAME -d $SITE_HTDOCS" | $atprgm now + $RENEW_DAYS days)| tee /tmp/ \
| mail -s "Request/Renewal of Certificate for $SITE_NAME"
echo -e "------- SITES LIST --------\n$(ls -1 /etc/apache2/sites-enabled/ | egrep -v '^00|^wptest1')\n\n--------- CERTIFICATES LIST ---------$(ls -l /etc/letsencrypt/live/ | cut -c29-)\n\n------- AT Jobs LIST -------\n$(/root/bin/" | mail -s "Request/Renewal of Certificate request LIST" $EMAIL
cat /tmp/
exit 0
(echo "ERROR: The certificate request/renewal FAILED.")| tee /tmp/ \
| mail -s "Request/Renewal of Certificate for $SITE_NAME" $EMAIL
cat /tmp/
exit 2

Status of the certificates

Here is a useful script that will display the following information:
– List of AT Jobs ready to start at the required time
– List of present certificates and their file timestamps
Since each letsencrypt is only valid for 90 days this will give you an overview of how old the present certificates are and when is the next time the requests for certificates will be done.
# Description: Displays all 'at' jobs and their respective commands
# Systax:
# Changes: 05.11.2016 First inplementation
# Get the short jobs list and expand from there
echo "================ AT Jobs ready to start at the required times ==============="
atq | while read line ; do
jobnr=$(echo $line | awk '{print $1}')
echo $line
# Pickup all the command lines after first line matching '}'.
# This excludes all the environment variables and the at exit line.
# Exclude the matching '}' line and empty lines
# Add an offset of 8 chars to each command line.
# at -c $jobnr | grep -A100 -m1 -e '^\}' | grep -v '^\}' | sed -e '/^$/d' -e 's/^/ /'
at -c $jobnr | at -c $jobnr | sed -e '1,/^\}/d' -e '/^$/d' -e 's/^/ /'
echo ; echo
echo "=============== Age of present certificates ====================="
ls -l /etc/letsencrypt/live/*/cert.pem | awk '{print $6" "$7" "$8" "$9}' | sed -e 's|/etc/letsencrypt/live/||' -e 's|/cert.pem||'

10 Dec 15 Creating a web certificate CSR file.

The process of buying an SSL certificate for a web site is usually as follows:
– You create a secret key and CSR files using the method showm in this post.
– You cut and paste the content of the CSR file into a field in a SSL Vendor web site
– The SSL vendor produces a certificate based on the CSR you provided and send it to you.
– You download the CA Certificate from the SSL provider’s site
– You install the private keyfile, the CA certificate and the certificate in the web server and bobs’s-your-uncle.

The following procdeure is an extract from the site:—openssl
Generate a CSR & Private Key:
openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privatekey.key

Fill out the following fields as prompted:
Note: The following characters can not be accepted: <> ~ ! @ # $ % ^ * / \ ( ) ?.,&

Field Example
============ ==========================================
Country Name US (2 Letter Code)
State or Province New Hampshire (Full State Name)
Locality Portsmouth (Full City name)
Organization GMO GlobalSign Inc (Entity's Legal Name)
Organizational Unit Support (Optional, e.g. a department)
Common Name (Domain or Entity name

06 Nov 15 Configuring HAproxy load balancer in Ubuntu 14.04

In this example HTTP requests are proxied directly as HTTP requests to the HTTP web servers. In the case of HTTPS requests, they are handled with the certificates by HAproxy and then proxied to the web servers as HTTP requests.

The certificates for all virtualhosts being proxied are stored as one PEM format file per certificate/key combination in the directory:
The CAs are also stored as one PEM format file per CA in the directory:

Install HAproxy:
apt-get update && apt-get install haproxy

Configure HAproxy for HTTP and HTTPS load-balancing:

Edit the file /etc/haproxy/haproxy.cfg
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
ssl-default-bind-options no-sslv3
tune.ssl.default-dh-param 2048
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
# Added to create separate error and access logs
option log-separate-errors
# ------- HTTP Frontend --------------
frontend http_in
bind *:80
mode http
reqadd X-Forwarded-Proto:\ http
default_backend http_out
# ------- HTTPS Frontend --------------
frontend https_glwp-in
bind *:443 ssl crt /etc/ssl/haproxy_certs/
mode http
reqadd X-Forwarded-Proto:\ https
default_backend http_out
listen stats :2000
mode http
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /stats
stats auth admin:mypasswd
# ------- HTTP Backend --------------
backend http_out
balance roundrobin
stick-table type ip size 200k expire 60m
stick on src
option forwardfor
option httpclose
http-request set-header X-Forwarded-Port %[dst_port]
option httpchk HEAD /
server web1 check
server web2 check
server web3 check
server web4 check

Preserving the source IP of client in TCP Proxying

In the above examples the protocols that are being load-balanced are application protocols, where you can retain the Source IP by retrieving it from the HTTP/HTTPS header X-Forwarded-For: (obtained by the option: option forwardfor), but if you use HAProxy as a TCP layer load balancer, in order to retain the source IP(client’s IP) see the following article:
It’s a tiny bit complex to understand and implement, especially in the backend server. I have not tried it yet, so I can’t guarantee its validity therefore I can’t give any examples. From what I understand, the only changes needed to the TCP proxying directives(not explained here) are the following 2 requirements:
1) HAProxy Backend configuration includes the extra entry: source usesrc clientip
2) The backend server network settings needs to be configured to have the HaProxy host IP address as the default Gateway.

This way the backend server sees the source IP of the client as if the client connected directly to the backend server and the responses from the backend server are returned via the HAProxy Host.
To be continued soon with practical examples …..

Happy load-balancing 🙂