De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.


iptables howto (Básico)

Colaboração: Rubens Queiroz de Almeida

Data de Publicação: 08 de setembro de 2015

Este texto é uma tradução livre do documento Basic iptables howto. O documento original foi publicado sob uma licença livre, que permite seu uso e compartilhamento. Comentários e sugestões para o aperfeiçoamento desta tradução são muito bem-vindos.

Iptables é um sistema de firewall, instalado por padrão em todas as distribuições oficiais Ubuntu (Ubuntu, Kubuntu, Xubuntu). Ao instalar o Ubuntu, iptables está lá, mas permitindo por padrão todo tipo de tráfego. A versão 8.04 do Ubuntu é distribuída com o programa ufw, que permite gerenciar as regras do iptables mais facilmente.

Existe uma grande quantidade de informação sobre iptables, mas muita desta informação é razoavelmente complexa, e se você quer realizar apenas algumas funções mais básicas, este tutorial é para você.

Comandos Básicos

O comando

$ sudo iptables -L

lista as regras definidas no iptables. Se você acabou de configurar o seu servidor, não existirá nenhuma regra definida, e você deverá ver:

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Opções básicas

Descrevemos a seguir algumas das opções do iptables que você verá neste tutorial. Não se preocupe em entender tudo agora, mas lembre-se de retornar e consultar esta lista à medida em que você encontre novas opções.

Diretiva Explicação
-A Adicione esta regra à cadeia de regras. Cadeias válidas para o que estamos fazendo são INPUT, FORWARD e OUTPUT, mas na maior parte dos casos nós usamos INPUT, o que afeta apenas o tráfego recebido.
-L Lista as regras em vigor
-m conntrack Permite que as regras de filtragem sejam atendidas com base no estado da conexão. Permite o uso da opção --ctstate.
--ctstate Define a lista de estados aos quais a regra se aplica. Estados válidos são:
+ NEW - A conexão ainda não foi vista
+ RELATED - A conexão é nova, mas está relacionada a outra conexão já permitida
+ ESTABLISHED - A conexão já está estabelecida
+ INVALID - Por alguma razão o tráfego não pôde ser identificado.
-m limit Requer que a regra seja atendida apenas um número limitado de vezes. Permite o uso da opção --limit. Útil para limitar as regras de logging
+ --limit - A taxa máxima de casamento da regra, dada como um número seguido por "/second", "/minute", "/hour", ou "/day", dependendo da frequência com que você deseja que a regra seja atendida. Se esta opção não for usada ou a opção -m limit for usada o default é "3/hour".
-p O protocolo de conexão utilizado
--dport a(s) porta(s) de destino exigidas para esta regra. Apenas uma porta pode ser especificada ou então uma faixa dada como start:end, que irá satisfazer a todas as portas especificadas no intervalo, incluindo a porta de início e a porta de fim
-j Pula para o alvo especificado. Por default, o iptables permite quatro alvos:
+ ACCEPT - aceita o pacote e encerra o processamento das regras nesta cadeia.
+ REJECT - Rejeita o pacote e notifica o remetente do ocorrido, e encerra o processamento das regras nesta cadeia.
+ DROP - Ignora o pacote silenciosamente, e encerra o processamento das regras nesta cadeia
+ LOG - Loga o pacote e continua o processamento das demais regras nesta cadeia. Permite o uso das opções --log-prefix e --log-level
--log-prefix ao logar, coloque este texto antes da mensagem de log. Use aspas duplas ao redor do texto a ser usado
--log-level logar os eventos usando o nível de syslog especificado. 7 é uma boa escolha, a menos que você especificamente precise de algo mais
-i Válido apenas se o pacote estiver entrando na interface especificada
-I insere uma regra. Aceita duas opções, a cadeia na qual inserir a regra e o número que a regra deve receber.
-I INPUT 5 insere a regra na cadeia INPUT e a torna a quinta regra na lista.
-v Exibe mais informação na saída. Útil se você possui regras que parecem semelhantes sem usar -v
-s --source endereço (máscara) especificando a origem
-d --destination endereço (máscara) especificando o destino
-o --out-interface nome da interface de rede de saída ([+] para coringa)

Autorizando Sessões Estabelecidas

Podemos autorizar que sessões estabelecidas recebam tráfego:

$ sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

A regra acima não possui espaços de nenhum dos lados da vírgula em ESTABLISHED,RELATED

Se a linha acima não funcionar, você pode estar em um VPS castrado cujo provedor não tornou a extensão disponível, neste caso uma versão inferior pode ser usada como último recurso:

$ sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Permitindo Tráfego com destino a portas específicas

Você pode começar bloqueando o tráfego, mas caso você esteja usando SSH, será necessário autorizar conexões SSH antes de bloquear o resto.

Para autorizar o tráfego de entrada na porta SSH default (22), você pode instruir ao iptables para autorizar todo o tráfego TCP que chegar naquela porta.

$ sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT

Consultando novamente a lista acima, podemos ver que isto diz ao iptables:

  • adicione esta regra à cadeia de entrada (-A INPUT), então o tráfego de entrada é verificado;
  • verifique se é uma conexão TCP (-p tcp);
  • se for, verifique se os dados vão para a porta SSH (--dport ssh);
  • caso seja, aceitar a entrada (-j ACCEPT).

Vamos verificar as regras: (apenas as primeiras linhas exibidas, você verá mais)

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTAB
LISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh

Agora, vamos autorizar todo o tráfego web:

$ sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Verificando as nossas regras temos:

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www

Nós autorizamos todo tráfego TCP para as portas ssh e web, mas como não bloqueamos nada, todo tráfego ainda pode entrar.

Bloqueando tráfego

Uma vez que se tenha decidido aceitar um pacote, nenhuma outra regra o afetará. Como nossas regras autorizando tráfego ssh e web foram definidas primeiro, e como nossa regra bloqueando todo o tráfego veio em seguida,nós ainda podemos aceitar o tráfego que desejamos. Tudo que precisamos fazer é colocar a regra bloqueando todo o tráfego ao final.

$ sudo iptables -A INPUT -j DROP
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
DROP       all  --  anywhere             anywhere

Como não especificamos uma interface ou protocolo, qualquer tráfego para qualquer porta, em qualquer interface, será bloqueado, exceto para as portas ssh e web.

Editando iptables

O único problema com nossa configuração até agora é que até mesmo a porta loopback está bloqueada. Nós poderíamos ter escrito a regra drop apenas para a interface eth0, especificando -i eth0, mas nós poderíamos também ter acrescentado uma regra para a interface loopback. Se adicionarmos esta regra, será tarde demais, pois todo o tráfego já terá sido rejeitado. Nós precisamos inserir a regra antes disto. Como isto é muito tráfego, vamos inserir esta regra primeiro, para ser processada antes de todas as demais.

$ sudo iptables -I INPUT 1 -i lo -j ACCEPT
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
DROP       all  --  anywhere             anywhere

A primeira e a última linha são muito parecidas, então vamos listar o iptables em mais detalhes.

$ sudo iptables -L -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts  bytes target prot opt in     out      source              destination
0     0     ACCEPT all  --  lo     any     anywhere             anywhere
0     0     ACCEPT all  --  any    any     anywhere             anywhere state RELATED,ESTABLISHED
0     0     ACCEPT tcp  --  any    any     anywhere             anywhere tcp dpt:ssh
0     0     ACCEPT tcp  --  any    any     anywhere             anywhere tcp dpt:www
0     0     DROP   all  --  any    any     anywhere             anywhere

Você pode ver muito mais informação. Esta regra é na verdade muito importante, pois muitos programas usam a interface loopback para comunicarem entre si. Se você não lhes permitir que conversem, você pode comprometer o funcionamento destes programas.

Logging

Nos exemplos acima, nenhum tráfego será logado. Se você quiser logar os pacotes rejeitados (dropped) no syslog do sistema, esta seria a maneira mais rápida:

$ sudo iptables -I INPUT 5 -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

Veja a seção de dicas para mais ideias sobre registro de ocorrências (logging)

Salvando iptables

Ao rebootar a máquina, a configuração iptables desaparece. Ao invés de digitar estas regras todas as vezes que a máquina rebootar, entretanto, você pode salvar a configuração e iniciá-la automáticamente. Para salvar a configuração, você pode usar os comandos iptables-save e iptables-restore.

Configuração para a inicialização

