Balanceamento de carga com base no certificado de cliente com o mod_proxy_ajp e o Tomcat do Apache

1

Atualmente, estou usando mod_proxy_ajp para carregar solicitações de saldo para vários servidores Tomcat. Os chamadores são autenticados usando certificados de cliente e uma ACL. Isso tem funcionado bem, os chamadores são roteados para qualquer servidor em uma taxa uniforme. Agora, quero fazer uma pré-busca e armazenar em cache os dados por usuário, para que cada servidor Tomcat atenda a um conjunto conhecido de usuários. Então, estou pensando que seria bom dividir o autor da chamada em ordem alfabética; usuário com um nome (CN ou DN) começando com A-M ir para o servidor 1, os usuários com nomes começando com [N-Z] vão para o servidor 2. Mas eu não sei como fazer isso funcionar.

Atualmente, tenho:

<Proxy balancer://lb-service>
   BalancerMember ajp://svr1:8009 loadfactor=1 
   BalancerMember ajp://svr2:8009 loadfactor=1 
</Proxy>

<Location /lookup>
   ProxyPass balancer://lb-service/lookup
</Location>

Estou pensando em usar mod_rewite para alterar o URL para incluir o CN do usuário, mas não consigo fazer isso funcionar.

Estou bastante preso usando o apache mod_proxy_ajp e o Tomcat para balanceamento de carga. Eu posso mudar os serviços que executam o Tomcat para aceitar solicitações diferentes.

Alguém tem uma boa maneira de fazer isso?

    
por John in MD 03.01.2012 / 19:39

1 resposta

1

Idéia interessante para armazenamento em cache! Vamos ver se conseguimos que funcione ..

Eu tenho algumas opções: uma que seria mais eficiente, mas eu realmente não tenho ideia se isso funcionará, e uma que é menos eficiente, mas estou razoavelmente certo de que funcionará bem.

O problema com a opção mais eficiente (e, mais geralmente, usando algo como o certificado do cliente para determinar a atribuição do balanceador de carga) é que, até onde eu sei, não há como alterar a mente do mod_proxy_balancer na atribuição do nó após a solicitação in - há provavelmente alguns hackers criativos que poderiam fazer isso acontecer, mas eu não estou chegando com ideias melhores do topo da minha cabeça. O ponto crucial disso é que ele está fazendo um redirecionamento para o mesmo local em que está, a fim de ter o cookie no local para a primeira solicitação que é intermediada por proxy, para obter a rota correta - e não tenho certeza se isso funcionará . Vale um tiro:

RewriteEngine On

RewriteCond %{ENV:BALANCER_ROUTE_CHANGED} 1
RewriteCond %{SSL:SSL_CLIENT_S_DN} ^[a-m] [NC]
RewriteRule ^(.*)$ /.$1 [R,CO=ROUTEID:route.1:.yourdomain.com]

RewriteCond %{ENV:BALANCER_ROUTE_CHANGED} 1
RewriteCond %{SSL:SSL_CLIENT_S_DN} ^[n-z] [NC]
RewriteRule ^(.*)$ /.$1 [R,CO=ROUTEID:route.2:.yourdomain.com]

<Proxy balancer://lb-service>
    BalancerMember ajp://svr1:8009 loadfactor=1 route=1
    BalancerMember ajp://svr2:8009 loadfactor=1 route=2
    ProxySet stickysession=ROUTEID
</Proxy>

<Location /lookup>
   ProxyPass balancer://lb-service/lookup
</Location>

Se isso não funcionar, então aqui está o plano B; basta combinar o DN do certificado do cliente todas as vezes. Adicionando uma sobrecarga extra a cada solicitação, mas isso não deve ser um impacto de desempenho geral.

<Proxy */lookup>
    RewriteEngine On

    RewriteCond %{SSL:SSL_CLIENT_S_DN} ^[a-m] [NC]
    RewriteRule ^/lookup((?:/.*|))$ ajp://svr1:8009/lookup$1 [P,L]

    RewriteCond %{SSL:SSL_CLIENT_S_DN} ^[n-z] [NC]
    RewriteRule ^/lookup((?:/.*|))$ ajp://svr2:8009/lookup$1 [P,L]

    # This will take care of any other orphan requests (say, those with no client
    # cert) - we'll just lump those on server 1; if there's a lot then we can do
    # something else to balance randomly (like just leave the current config there)
    RewriteRule ^/lookup((?:/.*|))$ ajp://svr1:8009/lookup$1 [P,L]
</Proxy>

Eu tenho essa correspondência para uma barra depois de /lookup para evitar uma vulnerabilidade de segurança desagradável em que um invasor pode chegar à sua rede interna - se isso não funcionar para o seu aplicativo, podemos contorná-lo.

    
por 03.01.2012 / 20:42