01 setembro 2008

IPTABLES - Implementado um firewall em apenas 10 minutos

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: <Leia o post sobre NMAP>

# 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

o 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 servdior 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.

Fonte: José Messias Alves da Silva (Dicas-L) - http://www.Dicas-L.com.br/

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í.

Postar um comentário