IMPORTANTE: iptables e NetworkManager podem conflitar. Se você valoriza a segurança a ponto de instalar um firewall, você pode não querer confiar no NetworkManager. Observe também que o NetworkManager e o iptables possuem objetivos opostos. iptables visa bloquear qualquer tráfego suspeito. NetworkManager visa mantê-lo conectado o tempo todo. Então, se você deseja segurança o tempo todo, execute iptables durante o boot. Se você deseja segurança apenas parte do tempo, NetworkManager pode ser a escolha correta.

ALERTA: Se você usa o NetworkManager (instalado por default na versão Feisty e posteriores), estes passos irão impossibilitá-lo de usar o NetworkManager para as interfaces que você modificar. Por favor, ao invés disto, siga os passos descritos na próxima seção.

NOTA: Aparentemente na versão Hardy, o NetworkManager tem um problema em salvar e restaurar as regras do iptables corretamente quando se usa o método da próxima seção. Este primeiro método parece funcionar. Se você pensa o contrário, por favor, atualize esta nota.

Salve as suas regras de firewall em um arquivo

$ sudo sh -c "iptables-save > /etc/iptables.rules"

Neste ponto você tem muitas opções. Você pode fazer mudanças no arquivo /etc/network/interfaces ou acrescentar scripts ao diretório /etc/network/if-pre-up.d/ e /etc/network/if-post-down.d/ para alcançar uma funcionalidade equivalente. A solução dos scripts permite um pouco mais de flexibilidade.

Solução #1 - /etc/network/interfaces

NOTA: seja cuidadoso - especificar diretivas incorretas de configuração na interface pode desabilitar todas as interfaces, impedindo o seu acesso à máquina remota.

Modifique o arquivo de configuração /etc/network/interfaces para aplicar as regras automaticamente. Você precisa conhecer a interface que está usando para aplicar as regras - se não sabe, você provavelmente está usando a interface eth0. Verifique com o comando a seguir para verificar se existe alguma interface wireless:

iwconfig

Se você obter uma saída semelhante a que se segue, então você não possui nenhuma interface wireless e a sua melhor aposta é provavelmente eth0.

$ iwconfig
lo        no wireless extensions.
eth0      no wireless extensions.

Quando você descobrir a interface que está usando, edite (usando sudo) o arquivo /etc/network/interfaces:

$ sudo nano /etc/network/interfaces

No arquivo, procure pela interface que você descobriu, e no final das linhas relacionados para aquela interface, acrescente as linhas:

pre-up iptables-restore < /etc/iptables.rules

Você pode também preparar um conjunto de regras para descarte de pacotes (down rules), salve-as em um segundo arquivo /etc/iptables.downrules e aplique-as automaticamente usando os passos acima:

post-down iptables-restore < /etc/iptables.downrules

Um exemplo totalmente funcional usando ambos os passos acima:

auto eth0
iface eth0 inet dhcp
  pre-up iptables-restore < /etc/iptables.rules
  post-down iptables-restore < /etc/iptables.downrules

Você pode também querer manter informação de contadores de bytes e pacotes.

$ sudo sh -c "iptables-save -c > /etc/iptables.rules"

O comando acima irá salvar o conjunto completo de regras em um arquivo chamado /etc/iptables.rules com os contadores de bytes e pacotes ainda intactos.

Solução #2 /etc/network/if-pre-up.d e ../if-post-down.d

NOTA: esta solução usa iptables-save -c para salvar os contadores. Remova a diretiva -c para salvar apenas as regras.

Alternativamente, você poderia acrescentar os comandos iptables-restore e iptables-save aos diretórios if-pre-up.d e if-post-down.d no diretório /etc/network ao invés de modificar o arquivo /etc/network/interface diretamente.

NOTA: scripts nos diretórios if-pre-up.d and if-post-down.d não podem conter pontos em seus nomes.

O script /etc/network/if-pre-up.d/iptablesload conterá:

#!/bin/sh
iptables-restore < /etc/iptables.rules
exit 0

e o arquivo /etc/network/if-post-down.d/iptablessave conterá:

#!/bin/sh
iptables-save -c > /etc/iptables.rules
if [ -f /etc/iptables.downrules ]; then
   iptables-restore < /etc/iptables.downrules
fi
exit 0

