O iptables é uma ferramenta Linux que controla regras de firewall, redirecionamento de portas, NAT, etc, a nível de Kernel.
Não pretendo entrar em detalhes teóricos aqui sobre a ferramenta, mas apenas mostrar - de forma prática - o que se pode fazer com ela :)
Antes de começar a se aventurar com o iptables é necessário conhecer um pouco da sua estrutura, ou como são armazenadas as informações que passamos para ele.
O iptables se utiliza de tabelas, chains e roles.
De uma forma um tanto simplista pense assim: as tabelas armazenam chains, chains armazenam roles.
As roles são as regras que enviamos manualmente para o iptables.
Existem três tabelas no iptables: filter (a default), nat e mangle. Estas contém as seguintes chains:
1. Filter: INPUT, OUTPUT e FORWARD
2. Nat: PREROUTING, OUTPUT, POSTROUTING
3. Mangle: INPUT, FORWARD, PREROUTING, POSTROUTING, OUTPUT
Os chains, por sua vez, podem ser de dois tipos:
1. Chains embutidos: INPUT, OUTPUT e FORWARD
2. Chains criados pelo usuario.
As chains do sistema devem ser especificadas sempre com letras maiúsculas.
Vamos ao que interessa.. :)
Bloquear PING em 127.0.0.1
# iptables -t filter -A INPUT -p icmp -d 127.0.0.1 -j DROP
Tradução: bloqueie (DROP) todos os pacotes ICMP (-p icmp) de entrada (INPUT) onde o destino (-d) seja o host 127.0.0.1
Tente dar um ping agora em 127.0.0.1... :P
Verificar Regras
iptables -t -L
Opcoes:
-v: verbose
-n: mostra hosts de forma numérica
-x: mostra faixa de portas
--line-number: mostra o número da regra. Útil para quando se deseja apagar ou editar uma role (index).
Vamos ver a regra que cadastramos a cima:
# iptables -L
Como a tabela filter é a padrão não precisamos especificar ela aqui.
Para visualizar as regras da chain INPUT, por exemplo:
# iptables -t filter -L INPUT -nv
Para listar todas as regras NAT
# iptables -t nat -L -nv --line-numbers
Obs: Utilizo -nv para traduzir o nome de hosts para IP e trazer mais informações. O --line-numbers é útil para retornar o index da regra. Note que o index é sequencial dentro de cada chains e ao apagar alguma regra o index se reorganiza.
Editar regras - R
Utiliza-se a mesma sintaxe que utilizamos na criação da regra, mas trocamos o -A por -R e informamos o index da mesma.
# iptables -t filter -R INPUT 1 -p icmp -d 127.0.0.1 -j ACCEPT
Neste exemplo trocamos DROP por ACCEP, permitindo assim o recebimento de pacote novamente.
Apagar uma regra - D
Podemos apagar uma regra pelo seu index:
# iptables -t filter -D INPUT 1
Ou repetindo a sintaxe de criação, trocando -A por -D
# iptables -t filter -D INPUT -p icmp -d 127.0.0.1 -j DROP
Inserir uma regra em uma posição diferente
Por padrão, cada regra inserida fica no final da chain especificada.
O iptables trabalha de forma seguencial, e um pacote somente passa para a regra posterior se não foi descartado na regra anterior. Por isso, muitas vezes teremos que ter cuidado para não fazer uma regra tropeçar na outra, e adicionar a role em uma posição especifica. Vamos ao mesmo exemplo, mas agora imaginando que temos várias regras no iptables e queremos adicionar esta nova na posição 1 da chain INPUT da tabela filter:
# iptables -t nat -I INPUT 1 -p icmp -d 127.0.0.1 -j DROP
Apagando regras
iptables <-t [filter, nat, mangle]> -F
Exemplo 1: apagar todas as regras da tabela filter (como ela é a padrão, nao precisa ser especificada)
# iptables -F
Exemplo 2: apagar todas as regras do chains INPUT da tabela filter
# iptables -t filter -F INPUT
Exemplo 3: apagar todas as regras da tabela NAT
# iptables -t nat -F
Parâmetros
Alguns parâmetros que podemos utilizar no cadastro de regras:
i: interface de entrada (ppp0, ppp+, eth0, etc)
o: interface de saída
-p: protocolo
--sport: porta de origem
--dport: porta de destino
Obs: ppp+ representa todos as conexões ppp. Utilize o "+" como coringa.
Bloqueando pacotes SYN
# iptables -t filter -A INPUT -p tcp --syn --dport 23 -i ppp0 -j DROP
Bloquear (DROP) todos os pacoes syn (--syn) do protocolo tcp (-p tcp) com destino a porta 23 (--dport 23) que venham da interface ppp0 (-i ppp0)
Exceções (!)
Exemplo 1: Bloquear todos os pacoes vindos de 200.1.2.3, exceto TCP
# iptables -t filter -A INPUT -s 200.1.2.3 ! -p tcp -j DROP
Exemplo 2: Bloquear todos os pacoes, execto os de 192.168.2.1
# iptables -t filter -A INPUT ! -s 192.168.2.1 -j DROP
Exemplo 3: Bloquear todos os pacotes, exceto oque que iniciam conexões (syn), execto para os pacotes vindos pela interface eth0
# iptables -t filter -A INPUT -p tcp ! --syn -s 200.1.2.3 ! - i eth0 -j DROP
Alvos (-j)
Cada regra é direcionada para um alvo, ou seja, o que se deve fazer com o pacote. Até aqui vimos dois alvos: ACCPET e DROP. Porém, existem outros:
ACCEPT: aceitar o pacote
DROP: bloquear o pacote
LOG: registrar no syslog (esta regra apenas registr no log. Após ela deve ser inserida a mesma regra porém com a especificação para onde enviar o pacote)
REJECT: rejeita o pacote. Diferente de DROP, este alvo envia como resposta ao cliente um pacote ICMP de host não alcançado, fazendo parecer que o serviço ou servidor não existe. Útil para enganar portscanners. O DROP causa uma parada de tempo que evidencia ao portscanner que existe um firewall bloqueando o acesso.
REDIRECT: redireciona o pacote
RETURN: retorna para a chain anterior
QUEUE: passa o pacote para ser tratado por um programa externo
SNAT: Source NAT - Nat na porta de Origem
DNAT: Destination NAT - Nat na porta de Destino
NAT
IP dinâmico => MASQUERAD
IP fixo => SNAT
MASQUERADING: Digamos que o servidor acessa a internet através de uma conexão com IP dinâmico na interface ppp0 e queremos que todas as máquinas da rede interna (ligadas com eth0) acessem a internet através dele. Para isso utilizamos a tecnica de masquerad, que recebe o pacote do cliente da rede interna, troca o IP dele pelo do servidor e envia o pacote para a internet. Quando o pacote voltar o iptables reconhece o pacote, troca para o IP original e repassa ao host que realizou a requisição.
Para ativar o masquerading basta estes dois comandos:
# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j MASQUERADE
Agora é só configurar o gateway de cada cliente da rede interna para apontar para o nosso servidor e pronto :)
O primeiro comando habilita o ip_forward no Linux, e isso deve ser executado somente uma vez. Para desativar é só trocar o 1 por 0 no comando informado.
SNAT: Consiste em modificar o endereço de origem das máquinas clientes antes dos pacotes serem enviados. Quando receber o retorno a máquina proxy (que roda as regras iptables) faz a conversão e encaminha o pacote para o host que realizou a requisição. Toda a operação de NAT é realizada no chain POSTROUTING. Nenhuma máquina da internet terá acesso direto às máquinas da rede interna.
# iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth1 -j SNAT --to 200.1.2.3
DNAT: Consiste em modificar o endereço de destino das máquinas clientes. Muito usado para fazer redirecionamento de pacotes, proxys transparentes, etc. Toda a configuração do DNAT é feita na chain PREROUTING.
Exemplo 1: Enviar para 192.168.2.1 todos os pacotes que chegam da internet
# iptables -t nat -A PREROUTING -s 200.1.2.3 -i eth0 -j DNAT --to 192.168.2.1
Exemplo 2: Enviar os pacotes da rede interna para o servidor
# iptables -t nat -A PREROUTING -i eht0 -s 192.1682.0/24 -j DNAT --to 200.1.2.3
Exemplo 3: Enviar para o host 192.168.2.1 todos os pacotes que chegam da internet com destino a porta 21
# iptables -t nat -A PREROUTING -p tcp -d 200.1.2.3 --dport 21 -j DNAT -to 192.168.2.1:21
NAT para rede interna
Se pretendemos redirecionar pacotes entre hosts que estão na mesma subnet é necessário configurar o SNAT apontando para o host que roda as regras iptables para que o pacote possa voltar.
CENARIO:
PC 1 PC 2 PC 3
192.168.2.235 192.168.2.234 192.168.2.230
(cliente) (iptables) (servidor FTP)
1. Configurar o nat NAT para o servidor
# iptables -t nat -A PREROUTING -p tcp --dport 21 -j DNAT --to 192.168.2.230:21
2. Configurar o SNAT para receber a resposta do servidor. Sem isso a conexao se estabelece, mas a comunicacao nao se realiza, pq a resposta do servidor nao chegaria ao cliente.
# iptables -t nat -A POSTROUTING -p tcp -d 192.168.2.230 --dport 21 -j SNAT --to 192.168.2.234:21
Redirecionamento de Portas
Permite repassar conexões com destino a uma porta para outra na mesma máquina.
Exemplo: enviar todas as conexões recebidas na porta 80 para a porta 81 (squid)
# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 81
Mostrar conexões NAT
# cat /proc/net/ip_conntrack
Salvar e Recuperar regras
1. Salvando regras:
# iptables-save > regras.txt
2. Restaurando regras:
# iptables-restore < regras.txt
Simples assim :)
Observações:
Todas as configurações do IPTABLES não são persistentes, e se perdem após o reboot.
Se a configuração de ip_forward não funcionar apenas com a configuração anterior, tentar o seguinte:
Ediar o arquivo /etc/sysctl.conf e adicionar, ou descomentar, a seguinte linha:
net.ipv4.ip_forward=1
Depois verificar:
# sysctl -p
Basicamente é isso.
Bem vindo ao mundo do controle de pacotes :)
Ivan S. Vargas