Proxy reverso NGINX com autenticação de cliente SSL opcional

1

Temos um proxy NGINX que deve estar multiplexando um aplicativo no link e uma API localizada em link . Dificuldade adicional é proteger a API via autenticação de cliente SSL.

Esta é a minha tentativa de configuração do servidor NGINX:

server {
    listen       443 ssl;
    server_name  server;

    ssl_certificate     /etc/nginx/certs/site.crt;
    ssl_certificate_key /etc/nginx/certs/site.key;

    ssl_client_certificate /etc/nginx/certs/rootCA.pem;
    ssl_verify_client optional;

    location / {
        if ($request_method = GET) {
            return 301 https://$host/app/;
        }

        if ($ssl_client_verify != SUCCESS) {
            return 403;
        }

        limit_except GET {
            allow <SOME_IP>;
            deny  all;
        }

        add_header X-Client-Authentication "$ssl_client_verify";

        proxy_pass http://backend:8080/;
    }

    location /app {
        ...
    }
}

Infelizmente, mesmo os clientes não autenticados são encaminhados para o back-end. Como isso pode ser? A linha if($ssl_client_verify != SUCCESS) deve estar lidando com este caso. Eu adicionei o conteúdo de $ssl_client_verify a um cabeçalho de resposta e é NONE como esperado. Então, claramente, a instrução if com o return 403 não está sendo avaliada.

Entre. não é possível mover a API para uma porta ou caminho diferente

    
por Adam Szalkowski 10.01.2018 / 17:56

1 resposta

1

usar se diretiva no bloco de localização é algo que precisa ser evitado. Porque configuração nginx usando linguagem declarativa. Portanto, se você estiver usando if diretiva no bloco de localização e a primeira condição se for cumprida, a outra diretriz if não será executada. então minha sugestão é mudar se diretiva de bloco de localização para bloco de servidor. aqui está a documentação e o artigo se você quiser saber mais:

  • link
  • agentzh.blogspot.com/2011/03/how-nginx-location-if-works.html

Atualização: você pode fazer algo assim. Eu não testei sozinho, então eu acho que vai ter um erro de sintaxe. Mas acho que você entendeu a ideia.

server{
    ...

    #for location /
    set $Location_VerifySSL 'root';

    #for location /app/
    if ($request_uri ~* '^(/app)){
        set $Location_VerifySSL 'app';
    }

    set $Location_VerifySSL "$Location_VerifySSL_success";
    if ($ssl_client_verify != 'SUCCESS'){
        set $Location_VerifySSL "$Location_VerifySSL_fail";
    }

    if ($Location_VerifySSL = "root_fail") {
        return 403;
    }
    if ($Location_VerifySSL = "app_success") {
        return 200 'This is when url match ^(/app) and ';
    }
    ...

    location /{
        ...
    }
    ...
}
    
por 11.01.2018 / 03:09