O AWS ELB com backend SSL adiciona o protocolo proxy dentro do fluxo SSL

2

Note, this has been also posted in http://thread.gmane.org/gmane.comp.web.haproxy/27737

estamos tentando configurar essa arquitetura:

  • ELB que encerra o SSL, usando certificados pré-configurados. (isto é um exigência porque apenas pessoas restritas tem acesso ao fim certificados de usuário)
  • O
  • ELB conecta-se ao back-end do HAproxy usando o SSL (também obrigatório)
  • O ELB envia cabeçalhos de proxy conforme descrito no link

  • O HAproxy escuta SSL em 443

  • O HAProxy é usado para fazer algumas transformações HTTP (modificar cabeçalho, etc).

Quando o ELB é configurado como SSL + Proxy, tentamos configurar HAProxy adicionando o accept-proxy na ligação do frontend HTTPS:

frontend https-in
    mode http
    # Note, I truncated this line because the maillist 80 chars limitations
    bind :443 accept-proxy ssl crt \
     /var/vcap/jobs/haproxy/config/cert.pem \
     no-sslv3 ciphers ...
    ...

Mas isso falha: Received something which does not look like a PROXY protocol header .

Solução de problemas, descobri que o ELB envia o cabeçalho PROXY INSIDE de o fluxo SSL. Por exemplo, eu executo o openssl como um servidor:

$ openssl s_server -accept 443 -cert cert.pem
...

ACCEPT
bad gethostbyaddr
-----BEGIN SSL SESSION PARAMETERS-----
MFUCAQECAgMDBAIAnwQABDBsAWD78V/tz9KhYw4R/kpL5YPBxfF1qcmzxlclNDuz
0KWw9aGojVogjtBkH/zZOLWhBgIEVyoquqIEAgIBLKQGBAQBAAAA
-----END SSL SESSION PARAMETERS-----
Shared
ciphers:...
CIPHER is DHE-RSA-AES256-GCM-SHA384
Secure Renegotiation IS supported
PROXY TCP4 80.194.77.90 192.168.6.14 39220 443
GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: something.com
Accept: */*

Então eu fiz uma configuração "encadeada" no haproxy, uma para fazer a terminação SSL com TCP puro e outro para "extrair" o protocolo de proxy e fazer o Transformações HTTP:

listen https-in
    mode tcp
    bind :443 ssl crt /var/vcap/jobs/haproxy/config/cert.pem no-sslv3
ciphers ...
    server http 127.0.0.1:8081

frontend http-in-from-ssl
    mode http
    bind :8081 accept-proxy
    option httplog
    option forwardfor
    reqadd X-Forwarded-Proto:\ https
    default_backend http-routers

E isso funciona !!!

Então, minhas perguntas são:

  • Isso é normal e esperado? Não consigo encontrar nenhuma informação sobre isso.
  • É possível alterar o comportamento do ELB para colocar o protocolo de proxy cabeçalho FORA do fluxo SSL? Não encontrei nenhuma informação sobre isso.
  • Se não. É possível alterar o comportamento do HAProxy para usar um frontend, mas leia o cabeçalho do protocolo de proxy de dentro do SSL fluxo?
  • Se não, existe uma maneira melhor de 'encadear' a configuração como eu fiz acima.

Obrigado!

    
por Keymon 05.05.2016 / 14:46

2 respostas

1

Aqui estão as informações para sua pergunta 1, confira o URL abaixo.

link

Roubo na última linha da tabela Balanceador de carga TCP / SSL (segunda tabela). É apenas o seu caso. E diz explicitamente

Does not support the Proxy Protocol header.

Então, para sua pergunta 2, a resposta é não.

E me desculpe, eu não posso fornecer mais ajuda para suas perguntas 3 e 4. (Na verdade, com base na minha experiência, para a pergunta 4, eu acho que o seu caminho é bom o suficiente. Talvez minha experiência não seja suficiente; )

    
por 29.11.2017 / 03:34
0

Eu me deparei com esse problema também. No entanto, uso o nginx e não o HA-proxy em meus balanceadores de carga internos.

A solução é semelhante, mas acho que vale a pena postar:

#nginx.conf

user  nginx;
worker_processes  1;

error_log  /dev/stderr debug;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

stream {
    upstream stream_backend {
        server 127.0.0.1:500;
    }

    server{
        listen 443 ssl;
        proxy_pass stream_backend;

        ssl_certificate /certs/local/public.crt;
        ssl_certificate_key /certs/local/private.key;
        ssl_protocols TLSv1.2;
        ssl_ciphers HIGH:!aNULL:!MD5;
    }
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '[$host] $remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /dev/stdout  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  60;

    #gzip  on;
    server {
        listen 8000;
        location /elb-status {
        keepalive_timeout 0;    # Disable HTTP keepalive

            access_log off;
            return 200;
        }
    }

    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    server {
        listen 80 proxy_protocol;
        server_name test-nginx.corp.com;

        location / {
            keepalive_timeout 0;    # Disable HTTP keepalive
            return 301 https://$host$request_uri;
        }
    }

    upstream nginx-test-stack {
        server 10.42.111.6:80;
    }

    server {
        listen 127.0.0.1:500 proxy_protocol;
        server_name test-nginx.corp.com;
        real_ip_header proxy_protocol;

        location / {
            proxy_pass http://nginx-test-stack;
        }

    }
}

Isso permite que eu habilite a criptografia E2E para qualquer conexão TCP. Se necessário, posso proxy websockets ou https ou apenas TCP direto

    
por 03.03.2017 / 03:12