iptables

De LinuxPédia
Ir para: navegação, pesquisa

Definição

Netfilter é um software para filtrar pacotes que está inserido no kernel linux. Para operar o netfilter utilizamos o comando iptables. A idéia dessa página é servir de guia rápido para implementar regras de um firewall iptables.

Estrutura do Netfilter

Tabelas e cadeias

Tabelas

As tabelas são conjuntos de cadeias utilizadas para determinado fim.

  • Mangle – Tabela usada para alterar pacotes. Altera QOS por exemplo.
  • Nat – PREROUTING - altera o pacote antes de rotear; Isso ajuda a mudar o endereço IP dos pacotes para bater com o servidor local é usado pelo DNAT. POSTROUTING altera os pacotes que devem ser roteados no servidor destino é usado pelo SNAT.
  • Filter – A tabela padrão do iptables usada pra filtrar pacotes.Quando não especificamos nenhuma tabela a regra é adicionada na tabela filter.

Dentro de cada uma dessas tabelas temos as cadeias que são um conjunto de regras. Em cada cadeia as regras são verificadas de cima a baixo (da regra de menor múmero para a regra de maior número) e ao bater em uma regra a execução é parada e a ação programada é executada. Caso não bata em nenhuma regra a ação tomada será a política dessa cadeia.

  • Raw – PREROUTING; OUTPUT
  • Mangle – PREROUTING; POSTROUTING; INPUT; OTPUT; FORWARD
  • Nat – PREROUTING; POSTROUTING; OUTPUT
  • Filter – INPUT; FORWARD; OUTPUT

Cadeias

  • FORWARD – O que fui através do computador, que usa o gateway como caminho.
  • INPUT – Antes que seja entregado ao processo local.
  • OUTPUT – Logo depois e sair do processo local.
  • POSTROUTING – Logo antes de sair pela interface
  • PREROUTING – Assim que chega na interface.

A estrutura das tabelas e cadeias ao receber e enviar o pacote é um pouco complexa. Essa imagem é um diagrama de como o pacote flui no netfilter.

Iptables-1.png Fonte: https://cs.senecac.on.ca/~michal.heidenreich/ops335/journal.shtml

Uso

A ideia dessa sessão é mostrar os comandos mais comuns do iptables com exemplos. Para isso temos que explorar cada item de um comando comum.

Sintaxe dos comandos iptables:

Iptables-2.png Fonte: http://www.cnblogs.com/my_life/articles/3242602.html

Comandos

Comandos para exibir

-h ou --help mostra como utilizar o iptables
--line-numbers mostra o número de linhas da cadeia. Podemos inserir regras no número que queremos com o comando -I e deletar regras específicas com -D.
-n mostra os endereços númericos não resolvendo DNS.
-v produz uma saida verbose
-V ou --version mostra a versão do iptables
-Z cadeia-x ou --zero cadeia-x Zera a contagem de pacotes e bytes de uma cadeia de nome cadeia-x. Zera a de todas se nanhuma cadeia for especificada.

Normalmente quando quero exibir as regras do iptables utilizo o comando:

# iptables -L -n -v

Comandos para manipular o netfilter

-A ou --append adicionar a regra a uma cadeia.
-D ou --delete Deleta uma regra por descrição ou pelo número.
-X ou --delete-chain Deleta a cadeia
-E cadeia-x cadeia-nova ou --rename-chain cadeia-x cadeia-nova Muda o nome da cadeia de cadeia-x para cadeia-nova
-F cadeia-x ou --flush cadeia-x Deleta todas as regras da cadeia-x. Se não for especificado nenhuma cadeia apaga a regra de todas cadeias.
-I numero insere uma regra na cadeia na posição index. Se nenhuma posição for dada adiciona no topo da cadeia.
-L cadeia-x Lista as regras de uma cadeia cadeia-x. Se nenhuma cadeia for especificada lista conteúdo de todas as cadeias.
-N cadeia-x ou --new-chain cadeia-x Cria uma nova cadeia.
-P cadeia-x ação ou --policy cadeia-x ação Determinar a política da cadeia-x . A política é a ação tomada caso o pacote não bata em nenhuma regra.
-R cadeia-x numero regra ou --replace cadeia-x regra troca uma regra de numero igual a numero pela nova regra inserida.

Parâmetros

-p determina o protocolo (tcp udp icmp)
-m módulo do kernel (lenght; limit ...)
-s endereço de origem (ip X.X.X.X)
-d endereço de destino (ip X.X.X.X)
-i Interface entrada
-o Interface de saída
-f Pacotes fragmentados


