Alguns antecedentes:
Criei uma rede moderadamente complexa usando o vpc da Amazon. É uma rede de três camadas em duas zonas de disponibilidade. Cada camada possui uma sub-rede na zona-ae na zona-b. A camada de apresentação está no topo, há uma camada de aplicativo no meio e uma camada de núcleo na parte inferior.
Todos os grupos de segurança e ACLs das sub-redes estão atualmente permitindo TODO o tráfego de entrada e saída para me ajudar a reduzir a área de superfície do problema.
A tabela de roteamento da camada de apresentação está apontando todo o tráfego para um gateway da Internet. O gateway NAT está em uma sub-rede segregada, apontando também todo o tráfego para o gateway da Internet.
Meu aplicativo possui dois componentes, uma interface do usuário (React.js) e uma API (Node / Express). Eles são implantados como imagens de janela de encaixe. Na frente de cada um existe um balanceador de carga clássico.
O UI-ELB está voltado para a Internet e reside na camada de apresentação, roteando o tráfego de 80/443 para a porta 8080 e está associado ao meu app-ec2, que é colocado na sub-rede da camada de aplicativo.
Minha API tem um balanceador de carga interno à sua frente. O API-ELB está na camada de aplicativo (na mesma sub-rede que o app-ec2) e pega o tráfego na porta 80/443 e o direciona para o api-ec2 no núcleo na porta 3000.
Ambos os balanceadores de carga estão transferindo o certificado antes de passar o tráfego para suas instâncias.
Eu tenho ambos os meus balanceadores de carga associados como alias no Route53 e referenciados nos aplicativos por seu bonito URL ( https://app.website.com ). Cada balanceador de carga passa as verificações de integridade definidas e relata todas as instâncias ec2 em uso.
Por fim, na API, habilitei o cors usando o pacote cors nodejs.
Aqui está um diagrama rápido e sujo da minha rede.
O problema:
O APP-ELB me encaminha com êxito para o aplicativo. No entanto, quando o aplicativo tenta enviar uma solicitação GET para o API-ELB, ele primeiro envia uma solicitação OPTIONS que atinge o tempo limite com o código de erro 408.
Onde fica estranho
Algumas das coisas mais estranhas que encontrei durante a depuração são:
- Posso fazer o SSH na instância app-ec2 e executar uma curvatura bem-sucedida no API-ELB. Eu tentei muitos, e todos eles funcionam. Alguns exemplos são:
curl -L https://api.website.com/system/healthcheck
ecurl -L -X OPTIONS https://api.website.com/system/healthcheck
. Ele sempre retorna as informações desejadas. - Mudei o aplicativo inteiro da minha rede para um vpc padrão público e ele funciona como deveria.
- Eu tenho o api-ec2 gravando todas as solicitações de rede no console. Embora mostre as solicitações de verificação de integridade, não mostra nenhuma solicitação do app-ec2. Isso me leva a acreditar que o tráfego nem sequer está atingindo a API.
Realmente, a maior coisa que me deixa com uma perda total é que o enrolamento do api elb interno funciona, mas os axios solicitam o mesmo URL exato não. Isso não faz sentido para mim.
O que eu tentei
No início, passei muito tempo jogando com as regras da ACL e com os grupos de segurança, pensando que fiz algo errado. Eventualmente, acabei de dizer "estrague tudo" e abri tudo para tentar tirar esse pedaço da equação.
Passei muito tempo brincando com Cors na minha API. Eventualmente, aterrissando na configuração que tenho agora, que é o app.use(cors())
retorno de chamada padrão fornecido pelo pacote do nó cors. Também incluí o app.options('*', cors())
recomendado na documentação.
Eu pesquisei tudo no google, mas especificamente se preciso definir alguns cabeçalhos personalizados especiais com os elbs? Mas parece que não consigo encontrar nada. Além disso, quando mudei meu aplicativo para fora da rede, ele funcionou muito bem.
Tenho certeza de que tentei muitas outras coisas, mas essas parecem ser as mais pertinentes. o que estou perdendo? Sei que essa é uma questão potencialmente muito vaga e ampla, e um post enorme, mas agradeço qualquer insight e seu tempo de leitura!
curl -X OPTIONS 127.0.0.1...
no app-ec2? Só OPTIONS
está quebrado? Os ELBs são "Clássico" e não "Aplicativo", correto? Todas as instâncias conseguem acessar corretamente a Internet via NAT, por exemplo curl ipv4.icanhazip.com
? (Sim, eu pergunto por um motivo que pode parecer obscuro.)