HAProxy como proxy reverso para o AWS API Gateway

1

Como o título sugere, tenho um ponto de extremidade do AWS API Gateway que desejo colocar atrás do HAProxy.

Esta é a minha configuração atual do HAProxy

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    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
    maxconn                 3000

listen  http
        bind 127.0.0.1:8080
        maxconn     18000

        acl api_gateway path_beg /api-gateway
        use_backend api-gateway-backend if api-gateway

backend api-gateway-backend
        http-request set-header Host xxxxx.execute-api.ap-southeast-2.amazonaws.com
        server api-gateway xxxxx.execute-api.ap-southeast-2.amazonaws.com:443

Quando eu atingi o endpoint /api-gateway no meu HAProxy, recebo 400 Bad Request . Veja abaixo:

Eutenteialteraroback-endparausaresteserverapi-gatewayxxxxx.execute-api.ap-southeast-2.amazonaws.com:443sslverifynone,masrecebi503ServiceUnavailable.

AchoqueissopodeestarrelacionadoàconfiguraçãodoSSLSNIqueprecisoativarnoHAProxy,vejaestapostagemnofórum link

    
por Rudy Lee 02.02.2017 / 07:14

1 resposta

5

Se você não usar HTTPS, o CloudFront retornará o erro 400 Bad Request porque o Gateway da API não oferece suporte a HTTP.

Ao adicionar ssl verify none habilita o HTTPS para o back-end, o CloudFront apenas fecha a conexão, fazendo com que o HAProxy registre o estado da sessão na desconexão como SC-- e retorna o erro 503 Service Unavailable local.

A solução está, de fato, enviando o Server Name Identification (SNI). Caso contrário, o front-end do CloudFront não saberá qual certificado SSL oferecer a você - o certificado genérico *.cloudfront.net curinga ou aquele para *.execute-api.ap-southeast-2.amazonaws.com ou provavelmente uma dentre centenas de milhares de outras possibilidades. Isso é o que a SNI faz neste caso - diz ao servidor qual nome você está conectando.

A solução - esta é uma linha única, mostrada como várias linhas para maior clareza:

server api-gateway 
       xxxxx.execute-api.ap-southeast-2.amazonaws.com:443
       ssl
       verify none
       sni str(xxxxx.execute-api.ap-southeast-2.amazonaws.com)

Você precisa usar a str() string busca de amostra aqui, porque a sni server keyword espera uma expressão de busca de amostra (para casos em que você queria usar o SNI da solicitação recebida, por exemplo).

O problema na pergunta no formulário não estava realmente relacionado ao SNI - essa parte da configuração estava correta. O problema foi que eles falharam em fazer o que você já fez corretamente - http-request set-header host ... para que o CloudFront veja o cabeçalho Host: correto.

Note também que o conselho no fórum de que esta é uma "idéia muito ruim" parece claramente equivocado. Ainda não estou usando o API Gateway em produção, mas isso é exatamente do jeito que vou fazer, quando faço isso.

    
por 03.02.2017 / 04:17