Certifique-se de que ambos os scripts possuem permissão de execução:

$ sudo chmod +x /etc/network/if-post-down.d/iptablessave
$ sudo chmod +x /etc/network/if-pre-up.d/iptablesload

Solução #3 iptables-persistent

Instale e uso o pacote iptables-persistent.

Configuração de inicialização para o NetworkManager

O NetworkManager inclui a habilidade de rodar scripts quando ativa ou desativa uma interface. Para salvar as regras do iptables no shutdown, e restaurá-las na inicialização, criaremos um destes scripts. Para começar, pressione as teclas Alt+F2 e emita este comando:

Ubuntu:

$ gksudo gedit /etc/NetworkManager/dispatcher.d/01firewall

Kubuntu:

$ kdesu kate /etc/NetworkManager/dispatcher.d/01firewall

Em seguida, cole este script em seu editor, salve, e saia do editor.

if [ -x /usr/bin/logger ]; then
        LOGGER="/usr/bin/logger -s -p daemon.info -t FirewallHandler"
else
        LOGGER=echo
fi

case "$2" in
        up)
                if [ ! -r /etc/iptables.rules ]; then
                        ${LOGGER} "No iptables rules exist to restore."
                        return
                fi
                if [ ! -x /sbin/iptables-restore ]; then
                        ${LOGGER} "No program exists to restore iptables rules."
                        return
                fi
                ${LOGGER} "Restoring iptables rules"
                /sbin/iptables-restore -c < /etc/iptables.rules
                ;;
        down)
                if [ ! -x /sbin/iptables-save ]; then
                        ${LOGGER} "No program exists to save iptables rules."
                        return
                fi
                ${LOGGER} "Saving iptables rules."
                /sbin/iptables-save -c > /etc/iptables.rules
                ;;
        *)
                ;;
esac

Finalmente, precisamos nos certificar de que o NetworkManager pode executar este script. Em uma janela de terminal, digite este comando:

$ sudo chmod +x /etc/NetworkManager/dispatcher.d/01firewall

Dicas

Se você edita o iptables regularmente:

Os passos acima explicam como configurar as regras de seu firewall e assumem que elas serão relativamente estáticas (e para a maior parte das pessoas elas devem ser). Mas se você realiza muito trabalho de desenvolvimento, você pode querer que as suas regras sejam salvas todas as vezes em que o sistema rebootar. Você pode acrescentar uma linha como esta ao arquivo /etc/network/interfaces:

pre-up iptables-restore < /etc/iptables.rules post-down iptables-save > /etc/iptables.rules

A linha post-down iptables-save > /etc/iptables.rules irá salvar as regras a serem usadas no próximo boot.

Usando iptables-save/restore para testar as regras

Se você edita as regras do iptables além deste tutorial, você pode querer usar os comandos iptables-save e iptables-restore para editar e testar as suas regras.

Para isto, abra o arquivo de regras em seu editor de textos preferido (neste caso gedit).

$ sudo sh -c "iptables-save > /etc/iptables.rules"
$ gksudo gedit /etc/iptables.rules

Você terá um arquivo semelhante a (seguindo o exemplo acima):

# Generated by iptables-save v1.3.1 on Sun Apr 23 06:19:53 2006
*filter
:INPUT ACCEPT [368:102354]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [92952:20764374]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A INPUT -j DROP
COMMIT
# Completed on Sun Apr 23 06:19:53 2006

Observe que estes são comandos iptables menos o comando iptable. Sinta-se a vontade para editar estes comandos em um arquivo e salvá-los ao terminar. Para testar, simplesmente digite:

$ sudo iptables-restore < /etc/iptables.rules

NOTA: A partir da versão 1.4.1.1-1 do iptables ou versões superiores, um script lhe permite testar novas regras sem correr o risco de tornar o seu servidor remoto inacessível. Se você estiver aplicando as regras em um servidor remoto, você deve antes testar as regras com o comando:

$ sudo iptables-apply /etc/iptables.rules

Aopis testar, se você ainda não acrescentou o comando iptables-save ao arquivo /etc/network/interfaces, lembre-se de executar o comando abaixo para não perder as suas mudanças.

$ sudo sh -c "iptables-save > /etc/iptables.rules"

Logs mais detalhados

