Firewall para Debian Squeeze

Saudações livres,

abaixo publico um script desenhado para se adequar ao Debian Lenny e, consequentemente, ao LSB para scripts de inicialização.

Vale ressaltar que o software se divide em dois arquivos, o gfirewall.sh contem o firewall propriamente dito, o funcoes.sh contem funções bash que são utilizadas no primeiro arquivo. O objetivo dessa separação é deixar o arquivo de firewall mais limpo, contendo apenas as regras personalizadas, que exigem mais atenção.

Para “instalar” os scripts mova os dois arquivos para /etc/init.d/, execute o comando: insserv -v gfirewall.sh e edite este último arquivo descomentando as linhas que lhe servirem e/ou acrescentando novas regras.

gfirewall.sh

[codesyntax lang=”bash”]

#!/bin/bash
### BEGIN INIT INFO
# Provides:          gfirewall
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: firewall initscript
# Description:       GFirewall <gnu.eti.br>
### END INIT INFO

# Script com regras iptables para Debian GNU/Linux
# criado por Tobias <tobias@gnu.eti.br>
# licenciado pela GPL v3
# versao 0.5 11/07/2011

#TODO
# criar possibilidade de ter mais de uma interface para
# rede interna e internet.

##### VARIAVEIS GLOBAIS
iptables=$(which iptables) #/sbin/iptables
rede_ip="192.168.20.0" #192.168.1.0
rede_mascara="255.255.255.0" #255.255.255.0
interface_rede_interna="eth0" #eth1 | vazio para pegar a primeira placa com ip
interface_internet="ppp0" #eth0 | vazio para pegar a primeira placa com ip
ssh="6543" #porta utilizada pelo sshd
# arquivo de log do firewall - opcional
# nao confundir com o -J log
log=""

# - FUNCOES EXTRAS - #
source funcoes.sh

######################
# - FUNCOES PADRAO - #
######################

function iniciar  {
    echoall "Iniciando firewal."    

    carrega_modulos
    limpa_regras
    politica_padrao
    salva_vidas
    seguranca
    compartilha_internet
    redireciona_squid

    # liberando a porta 80 com destino a internet
    #$iptables -A FORWARD -i $interface_rede_interna -p tcp --dport 80 -j ACCEPT #http

    # liberando a porta 443 com destino a internet
    #$iptables -A FORWARD -i $interface_rede_interna -p tcp --dport 443 -j ACCEPT #https

    # libera a porta 80 deste servidor
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 80 -j ACCEPT #www

    # libera a porta 3128 deste servidor
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 3128 -j ACCEPT #squid

    # liberando https deste servidor
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 443 -j ACCEPT #https
    #$iptables -A INPUT -p udp -s $rede_ip/$rede_mascara --dport 443 -j ACCEPT #https

    # liberando consulta DNS
    #$iptables -A INPUT -p udp -s $rede_ip/$rede_mascara --dport 53 -j ACCEPT #domain
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 53 -j ACCEPT #domain

    # liberando servidor rsync
        #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 873 -j ACCEPT #rsync
        #$iptables -A INPUT -p udp -s $rede_ip/$rede_mascara --dport 873 -j ACCEPT #rsync

    # liberando ftp
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 20 -j ACCEPT
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 21 -j ACCEPT

    # liberando sftp
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 115 -j ACCEPT

    # liberando Webmin
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 10000 -j ACCEPT

    # liberando e-mail
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 25 -j ACCEPT #mail
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 143 -j ACCEPT #imap2
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 220 -j ACCEPT #imap3

    # libera banco de dados firebird
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 3050 -j ACCEPT #fb_inet_serve

    # libera banco de dados MySQL
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 3306 -j ACCEPT #mysql
    #$iptables -A INPUT -p udp -s $rede_ip/$rede_mascara --dport 3306 -j ACCEPT #mysql
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 6446 -j ACCEPT #mysql-proxy
    #$iptables -A INPUT -p udp -s $rede_ip/$rede_mascara --dport 6446 -j ACCEPT #mysql-proxy

    # libera Sicoob - Cedente
    #$iptables -A FORWARD -p tcp -s $rede_ip/$rede_mascara --dport 5006 -j ACCEPT
    #$iptables -A FORWARD -p tcp -s $rede_ip/$rede_mascara --dport 8080 -j ACCEPT

    # liberando samba/compartilhamento de arquivos
    #$iptables -A INPUT -p udp -s $rede_ip/$rede_mascara --dport 137 -j ACCEPT #netbios-ns
    #$iptables -A INPUT -p udp -s $rede_ip/$rede_mascara --dport 138 -j ACCEPT #netbios-dgm
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 139 -j ACCEPT #netbios-ssn
    #$iptables -A INPUT -p tcp -s $rede_ip/$rede_mascara --dport 445 -j ACCEPT #microsoft-ds

    echoall "Firewall iniciado."
}

function parar  {
    echoall "Parando firewall."
    desfaz_seguranca
    limpa_regras
    politica_padrao
    salva_vidas
    echoall "Firewall parado."
}

