você está aqui: Home  → Arquivo de Mensagens

IPTABLES e SIP

Colaboração: Ivan de Gusmão Apolonio

Data de Publicação: 23 de agosto de 2012

Para quem trabalha com telefonia IP (SIP), sabe o quão trabalhoso é ficar controlando os acessos de ramais IP no firewall a fim de se evitar tentativas de acesso por força bruta ou algum tipo de negação de serviço (DoS). No meu caso isso se torna ainda mais complicado, pois minha empresa conta com vendedores na rua, que precisam acessar o sistema de telefonia da empresa através de IPs dinâmicos (smartphones e tablets).

Após muita pesquisa, consegui uma forma relativamente simples de fazer o controle de acesso SIP, usando apenas regras do iptables. Ao olhar o script abaixo, a princípio parece complicado, mas depois que você entende a sequência lógica, vê que é bastante simples, conforme mostra o fluxograma abaixo:

Nas versões mais recentes do iptables, exite um módulo chamado recent, que gera e mantém listas dinâmicas para serem usadas nos controles de acesso. Todas vez que o serviço de firewall é parado ou reiniciado, as listas são zeradas. No exemplo abaixo, criei 2 listas: BLACKLIST e IP_RAMAIS. As listas podem ser consultadas diretamente pelo diretório /proc, porém percebi que diferentes distribuições de Linux, armazenam as listas em caminhos diferentes dentro do /proc. No meu caso, utilizo do Red Hat Enterprise 6, o qual mantém as litas em /proc/net/xt_recent/BLACKLIST e /proc/net/xt_recent/IP_RAMAIS

Vou tentar deixar bem explicado o que cada parte do script faz. Obviamente este é um script de firewall simplificado, criado apenas para exemplificar o conceito.

  
  # inteface pública
  IF=eth0
  
  #caminho do iptables
  IPT=/sbin/iptables
  
  # lista de ramais a serem liberados
  RAMAIS="5555" # José
  RAMAIS="$RAMAIS 5556 5557" # Carlos
  RAMAIS="$RAMAIS 5586" # Maria
  RAMAIS="$RAMAIS 5590 5591 5592" # Juliana
  
  
  # Chain log and drop (LD), para jogar num arquivo de log os pacotes dropados.
  $IPT -N LD
  $IPT -A LD -j LOG --log-level debug --log-prefix "DENY by rule: "
  $IPT -A LD -j DROP
  
  
  # REGRAS DE BLOQUEIO #
  # Bloqueia IPs com erro de authenticação SIP
  # Se o pacote vier de um IP que está na BLACKLIST, dropa o pacote.
  # O IP fica na lista por 1 hora e a cada acesso, o tempo é renovado.
  $IPT -A INPUT -m recent --update --seconds 3600 --name BLACKLIST -j LD
  # Se houver algum pacote SIP de retorno com a string "403 Forbiden", Adiciona o IP na BLACKLIST
  $IPT -I OUTPUT -o $IF -p udp -m string --string "403 Forbidden" --algo bm -m recent --set --rdest --name BLACKLIST -j LD
  
  # REGRAS DE INPUT #
  # adicione suas regras de permissão de entrada a partir daqui
  # $IPT -A INPUT -p tcp --dport 22 -j ACCEPT
  
  # Se o pacote UDP for de registro de algum dos ramais especificados em $RAMAIS
  # o IP de origem do pacote será adicionado na lista IP_RAMAIS 
  for a in $RAMAIS ; do
    $IPT -A INPUT -p udp --dport 5060:5061 -m string --string "sip:${a}@" --algo bm -m recent --set --name IP_RAMAIS -j ACCEPT
  done
  
  # Se o pacote estiver na lista IP_RAMAIS, libera o tráfego de INPUT VoIP (SIP e RTP) e 
  # atualiza o último acesso deste IP na lista IP_RAMAIS.
  # O IP fica na lista por 10 minutos e a cada acesso, o tempo é renovado.
  $IPT -A INPUT  -p udp --dport 5060:32768 -m recent --update --name IP_RAMAIS --seconds 600 -j ACCEPT
  
  
  # Permite todas as conexões previamente estabelecidas, fluam normalmente
  $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  # Loga e Dropa qualquer pacote que não tenha sido liberado por nenhuma regra anterior
  # (estas devem ser as últimas linhas na parte de INPUT
  $IPT -A INPUT -m limit --limit 1/s --limit-burst 1 -j LOG --log-level debug --log-prefix "DENY Input: "
  $IPT -A INPUT -j DROP
  
  # REGRAS DE OUTPUT #
  # adicione suas regras de permissão de saída a partir daqui
  # $IPT -A OUTPUT -p tcp -d 0/0 -m multiport --dport 20,21,80,443 -j ACCEPT
  
  # se o pacote estiver na lista IP_RAMAIS, libera o tráfego de OUTPUT VoIP (SIP e RTP)
  $IPT -A OUTPUT -p udp --dport 5060:32768 -m recent --update --name IP_RAMAIS --seconds 600 -j ACCEPT
  
  # Permite todas as conexões previamente estabelecidas, fluam normalmente
  $IPT -A OUTPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
  # Loga e Dropa qualquer pacote que não tenha sido liberado por nenhuma regra anterior
  # (estas devem ser as últimas linhas na parte de OUTPUT
  $IPT -A OUTPUT -m limit --limit 1/s --limit-burst 1 -j LOG --log-level debug --log-prefix "DENY Output: "
  $IPT -A OUTPUT -j DROP


 

 

Veja a relação completa dos artigos de Ivan de Gusmão Apolonio

Opinião dos Leitores

Junior
16 Fev 2017, 15:59
Magnífico!!!
Fernando
23 Ago 2012, 08:51
Show de bola... me deu uma idéia para mim implantar o scritp na minha central AVAYA, valeu...
Fernando
23 Ago 2012, 07:58
Isso sim é uma dica útil.
Denis
23 Ago 2012, 07:01
Esqueci de dizer que é muito útil também para bloquear tentativas de brute force em SMTP, POP, IMAP, FTP e outros protocolos autenticados.
Denis
23 Ago 2012, 06:53
Muito boa ideia. Já utilizo o recent para bloquear quando ocorrem muitas conexões partindo do mesmo IP, mas basear o bloqueio no retorno é muito mais esperto. Vale observar, como sugestão, que se for possível 3 tentativas antes do bloqueio, ficaria um brinco.
*Nome:
Email:
Me notifique sobre novos comentários nessa página
Oculte meu email
*Texto:
 
  Para publicar seu comentário, digite o código contido na imagem acima
 


Powered by Scriptsmill Comments Script