Existem vários módulos que podemos usar (parâmetro -m), um que merece atenção especial é o --conntrack que rastreia uma conexão e determina o seu estado.

ESTABLISHED
A conexão que já foi iniciada com um pacote na direção contrária.
INVALID
Os pacotes que não pertencem as conexões rastreadas.
NEW
Pacotes que estão começando uma nova conexão.
RELATED
Pacotes que estão começando uma nova conexão, mas relacionadas com uma conexão existente (por exemplo, uma conexão para transferência de dados FTP).

A lógica de rastreamento de conexão do iptables permite regras plugins para ajudar a identificar conexões novas que estão relacionadas a conexão existentes. Esses plugins são necessários se desejamos fazer com que esses protocolos multiconexão atravessem corretamente o firewall.

Exemplos:

ip_conntrack_amanda ip_conntrack_ftp ip_conntrack_sip

No caso de um servidor sip por exemplo podemos usar um módulo para sip:

# modprobe ip_conntrack_sip ip_nat_sip

Ações (target)

-j ACCEPT Aceita o tráfego e não verifica o resto das regras
-j DROP para o processamento do pacote completamente e descarta o patoce.
-j REJECT retorna para o remetente do pacote alguma mensagem de erro e descarta o pacote
-j REDIRECT Redireciona o pacote para outro socket (IP+porta).
-j LOG registra pacotes que cairam na regra no arquivo /var/log/messagess. Podemos trocar o local de log se quisermos mas não é uma tarefa simples.
-j MASQUERADE Realiza o nat mascarando os IPs com um IP externo
-j DNAT Muda endereço/porta destino do NAT.
-j SNAT Muda endereço/porta origem do NAT.
-j QUEUE Manda o pacote para o userspace (envia para um código que não está no Kernel).
-j nome-cadeia Ao cair nessa regra a ação é direcionar o pacote para a cadeia de nome nome-cadeia.
-j RETURN Essa regra vai fazer com que o pacote pare de seguir na cadeia atual. Se essa cadeia foi chamada por outra, o pacote segue da próxima regra da cadeia anterior como se nada tivesse acontecido. Se essa cadeia for uma cadeia principal, o a política padrão é executada.

Aplicações práticas

A idéia dessa sessão é apresentar os módulos e parâmetros mais usados no iptables com exemplo para melhor entendimento.

iptables em aplicações práticas:

  1. Antes de qualquer coisa temos que ter em mente que o IP do localhost 127.0.0.1 TEM QUE ESTAR LIBERADO. Ocorre que algumas funções do sistema precisam que este IP esteja liberado.
  2. Temos que levar em consideração que fluxos UDP não são orientados a conexão como o TCP. Logo, os parâmetros de status de conexão como ESTABLISHED podem não funcionar bem..
  3. Para que os pacotes possam passar pelo firewall e serem encaminhados a outros destinos temos que ativar o forward com o comando: echo 1 > /proc/sys/net/ipv4/ip_forward
  4. Se for logar as regras, utilizar o módulo limit para limitar a quantidade de logs que são geradas por segundo.
  5. Para monitorar o log do iptables em tempo real o comando é: tail -f /var/log/messages
  6. Para grandes firewalls é interessante verificar somente os pacotes de novas conexões (--cstate NEW) sempre que possível.

IPs de origem

iptables -A INPUT -s X.X.X.X/Y

Verifica pacotes que tenham caiam na regra IP-origem=X.X.X.X e máscara=Y

Exemplos:

iptables -A INPUT -s 10.1.1.54/24 -j DROP

Este comando adiciona a regra (-A) a cadeia INPUT e a regra bate quando a origem do pacote está na rede 10.1.1.0 (IP+Máscara) e ao bater na regra o pacote é descartado (DROP).

Para a regra bater somente com o host que queremos a máscara tem que ser=32 (que significam todos os bits da máscara iguais a 1):

IPs de destino

iptables -A INPUT -d X.X.X.X/Y

verifica pacotes que tenham caiam na regra IP-destino=X.X.X.X e máscara=Y

Exemplo:

iptables -A FORWARD -d 10.1.1.10/32 -j DROP

Essa regra nega o pacote de passar através do servidor com o IP de destino = 10.1.1.10.

Diferente de

diferente de…: O símbolo para bloquear o diferente de é o operador !.

Exemplo:

