você está aqui: Home  → Arquivo de Mensagens

Ebook Gratuito: Dá para fazer em Shell?, com o Prof. Julio Neves

Implementando em 10 minutos um Firewall Pessoal via iptables

Colaboração: José Messias Alves da Silva

Data de Publicação: 02 de abril de 2008

Atualmente, vivemos em uma contínua guerra virtual, onde tentativas de invasão são frequentes não só em ambientes corporativos como também em ambientes domésticos. Assim, pretende-se mostrar aqui como se pode implementar um pequeno firewall pessoal como base no iptables, o filtro de pacotes instalado por padrão em todas as distribuições de GNU/Linux, com o intuito de aumentar a segurança das estações de trabalho de usuários domésticos. Para tanto, utilizar-se-á apenas a tabela filter do iptables, visto que para este caso as demais tabelas são desnecessárias.

Vale ressaltar que nessa dica não há uma rigidez na construção das regras para o firewall, visto que o que pode ser bom para um certo usuário pode não ser bom para outro.

Entretanto, a intenção aqui é procurar apresentar um conjunto comum de regras aplicáveis a todos, podendo posteriormente, de acordo com o usuário, ser realizado apenas algumas adaptações.

A dica baseia-se na distribuição Debian, porém, pode ser utilizada para todas as distribuições. Como requerimentos, caso ainda não estejam carregados, será necessário o acréscimo dos módulos do Kernel ip_tables e ipt_LOG

# modprobe ip_tables
# modprobe ipt_LOG

Verificando serviços instalados e portas abertas

O primeiro passo é verificar quais são os serviços que estão sendo executados na estação já que, em geral, de acordo com a instalação de uma dada distribuição, certos serviços já estarão rodando, tais como:

sshd Secure Shell Server, serviço de terminal remoto seguro.
http Servidor web Apache
rpcbind utilizado por alguns serviços de arquivos, como NFS. Seu uso deve ser evitado.

Para tanto, pode-se fazer uso das ferramentas netstat ou nmap.

Tendo nmap instalado na máquina, pode-se executar o seguinte comando para identificar os serviços e portas abertas na estação:

