nginx proxy_pass com um backend solicitando certificados de cliente

2

Estamos fazendo proxy de um back-end que não controlamos & o backend está solicitando um certificado de cliente ao se conectar em https.

Quando solicitamos essas páginas por meio do proxy, a conexão expira sem resposta do back-end, no entanto, as páginas funcionam bem se ignorarmos o proxy. Isso é um problema com o nginx manipulando o certificado do cliente ou deveríamos estar procurando em outro lugar?

Configuração do Nginx:

server {
        listen 443 ssl;

        ssl on;
        ssl_certificate /etc/nginx/ssl/webserver.pem;
        ssl_certificate_key /etc/nginx/ssl/webserver.key;

        location / {
                 proxy_pass https://www.backendsite.com;
                 proxy_set_header X-Forwarded-For $http_x_forwarded_for;
        }
}
    
por Glenn Slaven 20.02.2014 / 06:34

1 resposta

3

Não tenho certeza se você percebe isso ou não, mas o que você está fazendo é um ataque Man-In-The-Middle em www.backendsite.com .

Para entender por que isso não funciona no seu cenário, precisaremos explicar a real função dos certificados e chaves no TLS. Então aqui vamos nós.

Antes de mais nada, precisamos estabelecer uma chave clara. Nós não temos e por razões de eficiência não podemos ter um canal seguro, então usamos o Diffie Hellman como nosso protocolo de troca de chaves. Anteriormente, poderíamos ter estabelecido os parâmetros que usamos. O pensamento moderno diz que é uma má ideia, vamos fazer algumas coisas à medida que avançamos. Isso é chamado DHE (Ephemeral Diffie Hellman). Se você está se sentindo realmente gostoso, você pode fazer isso em EC (EC-DHE).

Agora, a pergunta é: como você sabe que eu te enviei os parâmetros que fiz, usando DH? Para verificar isso, precisamos de um algoritmo de assinatura digital para que você possa ter algumas informações públicas sobre mim para verificar se a assinatura feita com minha chave privada só pode ser feita por mim.

O material da chave do servidor fornece que, para o servidor final - uma chave privada e uma chave pública (contidas no certificado, junto com assinaturas da CA dizendo sim, confiamos também nisso).

NORMALMENTE, o cliente pode apenas gerar um par de chaves pública / privada para conexões anônimas da forma como se parece. Então, sob circunstâncias usuais:

  • O cliente tem um par de chaves antigo.
  • Ela estabelece uma conexão ativa com seu proxy. O tráfego é criptografado / descriptografado sobre este túnel.
  • O proxy tem o seu próprio "qualquer par de chaves antigo" com o qual estabelece uma conexão com o servidor.
  • O servidor não se importa muito com quem é o cliente, ele estabelecerá uma conexão com praticamente qualquer pessoa, por isso usa a chave pública do seu proxy.
  • A sessão está estabelecida.

No entanto, agora o cliente fornece um par de chaves específico. Este par de chaves é usado para proteger os parâmetros do protocolo, então aqui está o que acontece:

  • O cliente tem um par de chaves específico, solicita o TLS e envia seus parâmetros e chave pública.
  • O Proxy descriptografa e pode reempacotar essa de duas maneiras (não sei qual delas realmente aconteceria - depende da implementação - estou apenas explicando por que isso não funciona):
    • Fornece o certificado público do cliente em vez do seu próprio. Não tendo a chave privada, não é possível descriptografar nenhuma das respostas da sessão.
    • Então, em um mau humor (mais uma vez isso não é realmente o que acontece, apenas uma ilustração) e gera seus próprios certificados. No entanto, o servidor não vai falar com certificados, exceto aqueles em um determinado critério (por exemplo, assinado por algum certificado conhecido) e se recusa a negociar a conexão.

A razão pela qual isso não funciona é porque o nginx está tentando atuar como um proxy http, retirando e reaplicando https conforme necessário, e com certificados confiáveis estabelecidos nas duas extremidades, o TLS está impedindo o MITM por design.

Existem algumas decisões de projeto alternativas que os engenheiros podem tomar onde o back-end está sob seu controle. Eu acabei aqui porque queria fazer proxy para um soquete unix passando algumas informações de certificado em diante. Isso pode ser feito usando estas notas sobre a autenticação de certificados com nginx e esta observação nos cabeçalhos HTTP (não passe a matéria-prima inteira certificado).

    
por 04.03.2014 / 10:37