iptables -A INPUT ! -s 10.1.1.54/24 -j ACCEPT

Aceita todos os pacotes com IP de origem diferente de 10.1.1.54.

Criar cadeia

iptables -N cadeia-x

Cria uma cadeia com o nome cadeia-x

Exemplos:

iptables -N GATE

Cria uma cadeia com o nome de GATE.

Deletar uma cadeia

  • iptables -X cadeia-x – Deleta uma cadeia de nome cadeia-x.

Obs: tem que deletar as referencias a cadeia antes de deletá-la.

Rastreando conexão

iptables -A INPUT -m conntrack --ctstate ''STATUS''

Verifica o status (de nome STATUS) da conexão para tomar a ação programada. Os status podem ser NEW;ESTABLISHED;RELATED ou INVALID.

Exemplos:

iptables -A INPUT -p tcp -m tcp --dport 22 -m conntrack --cstate '''NEW'''

Nesse exemplo estamos adicionando uma regra (-A) na cadeia INPUT protocolo TCP (-p tcp) porta 22 (-m tcp –dport 22) para aceitar somente pacotes de uma conexão nova (-m cconntrack --cstate NEW)

Permitir conexões estabelecidas:

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

Essa regra permite que a resposta de conexões efetuadas pelo servidor sejam aceitas. Tipo se acessarmos uma página da web conseguiremos, isso ocorre porque pedimos para receber a página da web e recebemos a resposta do servidor.

Várias portas

iptables -A INPUT -p tcp -m multiport (--dports ou --sports)
Regra para permitir ou negar várias portas com um só comando.

Exemplo:

iptables -A FORWARD -p tcp -m multiport --dports 80,443 -j ACCEPT

Libera as portas para atravessar o firewall desde que os pacotes tenham como destino as portas TCP 80 e 443.

Limita o tráfego em pacotes por segundo

-m limit --limit X/s
Aceita ou nega pacotes até X por segundo. Se a taxa ultrapassar esse valor, o iptables passa para próxima regra e analisa o resto da tabela normalmente.

Exemplo:

iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT

Aceita pacotes com a flag syn até a taxa de 1 pacote por segundo, caso haja mais de 1 pacote por segundo o firewall prossegue para próxima regra.

Bloqueia ou autoriza tráfego sainte por usuário ou grupo do sistema

Obs: Esse módulo é usado só com a chain OUTPUT e pode bloquear ou permitir qualquer pacote que seja criado por determinado usuário ou grupo

Os argumentos desse módulo podem ser:

--uid-owner -- userid especificado

--gid-owner -- Groupid especificado

--pid-owner -- número de processo específico

--sid-owner -- Pacote criado por processo concebido por session group

-- unclean -- EXPERIMENTAL, checa pacotes uspeitos.

Exemplo:

#iptables -A OUTPUT -m owner --gid-owner 81 -p udp -j DROP

Nesse exemplo dá drop em pacotes originados pelo groupid=81.

Limitar número de conexões por IP

Aplica a regra quando excede o valor de limite especificado por IP

Exemplo: Limitar a 1000 conexões simultâneas por IP:

iptables -A INPUT -m iplimit --iplimit-above 1000 -j REJECT

(Conexões acima de 1000 serão rejeitadas)

Limitar 10 conexões HTTP por rede classe C:

iptables -A INPUT -p tcp --syn --dport 80 -m iplimit --iplimit-above 10 --iplimit-mask 24 -j REJECT

Obs. Vi essa função no site do Netfilter http://www.netfilter.org/documentation/HOWTO/netfilter-extensions-HOWTO-3.html . Trata-se de novas extensões para o netfilter, eu pessoalmente não consegui habilitar essa funcionalidade. No caso de querer essa funcionalidade para barrar um ataque de negação de serviço (DOS), consegui minimizar esse ataque com esse script Script anti dos.

analisa por MAC

-m mac --mac-source AA:BB:CC:DD:EE:00
verifica se o MAC Address é igual a AA:BB:CC:DD:EE:00 e aplica a ação programada.

Exemplo:

iptables -t filter -A INPUT -m mac --mac-source 30:10:AD:B2:65:00 -j DROP

Descarta pacotes com o MAC Address igual a "30:10:AD:B2:65:00".

Verificar flags TCP

-m tcp --tcp-flags [flag]
Regra que bate com determinada flag TCP.

Exemplo:

iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,URG SYN,URG -j DROP