function aceitar_tudo  {
    echoall "Aceitando todo o trafego."
    limpa_regras
    compartilha_internet
    redireciona_squid
    $iptables -A INPUT -j ACCEPT
    $iptables -A OUTPUT -j ACCEPT
    $iptables -A FORWARD -j ACCEPT
    echoall "Feito."
}

##########################
# - FIM FUNCOES PADRAO - #
##########################

# - CHECAGENS - #
checagens

case "$1" in
    "start"|"iniciar") iniciar ;;
    "stop"|"parar") parar ;;
    "restart"|"reiniciar") parar; iniciar ;;
    "limpar_regras") limpa_regras ;;
    "aceitar_tudo") aceitar_tudo ;;
    "-h") echo "Uso: $0 (start|iniciar) | (stop|parar) | (restart|reiniciar) | limpar_regras | aceitar_tudo" ;;
    *) iniciar;;
esac

# EOF

[/codesyntax]

 

funcoes.sh

[codesyntax lang=”bash”]

#!/bin/bash
# Este arquivo eh parte do script com regras iptables
# para Debian GNU/Linux
# criado por Tobias <tobias@gnu.eti.br>
# licenciado pela GPL v3

### BEGIN INIT INFO
# Provides:          gfirewall_funcoes
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog $network
# Should-Start:      gfirewall
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: firewall initscript
# Description:       GFirewall <gnu.eti.br>
### END INIT INFO

LANG=pt_BR.UTF-8

######################
# - FUNCOES EXTRAS - #
######################

function echoall {
    echo $1 2>&1 | tee -a $log
}

function carrega_modulos {
    echoall "Carregando modulos..."
    modulos=('ip_tables' 'ip_conntrack' 'ip_conntrack_ftp' 'iptable_nat' 'ip_nat_ftp' 'ipt_MASQUERADE' 'ip_conntrack_pptp' 'ip_nat_pptp')
    for modulo in "${modulos[@]}"; do
        r=$(modprobe $modulo 2>&1 )
        if [ "$?" -ne '0' ]; then
            echoall "Erro ao carregar o modulo $modulo:$r"
        fi
    done
    #echo "[OK]"
}

function limpa_regras  {
    echoall "Limpando regras... "
    $iptables -F #limpa as chains
    $iptables -X #apagar chains vazias
    $iptables -t nat -F #limpa tabela nata
    $iptables -t nat -X #apaga chains vazias na tabela nat
    $iptables -Z #zerar contadores
    #echo "[OK]"
}

function seguranca {
    echoall "Executando medidas de seguranca..."
    # ligando proteção para SYN flood.
    echo 1 > /proc/sys/net/ipv4/tcp_syncookies
    # Limite contra ping da morte e DoS
    $iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
    $iptables -A INPUT -p icmp --icmp-type echo-reply -m limit --limit 1/s -j DROP
    # Impede ip spoofing SAINDO da rede
    $iptables -A FORWARD -i $interface_rede_interna ! -s $rede_ip/$rede_mascara -j DROP
    # Configurando a proteção anti-spoofing
    for spoofing in /proc/sys/net/ipv4/conf/*/rp_filter; do
            echo "1" > $spoofing
    done
    # Impede que um atacante possa maliciosamente alterar alguma rota
    echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
    # Utilizado em diversos ataques, isso possibilita que o atacante determine o "caminho" que seu
    # pacote vai percorrer (roteadores) ate seu destino. Junto com spoof, isso se torna muito perigoso.
    echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
    # Protecao contra responses bogus
    echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

    # http://www.dicas-l.com.br/arquivo/como_agir_em_casos_de_ataque_do_tipo_denial_of_service_dos.php
    # http://sourceforge.net/projects/mod-qos/
    #iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --set
    #iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 60 --hitcount 6 -j DROP
    #echo "[OK]"

}

function desfaz_seguranca {
    echoall "Desfazendo medidas de seguranca..."
    echo 0 > /proc/sys/net/ipv4/tcp_syncookies
    $iptables -D INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
    $iptables -D INPUT -p icmp --icmp-type echo-reply -m limit --limit 1/s -j DROP
    $iptables -D FORWARD -i $interface_rede_interna ! -s $rede_ip/$rede_mascara -j DROP
    for spoofing in /proc/sys/net/ipv4/conf/*/rp_filter; do
            echo "0" > $spoofing
    done
    echo 1 > /proc/sys/net/ipv4/conf/all/accept_redirects
    echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
    echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
    #echo "[OK]"
}

function politica_padrao  {
    echoall "Definindo politica padrao..."
    $iptables -P INPUT DROP
    $iptables -P OUTPUT ACCEPT
    $iptables -P FORWARD DROP

    #$iptables -t filter -P INPUT DROP
    #$iptables -t filter -P OUTPUT ACCEPT
    #$iptables -t filter -P FORWARD DROP
    #$iptables -t nat -P PREROUTING ACCEPT
    #$iptables -t nat -P OUTPUT ACCEPT
    #$iptables -t nat -P POSTROUTING ACCEPT
    #$iptables -t mangle -P PREROUTING ACCEPT
    #$iptables -t mangle -P OUTPUT ACCEPT
    #echo "[OK]"
}