# nmap -sS Nome_da_sua_Maquina  ou Seu_endereco_IP
Starting Nmap 4.50 ( http://insecure.org ) at 2008-03-18 17:18 BRT
Interesting ports on Sua_Maquina (Seu endereco_IP):
Not shown: 1704 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
111/tcp  open  rpcbind
113/tcp  open  auth

Nmap done: 1 IP address (1 host up) scanned in 0.671 seconds

Pela saída do comando, podemos observar que há na estação os serviços ssh, o servidor web Apache (http), o serviço rpcbind (Remote Procedure Call, Chamada Remota de Procedimentos), utilizado pelo NFS para montar uma unidade remotamente. Há, também, o serviço auth, que é utilizado para identificação e autorização, muito freqüentemente usado por servidores de notícias, IRC (Internet Relay Chat) ou Correio.

Todos esse serviços da estação estão abertos a conexões provenientes de outras máquinas e, em geral, não se necessita disponibilizá-los, exceto feita ao serviço ssh, que poderá ser necessário para se conectar a partir de uma outra máquina e que se costuma liberar apenas se esta tiver um endereço IP fixo.

Assim, é necessário apenas escolher quais serviços se deseja disponiblizar o acesso externo. Para esta dica foi escolhido o seguinte esquema de filtragem:

  • Acesso total a estação localmente. Ou seja, todos os serviços devem estar disponíveis para o localhost ou endereço IP 127.0.0.1.

  • Tentativas de conexão originadas de uma máquina remota para os serviços rcpbind, http e auth devem ser bloqueadas.

  • Permitir acesso por meio do protocolo udp apenas para servidores DNS.

  • Permitir a acesso ssh apenas a apartir de certos endereços específicos, por exemplo, 192.168.0.10.

  • Conexões estabelecidas e já relacionadas a algum conexão devem ser autorizadas.

Nota: Convém comentar (para os leitores iniciantes) sobre os termos new, established e related, relacionados ao protocolo TCP. TCP é um protocolo orientado a Conexão. Por Orientado a Conexão entende-se que todos os pacotes chegarão ao destino, sem qualquer perda de pacotes em trânsito. Caso um pacote seja perdido, há a retransmissão do mesmo. Essas propriedades são obtidas por meio de um conjunto de flags. As principais flags são SYN (SYNchronize, Sincronizar) e ACK (ACKnowledge, Confirmar). Por exemplo, quando se clica em um determinado link no navegador, seu computador envia um pacote SYN para o servidor remoto que hospeda o link. Esse processo é o ínicio de nova conexão, representado por NEW.

Quando o servidor recebe o pedido que tem a flag SYN, envia um aviso de confirmação de volta para a sua máquina, fixando a ele uma flag SYN-ACK . Podemos chamar essa etapa de "relacionamento" da conexão, representada por RELATED. Assim que a sua máquina recebe o pacote SYN-ACK, ela responde com um pacote ACK final, que informa a máquina remota que o pacote foi realmente recebido. Nesse momento, a conexão está estabelecida, o que se representa por ESTABLISHED.

Esse mecanismo é chamado de Three-Way-Handshake.

  • Não permitir o ínicio de uma nova conexão (NEW) para a estação a partir de uma máquina remota, ou seja, conexões só devem ser iniciadas pela estação.

  • Permitir todas as conexões originadas a partir estação.

  • Restringir todas as demais conexões de entrada.

Construindo as Regras

Permitir a localhost acesso a tudo

iptables -A INPUT -s 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -s 127.0.0.1 -j ACCEPT

Permitir todas conexões tcp estabelecidas e já relacionadas a alguma conexão para a máquina

 iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

Permitir acesso pelo protocolo udp apenas para o servidor DNS, supondo que este seja 192.168.0.1

 iptables -A INPUT -p udp -s 192.168.0.1 -j ACCEPT

Permitir acesso SSH apenas a partir do IP 192.168.0.10

 iptables -A INPUT -p tcp -s $IP_LIBERADO --dport 22 -j ACCEPT

Permitir todas as conexões de saída a partir da máquina

 iptables -A OUTPUT -j ACCEPT

Deste ponto em diante, colocar-se-á Regras de Negação.

Negar todas as novos conexões tcp a partir de máquinas remotas, registrando as tentativas.

iptables -A INPUT -p tcp -m state --state NEW -j LOG
iptables -A INPUT -p tcp -m state --state NEW -j DROP

Bloquear a porta 80 do servidor web Apache da máquina e, da mesma forma, também registrar as tentativas de conexão.

iptables -A INPUT -p tcp -s 0/0 --dport 80 -j LOG
iptables -A INPUT -p tcp -s 0/0 --dport 80 -j DROP

Nota: A regra LOG sempre deve anteceder a respectiva regra de filtragem.

Bloquear os demais acessos a SSH para a máquina, registrando tentativas.

iptables -A INPUT -p tcp -s 0/0 --dport 22 -j LOG
iptables -A INPUT -p tcp -s 0/0 --dport 22 -j DROP

Por fim, negar tudo que não se enquadrar em nenhuma das regras.

iptables -A INPUT -j DROP
iptables -A FORWARD -j DROP

Elaborando um script para automatizar o processo

Para automatizar, cria-se um arquivo em /etc/init.d/firewall com o seguinte contéudo:

#!/bin/sh
#
# Exemplo de script Firewall Pessoal para GNU/Linux 2.6.x e iptables
#
# por Jose' Messias Alves da Silva
#
#

LO_IFACE="lo"
LO_IP="127.0.0.1"

IP_LIBERADO="192.168.0.10"
DNS="192.168.0.1"

IPTABLES="/sbin/iptables"

case "$1" in

start)

        echo -e 'Iniciando Firewall Pessoal..\n'

        # Carregando os Modulos do Kernel

        modprobe ip_tables
        modprobe ipt_LOG

        # LocalHost - Aceita todos os pacotes

        $IPTABLES -A INPUT -s $LO_IP -j ACCEPT
        $IPTABLES -A OUTPUT -s $LO_IP -j ACCEPT

        $IPTABLES -A OUTPUT -j ACCEPT

        $IPTABLES -A INPUT -p udp -s $DNS -j ACCEPT

        $IPTABLES -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

        $IPTABLES -A INPUT -p tcp -m state --state NEW -j LOG
        $IPTABLES -A INPUT -p tcp -m state --state NEW -j DROP

        $IPTABLES -A INPUT -p tcp -s 0/0 --dport 80 -j LOG
        $IPTABLES -A INPUT -p tcp -s 0/0 --dport 80 -j DROP

        # Permitir acesso SSH apenas a partir do IP 192.168.0.10
        $IPTABLES -A INPUT -p tcp -s $IP_LIBERADO --dport 22 -j ACCEPT

        #As demais tentativas a SSH, negar
        $IPTABLES -A INPUT -p tcp -s 0/0 --dport 22 -j LOG
        $IPTABLES -A INPUT -p tcp -s 0/0 --dport 22 -j DROP

        # Negar tudo que nao se enquadrar nas regras anteriores
        $IPTABLES -A INPUT -j DROP
        $IPTABLES -A FORWARD -j DROP

        echo -e 'Firewall Pessoal Iniciado ..\n'

;;

stop)

        echo -e 'Parando Firewall Pessoal ..\n'

        # Limpando regras
        $IPTABLES -F

;;

restart)

        echo -e 'Reiniciando Firewall Pessoal, aguarde ..\n'

        $0 stop
        sleep 2
        $0 start
;;

*)
        echo "Sintaxe: $0 [ start | stop | restart ]"
;;

esac

Após a criação do arquivo, é necessário torná-lo executável:

 # chmod +x /etc/init.d/firewall

Por fim, digita-se o seguinte comando para criar os links simbólicos nos diretórios de inicialização:

 # update-rc.d firewall defaults

Para iniciar o firewall, basta executar:

 # /etc/init.d/firewall start

ou

 # invoke-rc.d firewall start

Considerações Finais

Enfim, após a inicialização/execução do script as regras estarão carregadas no kernel, tendo se implementado um excelente firewall pessoal. Pode-se verificar se as regras foram corretamente aplicadas executando novamente o comando nmap, que mostrará que as portas estão filtradas pelo firewall:

 # nmap -sS Nome_da_sua_Maquina  ou Seu_endereco_IP -p 22,80,111,113

Ou simplesmente listando as regras utilizadas por meio do comando:

 # iptables -L

Ademais, essa dica serve para os usuários perceberem a importância da segurança também em suas estações, incentivar e estimular a criação de firewalls pessoais bem mais poderosos.

José Messias Alves da Silva é Matemático, Cientista da Computação pela UFPI, Especialista em Administração em Redes Linux e Coordenador Geral do Grupo de Usuários Debian do Piauí.



Veja a relação completa dos artigos de José Messias Alves da Silva