HAProxy + RabbitMQ + Websocket
Há duas formas de usar o HAProxy como proxy para o RabbitMQ, seja para conexões WebSocket, HTTP, AMQP e MQTT.
A forma mais tradicional, e funciona apenas para conexões HTTP é usando o cabeçalho X-Forwarded-For. A cada mensagem que chega no servidor de proxy, ele preencherá este cabeçalho com o endereço real do remetente da mensagem.
A forma alternativa e mais genérica (funciona também para TCP puro) é usando o padrão Proxy Protocol.
Para o Proxy Protocol funcionar, o software que receberá o proxy precisa ser compatível. O RabbitMQ possui essa compatibilidade.
Proxy com X-Forwarded-For
Só funciona para conexões HTTP e WS (web socket). Não consegui fazer funcionar ela no HAProxy, consegui apenas com o Nginx.
Referências para HAProxy com WebSocket via HTTP (cabeçalho X-Forwarded-For)
Discussão de erro de WebSocket com o HAProxy
https://stackoverflow.com/questions/4360221/haproxy-websocket-disconnection
Exemplo de configuração HAProxy + WebSocket
1) https://gist.github.com/sourcec0de/0834e50e0470e573419f979597c701c8 (testei e não funcionou)
2) https://gist.github.com/lackac/3767467 (testei e não funcionou)
3) https://discourse.haproxy.org/t/using-reverse-proxy-with-secured-web-sockets-wss/2917 (testei e não funcionou)
Proxy com Proxy Protocol
O Proxy Protocol funciona adicionando um cabeçalho no pacote de camada 7 (camada de aplicação), por isso funciona para todos os tipos de protocolos do RabbitMQ, AMQP, MQTT, HTTP, WS (web socket), STOMP.
O HAProxy precisa escutar em TCP, já que o cabeçalho inserido pelo proxy protocol é genérico e funciona para todos protocolos TCP além do HTTP.
A melhor configuração de exemplo que encontrei foi esta:
No exemplo de configuração abaixo, abrimos 3 portas diferentes no HAProxy:
A primeira sem criptografia, apenas repassando as conexões para o RabbitMQ
A segunda com criptografia, mas apenas entre o cliente e o HAProxy. Do HAProxy até o RabbitMQ a conexão ocorre sem criptografia.
A terceira com criptografia, em ambas as partes, do cliente até o HAProxy e do HAProxy até o RabbitMQ.
# Entrando Websocket MQTT (WS), saindo Websocket MQTT (WS)listen web_mqtt_front_plain bind :15676 mode tcp balance roundrobin server rabbit 127.0.0.1:15675 send-proxy # Entrando Secure Websocket MQTT (WSS), saindo Websocket MQTT (WS) # TLS/SSL Offloading listen web_mqtt_front_tls_termination bind :15677 ssl crt /tmp/haproxy-1.8.14/haproxy-secure.crt mode tcp balance roundrobin server rabbit 127.0.0.1:15675 send-proxy # Entrando Secure Websocket MQTT (WSS), saindo Secure Websocket MQTT (WSS) # SSL/TLS bridging or re-encryption listen web_mqtt_front_tls bind :15678 ssl crt /tmp/haproxy-1.8.14/haproxy-secure.crt mode tcp balance roundrobin server rabbit 127.0.0.1:15673 send-proxy ssl verify none
Este exemplo utiliza o proxy protocol v1. Para usar o proxy protocol v2, trocar send-proxy por send-proxy-v2
Exemplo de configuração do /etc/rabbitmq/rabbitmq.conf
log.connection.level = infoloopback_users.guest = false listeners.tcp.default = 5672 #proxy_protocol = true # Para liberar o Web MQTT web_mqtt.tcp.port = 15675 web_mqtt.proxy_protocol = true # Para liberar o Web Stomp web_stomp.tcp.port = 15674 web_stomp.proxy_protocol = true
Referências
Discussão sobre o uso do Proxy Protocol com o HAProxy
https://serverfault.com/questions/839965/send-proxy-protocol-header-from-haproxy