詳細検索

Transferência SSL com ELB e autenticação do cliente e terminação SSL com nginx para obter IP de origem com ProxyProtocol

Avatar
por komi
5 min de leitura

Transferência SSL com ELB e autenticação do cliente e terminação SSL com nginx para obter IP de origem com ProxyProtocol
Traduzido do 日本語 • Ver original

Olá. O título é longo, mas não sei se há demanda porque já faz sucesso há muito tempo, mas vou registrar.

Por favor, faça isso quando tiver tempo.

O objetivo é externar ELB→nginx (terminação SSL e autenticação de clientes) → ELB→app interno

Em outras palavras, quero autenticar o cliente, mas o ELB não tem essa função, então encaminho o tcp443 e faço isso com nginx, mas como o IP de origem que pode ser assumido pelo servidor superior será o IP do ELB, quero habilitar o ProxyProtocol no ELB, ouvir o ProxyProtocol e registrar o IP de origem durante a terminação do SSL com nginx.

Omita partes como securityGroup e criar uma instância.

1. Criando um ELB no awscli, configurando proxi-protocol

Referência:

Ative ou desative o suporte ao protocolo proxy - balanceamento de carga elástico agora tente ELB entre múltiplas AZs em uma VPC (2) - Usando awscli - Yohei no Days Devotion XP

- Criação do ELB
perfil=xxxxx
elbname-ext=xxxx-elb
securitygrops="SG-xxxxxxxx SG-yyyy" 
subnets="subnet-xxxxxxxx subnet-yyyy" 
sudo bash -c "aws elb create-load-balancer --load-balancer-name ${elbname-ext} --listeners Protocol=TCP,LoadBalancerPort=443,InstanceProtocol=TCP,InstancePort=443 --subnets ${subnets} --security-groups ${securitygrops} --profile ${profile}" 

*O ELB externo está configurado para transferir apenas do TCP443 para o TCP443 e não inclui um certificado.

elbname-int=yyyy-elb
securitygrops="SG-xxxxxxxx SG-zzzzzzzzzz" 
sudo bash -c "aws elb create-load-balancer --load-balancer-name ${elbname-int} --listeners Protocol=TCP,LoadBalancerPort=80,InstanceProtocol=TCP,InstancePort=8xxx --subnets ${subnets} --security-groups ${securitygrops} --scheme internal --profile ${profile}" 
・helthcheck configurações
sudo bash -c "aws elb configure-health-check --load-balancer-name ${elbname-ext} --health-check Target="TCP:443",Interval=30,Timeout=5,UnhealthyThreshold=2,HealthyThreshold=10 --profile ${profile}" 

sudo bash -c "aws elb configure-health-check --load-balancer-name ${elbname-int} --health-check Target="TCP:80",Interval=30,Timeout=5,UnhealthyThreshold=2,HealthyThreshold=10 --profile ${profile}" 
Registro de Instância
instances-ext="i-xxxxxxxx i-yy" 
instances-int="i-zzzzzzzzzz i-aaaaa" 
sudo bash -c "AWS ELB Register-instances-with-load-balancer --load-balancer-name ${elbname-ext} --instances ${instances-ext} --profile ${profile}" 
sudo bash -c "AWS ELB Register-instances-with-load-balancer --load-balancer-name ${elbname-int} --instances ${instances-int} --profile ${profile}" 
Ativação do protocolo Proxy

Crie uma política

sudo bash -c "aws elb create-load-balancer-policy --load-balancer-name ${elbname-ext} --policy-name EnableProxyProtocol --policy-type-name ProxyProtocolPolicyType --policy-attributes AttributeName=ProxyProtocol,AttributeValue=true --profile ${profile}" 

Revise sua apólice de ######

sudo bash -c "aws elb set-load-balancer-policies-for-backend-server --load-balancer-name ${elbname-ext} --instance-port 443 --policy-names EnableProxyProtocol --profile ${profile}" 

Se quiser desativá-lo, pode especificar uma especificação vazia de '--policy-names []' para desativá-lo

Garanta que os protocolos proxy estejam ativados

