IPTables – Firewall SIP – Hosts Internacionais

Pessoal,

Hoje estou disponibilizando uma rotina em iptables/netfilter que pode ser usada no seu servidor SIP. A idéia dessa rotina é criar uma chain no iptables
e jogar todo o tráfego SIP para ela. Essa chain, por padrão, não aceita nenhum host internacional mas aceita todos os
hosts brasileiros. Se houver a necessidade de liberar algum host internacional, basta setá-lo na variável $ACC_SIP e
caso haja a necessidade de se bloquear algum host nacional, adicioná-lo na variável $NO_SIP.

Abaixo um diagrama do seu funcionamento:

O diagrama mostra que toda requisição UDP/5060 com destino ao servidor, ao chegar na Mangle PREROUTING é redirecionada para
Mangle SIP. A mangle SIP é que aceita ou não às requisições e encaminha então à camada de aplicação.

Abaixo o bash script, na sequencia as suas dependências: um outro pequeno script em python para parse no arquivo do Lacnic
e o link para download do sendEmail, um cliente SMTP em Perl.

BASH SCRIPT:

#!/bin/bash

# ########################### ATENCAO! ################################
#
# O padrao desse firewall eh bloquear todo acesso internacional
# com destino ao servidor (UDP/5060). Hosts internacionais com
# permissao para UDP/5060 devem estar setados na variavel ACC_SIP.
#
# Hosts nacionais que devem ser negados para UDP/5060 devem ser
# setados na variavel NO_SIP.
#
#######################################################################
#
# 09/2011 - Thiago Jose Lucas | thiagojlucas@gmail.com
#
####
# CONSTANTES
LACNIC_FTP_FILE='ftp://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-latest'
LACNIC_FILE='/tmp/delegated-lacnic-latest'
PARSE_SCRIPT='./parse.py' # CAMINHO COMPLETO
IPT='/sbin/iptables'
CHAIN_NAME='SIP'
SIP_PORT='5060'
MAIL_CMD='./sendEmail'
WGET_TIMEOUT='14'
# HOSTS LIBERADOS PARA SIP
# (separado por espaco)
ACC_SIP='200.xxx.240.xxx x00.192.xxx.50'
NO_SIP=''

# COMANDO BASICOS NECESSARIOS
basic(){
  echo "Erro: Favor instalar o comando $1 antes de executar este script!"
  exit 0
}

BASIC_CMD="host iptables echo wget hostname ip $MAIL_CMD"
for CMD in $BASIC_CMD ;do
  which $CMD >/dev/null 2> /dev/null || basic $CMD
done

nameTest(){
  host ftp.lacnic.net > /dev/null || alert "Problema na resolucao de nomes - (DNS)"
}

alert(){
OPT=$1
IP_ADDRESS=`ip r g 200.192.243.50|head -n1|awk '{print $7}'`
MY_HOSTNAME=`hostname`
MAIL_FROM='suporte@wwww-it.com.br'
MAIL_TO='suporte@wwww-it.com.br'
MAIL_SUBJECT='SIPFirewall - Problema na Execucao'
MAIL_SERVER_SMTP='smtp.wwwww.com.br'
MAIL_USER_SMTP='alive@wwww-it.com.br'
MAIL_PASS_SMTP='E-*********O'
MAIL_BODY="
Erro ao executar $0:
$OPT

Hostname: $MY_HOSTNAME
IP Address: $IP_ADDRESS

Atenciosamente
--
NOC Nome da Empresa
noc@seudominio.com.br
noc@seudominio.com.br
55.14.3333.4444
"

$MAIL_CMD -f "$MAIL_FROM" -t "$MAIL_TO" -u "$MAIL_SUBJECT" -s "$MAIL_SERVER_SMTP" -xu "$MAIL_USER_SMTP" -xp "$MAIL_PASS_SMTP" -m "$MAIL_BODY"
}

# TESTA A EXISTENCIA E O PERMISSIONAMENTO DE $PARSE_SCRIPT
[ -e "$PARSE_SCRIPT" -o -x "$PARSE_SCRIPT" ] || alert "Problema ao chamar $PARSE_SCRIPT"

get(){
  wget -q -O $LACNIC_FILE $LACNIC_FTP_FILE -T $WGET_TIMEOUT|| alert "Erro ao baixar o Arquivo - (wget)"
}

parse(){
  $PARSE_SCRIPT $LACNIC_FILE
}

nameTest
get

# TRATA A CHAIN A SER UTILIZADA #
$IPT -t mangle -D PREROUTING -p UDP --dport $SIP_PORT -j $CHAIN_NAME 2>/dev/null
$IPT -t mangle -F $CHAIN_NAME 2>/dev/null
$IPT -t mangle -X $CHAIN_NAME 2>/dev/null
$IPT -t mangle -N $CHAIN_NAME 2>/dev/null

# DROP P/ TRAFEGO UDP/5060 - $CHAIN_NAME
$IPT -t mangle -I $CHAIN_NAME -p UDP --dport $SIP_PORT -j DROP

# ACCEPT P/ REDES DO BRASIL
parse|while read NETWORK ;do
  $IPT -t mangle -I $CHAIN_NAME -p UDP -s $NETWORK --dport $SIP_PORT -j ACCEPT
done

# ACCEPT PARA REDES SETADAS EM ACC_SIP
if [ ! -z "$ACC_SIP" ] ;then
  for _HOST in $ACC_SIP ;do
    $IPT -t mangle -I $CHAIN_NAME -p UDP -s $_HOST --dport $SIP_PORT -j ACCEPT
  done
fi

# DROP PARA REDES SETADAS EM NO_SIP
if [ ! -z "$NO_SIP" ] ;then
  for _HOST in $NO_SIP ;do
    $IPT -t mangle -I $CHAIN_NAME -p UDP -s $_HOST --dport $SIP_PORT -j DROP
  done
fi

# REDIR. DE TRAFEGO PARA $CHAIN_NAME
$IPT -t mangle -I PREROUTING -p UDP --dport $SIP_PORT -j $CHAIN_NAME

PYTHON SCRIPT:

#!/usr/bin/python
# Parse no arquivo de redes do lacnic
# thiagojlucas@gmail.com

import os
import sys

try:
    location = (sys.argv[2])
except:
    location = "BR"

for tmp in open(sys.argv[1]):
    tmp = tmp[:-2].split("|")
    x = 1
    i = 32
    if tmp[1]==location and tmp[2]=="ipv4":
        while not x == int(tmp[4]):
            x = x*2
            i = i-1
            if i==0:
                break
        if i != 0:
            print tmp[3]+"/%d" % (i)
        else:
            print tmp[3]+"/%d" % 16

SENDEMAIL:
http://freecode.com/projects/sendemail

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s