function salva_vidas  {
    echoall "Iniciando funcao \"salva vidas\"..."
    $iptables -A INPUT -i lo -j ACCEPT
    $iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    $iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
    # libera PING
    $iptables -A INPUT -p icmp -j ACCEPT
    # libera o SSH e faz log
    $iptables -A INPUT -p tcp --dport $ssh -j LOG
    $iptables -A INPUT -p tcp --dport $ssh -j ACCEPT
    #echo "[OK]"
}

function libera_porta  {
    if [ -z $1 ]; then
        echoall "Erro na funcao libera_porta: falta argumento!"
        exit 10;
    fi
    $iptables -A INPUT -p tcp --dport $1 -j ACCEPT
    $iptables -A INPUT -p udp --dport $1 -j ACCEPT
}

function bloqueia_porta  {
    if [ -z $1 ]; then
        echoall "Erro na funcao bloqueia_porta: falta argumento!"
        exit 10;
    fi
    $iptables -A INPUT -p tcp --dport $1 -j DROP
    $iptables -A INPUT -p udp --dport $1 -j DROP
}

function obtem_ip {
    # ifconfig eth0 |grep 'inet end'| cut -d : -f 2 | cut -d ' ' -f 2
    # ifconfig $1 | grep 'inet end.:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'

    if [ ! -z $1 ]; then
        ip=$(ifconfig $1 | grep "inet " | sed 's/^[^:]*: *//g;s/ .*//g')
    else
        # retorna todos os ips, exceto localhost
        ip=$(ifconfig  | grep 'inet '| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}')
    fi

    if [ ! -z $ip ]; then
        echo $ip
    else
        return 1
    fi
}

function obtem_mascara {

    if [ ! -z $1 ]; then
        mascara=$(ifconfig $1 | grep 'inet end.:'| grep -v '127.0.0.1' | cut -d: -f4)
    else
        # retorna todas as mascaras, exceto localhost
        mascara=$(ifconfig | grep 'inet end.:'| grep -v '127.0.0.1' | cut -d: -f4)
    fi

    echo $mascara
}

function lista_interfaces {
    # lista todas as interfaces ativas, exceto loopback
    for i in $(ifconfig | grep -vi 'loopback' | grep -i 'link encap' | cut -d ' ' -f 1); do
        echo $i
    done
}

function validar_ip {
    echo "$1" | egrep '^(((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))\.){3}((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))$'
    if [ $? -eq 0 ]; then
        return 0
    else
        return 1
    fi
}

function obtem_primeira_placa_com_ip {
    for iface in $(lista_interfaces); do
        ip=$(obtem_ip $iface)
        if [ "$?" -eq "0" ]; then
            echo "$ip $iface"
            return 0
        fi
        return 1
    done
}

function compartilha_internet  {
    echoall "Compartilhando conexao a internet..."
    # compartilha conexao com a internet
    echo 1 > /proc/sys/net/ipv4/ip_forward
    $iptables -t nat -A POSTROUTING -o $interface_internet -j MASQUERADE
    #echo "[OK]"
}

function redireciona_squid {
    echoall "Redirecionando trafego para o squid..."
    # redireciona trafego para o squid trasparente
    $iptables -t nat -A PREROUTING -s $rede_ip/$rede_mascara -p tcp --dport 80 -j REDIRECT --to-port 3128
    #echo "[OK]"
}

function checagens {
    if [ $(whoami) != "root" ]; then
        echoall "ERRO: por favor, execute o script de firewall com o usuario root."
        exit 2
    fi

    if [ -z $interface_rede_interna ]; then
        ip_interface=$(obtem_primeira_placa_com_ip)
        if [ $? -ne 0 ]; then
            echoall "ERRO: nao foi possivel determinar a interface da rede interna.";
        else
            read ip interface <<< $ip_interface
            interface_rede_interna=$interface
            rede_ip=$ip
        fi
    fi

    if [ -z $interface_internet ]; then
        interface_internet=$(obtem_primeira_placa_com_ip)
        if [ $? -ne 0 ]; then
            echoall "ERRO: nao foi possivel determinar a interface de acesso a internet.";
        fi
    fi

    if [ -z $rede_ip ]; then
        rede_ip=$(obtem_ip $interface_rede_interna)
        if [ -z $rede_ip ]; then
            echoall "ERRO: o endereco ip nao pode ser identificado."
        fi
    fi

    if [ -z $rede_mascara ]; then
        rede_mascara=$(obtem_mascara $interface_rede_interna)
        if [ -z $rede_mascara ]; then
            echoall "ERRO: a mascara de rede nao pode ser identificada."
        fi
    fi

}

#EOF

[/codesyntax]

Contribuições são muito bem vindas.

Referências:

http://wiki.debian.org/LSBInitScripts/DependencyBasedBoot

http://wiki.debian.org/LSBInitScripts

http://wiki.kartbuilding.net/index.php/Iptables_Firewall#LSB_Headers_for_Firewall_script