Regra verifica as flags (primeiro campo) [SYN,URG] e se as flags [SYN URG] estiverem habilitadas o pacote é descartado.

Pacotes fragmentados (-f)

Neste exemplo descartamos pacotes fragmentados:

iptables -A INPUT -f -j DROP

tipo de pacotes (boradcast multicast)

-m pkttype –pkt-type (multicast broadcast)
Analisa tipo de pacote broadcast, multicast.
iptables -A FORWARD -i eth0 -o eth0 -m pkttype --pkt-type multicast -j DROP  – Descarta pacotes multicast.

verifica por tamanho de pacote

Exemplos:

  • Bloqueia qualquer pacote ICMP maior que 30Kb
iptables -A INPUT -i eth0 -m length --length 30000: -j DROP 
  • Bloqueia qualquer pacote com o tamanho entre 20 e 2000 bytes
iptables -A INPUT -i eth0 -m length --length 20:2000 -j DROP

Por string

  • iptables -A INPUT -m string --string "X-Kazaa" -j DROP – Bloqueia pacotes que contenham a string X-kazaa.

Esse tipo de regra pode ser usado por exemplo para impedir download de arquivos .exe através de uma sessão HHTP:

iptables -A INPUT -m string --string ! ".exe" -j ACCEPT

Módulo time

O módulo time serve para determinar um horário ou um horário em alguns dias da semana para aplicar determinada regra.

Exemplos:

iptables -A INPUT -s 192.168.20.10 -p tcp --dport 10000 -m time --timestart 08:00 --timestop 18:00 -j DROP

Esta regra bloqueia pacotes do IP-origem 192.168.20.10, das 8 horas da manhã até às 18h.

iptables -A FORWARD -m string --algo bm --string "orkut" -m time --timestart 12:00 --timestop 14:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT

Esta regra aceita pacotes com a string "orkut" de 12h às 14h nos dias segunda, terça, quarta, quinta e sexta.

NAT

Para fazer o NAT:

iptables --table nat -A POSTROUTING --out-interface eth0 -j MASQUERADE

Para abrir a porta TCP 22 para o IP 10.0.2.5:

iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -j DNAT --to-destination 10.0.2.5

Fazer balanceamento de carga

O objetivo do balanceamento é o seguinte: encaminhar pacotes a dois servidores em modo round-robin para que cada hora um dos dois servidores responda à requisição que queremos.

iptables -A PREROUTING -t nat -d 200.177.177.1 -j DNAT --to 192.168.1.1-192.168.1.2

Nesse exemplo os pacotes que chegarem ao NAT IP público do servidor (200.177.177.1) ora será o encaminhadas para 192.168.1.1 ora para 192.168.1.2 poderíamos aumentar para mais servidores aumentando o range tipo --to 192.168.1.1-192.168.1.20 para 20 servidores.

L7 filter

No caso de ter o L7-filter no kernel (normalmente tem que recompilar o Kernel) a sintaxe é:

iptables -A FORWARD -m layer7 --l7proto msnmessenger -s 192.168.10.0/24 -j DROP

Nesse caso bloqueia protocolo msn messager.

No caso de usar o userspace, para mandar para o filter:

iptables -A INPUT -j NFQUEUE --queue-num 0

Port knocking

Port knocking é uma função que permite que para acessar determinada porta, antes tenhamos que “bater” em outra porta pré-determinada. Isso evita que a porta apareça como aberta para alguém que esteja fazendo portscan na máquina por exemplo. O netfilter não tem nativamente suporte a port knocking, mas podemos usar uma função chamada recent que pode gravar os pacotes que atendem a determinada condição e tomar decisões para esses pacotes por um período de tempo. Procedimento:

1 – Para criar o port knock precisaremos criar algumas cadeias:

 iptables -N KNOCK 
 iptables -N GATE1
 iptables -N PASSED

2 – Depois adicionamos na cadeia INPUT a linha

 iptables-A INPUT -j KNOCK

3 – Agora na cadeia KNOCK:

 iptables -A KNOCK -m recent --rcheck --seconds 30 --name AUTH1 -j PASSED 
 iptables -A KNOCK -j GATE

Nesta cadeia checamos se algum pacote já bateu em alguma regra recent na variável AUTH1 nos últimos 30 segundos, caso positivo passa esse pacote para a cadeia PASSED. Em caso negativo encaminhamos para cadeia GATE.

4 – Na cadeia GATE:

 iptables -A GATE -m recent --name AUTH1 --remove 
 iptables -A GATE -p tcp --dport 10000 -m recent --name AUTH1 --set -j DROP 
 iptables -A GATE -j DROP

