Varnish Disrupting Logins com Invision Power Board

1

Recentemente, transferi um dos meus sites primários para uma instalação do WordPress, mas infelizmente isso resultou em cargas de servidor extremamente altas. Originalmente, eu estava executando um servidor LAMP básico com vários sites. O que eu estou principalmente preocupado agora é um site que recebe cerca de 60.000 acessos por dia e tem um fórum muito ativo que usa o Invision Power Board.

Isso me leva para onde estou agora. Eu troquei o apache pelo nginx, otimizei um pouco o MySQL e instalei o Varnish. Isso ajudou muito e funciona com tudo, exceto com a instalação do Invision Power Board. Por qualquer motivo, o IPB não permitirá mais que eu faça o login ou a saída. Em um dos meus computadores em que estava logado, consigo ficar logado. Mas, se eu tentar entrar no ACP ou nos fóruns de outro computador ou navegador, ele não funcionará. Abaixo estão minhas configurações em verniz:

sub vcl_recv {
   if (req.http.host ~ "^(www\.)?domain1\.net$") {
       set req.http.host = "domain1.net";
       set req.backend = domain1;
       return (lookup);
   }
   if (req.http.host == "old.domain1.net") {
       #You will need the following line only if your backend has multiple virtual host names
       set req.http.host = "old.domain1.net";
       set req.backend = olddomain1;
       return (lookup);
   }
   if (req.http.host ~ "^(www\.)?domain2\.net$") {
       set req.http.host = "domain2.net";
       set req.backend = domain2;
       return (lookup);
   }
   if (req.http.host ~ "^(www\.)?domain3\.com$") {
       set req.http.host = "domain3.com";
       set req.backend = domain3;
       return (lookup);
   }
   if (req.http.host ~ "^(www\.)?domain4\.org$") {
       set req.http.host = "domain4.org";
       set req.backend = domain4;
       return (lookup);
   }
}


# Drop any cookies sent to Wordpress.
sub vcl_recv {
    #exclusion for one domain that has low-views and maybe have unexpected results
    if (!(req.http.host ~ "^(www\.)?domain4\.org$")) {
        if (!(req.url ~ "wp-(login|admin)")) {
            if (!(req.url ~ "forums")) {
                    unset req.http.cookie;
            }
        }
    }
}

# Drop any cookies Wordpress tries to send back to the client.
sub vcl_fetch {
    #exclusion for one domain that has low-views and maybe have unexpected results
    if (!(req.http.host ~ "^(www\.)?domain4\.org$")) {
            if (!(req.url ~ "wp-(login|admin)")) {
                if (!(req.url ~ "forums")) {
                        unset beresp.http.set-cookie;
                }
            }
    }
}

Sou muito novo no nginx e no verniz. Eu vi uma outra pergunta para isso, mas não há boas soluções.

    
por Jyosua 20.08.2014 / 21:07

2 respostas

0

Você está fazendo return(lookup) explícito em sua primeira vcl_recv. Isso significa que o código no segundo bloco vcl_recv só será executado se a solicitação não atingir nenhuma das condições no primeiro bloco (isto é, se não for ^(((www\.|old\.)?domain1\.net)|((www\.)?domain(2\.net|3\.com|4\.org))$ ) e todos os outras partes do segundo bloco vcl_recv if são bem-sucedidas.

Fundamentalmente, você está substituindo a lógica integrada perfeitamente do Varnish aqui, que teria passado as solicitações para os usuários logados (isto é, aqueles com cookies) para o backend, enquanto servia o resto fora do cache, se acessível. Você pode obter o resultado que está procurando simplesmente removendo todos os return(lookup) s. Mas se você insistir em fazer isso da maneira atual, basta adicionar:

sub vcl_hash {
  if ( req.http.Cookie ) {
    hash_data( req.http.Cookie );
  }
}

A vantagem de ignorar a lógica do Varnish é que mesmo os cookies que não têm qualquer tipo de responsabilidade no processamento da solicitação pelo servidor, como os IDs do urchin do Google Analytics, farão com que todas as solicitações atinjam o back-end. Para evitar isso, inclua na lista de permissões os cookies com os quais o servidor se preocupa ou liste na lista negra os que não são; Várias técnicas para realizar isso estão disponíveis na Web e no link .

Editar: Expandindo um pouco, o que está acontecendo aqui é que você está dizendo ao Vernish que, se uma solicitação entrar, digamos, domain1, usar o backend do domain1 e tentar recuperar esse objeto do cache. Se não estiver presente no cache, ele irá buscá-lo no back-end e armazená-lo no cache. Contanto que não exista um cabeçalho Set-Cookie presente na resposta (que, no default.vcl, faz com que o objeto fique inatingível), da próxima vez que alguém solicitar a mesma página, ele será visto como o usuário (ou o que for "não-usuário", no caso de alguém que não está logado, viu o último, presumindo que o TTL não expirou. O que fazemos com o código vcl_hash é dizer que o Varnish deve considerar objetos em cache diferentes com base no Cookie que foi entregue com a solicitação. Poderíamos melhorar isso facilmente - por exemplo, só poderíamos nos preocupar com o cookie para páginas que não terminam em \.(jpg|png|gif|AndSoForth)$ , mas o lugar certo para fazer isso é em vcl_recv , onde devemos simplesmente remover o cabeçalho Cookie totalmente para tais pedidos.

    
por 20.08.2014 / 22:29
0

Primeiro - você tem duas funções vcl_recv , você precisa combiná-las em uma.

Mas isso está relacionado apenas ao bloqueio de cookies enviados ao servidor; Parece que enviar cookies para o cliente é onde está o seu problema se uma sessão existente continuar funcionando.

Faça um login de teste sem verniz; quando o Set-Cookie está sendo enviado pelo servidor? Descubra onde isso acontece, teste com o Varnish novamente e veja se o Set-Cookie está sendo enviado corretamente nesse caso. Pode ser que a isenção de if (!(req.url ~ "forums")) { não esteja sendo capturada pelo recurso que envia o cookie.

    
por 20.08.2014 / 22:14

Tags