sábado, 15 de março de 2008

Openfire: como bloquear usuários MSN usando o Gateway IM e o Packet Filter

Uma pergunta que muitas vezes me fazem é: Usando o transporte MSN no Openfire como posso fazer para liberar o usuário X para falar com somente alguns contatos do MSN, já que o padrão é que ele possa falar com todos ?

Até hoje eu ainda não tinha respostas para essa pergunta, apesar de ter uma noção de como fazer, principalmente depois que me indicaram o plugin Packet Filter. Só que hoje resolvi testar o mesmo e encontrei uma forma de resolver isso.

O que faz o plugin Packet Filter ?
O Packet Filter é uma espécie de "iptables" para Openfire. Ele permite que você aceite, rejeite ou descarte vários tipos de pacotes XMPP baseado em regras que você pode estabelecer.

É mais ou menos assim: você pode dizer que o usuário fulano não pode enviar nem receber mensagens do usuário ciclano, ou que o grupo contabilidade pode mandar e receber mensagens do grupo diretoria, mas não do grupo rh, e por aí vai.

Vendo essas features imaginei que fosse de alguma forma possível usar o recurso para filtrar os contatos MSN (ou ICQ, ou AIM, ou o protocolo que for).

Bem, descobri que É POSSÍVEL sim, mas que é um trabalho árduo pelo menos da forma que estou implementando as regras. A forma de implementação padrão obriga que os filtros sejam feitos conta a conta e para que o mesmo funcione da forma que eu implementei você tem de liberar também um a um os contatos para qual seu usuário pode enviar/receber as mensagens (inclusive os contatos Jabber do servidor local). Ou seja, numa instalação com muitos usuários usando o transporte MSN isso pode ser inviável de gerenciar/administrar.

Mas porque isso é trabalhoso ?
Porque na realidade o packet filter não foi feito para trabalhar com os transportes, mas sim com contas locais. Mas já que no Openfire, todos os contatos de um transporte tem um JID válido você pode usar o plugin para isso também.

Você pode explicar isso melhor ?
Cada usuário do Openfire ganha um JID, que é a identificação do usuário para o servidor. No meu servidor de testes, chamado openfire.inet, meu usuário marcelo responde pelo JID marcelo@openfire.inet.

Agora vejamos o caso do transporte MSN: ao vincular minha conta local Jabber (marcelo@openfire.inet) a uma conta MSN usando o plugin Gateway IM, todos meus contatos MSN ganharam também um JID válido. Então, por exemplo, o meu contato marceloterres@dominio.com passou a ter um JID local chamado marceloterres\40dominio.com@msn.openfire.inet.

Agora que ele tem um JID, eu posso usá-lo para criar regras no Packet Filter. :-)

Mas de que forma o packet filter será eficaz ? Como posso implementá-lo ?
A melhor forma que encontrei até o momento é a seguinte:
  • em primeiro lugar você deve liberar todas os contatos que você quer permitir para o usuário (inclusive os contatos do servidor local e não só os do transporte MSN). A liberação é uma via de mão dupla, pois você precisa liberar o envio e precisa também liberar o recebimento de mensagens para cada contato do usuário (a não ser é claro que você queira que algum contato do usuário só possa mandar mensagens e não receber e vice versa).
  • em segundo lugar você deve criar 2 regras dizendo que os pacotes de mensagens de quaisquer outros usuários serão rejeitados (ATENÇÃO: para essas regras use só os pacotes de mensagens, porque se você usar os pacotes do tipo any (quaisquer) o usuário não conseguirá nem logar no servidor).
IMPORTANTE: O packet filter, assim como o Iptables, usa precedência para as regras, por isso a primeira regra que fechar é a que vale. Dessa forma, coloque antes as regras de liberação e depois as regras de bloqueio.

Tem um exemplo prático ?
A imagem abaixo ilustra melhor a questão (clique nela para ampliar e entender).

Nesse servidor de testes (openfire.inet) o usuário marcelo@openfire.inet pode mandar e receber mensagens para/do usuário local fulano (fulano@openfire.inet) e também do seu contato MSN (marceloterres@dominio.com). Todos as mensagens enviadas/recebidas de seus demais contatos serão rejeitadas, como pode ser visto nas 2 últimas linhas.


Isso não impede que o usuário veja todos seus contatos que estiverem online e nem que eles o vejam também, mas caso o usuário tente mandar uma mensagem para um contato bloqueado o servidor Openfire informa que a mensagem foi rejeitada (uma forma de resolver a questão da visibilidade seria rejeitar todos os pacotes (any) de cada contato bloqueado, mas aí isso teria de ser feito contato a contato, ou seja, mais trabalho manual).

Acredito que a solução acima não seja a mais elegante e mais simples mas de momento foi a forma que encontrei para resolver a questão.

Talvez em breve tenhamos um plugin só para isso, ou quem sabe o próprio Gateway IM não venha a implementar esse recurso, mas para quem não pode esperar, é uma solução que pode ser implementada agora.

PS: caso tenha outra sugestões de implementação, por favor poste aqui.

UPDATE (13/11/2008): Não deixem de ler o comentário de Sarunas, pois o mesmo parece simplificar e muito o uso do Packet Filter. Eu ainda não tive tempo de testá-lo, mas assim que for possível irei fazer, e conforme também vá recebendo feedback de outras pessoas, vou postar mais sobre isso aqui.


Leia também: