Linux 2.4 Packet Filtering HOWTO
Rusty Russell, mailing list netfilter@lists.samba.org
Tradução para Português do Brasil: Guilherme Ude Braz
(guilherme@linuxplace.com.br)
Revision: 1.19 Date: 2001/05/26 20:26:48
______________________________________________________________________
Índice geral
1. Introdução
2. Onde está o site oficial? Existe uma Mailing List?
3. Então, o que é um filtro de pacotes?
3.1 Porque filtrar os pacotes?
3.2 Como eu filtro pacotes no Linux?
3.2.1 iptables
3.2.2 Tornando as regras permanentes
4. Quem é você, e porque está alterando o meu kernel?
5. Guia ultra rápido do Rusty para filtragem de pacotes
6. Como os pacotes passam pelos filtros
7. Utilizando o iptables
7.1 O que será visto quando seu computador iniciar
7.2 Operações em uma única regra
7.3 Especificações para filtragem
7.3.1 Especificando endreços IP de origem e destino
7.3.2 Especificando Inversão
7.3.3 Especificando protocolo
7.3.4 Especificando uma interface
7.3.5 Especificando fragmentos
7.3.6 Extensões ao iptables: Novas Implementações
7.3.6.1 Extensões TCP
7.3.6.1.1 Uma explicação sobre as flags TCP
7.3.6.2 Extensões UDP
7.3.6.3 Extensões ICMP
7.3.6.4 Outras extensões
7.3.6.5 Checagens de estado dos pacotes (state match)
7.4 Especificações de alvo (Target)
7.4.1 Chains definidas por usuários
7.4.2 Extensões ao iptables: Novos alvos (targets).
7.4.3 Alvos especiais padrão
7.5 Operações em uma chain
7.5.1 Criando uma nova chain
7.5.2 Apagando uma Chain
7.5.3 Esvaziando uma chain
7.5.4 Listando uma chain
7.5.5 Zerando contadores
7.5.6 Escolhendo política
8. Utilizando ipchains e ipfwadm
9. Misturando NAT e Filtragem de Pacotes
10. Diferenças entre iptables e ipchains
11. Conselhos sobre o projeto de filtros de pacotes
______________________________________________________________________
1. Introdução
Bemvindo, gentil leitor.
Parte-se do pressuposto que você sabe o que são: endereço IP, endereço
de rede, máscara de rede, roteamento e DNS. Caso contrário, é
recomendável que você leia o Network Concepts HOWTO (em inglês, por
enquanto).
Esse HOWTO passa de uma gentil introdução (a qual o deixará alegre e
entusiasmado agora, porém desprotegido no mundo real) para uma
discussão um pouco mais árida (que vai deixar todos, exceto as almas
mais fortes, confusos e procurando por armamento pesado).
Sua rede não é segura. Permitir comunicação rápida e conveniente
restringindo seu uso para o bem, e não para ações mal intencionadas
involve questões muito mais amplas que o foco deste documento.
Portanto, tais questões não serão tratadas neste HOWTO.
Então, apenas você pode decidir até onde vai o compromisso. Tentarei
instruí-lo sobre o uso de algumas ferramentas disponíveis e algumas
vulnerabilidades conhecidas, e espero que você utilize isso para o
bem, e não para o mal.
(C) 2000 Paul `Rusty' Russell. Licenced under the GNU GPL.
2. Onde está o site oficial? Existe uma Mailing List?
Esses são os três sites oficiais:
· Obrigado Filewatcher .
· Obrigado The Samba Team and SGI .
· Obrigado Harald Welte .
A mailing list oficial do netfilter está em Netfilter List
.
3. Então, o que é um filtro de pacotes?
Um filtro de pacotes é um sofware que analiza o cabeçalho (header) dos
pacotes enquanto eles passam, e decide o destino do pacote como um
todo. Ele pode decidir entre descartar (DROP) o pacote (descartando-o
como se nunca o tivesse recebido), aceitar (ACCEPT) o pacote (deixar o
pacote seguir seu caminho), ou algo mais complicado que isso.
No Linux, filtragem de pacotes está implementada diretamente no kernel
(como um módulo ou diretamente compilado), e há várias coisas
interessantes que podem ser feitas com os pacotes, mas o princípio
geral é analizar o cabeçalho dos pacotes e decidir o que ser feito com
o pacote.
3.1. Porque filtrar os pacotes?
Controle. Segurança. Vigilância.
Controle:
quando uma máquina Linux é utilizada para conectar sua rede
interna em outra rede (a Internet, por exemplo) há a
oportunidade de permitir certo tipo de tráfego, e rejeitar
outro. Por exemplo, o cabeçalho do pacote contém o endereço de
destino do pacote, logo você pode evitar que os pacotes saiam em
direção a um endereço. Por exemplo, eu utilizo o Konqueror para
ler as tirinhas do Dilbert. Há publicidade do doubleclick.net
nesta página, e o Konqueror gasta meu precioso tempo baixando-a.
Pode-se dizer ao netfilter para não permitir pacotes vindos de
doubleclick.net (há melhores maneiras de se fazer isso: veja o
Junkbuster).
Segurança:
quando uma máquina Linux é a única coisa entre o caos da
Internet e sua calma e organizada rede, é bom saber que é
possível restringir o tráfego vindo do mundo externo. Por
exemplo, você pode permitir que qualquer tipo de pacote saia da
sua rede, mas você é preocupado com o famoso ataque `Ping of
Death (Ping da Morte)' vindo de mal-feitores do mundo externo.
Como outro exemplo, você pode não gostar da idéia de permitir
que qualquer um da rede externa conecte-se via telnet na sua
máquina Linux, mesmo que todas as contas da máquina tenham
senhas. Talvez você queira (como a maioria das pessoas) ser
apenas um observador, e não um servidor. Simplesmente não deixe
ninguém conectar, dizendo ao filtro de pacotes para rejeitar
pacotes requisitando a criação de novas conexões.
Vigilância:
às vezes uma máquina mal configurada na rede local pode decidir
enviar pacotes descontroladamente para o mundo externo. É
interessante dizer ao filtro de pacotes para te informar se algo
anormal ocorrer, talvez você possa fazer algo para resolver o
problema, ou você pode ser apenas mais um curioso :)
3.2. Como eu filtro pacotes no Linux?
Os kernels Linux têm tido filtros de pacotes desde a série 1.1. A
primeira geração, baseada no ipfw do BSD, foi portada por Alan Cox no
final de 1994. Essa implementação foi melhorada por Jos Vos e outros
para o Linux 2.0; a ferramenta userspace `ipfwadm' controlava as
regras de filtragem do kernel. Em meados de 1998, para o Linux 2.2, eu
reescrevi muitas linhas de código do kernel, com a ajuda de Michael
Neuling, e introduzi a ferramente userspace `ipchains'. Finalmente, a
ferramenta da quarta geração, o `iptables', e mais um árduo trabalho
de reedição do kernel ocorreu em meados de 1999 para o Linux 2.4. Este
HOWTO concentra-se no iptables.
É necessário um kernel que possua a infraestrutura netfilter
implementada: netfilter é um framework dentro do kernel Linux com o
qual outras coisas (como o módulo do iptables) podem conectar-se. Isso
significa que você precisa do kernel 2.3.15 ou posteriores, e respoder
`Y (SIM)' para CONFIG_NETFILTER na sua configuração do kernel.
A ferramenta iptables conversa com o kernel e fala quais são os
pacotes a serem filtrados. Ao menos que você seja um programador, ou
apenas um curioso, esta é a forma pela qual você controlará a
filtragem dos pacotes.
3.2.1. iptables
A ferramenta iptables insere e apaga regras da tabela de filtragem de
pacotes do kernel. Isso significa que qualquer coisa que você
configure será perdida assim que o Linux for reiniciado.
iptables é uma substituição para ipfwadm e ipchains: veja ``Utilizando
ipchains e ipfwadm'' para saber como evitar a utilização de iptables
se você está utilizando alguma dessas ferramentas.
3.2.2. Tornando as regras permanentes
Sua configuração atual de firewall está guardada no kernel, logo será
perdida na próxima vez que a máquina for reiniciada. Escrever o
iptables-save e o iptables-restore está na minha lista de afazeres.
Quando eles existirem, prometo que funcionarão muito bem.
Por enquanto, coloque os comandos necessários para configurar suas
regras em um script de inicialização. Esteja certo de que o script
faça algo inteligente caso algum dos comandos falhe (usualmente `exec
/sbin/sulogin').
4. Quem é você, e porque está alterando o meu kernel?
Eu sou Rusty; o mantenedor do Linux IP Firewall e mais um programador
que apareceu na hora certa e no lugar certo. Eu escrevi ipchains (veja
``Como eu filtro pacotes no Linux?'' para saber quem realmente
trabalhou no projeto), e aprendi o suficiente para que o filtro de
pacotes tenho sido feito da forma correta. Eu espero.
WatchGuard , uma excelente empresa de
firewall que vende uma interessante plug-in Firebox, se ofereceu para
pagar-me para fazer nada, assim eu poderia gastar todo o meu tempo
escrevendo tudo isso, e mantendo coisas anteriores. Eu previ 6 meses,
e levei 12, mas senti, ao terminar, que havia feito a coisa da forma
que ela deveria ser. Depois de muitas reedições, um crash no meu disco
rígido, o roubo de meu laptop, alguns sistemas de arquivos corrompidos
e uma tela quebrada, aqui está.
Eu gostaria de esclarecer alguns desentendimentos das pessoas: eu nao
sou nenhum guru do kernel. Sei disso porque meu trabalho me colocou em
contato com alguns dos verdadeiros gurus: David S. Miller, Alexey
Kuznetsov, Andi Kleen, Alan Cox. De qualquer forma, eles estão
ocupados fazendo a verdadeira mágica, deixando-me em paz, fazendo meu
serviço, que é mais seguro.
5. Guia ultra rápido do Rusty para filtragem de pacotes
A maioria das pessoas possui uma simples conexão PPP connection com a
Internet, e não querem ninguém entrando em sua rede:
## Carregando módulos de acompanhamento de conexões (desnecessário se compilados diretamente no kernel).
# insmod ip_conntrack
# insmod ip_conntrack_ftp
## Cria chain que rejeita novas conexões, exceto as vindas da rede interna.
# iptables -N block
# iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT
# iptables -A block -j DROP
## Saltar das chains INPUT e FORWARD para a chain block.
# iptables -A INPUT -j block
# iptables -A FORWARD -j block
6. Como os pacotes passam pelos filtros
O kernel começa com três listas de regras na tabela `filter'; tais
listas são denominadas firewall chains ou apenas chains. As três
chains chamam-se INPUT, OUTPUT e FORWARD.
Para os fãs de ASCII-art, as chains estão organizadas da seguinte
forma: (Nota: é uma organização bem distinta dos kernels 2.0 e 2.2!)
_____
Entrada / \ Saída
-->[Decisão de]-->|FORWARD|------->
[Roteamento] \_____/ ^
| |
v ____
___ / \
/ \ |OUTPUT|
|INPUT| \____/
\___/ ^
| |
--> Processamento Local --
Os três "círculos" representam as chains mencionadas acima. Quando o
pacote atinge um círculo no diagrama, a chain é examinada a fim de
decidir o destino do pacote. Se a chain diz para rejeitar (DROP) o
pacote, ele é descartado, mas se a chain diz para aceitar o pacote
(ACCEPT), ele continua a viajar no diagrama.
Uma chain é uma lista de regras. Cada regra diz `se o cabeçalho do
pacote se parece com isso, então aqui está o que deve ser feito com o
pacote'. Se a regra não associa-se com o pacote, então a próxima
regra na chain é consultada. Se não há mais regras a consultar, o
kernel analiza a política da chain para decidir o que fazer. Em um
sistema preocupado com segurança, a política diz ao kernel para
rejeitar (DROP) o pacote.
1. Quando o pacote chega (pela placa Ethernet, por exemplo) o kernel
analiza o destino do pacote: isso é chamado roteamento (routing).
2. Se ele é destinado a própria máquina, o pacote desce no diagrama,
indo para a chain INPUT. Se ele passar pela chain INPUT, então a
máquina recebe o pacote.
3. Depois, se o kernel não tem suporte a forwarding, ou não sabe como
repassar (forward) o pacote, este é descartado. Se há suporte a
forwarding e o pacote é destinado a outra interface de rede (se
você possui outra), o pacote vai para a chain FORWARD. Se ele for
aceito (ACCEPT), ele será enviado.
4. Finalmente, um programa rodando na máquina firewall pode enviar
pacotes. Esses pacotes passam pela chain OUTPUT imediatamente: se
ela aceitar o pacote, ele continua seu caminho, caso contrários ele
é descartado.
7. Utilizando o iptables
O iptables tem uma página de manual muito detalhada (man iptables), se
você necessitar de informações mais específicas. Aqueles mais
familiarizados com o ipchains provavelmente gostarão de ler
``Diferenças entre iptables e ipchains''; eles são bem similares.
Há muitas coisas que podem ser feitas com iptables. Você começa com
três chains built-in INPUT, OUTPUT e FORWARD as quais não podem ser
apagadas. Estas são as operações para gerenciar chains:
1. Criar nova chain (-N).
2. Apagar uma chain vazia (-X).
3. Mudar a política de uma chain built-in. (-P).
4. Listar as regras de uma chain (-L).
5. Apagar todas as regras de uma chain (-F).
6. Zerar os contadores de pacotes e bytes de todas as regras de uma
chain (-Z).
Há várias formas de manipular regras dentro de uma chain:
1. Adicionar uma nova regra na chain (-A).
2. Inserir uma nova regra em alguma posição da chain (-I).
3. Substituir uma regra em alguma posição da chain (-R).
4. Apagar uma regra em alguma posição da chain (-D).
5. Apagar a primeira regra que associa (com alguma condição) numa
chain (-D).
7.1. O que será visto quando seu computador iniciar
O iptables pode ser um módulo, chamado (`iptable_filter.o'), que deve
ser automaticamente carregado quando você rodar iptables pela primeira
vez. Ele também pode ser compilado diretamente no kernel.
Antes dos comandos do iptables rodarem (cuidado: algumas distribuições
rodarão iptables em seus scripts de inicialização), não haverão regras
em quaisquer chains (`INPUT', `FORWARD' and `OUTPUT') e todas as
chains terão a política ACCEPT. A política padrão da chain FORWARD
pode ser alterada fornecendo o parâmetro `forward=0' para o módulo
iptable_filter.
7.2. Operações em uma única regra
Este é o arroz com feijão da filtragem de pacotes: manipular regras.
Usualmente, você provavelmente utilizará os comandos para adicionar
(-A) e apagar (-D). Os outros (-I para inserir e -R para substituir)
são apenas extensões destes conceitos.
Cada regra especifica uma série de condições que o pacote deve
atender, e o que fazer com o mesmo se ele atendê-las (um alvo
`target'). Por exemplo, você pode desejar descartar todos os pacotes
ICMP vindos do endereço IP 127.0.0.1. Então neste caso nossas
condições são que o protocolo precisa ser ICMP e o endereço de origem
deve ser 127.0.0.1. Nosso alvo (target) é `DROP'.
127.0.0.1 é a interface `loopback', que existirá mesmo que você não
tenha nenhuma conexão de rede real. Pode-se utilizar o programa `ping'
para gerar esse tipo de pacote (ele simplesmente manda um ICMP tipo 8
(requisição de eco) que é respondido pelos hosts com um ICMP tipo 0
(resposta de eco)).
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.2 ms
# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#
Pode-se ver que o primeiro ping é bem sucedido (a opção `-c 1' diz ao
ping para mandar um único pacote).
Então foi adicionada (-A) à chain `INPUT', uma regra especificando que
pacotes vindos de 127.0.0.1 (`-s 127.0.0.1') com o protocolo ICMP (`-p
icmp') devem ser mandados para DROP (`-j DROP').
Logo depois, testamos nossa regra, usando um segundo ping. Haverá uma
pausa antes que o programa desista de esperar pelo pacote que nunca
viria.
Pode-se apagar regras de duas maneiras. Primeiramente, desde que
sabemos que existe apenas uma regra na chain INPUT, podemos utilizar
um número para designar a regra, como abaixo:
# iptables -D INPUT 1
#
Para apagar a regra número 1 na chain INPUT.
A segunda forma, é fazer o mesmo que faríamos para adicionar a regra,
trocando -A por -D. Isso é útil quando você tem uma chain muito
complexa e não quer contar para descobrir que a regra 37 deve ser
apagada. Neste caso usaria-se:
# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
#
A sintaxe do -D deve ter exatamente as mesmas opções que seriam
passadas para a opção -A (ou -I ou -R). Se existem várias regras
idênticas na mesma chain, apenas a primeira será apagada.
7.3. Especificações para filtragem
Foi visto o uso do `-p' para especificar o protocolo, e `-s' para
especificar o endereço de origem, mas existem outras opções que podem
ser utilizadas para especificar outras características dos pacotes. O
que segue é uma explicação exaustiva.
7.3.1. Especificando endreços IP de origem e destino
Endereços IP de Origem (`-s', `--source' or `--src') e destino (`-d',
`--destination' or `--dst') podem ser especificados em quatro formas
diferentes. A mais comum é utilizar o nome completo, como `localhost'
ou `www.linuxhq.com'. A segunda é dizer o IP, como `127.0.0.1'.
A terceira e a quarta formas permitem a especificação de um grupo de
endereços IP, como `199.95.207.0/24' ou `199.95.207.0/255.255.255.0'.
Ambas especificam qualquer endereço IP de 199.95.207.0 até
199.95.207.255; os dígitos depois da `/' dizem quais partes do
endereço IP são significantes. `/32' ou `/255.255.255.255' é o padrão
(associando o endereço IP inteiro). Para especificar qualquer endereço
IP pode-se utilizar `/0', conforme descrito abaixo:
[ NOTA: `-s 0/0' é redundante. ]
# iptables -A INPUT -s 0/0 -j DROP
#
Isso raramente é utilizado, uma vez que o efeito da regra acima é o
mesmo que se não fosse especificada nenhuma origem.
7.3.2. Especificando Inversão
Muitas flags, incluindo `-s' (or `--source') e `-d' (`--destination')
podem ter seus argumentos precedidos de `!' (pronunciado `não') para
associar-se com endereços DIFERENTES aos passados à opção. Por
exemplo, '-s ! localhost' associa-se com qualquer pacote que não venha
de localhost.
7.3.3. Especificando protocolo
O protocolo pode ser especificado com `-p' (ou `--protocol'). O
protocolo pode ser um número (se você sabe o valor numérico dos
protocolos) ou um nome para casos especiais como `TCP', `UDP' or
`ICMP'. Digitar em maiúsculas ou minúsculas não faz diferença, `tcp'
funciona tão bem como `TCP'.
Se o nome do protocolo é precedido de `!', a fim de invertê-lo, como
`-p! TCP', a regra especificará todos os pactoes que não são TCP.
7.3.4. Especificando uma interface
As opções `-i' (or `--in-interface') e `-o' (or `--out-interface')
especificam o nome de uma interface a especificar. Uma interface é um
dispositivo físico pelo qual o pacote veio (`-i') ou está saindo
(`-o'). Pode-se usar o comando ifconfig para listar as interfaces
ativas.
Pacotes atravessando a chain INPUT não possuem interface de saída,
logo qualquer regra utilizando `-o' nessa chain nunca aplicar-se-á. Da
mesma forma, pacotes atravessando a chain OUTPUT não têm interface de
entrada, logo qualquer regra utilizando `-i' nessa chain nunca
aplicar-se-á.
Apenas pacotes passando pela chain FORWARD têm interfaces de entrada e
saída.
Não há nenhum problema em especificar uma interface que ainda não
existe; a regra não associar-se-á com quaisquer pacotes até que a
interface torne-se ativa. Isso é extremamente útil para links discados
PPP (usualmente com a interface ppp0) e similares.
Como um caso especial, um nome de interface terminando com um `+' vai
associar-se com todas as interfaces (existam elas ou não) que comecem
com aquela string. Por exemplo, para especificar uma regra que se
associa com todas as interfaces PPP, a opção -i ppp+ deve ser criada.
O nome da interface pode ser precedido de `!' para se associar com um
pacote que não é representado pelas interface(s) especificada(s).
7.3.5. Especificando fragmentos
Às vezes um pacote é muito grande para ser enviado todo de uma vez.
Quando isso ocorre, o pacote é dividido em fragmentos, e é enviado
como múltiplos pacotes. Quem o recebe, remonta os fragmentos
reconstruindo o pacote.
O problema com os fragmentos é que o fragmento incial tem os campos de
cabeçalho completos (IP + TCP, UDP e ICMP) para examinar, mas os
pacotes subsequentes só têm um pequeno grupo de cabeçalhos (somente
IP, sem os campos dos outros protocolos). Logo examinar o interior dos
fragmentos subsequentes em busca de cabeçalhos de outros protocolos
(como extensões de TCP, UDP e ICMP) é impossível.
Se você está fazendo acompanhamento de conexões ou NAT, todos os
fragmentos serão remontados antes de atingirem o código do filtro de
pacotes, então você não precisa se preocupar sobre os fragmentos.
Caso contrário, é importante entender como os fragmentos são tratados
pelas regras de filtragem. Qualquer regra de filtragem que requisitar
informações que não existem não será válida. Isso significa que o
primeiro fragmento é tratado como um pacote qualquer. O segundo e os
seguintes não serão. Então uma regra -p TCP --sport www (especificando
'www' como porta de origem) nunca se associar-se-á com um fragmento
(exceto o primeiro). O mesmo se aplica à regra oposta -p TCP --sport !
www.
De qualquer forma, você pode especificar uma regra especial para o
segundo e os fragmentos que o sucedem, utilizando a flag `-f' (ou
`--fragment'). Também é interessante especificar uma regra que não se
aplica ao segundo e os outros fragmentos, precedendo a opção `-f' com
`!'.
Geralmente é reconhecido como seguro deixar o segundo fragmento e os
seguintes passarem, uma vez que o primeiro fragmento será filtrado,
logo isso vai evitar que o pacote todo seja remontado na máquina
destinatária. De qualquer forma, há bugs que levam à derrubada de uma
máquina através do envio de fragmentos. A decisão é sua.
Nota para os administradores de rede: pacotes mal formados (pacotes
TCP, UDP e ICMP muito pequenos para que o código do firewall possa ler
as portas ou o código e tipo dos pacotes ICMP) são descartados quando
ocorrem tais análises. Então os fragmentos TCP começam na posição 8.
Como um exemplo, a regra a seguir vai descartar quaisquer fragmentos
destinados ao endereço 192.168.1.1:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
7.3.6. Extensões ao iptables: Novas Implementações
O iptables é extensível, assim, tanto o kernel quanto o iptables podem
ser extendidos para fornecer novas funcionalidades.
Algumas dessas extensões são padronizadas, e outras são mais exóticas.
Extensões podem ser feitas por qualquer um e distribuídas
separadamente para usuários de nichos mais específicos.
As extensões do kernel geralmente estão no subdiretório de módulos do
kernel como, por exemplo, /lib/modules/2.3.15/net. Elas são carregadas
por demanda se seu kernel foi compilado com a opção CONFIG_KMOD
marcada, não havendo a necessidade de inserí-las manualmente.
As extensões do iptables são bibliotecas compartilhadas as quais
geralmente estão em /usr/local/lib/iptables/, mas uma distribuição os
colocaria em /lib/iptables ou /usr/lib/iptables.
Extensões vêm em dois tipos diferentes: novos alvos (targets), e novas
associações (depois falaremos mais sobre novos alvos 'targets').
Alguns protocolos automaticamente oferecem novos testes: atualmente
são eles TCP, UDP e ICMP como mostrado abaixo.
Para esses protocolos você poderá especificar novos testes na linha de
comando depois da opção `-p', que carregará a extensão. Para novos
testes explícitos, utilize a opção `-m' para carregar a extensão,
depois de -m, todas as opções da extensão estarão disponíveis.
Para conseguir ajuda com uma extensão, utilize a opção que a carrega
(`-p', `-j' ou `-m') sucedida por `-h' ou `--help', conforme o
exemplo:
# iptables -p tcp --help
#
7.3.6.1. Extensões TCP
As extensões TCP são automaticamente carregadas se é especificada a
opção `-p tcp'. Elas provêm as seguintes opções (nenhuma associa-se
com fragmentos).
--tcp-flags
seguida por uma opcional `!', e por duas strings indicando
flags, permite que sejam filtradas flags TCP específicas. A
primeira string de flags é a máscara: uma lista de flags que
serão examinadas. A segunda string diz quais flags devem estar
ativas para que a regra se aplique. Por exemplo:
# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DROP
Essa regra indica que todas as flags devem ser examinadas (`ALL' é
sinônimo de `SYN,ACK,FIN,RST,URG,PSH'), mas apenas SYN e ACK devem
estar ativadas. Também há um argumento `NONE' que significa nenhuma
flag.
--syn
opcionalmente precedido por `!', é um atalho para `--tcp-flags
SYN,RST,ACK SYN'.
--source-port
seguido por `!' opcional, e uma única porta TCP, ou um conjunto
(range) de portas. As portas podem ser descritas pelo nome,
conforme listado em /etc/services, ou pelo número. Conjuntos
(ranges) são dois nomes de portas separados por `:', ou (para
especificar uma porta maior ou igual à especificada) uma porta
sucedida por `:', ou (para especificar uma porta menor ou igual
à especificada), uma porta precedida por `:'.
--sport
é sinônimo de `--source-port'.
--destination-port
e
--dport
funcionam de forma idêntica a
--source-port
, a única diferença é que elas indicam a porta de destino, e não
a porta de origem.
--tcp-option
seguida por `!' opcional e um número, associa-se com um pacote
com a opção TCP igual ao do número passado. Um pacote que não
tem um cabeçalho TCP completo é automaticamente descartado se há
uma tentativa de examinar suas opções TCP.
7.3.6.1.1. Uma explicação sobre as flags TCP
Às vezes é util permitir conexões TCP em uma única direção, mas não
nas duas. Por exemplo, você permitirá conexões em um servidor WWW
externo, mas não conexões vindas deste servidor.
Uma tentativa ingênua seria bloquear pacotes TCP vindos do servidor.
Infelizmente, conexões TCP necessitam de pacotes bidirecionais para um
funcionamento perfeito.
A solução é bloquear apenas os pacotes utilizados para requisitar uma
conexão. Tais pacotes são chamados pacotes SYN (ok, tecnicamente eles
são pacotes com a flag SYN marcada, e as flags RST e ACK desmarcadas,
mas dizemos pacotes SYN como atalho). Ao não permitir tais pacotes,
nós impedimos conexões vindas do servidor.
A opção `--syn' é utilizada para isso: só é válida para regras que
especificam TCP como protocolo. Por exemplo, para especificar conexões
TCP vindas do endereço 192.168.1.1:
-p TCP -s 192.168.1.1 --syn
Essa opção pode ser invertida se precedida por `!', o que significa
qualquer pacote exceto os que iniciam conexões.
7.3.6.2. Extensões UDP
Essas extensões são automaticamente carregadas se a opção `-p udp' é
especificada. Ela provê as opções `--source-port', `--sport',
`--destination-port' and `--dport' conforme detalhado para o TCP
acima.
7.3.6.3. Extensões ICMP
Essas extensões são automaticamente carregadas se a opção `-p icmp' é
especificada. Ela só possui uma opção diferente das demais:
--icmp-type
seguida por `!' opcional, e um nome de tipo icmp (por exemplo,
`host-unreachable'), ou um tipo numérico (exemplo `3'), ou um
tipo numérico e código separados por `/' (exemplo `3/3'). Uma
lista de tipos icmp é passada utilizando-se `-p icmp --help'.
7.3.6.4. Outras extensões
Outras extensões no pacote netfilter são extensões de demonstração,
que (caso instaladas) podem ser chamadas com a opção `-m'.
mac
Este módulo deve ser explicitamente especificado com `-m mac' ou
`--match mac'. Ele é usado para associar-se com o endereço
Ethernet (MAC) de origem do pacote, e logo só é útil nas chains
PREROUTING e INPUT. Só provê uma única opção:
--mac-source
seguida por `!' opcional e um endereço ethernet passado em
notação hexa, exemplo `--mac-source 00:60:08:91:CC:B7'.
limit
Este módulo deve ser explicitamente especificado com `-m limit'
ou `--match limit'. É usado para restringir a taxa de pacotes, e
para suprimir mensagens de log. Vai fazer com que a regra seja
válida apenas um número de vezes por segundo (por padrão 3 vezes
por hora, com um limite máximo def 5). Possui dois argumentos
opcionais:
--limit
seguido de um número; especifica a média máxima de pacotes
(ou LOGs, etc) permitida por segundo. Pode-se especificar a
unidade de tempo, usando `/second', `/minute', `/hour' ou
`/day', ou abreviações dos mesmos (assim, `5/second' é o
mesmo que `5/s').
--limit-burst
seguido de um número, indicando o máximo de entradas antes do
limite tornar-se válido.
Essa extensão pode ser usada com o alvo (target) LOG para criar
registros (logs) limitados por taxa de incidência. Para entender
o funcionamento disso, olhe a regra abaixo, que loga pacotes com
os parâmetros padrão de limite:
# iptables -A FORWARD -m limit -j LOG
Na primeira vez que essa regra é analizada, o pacote será logado;
na realidade, uma vez que o padrão máximo é 5, os cinco primeiros
pacotes serão logados. Depois disso, passar-se-ão vinte minutos
antes de que essa regra faça um novo logo, independente do número
de pacotes que entrarem. Além disso, a cada vinte minutos que se
passam sem que um pacote associe-se com a regra, o contador é
diminuido em uma unidade. Logo, se nenhum pacote associar-se com a
regra em 100 minutos, o limite estará zerado, voltando ao estágio
inicial.
Nota: não é possível criar uma regra com tempo de recarga superior
a 59 horas, então se você configura uma taxa média de um por dia,
seu limite máximo deve ser menor que 3.
Esse módulo também pode ser usado para evitar uma série de ataques
do tipo negativa de serviço (denial of service 'DoS') com uma taxa
mais rápida, a fim de aumentar a sensibilidade do sistema.
Proteção contra Syn-flood:
# iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
Port scanner suspeito:
# iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
Ping da morte:
# iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
Esse módulo funciona como uma "porta com resposta retardada",
conforme o gráfico abaixo.
taxa (pkt/s)
^ .---.
| / DoS \
| / \
Auge do DoS -|.....:.........\.......................
= (média * | /: \
média-máxim) | / : \ .-.
| / : \ / \
| / : \ / \
Fim do DoS -|/....:..............:.../.......\..../.
= média | : :`-' `--'
-------------+-----+--------------+------------------> time (s)
LOGICA => Passa | Não passa | Passa
Digamos que aprovamos um pacote por segundo com um limite máximo de
cinco pacotes, mas os pacotes começam a vir quatro por segundo,
durante três segundos, e recomeçam depois de mais 3 segundos.
<--Flood 1--> <---Flood 2--->
Total ^ Line __-- YNNN
de | Rate __-- YNNN
Pacotes| mum __-- YNNN
10 | Maxi __-- Y
| __-- Y
| __-- Y
| __-- YNNN
|- YNNN
5 | Y
| Y Legenda: Y -> Regra válida
| Y N -> Regra deixou de valer
| Y
|Y
0 +--------------------------------------------------> Time (seconds)
0 1 2 3 4 5 6 7 8 9 10 11 12
Nota de Tradução: Desculpem-me, mas eu não consegui traduzir esse gráfico sem
deformá-lo completamente, então algumas coisas ficaram em inglês :)
Percebe-se que os cinco primeiros pacotes podem exceder um pacote
por segudo, depois o limite máximo passa a ser válido. Se há uma
nova tentativa de flood, os pacotes são aceitos, mas apenas no
limite estabelecido pela regra (1 pacote por segundo pois a cota do
limite máximo já foi gasta).
owner
Esse módulo tenta associar-se com várias características do
criador do pacote, para pacotes gerados localmente. Só é válido
na chain OUTPUT, e mesmo assim alguns pacotes (como respostas de
ping ICMP) podem nao ter dono, e nunca serão analizados pela
regra.
--uid-owner userid
Associa-se com o pacote se este foi criado por um processo
com o userid igual ao passado na opção.
--gid-owner groupid
Associa-se com o pacote se este foi criado por um processo
com o groupid igual ao passado na opção.
--pid-owner processid
Associa-se com o pacote se este foi criado por um processo
com o proccessid igual ao passado na opção.
--sid-owner sessionid
Associa-se com o pacote se este foi criado por um processo
com o sessionid igual ao passado na opção.
unclean
Esse módulo experimental deve ser explicitamente especificado
com `-m unclean' ou `--match unclean'. Ele faz diversas
checagens de sanidade nos pacotes. Esse módulo não foi auditado,
e não deve ser utilizado como dispositivo de segurança (ele
provavelmente torna as coisas piores, uma vez que provavelemente
está cheio de bugs). Não possui opções
7.3.6.5. Checagens de estado dos pacotes (state match)
O critério para filtragem de pacotes mais útil é provido pela extensão
'state' que interpreta a análise do controle da conexão feita pelo
módulo `ip_conntrack'. Essa extensão é altamente recomendada.
Especificando `-m state' a opção `--state' torna-se disponível, a qual
é uma lista dos estados possíveis dos pacotes separada por vírgula (a
opção `!' indica para que a regra não se associe com os estados
passados). Os estados são:
NEW
Um pacote que cria uma nova conexão.
ESTABLISHED
Um pacote que pertence a uma conexão existente (um pacote de
resposta, um pacote saindo por uma conexão na qual já houveram
respostas).
RELATED
Um pacote relacionado, mas que não faz parte, de uma conexão
existente, como um erro ICMP, ou (com o módulo FTP carregado),
um pacote estabelecendo uma conexão de dados FTP.
INVALID
Um pacote que não pôde ser identificado por alguma razão: isso
inclui falta de memória e erros ICMP que não correspondem a
qualquer conexão conhecida. Geralmente tais pacotes devem ser
descartados.
7.4. Especificações de alvo (Target)
Agora que sabemos quais as análises podem ser feitas em um pacotes,
precisamos de uma forma de dizer o que fazer com os pacotes que passam
nas condições que estabelecemos. Isso é chamado de alvo (target) da
regra.
Há dois alvos bem simples: DROP (descartar) e ACCEPT (aceitar). Nós já
os vimos. Se a regra se associa com o pacote e seu alvo é um desses
dois, nenhuma outra regra é consultada: o destino do pacote já foi
decidido.
Há dois tipos de alvos diferentes dos descritos acima: as extensões e
as chains definidas por usuários.
7.4.1. Chains definidas por usuários
Uma funcionalidade que o iptables herdou do ipchains é a possibilidade
do usuário criar novas chains, além das três padrão (INPUT, FORWARD e
OUTPUT). Por convenção, chains definidas pelo usuário são escritas em
minúsculas, diferenciando-as (como criar chains definidas pelo usuário
será descrito abaixo ``Operações em uma chain'').
Quando um pacote associa-se com uma regra cujo alvo (target) é uma
chain definida pelo usuário, o pacote passa a ser analizado pelas
regras dessa chain definida pelo usuário. Se a chain não decide o que
deve ser feito com o pacote, o mesmo volta a ser analizado pela chain
padrão que continha a regra que o levava para a chain definida pelo
usuário.
Mais arte ASCII. Considere duas chains: INPUT (a chain padrão) e test
(uma chain definida pelo usuário).
`INPUT' `test'
---------------------------- ----------------------------
| Regra1: -p ICMP -j DROP | | Regra1: -s 192.168.1.1 |
|--------------------------| |--------------------------|
| Regra2: -p TCP -j test | | Regra2: -d 192.168.1.1 |
|--------------------------| ----------------------------
| Regra3: -p UDP -j DROP |
----------------------------
Considere um pacote TCP vindo de 192.168.1.1, indo para 1.2.3.4. Ele
entra na chain INPUT e é testado pela Regra1 - não se associa. Já a
Regra2 se associa, e seu alvo é test, logo a próxima regra examinada
está no início de test. A Regra1 na chain test se associa, mas não
especifica um alvo, então a próxima regra é examinada, Regra2. Ela não
se associa, e nós chegamos no final da chain. Então, a chain INPUT
volta a ser examinada, e como a úlitma regra desta chain que foi
examinada foi a Regra2, a regra a ser examinada agora é a Regra3, que
também não se associa com o pacote.
Logo, o caminho que o pacote faz é o seguinte:
v __________________________
`INPUT' | / `test' v
------------------------|--/ -----------------------|----
| Regra1 | /| | Regra1 | |
|-----------------------|/-| |----------------------|---|
| Regra2 / | | Regra2 | |
|--------------------------| -----------------------v----
| Regra3 /--+___________________________/
------------------------|---
v
Chains definidas por usuário podem ter como alvo outras chains
definidas por usuário (mas não faça loops: seus pacotes serão
descartados se entrarem em loop).
7.4.2. Extensões ao iptables: Novos alvos (targets).
O outro tipo de alvo é uma extensão. Uma extensão-alvo consiste em um
módulo do kernel, e uma extensão opcional ao iptables para prover
opções de linha de comando. Há diversas extensões na distribuição
padrão do netfilter:
LOG
Esse módulo provê logging dos pacotes submetidos. Possui as
seguintes opçoes adicionais: packets. It provides these
additional options:
--log-level
Seguido de um número de nível ou nome. Os nome válidos
(sensíveis a maiúsculas/minúsculas) são `debug', `info',
`notice', `warning', `err', `crit', `alert' and `emerg',
correspondendo a números de 7 até 0. Veja a página de manual
do syslog.conf para uma explicaçao mais detalhada desses
níveis.
--log-prefix
Seguido de uma string de até 29 characters, esta será
adicionada no início da mensagem de log, permitindo melhor
identificação da mesma.
Esse módulo é últil após de uma comparação por limite (limit
match), assim, você não enche seus logs.
REJECT
Esse módulo tem o mesmo efeito de `DROP', a não ser que o
remetente tenha enviado uma mensagem de erro ICMP `port
unreachable' (porta inalcançável) A mensagem de erro ICMP não
será enviada se (veja RFC 1122):
· O pacote que está sendo filtrado era uma mensagem de erro
ICMP no início, ou um tipo desconhecido de ICMP
· O pacote sendo filtrado era um fragmente sem cabeçalho
· Já enviamos muitas mensagens de erro ICMP para o mesmo
destinatário recentemente.
REJECT também tem o argumento opcional '-reject-with' que altera
o pacote de resposta utilizado: veja a página de manual.
7.4.3. Alvos especiais padrão
Há dois tipos especiais de alvos padrão: RETURN e QUEUE.
RETURN tem o mesmo efeito de chegar ao final da chain: para uma regra
numa chain padrão, a política da chain é executada. Para uma chain
definida por usuário, a travessia continua na chain anterior,
exatamente após a regra que saltou para a chain definida pelo usuário.
QUEUE é um alvo especial, que manda o pacote para uma fila para
processamento em nível de usuário. Para isso ser útil, dois
componentes são necessários:
· um "gerenciador de filas", que trata com a mecânica de passar os
pacotes do kernel para o espaço do usuário;
· uma aplicação no espaço do usuário para receber, possivelmente
manipular e decidir o que fazer com os pacotes.
O gerenciador de filas padrão para o iptables IPv4 iptables é o
módulo ip_queue, que é distribuído com o kernel e é atualmente
experimental.
O seguinte é um rápido exemplo de como utilizar o iptables para
enfileirar pacotes para processamento em nível de usuário:
# modprobe iptable_filter
# modprobe ip_queue
# iptables -A OUTPUT -p icmp -j QUEUE
Com essa regra, pacotes ICMP de saída gerados localmente (como, por
exemplo, criados pelo ping) são passados ao módulo ip_queue, que então
tenta mandar os pacotes para uma aplicação em nível de usuário. Se não
há nenhuma aplicação em nível de usuário está esperando, os pacotes
são descartados.
Para escrever uma aplicação em nível de usuário, utilize a API libipq,
que é distribuída com o iptables. Códigos de exemplo podem ser
encontradas com as ferramentas testsuite (por exemplo redirect.c) no
CVS.
O estado de ip_queue pode ser consultado através de:
/proc/net/ip_queue
O comprimento máximo da fila (exemplo, o número de pacotes entregues
ao espaço do usuário sem que nenhuma resposta fosse passada) pode ser
controlado por:
/proc/sys/net/ipv4/ip_queue_maxlen
O valor padrão para o comprimento máximo da fila é 1024. Uma vez que
esse limite foi atingido, novos pacotes serão descartados até que o
tamanho da fila diminua abaixo do limite. Bons protocolos como o TCP
interpretam pacotes descartados como congestionamento, que talvez
voltem quando a fila diminua. De qualquer forma, experimentos para
determinar o tamanho ideal da fila pois às vezes o tamanho padrão é
muito pequeno.
7.5. Operações em uma chain
Uma funcionalidade muito importante do iptables é a habilidade de
ajuntar regras em chains (cadeias). Você pode dar o nome que quiser
para as chains, mas é recomendada a utilização de minúsculas para
evitar confusão com as chains padrão ou com os alvos (targets). Nomes
de chains podem ter até 31 letras.
7.5.1. Criando uma nova chain
Criemos uma nova chain. Devido à minha imensa criatividade, vou
chamá-la de test. Utiliza-se as opções `-N' ou `--new-chain':
# iptables -N test
#
É tão simples assim. Agora é possível acrescentar regras conforme
descrito em todo o documento.
7.5.2. Apagando uma Chain
Apagar uma chain é tão simples quanto criá-la, utilizando as opções
`-X' ou `--delete-chain'. Porque `-X'? Bem, todas as boas letras já
haviam sido utilizadas.
# iptables -X test
#
Há uma série de restrições ao se apagar uma chain: ela deve estar
vazia (veja ``Esvaziando uma chain'', logo abaixo) e ela não deve ser
alvo de NENHUMA regra. É impossível apagar nenhuma das três chains
padrão.
Se uma chain não for especificada, todas as chains definidas por
usuário serão apagadas, desde que seja possível.
7.5.3. Esvaziando uma chain
Há uma forma muito simples de retirar todas as regras de uma chain,
utilizando as opções `-F' (ou `--flush').
# iptables -F FORWARD
#
Se uma chain nao for especificada, todas as chains serão esvaziadas.
7.5.4. Listando uma chain
Pode-se listar todas as regras de uma chain utilizando as opções `-L'
(ou `--list')
O valor `refcnt' listado para cada chain definida por usuário é o
número de regras que têm tal chain como alvo (target). Este valor deve
ser zero (e a chain deve estar vazia) antes que essa chain possa ser
apagada.
Se o nome da chain é omitido, todas as chains são listadas, até as
vazias.
Há três opçoes que podem acompanhar `-L'. A opção `-n' (numérico) é
muito útil uma vez que previne que o iptables tente resolver os
endereços IP, o que (se você utiliza DNS assim como a maioria das
pessoas) causaria grandes atrasos se o DNS não está configurado
corretamente, ou você está filtrando requisições DNS. Essa opção
também faz as portas TCP e UDP serem impressas como números em vez de
nomes.
A opção `-v' mostra todos os detalhes das regras, como os contadores
de pacotes e bytes, as comparações TOS, e as interfaces. Caso tal
opção não seja passada, esses valores sao omitidos.
Note que os contadores de pacotes e bytes são impressos com os sufixos
`K', `M' ou `G' para 1.000, 1.000.000 e 1.000.000.000 respectivamente.
Utilizando a flag `-x' (expandir números) os números serão impressos
inteiros, independente de seu tamanho.
7.5.5. Zerando contadores
É útil zerar os contadores. Isso pode ser feito com a opção `-Z' (ou
`--zero').
Considere o seguinte:
# iptables -L FORWARD
# iptables -Z FORWARD
#
No exemplo acima, alguns pacotes passariam pelos comandos `-L' e `-Z'.
Por isso, você pode utilizar `-L' e `-Z' em conjunto, para zerar os
contadores enquantos estes são lidos.
7.5.6. Escolhendo política
Já discutimos sobre o que ocorre quando um pacote chega ao fim de uma
chain padrão quando o caminho dos pacotes através das chains. Nesse
caso, a política da chain determina o destino do pacote. Apenas as
chains padrão (INPUT, OUTPUT e FORWARD) têm políticas, porque se um
pacote chega ao fim de uma chain definida por usuário, o caminho do
pacote continua pela chain anterior.
A política pode ser tanto ACCEPT (aceitar) quanto DROP (rejeitar), por
exemplo:
# iptables -P FORWARD DROP
#
8. Utilizando ipchains e ipfwadm
Há módulos na distribuição do netfilter chamados ipchains.o e
ipfwadm.o. Carregue-os em seu kernel (NOTA: eles são incompatíveis
com ip_tables.o!). Entao você poderá usar ipchains ou ipfwadm como nos
bons e velhos tempos.
Isso ainda terá suporte por mais algum tempo. Penso que uma fórmula
razoável seria 2 * [anúncio de substituição - versão estável inicial],
depois dessa data que uma versão estável da substituição está
disponível.
Isso significa que o fim do suporte para o ipfwadm é:
2 * [Outubro de 1997 (versão 2.1.102) - Março 1995 (ipfwadm 1.0)]
+ Janeiro 1999 (versão 2.2.0)
= Março 2004.
Isso significa que o fim do suporte para o ipfwadm é:
2 * [Agosto 1999 (versão 2.3.15) - Outubro 1997 (versão 2.2.0)]
+ Julho 2000 (versão 2.4.0?)
= Março 2004.
Logo não se preocupe até 2004.
9. Misturando NAT e Filtragem de Pacotes
É muito comum a utilização de Network Address Translation (veja o NAT
HOWTO) em conjunto com a filtragem de pacotes. A boa notícia é que
eles se misturam muito bem.
Primeiramente, você projeta e constrói seu filtro de pacotes ignorando
totalmente qualquer NAT a ser feito. As origens e destinos que o
filtro de pacotes verá serão as origens e destinos reais. Por exemplo,
se você fará DNAT para mandar conexões do endereço 1.2.3.4 porta 80
para 10.1.1.1 porta 8080, o filtro de pacotes verá pacotes indo para
10.1.1.1 porta 8080 (o destino real), e não 1.2.3.4 porta 80.
Similarmente, você pode ignorar o masquerading: os pacotes vão parecer
que têm como origem o real enderço IP interno (por exemplo 10.1.1.1),
e as respostas vão parecer que têm como destino esse mesmo endereço.
Pode-se utilizar a extensão de checagem do estado dos pacotes (state
match) sem fazer com que o filtro de pacotes tenha qualquer trabalho
extra, uma vez que NAT já requer acompanhamento de conexão. Para
melhorar o simples exemplo de masquerading descrito no NAT HOWTO a fim
de rejeitar quaisquer novas conexões vindo na interface ppp0, isso
seria feito:
# Fazer masquerade pela interface ppp0
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# Rejeitar conexões novas (NEW) e inválidas (INVALID) de pacotes com destino à
maquina local ou que devem ser repassados vindos de ppp0.
iptables -A INPUT -i ppp0 -m state --state NEW,INVALID -j DROP
iptables -A FORWARD -i ppp0 -m state --state NEW,INVALID -j DROP
# Habilitar IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
10. Diferenças entre iptables e ipchains
· Primeiramente, os nomes das chains padrão passaram a ser escritos
com MAIÚSCULAS em vez de minúsculas, porque as chains INPUT e
OUTPUT apenas recebem pacotes destinados localmente e gerados
localmente. Antes, essas chains viam todos os pacotes entrando e
saindo, respectivamente.
· A flag `-i' agora significa interface de entrada, e apenas funciona
nas chains INPUT e FORWARD. Regras nas chains FORWARD e OUTPUT que
utilizavam `-i' devem ser alteradas para `-o'.
· Portas TCP e UDP agora precisam ser descritas com as opções
--source-port ou --sport (ou --destination-port/--dport), que devem
se colocadas depois das opções `-p tcp' ou `-p udp', já que essas
carregam as extensões TCP ou UDP respectivamente.
· A flag TCP -y agora é --syn, e deve ser posicionada depois de `-p
tcp'.
· Finalmente o alvo DENY agora é DROP.
· Zerar chains enquanto listando-as funciona.
· Zerar chains padrão também apaga os contadores de suas políticas.
· Listar as chains também mostra os contadores.
· REJECT e LOG são agora alvos-extensões, ou seja, eles são módulos
do kernel separados
· Nomes das chains podem ter até 31 caracteres.
· MASQ agora é MASQUERADE e utiliza uma sintaxe diferente. REDIRECT,
embora tenha mantido o nome, também sofreu uma mudança de sintaxe.
Veja o NAT HOWTO para mais informaçoes sobre como configurar ambos.
· A opção -o não é mais utilizada para mandar os pacotes para o
dispositivo userspace (veja -i acima). Pacotes agora são mandados
para o espaço do usuário com o alvo QUEUE.
· Provavelmente milhares de outras coisas que esqueci.
11. Conselhos sobre o projeto de filtros de pacotes
Um desejo comum na área de segurança de computadores é bloquear tudo,
e então abrir os buracos necessários. Isso pode ser chamado de "o que
não está explicitamente permitido, é proíbido". Eu recomendo essa
visão para uma maior segurança.
Não rode nenhum serviço desnecessário, mesmo que você ache que
bloqueou o acesso aos mesmos
Se você está criando um firewall dedicado, comece sem rodar qualquer
serviço, e bloqueando todos os pacotes, e então adicione serviços e vá
deixando os pacotes passarem conforme necessário.
Recomendo segurança profunda: combine tcp-wrappers (para conexões na
própria máquina do filtro de pacotes), proxies (para conexões que
apenas passam pelo filtro de pacotes), verificação de rotas e
filtragem de pacotes. Verificação de rotas é quando um pacote vem de
uma interface inexperada ele é descartado: por exemplo, se a sua LAN
possui endereços 10.1.1.0/24, e um pacote com essa origem vem pela sua
interface externa, ele será descartado. Isso pode ser habilitado para
uma interface (ppp0) conforme descrito abaixo:
# echo 1 > /proc/sys/net/ipv4/conf/ppp0/rp_filter
#
Ou para todas as interfaces existentos e futuras conforme abaixo:
# for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
# echo 1 > $f
# done
#
Debian faz isso por padrão sempre que possível. Se você tem roteamento
assimétrico (exemplo, você espera pacotes vindos de locais estranhos)
você vai querer desabilitar esse tipo de filtragem nessas interfaces.
Registrar (logging) é muito útil em um firewall para saber se algo não
está funcionando corretamente, mas em um firewall de produção é sempre
interessante utilizar o controle de limite (limit match), a fim de
prevenir que alguém faça flood em seus logs.
É altamente recomendado o acompanhamento de conexões para sistemas
seguros: isso provoca um pouco de overhead, uma vez que todas as
conexões são acompanhadas, mas é muito útil para controlar os acessos
à sua rede. Você terá de carregar o módulo `ip_conntrack.o' se seu
kernel não carrega módulos automaticamente, ou ele não está compilado
diretamente no kernel. Se você quer acompanhar conexões de protocolos
complexos, você terá de carregar um módulo auxiliar apropriado (por
exemplo, `ip_conntrack_ftp.o').
# iptables -N no-conns-from-ppp0
# iptables -A no-conns-from-ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A no-conns-from-ppp0 -m state --state NEW -i ! ppp0 -j ACCEPT
# iptables -A no-conns-from-ppp0 -i ppp0 -m limit -j LOG --log-prefix "Bad packet from ppp0:"
# iptables -A no-conns-from-ppp0 -i ! ppp0 -m limit -j LOG --log-prefix "Bad packet not from ppp0:"
# iptables -A no-conns-from-ppp0 -j DROP
# iptables -A INPUT -j no-conns-from-ppp0
# iptables -A FORWARD -j no-conns-from-ppp0
Construir um bom firewall está além do escopo deste HOWTO, mas meu
conselho é "sempre seja detalhista". Veja o HOWTO Segurança (Security
HOWTO) para mais informações sobre como testar sua máquina.
Tradução para o Português do Brasil: Guilherme Ude Braz
(guilherme@linuxplace.com.br).