Proxy HA e Websockets

4

Estou configurando meu primeiro servidor proxy reverso HAProxy. Será um proxy para um aplicativo HTML5 executado no tomcat de outro servidor. Consegui obtê-lo através de HTTP, redirecionar todas as solicitações para HTTPS e implementar o HSTS. No entanto, depois de fazer isso, percebi que ele também tenta carregar uma conexão de websocket. O problema é que a conexão websocket que ele carrega é insegura (ws: //) e não segura (wss: //). É claro que o Chrome (e provavelmente vários navegadores) reclamam de carregar um script inseguro em uma conexão segura. Aqui está o erro que recebo:

Connecting via WebSocket using url ws://website.domain.com:9091/webclient/
Mixed Content: The page at 'https://website.domain.com/webclient/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://website.domain.com:9091/webclient/'. This request has been blocked; this endpoint must be available over WSS.
Caught WebSocket error: SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.

Todos foram carregados por /webclient/script/ajaxclient.js:210

Como este é um aplicativo de terceiros, não tenho certeza se poderei fazer com que eles alterem o aplicativo. Portanto, eu queria saber se há algo que eu possa fazer no servidor HAProxy para forçar uma conexão segura de websocket. Alguma idéia?

Aqui está o meu arquivo conf HAProxy para referência:

global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     1000
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

    # Default SSL cert locations
    ca-base /etc/haproxy/ssl_2015
    crt-base /etc/haproxy/ssl_2015

    # Default ssl ciphers
    ssl-default-bind-ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4

    # max size of temp DHE keys that are generated
    tune.ssl.default-dh-param 4096

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    option                  http-server-close
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    timeout tunnel          4hrs                # long timeout for Websocket connections
    maxconn                 3000

#---------------------------------------------------------------------
# http frontend
#---------------------------------------------------------------------
frontend http_https_frontend
    bind 192.168.2.201:80
    redirect scheme https if !{ ssl_fc }
    bind 192.168.2.201:443 ssl crt /etc/haproxy/ssl_2015/ssl_crt.pem
    acl secure dst_port eq 443
    rspadd Strict-Transport-Security:\ max-age=16000000;\ includeSubDomains;\ preload;
    rsprep ^Set-Cookie:\ (.*) Set-Cookie:\ ;\ Secure if secure

#   # routing based on websocket protocol header
#   acl is_websocket hdr(Upgrade) -i WebSocket
    acl is_websocket hdr_beg(Host) -i ws
    use_backend ws_backend if is_websocket


#    # 16000000 seconds: a bit more than 6 months
#    http-response set-header Strict-Transport-Security max-age=16000000;\ includeSubDomains;\ preload;
    default_backend https_backend

#---------------------------------------------------------------------
# http backend
#---------------------------------------------------------------------
backend https_backend
    reqadd X-Forwarded-Proto:\ https
    server websvr1_http 192.168.1.125:8080

#---------------------------------------------------------------------
# ws backend
#---------------------------------------------------------------------
backend ws_backend
    server websvr1_ws 192.168.1.125:9091

O servidor HAProxy é um servidor CentOS 7.1.1503 que executa o HAProxy 1.5.4.

Obrigado antecipadamente!

    
por JoeInVT 30.07.2015 / 14:38

1 resposta

1

As this is a 3rd party app, I'm not sure if I'm going to be able to get them to change their app. Therefore, I was wondering if there's something I can do on the HAProxy server to force a secure websocket connection.

Isso depende principalmente do aplicativo de terceiros. Se o aplicativo está usando especificamente o protocolo ws: , não há nada que você possa fazer no lado HAProxy - os navegadores nem se conectam à instância HAProxy, então você nem sequer tem a chance de fazer algo a respeito.

Você precisaria abrir um problema com os desenvolvedores de aplicativos de terceiros e fazer com que eles sejam configuráveis pelo protocolo de soquete da Web ou adicionar alguma detecção (se a página for carregada por HTTPS e usar o WSS).

Como alternativa, você pode introduzir a regravação de conteúdo, em que você tem algo que modifica o conteúdo de saída para reescrever ws: / to wss: //. HAProxy não pode fazer isso, mas o Nginx junto com o módulo sub_filter pode.

    
por 30.07.2015 / 16:37