sudo bash -c "AWS ELB describe-load-balancers --load-balancer-name ${elbname-ext} --profile ${profile}" 
"BackendServerDescriptions": [ 
{ 
"InstancePort": 443, 
"NomesPolíticas": [ 
"EnableProxyProtocol" 
]
}

2. Sobre a Configuração Nginx

chef, mas vou omitir os detalhes e só adicionar as configurações relevantes. A configuração 'proxi-protocol' deveria estar refletida em 'reiniciar' em vez de 'recarregar', então você precisa realizar o 'reiniciar' do nginx ao confirmar o login.

Referência:

Usando Protocolo Proxy com Nginx | chris lea Módulo ngx_http_realip_module #355 (Suporte a Protocolo Proxy) - nginx

Arquivo de configuração nginx real

(A versão na época do sucesso é 1.7.4-1)

/etc/nginx/nginx.conf
----------------------------------------------- 
log_format principal '$proxy_protocol_addr - $remote_user [$time_local] "$request" ' 
'$status $body_bytes_enviados "$http_referente" ' 
'"$http_agente_usuário" "$http_x_encaminhado_para"' 
'$http_x_userid - $http_x_assinatura - $http_x_sessãokey "$request_corpo"'; 
----------------------------------------------- 

*Alterado para '$proxy_protocol_addr' em vez de '$remote_addr' *Trechos apenas quando relevantes são (copiar e colar de 'mastering Nginx', como http_x_sessionkey, etc., mas por favor remova se não for necessário)

/etc/nginx/conf.d/ssl.conf
----------------------------------------------- 
server { 
# Ouça 443 SSL padrão; 
Listen 443 SSL padrão proxy_protocol; 

server_name <%= nó['nginx']['nome do servidor1'] %>; 
set_real_ip_from <%= nó['nginx']['set_real_ip_from'] %>; 
real_ip_header proxy_protocol; 

ssl_certificate /etc/nginx/<%= nó['nginx']['sslcrt1'] %>; 
ssl_certificate_key /etc/nginx/<%= nó['nginx']['sslkey1'] %>; 

ssl_prefer_server_ciphers em frente; 
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
ssl_session_cache compartilhado:WEB:10m; 
ssl_session_timeout 10m; 
ssl_ciphers RC4:ALTO:!ANULO:! MD5:@STRENGTH; 

## Configuração cliente-autenticação
ssl_verify_client em frente; 
ssl_verify_depth 3; 
ssl_client_certificate /etc/nginx/<%= nó['nginx']['clientcrt'] %>; 
# ssl_crl /etc/nginx/<%= nó['nginx']['clientcrl'] %>; 

resolver <%= nó['nginx']['resolver'] %> valid=5s; 
resolver_timeout 3s; 

Localização / { 
proxy_set_header X-FORWARDED-PROTO https; 
proxy_set_header X-Encaminhado-Para $proxy_add_x_forwarded_for; 
proxy_set_header X-Real-IP $remote_addr; 
proxy_connect_timeout 10s; 
proxy_read_timeout 10s; 
proxy_pass http://<%= @upstream1 %>:<%= @upstreamport %>$request_uri; 

## Passar o certificador do cliente para o servidor backend. 
# proxy_set_header ssl_client_cert $ssl_cliente_cert; 

# root /usr/share/nginx/html; 
# Índice index.html index.htm; 
}
}
----------------------------------------------- 

*Entre as acima, as diretrizes relacionadas ao 'ProoxyProtocol' são as seguintes: 'ouça', 'set_real_ip_from', 'real_ip_header'.

※<%= .. Note que a parte incluída em %> é um atributo (variável) e é substituída pelo conjunto de valores quando a receita do chef é executada, e ele é diferente do valor real. @の変数はroleとenvironmentで吸収しきれずdata_bags, etc. *'set_real_ip_from' especifica o endereço do segmento da VPC (por exemplo, 10.0.0.0/17). É necessário escrever o endereço real do ELB, mas ele não pode ser identificado e é automaticamente agitado. *'ssl_crl' (lista de prova de destruição) O comentário se deve a circunstâncias indefinidas.

**A versão que pode interpretar 'ProoxyProtocol' é 1.5.12 ou superior. Abaixo disso, há um erro com 'configtest'. **No sistema 1.4, não há necessidade de construir a partir do código-fonte com '--with-proxi-protocol', e embora seja a 1.7, consegui realizá-lo usando um pacote puro sem construir o problema. *Parei upstream e adicionei o resolvedor. A resolução de nomes nginx é resolvida toda vez que você coloca em uma variável com o conjunto de masterização Nginx P94 definido, e fora isso, parece que você vai perguntar no momento do ttl especificado no varid do resolvedor. Parece que o resolvedor é necessário apenas pela primeira vez para resolver o nome especificado em upstream e *_pass.

repositório yum para a série 1.7 da nginx (a principal de linha)

O conteúdo é o seguinte. Do ponto de vista do chef, é necessário escrever 'options "--disablerepo=epel"' no recurso do pacote para evitar a entrada do epel.

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/6/$basearch/ 
gpgcheck=0
habilitar=1

3. Verifique o IP de origem dos logs de acesso

Logar
SSH nginx-SRV1-dev
SSH nginx-SRV2-dev
Confirmação
RPM -Qa|Grep Nginx
Sudo Service nginx configtest
Reinício do serviço Sudo Nginx
Status do serviço Sudo NGINX
Sudo Netstat -LNPTU
chkconfig --list nginx
Se ele se tornar InService após adicioná-lo ao ELB, acesse pelo navegador e verifique os logs
$ cauda sudo -f /var/log/nginx/access.log
119.xxx.xxx.xxx - - [12/ago/2014:04:39:28 +0000] "GET / HTTP/1.1" 400 648 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, como Gecko) Chrome/36.0.1985.125 Safari/537.36" "-"- - - - - - "-" 
119.xxx.xxx.xxx - - [12/ago/2014:04:39:28 +0000] "GET /favicon.ico HTTP/1.1" 400 648 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, como Gecko) Chrome/36.0.1985.125 Safari/537.36" "-"- - - - - "-" 

Como o IP global da fonte de conexão apareceu assim, parece ter sido um sucesso em termos de 'ProoxyProtocol'. Não posso entrar em mais detalhes sobre autenticação de clientes aqui, mas por favor entenda.

Pessoalmente, tive dificuldade com as reviravoltas até perceber que precisava fazer o que está escrito na página do Chris Lea linkada no artigo, e a especificação errada do protocolo ELB. Não consegui encontrar um artigo que explicasse tudo junto, então escrevi. Em um evento na reunião de usuários do nginx, aprendi de perto parte do significado do desenvolvedor Igor recomendando uma nova versão se você quiser usar SSL. Pode ser útil quando você quer usar um dispositivo específico.

Obrigado por ler. Eu ficaria feliz se pudesse ser útil para alguém.

Related Articles