Para registrar os eventos mais detalhadamente no syslog do sistema, você pode criar uma cadeia adicional de regras. Este é um exemplo bastante simples do meu arquivo /etc/iptables.rules mostrando como eu configuro o meu iptables para gravar os dados do log no syslog.

# Generated by iptables-save v1.3.1 on Sun Apr 23 05:32:09 2006
*filter
:INPUT ACCEPT [273:55355]
:FORWARD ACCEPT [0:0]
:LOGNDROP - [0:0]
:OUTPUT ACCEPT [92376:20668252]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j LOGNDROP
-A LOGNDROP -p tcp -m limit --limit 5/min -j LOG --log-prefix "Denied TCP: " --log-level 7
-A LOGNDROP -p udp -m limit --limit 5/min -j LOG --log-prefix "Denied UDP: " --log-level 7
-A LOGNDROP -p icmp -m limit --limit 5/min -j LOG --log-prefix "Denied ICMP: " --log-level 7
-A LOGNDROP -j DROP
COMMIT
# Completed on Sun Apr 23 05:32:09 2006

Observe que existe uma nova cadeia de regras chamada LOGNDROP no topo do arquivo. Da mesma forma, o DROP padrão no final da cadeia INPUT de regras é substituído por LOGNDROP e adiciona descrições de protocolo de forma que faça sentido analisar o log. Finalmente, nós rejeitamos (DROP) o tráfego no final da cadeia LOGNDROP. As linhas a seguir dão uma ideia melhor do que está acontecendo.

--limit define o número de vezes que a mesma regra deve ser logada no syslog
--log-prefix "Denied..." adiciona um prefixo para tornar a localização no syslog mais fácil
--log-level 7 define o nível do syslog para informativo (consulte a documentação do syslog para mais informações -- man syslog --, mas provavelmente você não precisa)

Desativação do firewall

Se você precisa desativar o firewall temporariamente, você pode eliminar todas as regras usando o comando

$ sudo iptables -F

ALERTA: se você estiver conectado via ssh, este comando poderá bloquear seu acesso à máquina.

Alternativamente, você pode criar um script usando um editor de textos, como o editor nano:

$ sudo nano -w /root/fw.stop
echo "Stopping firewall and allowing everyone..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Certifique-se de que o script pode ser executado:

$ sudo chmod +x /root/fw.stop

Você pode executar o script da seguinte forma:

$ sudo /root/fw.stop

Configuração simplificada por meio de uma interface gráfica (GUI - Graphical User Interface)

UFW & GUFW

GUFW - Gufw é uma interface gráfica para o UFW (Uncomplicated Firewall).

Firestarter

Um usuário novato pode usar o Firestarter (interface gráfica), disponível em repositórios (Synaptic ou apt-get) para configurar as regras do iptables, sem precisar conhecer as regras da linha de comandos. Mas consulte o tutorial. A configuração é fácil, mas pode não ser o suficiente para o usuário avançado. Entretanto, deve ser o suficiente para a maioria dos usuários domésticos ... A configuração sugerida de saída é restritiva, permitindo, a partir da aba "policy", o desbloqueio (whitelisting) de cada tipo de conexão quando você precisar (porta 80 para http, 443 para https, 1863 para chat msn, e assim por diante). Você pode também usá-lo para visualizar as conexões ativas saindo e entrando de seu computador. O firewall permanece ativo uma vez que tenha sido configurado usando o wizard. Usuários de conexões discadas precisam configurá-lo para ser ativado automaticamente.

Homepage firestarter - (novamente, disponível nos repositórios, não é necessária a compilação. Tutorial em http://www.fs-security.com/docs/tutorial.php

Observação importante: O programa Firestarter não é atualizado desde 2005 e é considerado como abandonado pela comunidade: Em https://apps.ubuntu.com/cat/applications/quantal/firestarter/ encontramos a mensagem: Firestarter não é mais mantido e não possui alguns recursos críticos como suporte a IPv6, então aconselhamos os usuários a buscar alternativas mais modernas como gufw.

Observe que o Firestarter conflita com ufw

Informação adicional

Adicionar comentário

* Campos obrigatórios
5000
Powered by Commentics

Comentários

Nenhum comentário ainda. Seja o primeiro!


Veja a relação completa dos artigos de Rubens Queiroz de Almeida