Como redirecionar o tráfego para diferentes servidores com base no nome de domínio?

3

Estou tentando configurar o HAProxy para ser usado para conexões de tráfego HTTPS e OpenVPN através da porta 443. A configuração é direta (domínio de primeiro nível substituído por example.com para anonimato):

frontend www_ssl
    mode tcp
    bind *:443

    acl host_vpn hdr(host) -i vpn.example.com

    use_backend vpn_backend if host_vpn
    default_backend nginx_pool_ssl

backend nginx_pool_ssl
    balance first
    mode tcp
    server web1 192.168.1.2:443 send-proxy check
    server web2 192.168.1.3:443 send-proxy check

backend vpn_backend
    mode tcp
    server vpn1 192.168.1.4:443

Ao estabelecer uma conexão OpenVPN, ela falha com a seguinte mensagem:

WARNING: Bad encapsulated packet length from peer (18516), which must be > 0 and <= 1547 -- please ensure that --tun-mtu or --link-mtu is equal on both peers -- this condition could also indicate a possible active attack on the TCP link -- [Attempting restart...]

O que acontece é que, em vez de redirecionar o tráfego para 192.168.1.4, o HAProxy vai para 192.168.1.2, que tenta tratá-lo como uma solicitação HTTPS. O mesmo acontece quando eu abro vpn.example.com no navegador: acabei de receber o site servido por 192.168.1.2.

Se eu substituir a configuração acima por isso:

frontend www_ssl
    mode tcp
    bind *:443
    default_backend host_vpn

backend vpn_backend
    mode tcp
    server vpn1 192.168.1.4:443

então a conexão OpenVPN é estabelecida corretamente e o navegador não pode mostrar nada, o que significa que o problema vem da configuração do HAProxy.

O que está acontecendo aqui? Existe um erro na configuração original?

    
por Arseni Mourzenko 24.12.2017 / 16:27

1 resposta

3

Encontrado.

O problema óbvio é que a diretiva ACL está contando com cabeçalhos HTTP: dado que o HAProxy não conseguirá extrair os cabeçalhos do tráfego HTTPS e o OpenVPN não os possui, a ACL não tem efeito e o uso de default_backend é esperado aqui.

Meu primeiro pensamento foi usar req.ssl_sni em vez de hdr(host) . Isso tornaria possível - pensei - detectar se o tráfego é ou não HTTPS:

acl host_non_vpn req.ssl_sni -m sub -i example.com

use_backend vpn_backend if !host_non_vpn
use_backend nginx_pool_ssl if host_non_vpn

Embora funcionasse bem para solicitações do navegador, tive um problema em que parte do tráfego de svn para WebDAV por meio de HTTPS foi redirecionada para o servidor OpenVPN. Não tenho certeza do que está acontecendo aqui e, sem rastrear o tráfego de rede, foi difícil encontrar o problema, nem quais solicitações estavam com defeito e por quê.

Acabei mudando o OpenVPN para a porta 80. Usando pré-definida HTTP ACL , a configuração agora está parecendo assim:

frontend www_http
    mode tcp
    bind *:80
    use_backend nginx_pool_http if HTTP
    use_backend vpn_backend if !HTTP
    
por 24.12.2017 / 17:36

Tags