Nessa cadeia removemos o conteúdo da variável AUTH1 na primeira regra. Na segunda regra verificamos caso algum pacote bata na porta 10000 colocamos o IP de origem na variável AUTH1 e descartamos o pacote.

5 – Na cadeia PASSED colocamos as portas que queremos abrir caso o knock seja bem sucedido. No exemplo essa porta é a porta 22.

 iptables -A PASSED -m recent --name AUTH1 --remove 
 iptables -A PASSED -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT 
 iptables -A PASSED -j GATE

As regras do firewall nesse exemplo com port knock ficam assim:

 iptables -A INPUT -s 127.0.0.1/32 -j ACCEPT 
 iptables -A INPUT -p udp -m udp --dport 53  -j ACCEPT 
 iptables -A INPUT -p udp -m udp --dport 67  -j ACCEPT 
 iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 
 iptables-A INPUT -j KNOCK

KNOCK

 iptables -A KNOCK -m recent --rcheck --seconds 30 --name AUTH1 -j PASSED 
 iptables -A KNOCK -j GATE

GATE

 iptables -A GATE -m recent --name AUTH1 --remove 
 iptables -A GATE -p tcp --dport 10000 -m recent --name AUTH1 --set -j DROP 
 iptables -A GATE -j DROP

PASSED

 iptables -A PASSED -m recent --name AUTH1 --remove 
 iptables -A PASSED -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT 
 iptables -A PASSED -j GATE

Isso faz com que só seja possível acessar a porta TCP 22 após um pacote bater na porta 10000 do servidor dentro de 30 segundos.

Arquivo de regras e iniciar o firewall no boot

Arquivo com as regras do iptables:

Para reiniciar o computador e mantermos as nossas regras, precisamos salvá-las em um arquivo. Fazemos isso com o comando: iptables-save > /Arquivo

Salva a configuração no arquivo /home/iptables.txt:

iptables-save > /home/iptables.txt

Para resturar as regras a partir de um arquivo:

iptables-restore < /home/iptables.txt

Nesse caso restaura a configuração do arquivo para rodar.

O arquivo gerado é mais ou menos assim:

# Generated by iptables-save v1.4.21 on Wed Dec 17 12:29:10 2014
*filter 
:INPUT DROP [0:0] 
:FORWARD ACCEPT [0:0] 
:OUTPUT ACCEPT [22:3641] 
-A INPUT -s 127.0.0.1/32 -j ACCEPT 
-A INPUT -p udp -m udp --dport 53  -j ACCEPT 
-A INPUT -p udp -m udp --dport 67  -j ACCEPT 
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 
-A INPUT -j KNOCKING 
COMMIT 
# Completed on Wed Dec 17 12:29:10 2014 

Percebemos que os comando são colocados quase exatamente da mesma maneira que fazemos na CLI com a diferença que não tem o comando iptables antes.

  • Colocar o firewall para iniciar automaticamente (existe uma solução pronta chamada iptables-persist):

depois de aplicar as regras fazemos:

1 – Salvar as regras com o comando iptables-save:

# iptables-save > /home/iptables.txt

2 – Fazer um script para chamar o firewall. Criamos um arquivo firewall.sh dessa maneira:

#/bin/sh -e 
iptables-restore < /home/iptables.txt 
exit 0

3 – Damos permissão de execução para o arquivo e copiamos ele para /etc/init.d/

chmod +x Firewall.sh
cp Firewall.sh /etc/init.d/Firewall.sh

4 – Depois colocamos o script para iniciar no boot com o comando update-rc.d:

update-rc.d Firewall.sh defaults

Essa página é só uma introdução ao netfilter. Essa ferramenta tem muitas funcionalidades e é impossível englobar todas nesse tutorial. O objetivo é servir de base para um firewall simples e explicitar o funcionamento dessa ferramenta.

Fontes

Livro: Linux iptables pocket reference Autor: Gregor N. Purdy Editora: O'reilly

iptel Acessado em 17/12/2014

Geek Stuff Acessado em 17/12/2014

viva o linux Acessado em 17/12/2014

cnblogs Acessado em 17/12/2014

senecac Acessado em 18/12/2014

dicas-l Acessado em 18/12/2014

microhowto Acessado em 18/12/2014

Links Externos

debian.org

wikibooks

netfilter.org

netfilter.org/netfilter-extensions