Using HAProxy with SSL terminiation to add encryption to redis-redis communication

Hello all,

I am quite new to HAProxy, and was working on adding encryption to redis-redis communication using HAProxy with SSL termination. Redis does not support encryption. In order to implement setups where trusted parties can access a Redis instance over the internet or other untrusted networks, an additional layer of protection should be implemented, such as an SSL proxy.

My idea is to do this with HAProxy is as below:

           TCP                    TCP+TLS                      TCP

Redis-cli------------------> HAProxy----------------------------->HAProxy------------------------>Redis2

Is this a feasible approach using HAProxy to add encryption to redis-redis communication?

I tried using the above and getting Error: server closed connection

[root@serverA]# redis-cli
127.0.0.1:6379> auth pass
Error: Server closed the connection

On checking the Statistics Report i got:

L6OK (ssl) for Server A
L4OK (tcp) for Server B.

Does this means HAProxy side is fine and the issue is something to do with redis ? I would appreciate any help

My Haproxy config is as below:

HA-Proxy version 1.7.11 2018/04/30
Copyright 2000-2018 Willy Tarreau willy@haproxy.org

**HAProxy Config **

Server A:


global
   pidfile /var/run/haproxy.pid
   log 127.0.0.1 local0 debug
   ulimit-n        65536

defaults REDIS
   mode tcp
   log global
   option tcplog
   timeout connect 3s
   timeout server 6s
   timeout client 6s

listen stats
    bind *:1936
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /
    stats auth admin:admin

frontend redis
    bind serverA:6379
    mode tcp
    option tcplog
    default_backend redis_bk

backend redis_bk
   mode tcp
   option tcplog
   server B serverB_ip:6379 check check-ssl inter 60s ssl verify none

Server B


global
   pidfile /var/run/haproxy.pid
   log 127.0.0.1 local0 debug
   ulimit-n        65536
   ssl-default-bind-options no-sslv3 no-tls-tickets
   ssl-server-verify required
   tune.ssl.lifetime 600
   tune.ssl.default-dh-param 1024

defaults
   mode tcp
   log global
   timeout connect 3s
   timeout server 6s
   timeout client 6s

listen stats
    bind *:1936
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /
    stats auth admin:admin

frontend redis
    bind ServerB_ip:6379 ssl crt /etc/ssl/xip.io/xip.io.pem  ca-file /etc/ssl/xip.io/xip.io.crt verify optional crt-ignore-err all
    mode tcp
    option tcplog
    default_backend redis_bk

backend redis_bk
   mode tcp
   server C serverC_ip:6379 check

Thanks,
Maria

Yes, this is a perfectly valid use case, and I don’t see anything wrong with the configuration. Can you check haproxy logs on both sides?

@lukastribus: Thank you :slight_smile: Meantime I had combined the HAProxy configuration to one server and it worked. Can you please verify the below configuration?

HAProxy configuration as below:

    global
       pidfile /var/run/haproxy.pid
       log 127.0.0.1 local0 debug
       ulimit-n        65536

    defaults
       mode tcp
       log global
       timeout connect 3s
       timeout server 6s
       timeout client 6s

    listen stats
        bind *:1936
        mode http
        stats enable
        stats hide-version
        stats realm Haproxy\ Statistics
        stats uri /
        stats auth admin:admin

    frontend redis
        bind 127.0.0.1:6379
        mode tcp
        option tcplog
        default_backend redis_bk_ssl

    frontend redis_ssl
        bind ServerB_ip:6379 ssl crt /etc/ssl/xip.io/xip.io.pem  ca-file /etc/ssl/xip.io/xip.io.crt verify optional crt-ignore-err all
        mode tcp
        option tcplog
        default_backend redis_bk

    backend redis_bk_ssl
       mode tcp
       option tcplog
       server ServerB ServerB_ip:6379 check check-ssl inter 60s ssl verify none

    backend redis_bk
       mode tcp
       server ServerC ServerC_ip:6379 check

From HAProxy Statistics report,

Server B: L6OK
Server C: L4OK

and when i connect via redis-cli on ServerB, i am able to retrive ServerC details. So i hope this communication is encrypted. Please confirm

Yes, the communication between and from ServerB_ip:6379 with the SSL keyword is encrypted, so it does what you want.

You don’t need the ca-file in the frontend redis_ssl, you should put it into redis_bk_ssl instead and change to verify required, so that the certificate of the server is verified.

To understand why the configuration on different servers doesn’t work, we would need to see the logs in that case.

1 Like