Вы находитесь на странице: 1из 43

IPFW­HOWTO

Atenção:  este  documento  apesar  de  datado,  é  ainda  considerado  prático,  e  a  melhor  introdução  ao 
IPFIREWALL(4) disponível publicamente na Internet. Todas as informações aqui disponíveis continuam 
válidas e aplicáveis nas versões mais recentes do FreeBSD. Contudo, uma série de recursos não são 
documentados neste documento, a saber:

• Controle de Banda e QoS com WF2Q+

• ;Suporte ALTQ;

• Blocos OR;

• Tabelas e análise binária avançada;

• Grupos de Regras;

• Marcação de Pacotes;

• Filtro de Camada 2;

• Filtro de Camada 7 em conjunto com Netgraph;

• Balanceamento e Redundância de Firewall (IPFW TEE);

• Recursos anti­spoof nativos;

• Filtro IPv6;

• Outros de menor relevância;

O leitor deste documento é fortemente indicado a obter mais informações sobre os recursos acima. As 
fontes de informação recomendadas são o histórico da lista de discussões FUG­BR e o livro  FreeBSD: 
Poder para Servir, de Patrick Tracanelli e Jean M. Melo, este que por sua vez documenta todos os tópicos 
não abordados aqui, com amplos detalhes.

Este documento está em plena sincronia com a versão 0.4 deste HOW­TO. A diferença entre a versão 0.3 e a  
0.4 são correções ortográficas em língua inglesa.

Este   documento   encontra­se   disponível   no  website  da   FreeBSD   Brasil   por   referência   histórica 
(especialmente links referenciados por engines de busca). O endereco permanente deste documento em 
sua versão original é:

http://free.bsd.com.br/~eksffa/freebsd/ipfw.txt

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

V.0.3br_pt

Se existirem perguntas ou comentários, por favor, envie-os para


walt@erudition.net. A versão mais recente desse documento vai estar sempre
disponível em www.freebsd-howto.com. Os direitos de reprodução desse documento
são reservados. Versão em português desse documento sob responsabilidade de
Patrick Tracanelli (eksffa@freebsdbrasil.com.br) e Maurício Goto (freebsd-
brasil@uol.com.br). A versão mais recente do mesmo estará sempre disponível em
http://free.bsd.com.br/~eksffa/freebsd/ipfw.txt

Sumário.

1. Informacoes gerais sobre a Filtragem de Pacotes de Rede


2. Acionando o Ipfirewall(4)

2.1. O /etc/rc.firewall e firewalls com política aberta


(OPEN firewalls)
2.2. Carregando Rulesets (conjunto de regras)

2.2.1. Tipos de Firewall pré-definidos


2.2.2. Tipos de Firewall Personalizado

3. Sintaxe de regras básicas do Ipfw(8)

3.1. Listando Regras Ativas


3.2. Comandos básicos e suas funções
3.3. Especificando Protocolos
3.4. Especificando endereços de Origem e de Destino

3.4.1. Uma introdução à Netmask e Bitmask


3.4.2. Especificando Portas e Faixas de Portas

4. Sintaxe de regras avançadas do ipfw(8)

4.1. A ação "unreach"


4.2. Controle de Interface e de Fluxo
4.3. Combinando tipos de pacotes ICMP e TCP específicos

4.3.1. icmptypes
4.3.2. tcpflags, setup & established
4.3.3. ipoptions

4.4. Reconhecendo Pacotes Fragmentados


4.5. Filtragem baeada em UID e GID

5. Logs (Logging)

5.1. Propriedades de Logs


5.2. Configurações de Logs do sistema

5.2.1. Opções do Kernel

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

5.2.2. Configurando o syslog(8)


5.2.3. Configuração do newsyslog(8) pra fazer
rotacionamento de logs (log rotation)

5.3. Configuração de log nas regras

6. Introdução à filtragem 'Stateless' e 'Stateful' de pacotes

6.1. Configurações 'Stateful' Iniciais


6.2. Configurações 'Stateful' Avançadas
6.3. Anatomia de uma Regra Dinâmica

7. Traffic Shapping (controle de tráfego)

7.1. Probabilidade de Ocorrências (Probability Matching)


7.2. Dummynet

7.2.1. Enfileiramento de pipes (Pipe Queues)


7.2.2. Máscaras de pipes (Pipe Masks)
7.2.3. Remanejamento de pacotes por pipes (Packet
Reinjection)

8. Fluxo do Tráfego pelo Firewall

Apêndice A: Exemplos de Configurações de Firewall;

1. Informacoes gerais sobre a Filtragem de Pacotes de Rede;

IPFW(8), a interface de comando do IPFIREWALL(4) é o utilitário mais


comum e mais popular pra implementar a filtragem de pacotes IP e controle de
tráfego de rede no FreeBSD, e é a ferramenta de FIREWALL nativa com a qual o
FreeBSD trabalha por padrão (mesmo considerando que, inicialmente o firewall é
desabilitado a nível de kernel). A forma lógica como o IPFW trabalha suas
regras é parecida com a adotada em muitos outros filtros de pacotes (Packet
Filters), com excessão do IPFilter, que opera com um padrão pra tratar as
regras que é menos eficiente e requer bem mais cuidado na hora de ajustar o
firewall (se você tem familiaridade com o ipf(8), por exemplo, perceba a
utilização da chave 'quick', necessária para que o ipf(8) não traverse a regra
inteira, todas as vezes que ela é lida; entre outros fatores particulares de
utilização do IPFilter). Mas isso não tira a qualidade e o poder de
implementação de firewalls do ipf(8), que tem também suas próprias vantagens. A
escolha final em relação a qual ferramenta de Filtragem de Pacotes utilizar, é
uma decisão pessoal, a não ser que você tenha necessidade de alguma
característica de um Firewall que o outro não possua, contudo, nós vamos
abordar uma comparação entre as duas ferramentas posteriormente.

Como já dito antes, ipfirewall(4) é um firewall por filtragem de


pacotes, o que significa que ele atua monitorando pacote-a-pacote todas as
conexões, e a partir da série 4.x do FreeBSD (FreeBSD 4.0), o ipfirewall(4)
também pode gerenciar uma filtragem por estado (stateful) de conexões mais
rudimentares, de acordo com estados de conexão. Esse comportamento é sempre
transparente pros usuários, ou seja, ninguém vai notar que existe um firewall
presente, até que um evento aguardado seja bloqueado.

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

Um firewall costuma ser arquitetado de diversas formas, mas todas as


maneiras podem ser simplificadas com base em duas políticas de filtragem:
aberto e fechado. O Firewall que segue uma política aberta permite que todos os
pacotes sejam roteados por padrão, e bloqueia aqueles que pertencem a um tipo
de conexão que não é desejado, ou seja, "abre tudo e bloqueia os indesejados".
Já o firewall que segue uma política fechada, faz o inverso, bloqueando todo o
roteamento de pacotes, e libera um a um o tráfego de conexões permitidas. Essa
segunda implementação proporciona um firewall muito mais rígido, contudo sua
configuração é bem mais trabalhosa, porque você pode facilmente bloquear o
tráfego de algum serviço que esteja sendo utilizado na rede. Alguns protocolos
estabelecem conexões dinâmicas, que são bem mais difíceis de se prever, mas
você tem como estar atento a esse tipo de situação.

2. Acionando o Ipfirewall(4);

O ipfirewall(4) pode ser iniciado de duas formas: você pode adicionar


as opções apropriadas no seu kernel através do seu arquivo de configurações, e
compilar um novo kernel pro seu sistema; ou você pode usar o kldload(8) pra
carregar dinâmicamente o módulo base do ipfw(8), o ipfw.ko, no kernel. As duas
abordagens funcionam bem pra adicionar um firewall(4) com configurações
básicas, contudo, a compilação estática proporciona, com pouca diferença, uma
melhor performance, mas permite ainda que se adicione opções mais detalhadas de
configuração, como por exemplo, a geração e limitação de logs.

Pra carregar o ipfw de forma dinâmica, simplesmente use o comando:

root@eeviac~# kldload ipfw


root@eeviac~#

Pra acionar o ipfirewall(4) de forma estática, o equivalente seria


adicionar a seguinte linha no arquivo de configurações do seu kernel:

options IPFIREWALL

Em seguida a compilação e instalação acionaria o ipfirewall(4) estático


no kernel, logo após a próxima inicialização do sistema.

Contudo, as coisas não são tão simples quanto parecem, se você


simplesmente seguir os passos descritos acima quando estiver na frente da
máquina, vai perceber que existe a necessidade de algumas opções adicionais pra
poder usar a estação. Se você prestar atenção nos conceitos de política de
firewall citados acima (aberto e fechado), vai entender porque o uso do
equipamento vai se complicar muito, se você não perceber que o firewall usa uma
política padrão fechada. Se você simplesmente adicionar o ipfirewall(4) sem
nenhuma configuração posterior, todo o tráfego de rede vai ser bloqueado, ou
seja, nenhum pacote será roteado. Isso fatalmente pode se tornar um tormento se
você for adicionar o firewall remotamente. É claro que esse tipo de dor de
cabeça pode ser evitada, mesmo considerando que não é recomendado acionar o
ipfirewall(4) remotamente, tanto de forma estática quanto dinâmica.

Se, de qualquer maneira, você quiser carregar o ipfirewall(4) de um


computador remoto, então recomendados que se faça da seguinte forma:

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

root@eeviac~# kldload ipfw && \


ipfw -q add 65000 allow all from any to any
root@eeviac~#

Assim você vai automaticamente adicionar uma regra pra permitir todo o
tráfego da rede, ao invés de bloquea-lo, evitando assim que você perca a
conexão com a máquina remota. De qualquer forma, é recomendável que se carregue
o ipfirewall(4) dessa maneira em máquinas locais também, especialmente se elas
estiverem conectadas em rede, pra não perder uma conexão em andamento.

Acionar o ipfirewall(4) no kernel, de forma estátita em uma máquina


remota, contudo, requer um pouco mais de trabalho. O motivo é simples, quando
você termina de instalar um novo kernel, você é obrigado a rebootar a sua
máquina, ai sim, a partir da próxima inicialização ela irá utilizar o novo
kernel. Contudo se você somente adicionar o ipfirewall(4) no kernel, assim que
o sistema estiver no ar, ele não vai estar roteando os pacotes, ou seja, você
não vai conseguir estabelecer uma conexão remota novamente com a máquina. Então
antes de inicializar o sistema com um novo kernel você tem que definir alguma
maneira pra máquina aceitar a sua conexão, pra que assim você não seja
bloqueado pelo seu próprio firewall.

Pra você fazer isso, basta adicionar duas linhas no seu rc.conf, uma
que vai acionar o firewall na inicialização da máquina, e outra pra definir o
tipo de firewall que vai ser iniciado. No caso firewall do tipo aberto (OPEN).
Então basta adicionar as seguintes entradas no seu /etc/rc.conf:

firewall_enable="YES"
firewall_type="OPEN"

Existem ainda outros tipos de firewall previamente definidos no


/etc/rc.firewall, mas nós vamos tratar deles posteriormente. Por enquanto vamos
começar com uma política de firewall aberta (OPEN). Ainda existe uma
alternativa muito boa pra se definir uma política aberta como padrão pro
ipfw(8) no kernel. Você pode simplesmente adicionar a seguinte linha no arquivo
de configuração do seu kernel:

options IPFIREWALL_DEFAULT_TO_ACCEPT

Nesse caso, as opções que nós adicionamos no rc.conf anteriormente não


serão *necessárias*, porque nós não vamos *precisar* do /etc/rc.firewall pra
configurar uma política aberta de firewall, porque essa política já vai ser
iniciada por padrão no kernel. Contudo, ainda que você escolha definir uma
política de firewall padrão no kernel, é interessante adicionar aquelas opções
ao /etc/rc.conf porque posteriormente nós vamos usar o /etc/rc.firewall pra
carregar nossas próprias regras de configurações de firewall. Adicionar essas
opções ao /etc/rc.conf também é válido se você vai carregar o kernel
dinâmicamente, porque se eventualmente seu sistema for reinicializado, o módulo
ipfw.ko não vai ser carregado de forma automática. As funções de carregamento
do firewall pelo /etc/rc.conf permite-nos carregar o módulo ipfw.ko
automaticamente.

Ainda existem outras opções pro ipfirewall(4) que são possíveis se nós
formos acionar o firewall de forma estática no kernel, até o início da série
4.x do FreeBSD algumas dessas opções não podiam ser acionadas se não fosse de

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

forma estática no kernel, mas nas versões mais recentes foram definidas
algumas variávies do kernel, mutáveis via sysctl(8), que não restringem mais
essas opções ao kernel estático. Além do IPFIREWALL_DEFAULT_TO_ACCEPT nós ainda
temos as seguintes opções:

options IPFIREWALL_VERBOSE
options IPFIREWALL_FORWARD
options IPFIREWALL_VERBOSE_LIMIT=#

A opção IPFIREWALL_VERBOSE permite logar o tráfego de pacotes com o


ipfirewall(4), ecoando informações sobre atividade dos pacotes pro syslogd(4),
em cada regra que tiver a opção "log" definida. Vamos aborda-la com mais
detalhes posteriormente.

A opção IPFIREWALL_FORWARD permite que os pacotes sejam redirecionados


para outros hosts, utilizando o comando "fwd" do ipfirewall(4). Redirecionar o
pacote (FORWARD) é fazer com que ele siga de um ponto específico (host, rede,
porta) para outro. Vamos tratar desse assunto com mais detalhes ao longo do
documento.

A opção IPFIREWALL_VERBOSE_LIMIT=# define um limite de pacotes que


serão logados para uma regra específica. Dessa forma, o syslogd(8) não será
sobrecarregado com mensagens relativas à atividades do ipfirewall(4), os
comentários do kernel para essa opção diz que isso é uma forma de evitar
negação de serviço com os logs gerados para algumas regras de firewall, caso um
possível ataque gere muitas ocorrências da mesma regra. O "#" deve ser
substituído com o número de vezes que se deseje que as atividades de cada regra
seja logada. Dessa forma, se definirmos, por exemplo
IPFIREWALL_VERBOSE_LIMIT=100 (padrão), quando existirem 100 ocorrências da
mesma regra, as informações sobre a atividade de pacotes daquela regra deixará
de ser logada.

Se você usa IPv6, as seguintes opções no kernel terão efeito


correspondente sobre as ações do firewall quanto a pacotes IPv6:

options IPV6FIREWALL
options IPV6FIREWALL_VERBOSE
options IPV6FIREWALL_VERBOSE_LIMIT=100
options IPV6FIREWALL_DEFAULT_TO_ACCEPT

Pra habilitar as mesmas opções do ipfirewall(4) sem recompilar o seu


kernel, você vai definir as variáveis correspondentes por meio do sysctl(8),
por exemplo:

eksffa@eeviac~# sysctl -w net.inet.ip.fw.verbose=1


eksffa@eeviac~# sysctl -w net.inet.ip.fw.verbose_limit=100
eksffa@eeviac~# sysctl -w net.inet.ip.forwarding=1

Ainda existem mais quatro opções relacioadas ao ipfirewall(4) que podem


ser definidas no kernel, mas não serão discutidas no momento, porque não são
necessárias para a implementação básica de um firewall. Essas opções envolvem
situações mais complexas e específicas de roteamento de pacotes, e vamos tratar
delas assim que começarmos a tratar essas configurações.

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

2.1. O /etc/rc.firewall e firewalls com política aberta (OPEN firewalls);

Ainda que você defina ou não o tipo de firewall que você vai estar
trabalhando, sempre que a opção firewall_enable="YES" é adicionada no rc.conf e
o sistema é iniciado, o /etc/rc.firewall é lido e executado também, a partir
das configurações definidas no rc.conf, e os seguintes comandos são sempre
adicionados ao ipfw(8):

${fwcmd} add 100 pass all from any to any via lo0
${fwcmd} add 200 deny all from any to 127.0.0.0/8

A variável ${fwcmd} é definida anteriormente no rc.firewall, implicando


quando o ipfw(8) vai ser executado de forma silenciosa (opção -q) ou não. A
primeira regra em questão, permite todo tráfego proveniente da interface de
loopback (a lo0), e a segunda regra bloqueia todo o tráfego direcionado à rede
localhost (127.0.0.0). A primeira regra é necessária pra permitir comunicação
inter-processos locais (local IPC), e a segunda regra evita que qualquer pacote
externo adentre o endereço de host local (localhost address), que é o endereço
de loopback, protegendo assim o tráfego local. Se essas regras não existirem e
o firewall tiver uma política padrão fechada, você vai encontrar problemas na
inicialização de alguns serviços, especialmente serviços RPC(3), entre outros
problemas.

Por isso vale ressaltar a impostância de se definir o firewall da forma


correta, onde o uso do /etc/rc.firewall via rc.conf é altamente recomendável.
Se você fizer a opção por um script shell que carregue todas as suas regras e
que seja executado sempre que o sistema iniciar, você deve ficar atento a essas
e outras regras que não devem faltar ao seu firewall.

Em seguida, quando você define um firewall do tipo "OPEN" (aberto) no


rc.conf, o rc.firewall ativa a seguinte regra no firewall:

${fwcmd} add 65000 pass all from any to any

Essa regra permite que todo tráfego externo seja aceito como entrada
(com excessão pro loopback, já que a rede localhost é previamente bloqueada) e
todo o tráfego interno seja aceito como saída. A mesma função do
IPFIREWALL_DEFAULT_TO_ACCEPT no kernel. Se a política aberta é definida no
kernel, a regra número 65535 vai ser automaticamente carregada como "allow ip
from any to any" no lugar de "deny ip from any to any", posteriormente
adicionando a regra número 65000. Isso cria uma redundância de política de
firewall aberta. Então, é mais indicado definir o tipo de firewall como
"UNKNOWN" (desconhecido) se você adicionou a política aberta
(IPFIREWALL_DEFAULT_TO_ACCEPT) no kernel, e não quer permitir mais nenhuma
regra do rc.firewall. Para isso, inclua as seguintes linhas no seu
/etc/rc.conf:

firewall_enable="YES"
firewall_type="UNKNOWN"

Se você quer simplesmente habilitar o firewall para trabalhar algumas

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

regras e ver como o ipfirewall(4) do FreeBSD funciona, ou ainda, apenas


bloquear alguns hosts específicos, e manter as suas configurações propícias às
suas próprias regras, então você pode seguramente pular pro nosso capíulo 3.

Contudo, se sua intenção é usar algum dos conjuntos de regras nativas


já existentes no rc.firewall, ou criar seu próprio conjunto de regras, então as
opções "OPEN" ou "UNKNOWN" não são suficientes. Então não pule pra seção 3
(lol).

2.2. Carregando Rulesets (conjunto de regras);

Existem duas opções distintas em relação à um comjunto de regras pro


seu firewall: a primeira opção é usar uma das definições de firewall já
existentes no rc.firewall, e a segunda é criar sua própria definição, com seu
próprio conjunto de regras. Os autores do firewwall nativo do FreeBSD,
ipfirewall(4), recomendam o segundo caso, por duas rasões simples:

- Você pode customizar suas regras de firewall pra satisfazerem da


melhor forma as suas necessidades, sem nunca tocar no rc.firewall, que pode ser
mantido como uma referência geral sempre que você precisar.

- Você vai ser obrigado a se familiarizar com o uso do ipfw(8) e sua


sintaxe, se tornando mais experiente na definição de firewall, e ficando mais a
vontade com o ipfw(8).

2.2.1. Tipos de Firewall pré-definidos;

É óbvio que a decisão final é a do administrador da rede, ou do


responsável pelo firewall, no caso você que está lendo esse documento. Se você
preferir usar os conjuntos de regras de firewall pré-definidos no rc.firewall,
então é recomendado que você leia todas elas, pra se tornar familiar e saber
exatamente como cada tipo de firewall funciona, antes de ativar qualquer um dos
tipos pré-definidos. O controle que gerencia qual definição de firewall
carregar é feito pela opção firewall_type="" no rc.conf. Além de "OPEN" existem
ainda mais 3 tipos de firewall disponíveis:

"CLIENT" - Essa definição de tipo de firewall (firewall_type) permite


todo o tráfego proveniente da rede local (por exemplo, uma rede interna atrás
de NAT) pra ela mesma. Bloqueia pacotes fragmentados, permite que mensagens de
email, resoluções de nomes (DNS) e NTP sejam enviadas pra dentro e fora da
rede, e não permite nenhuma máquina que esteja fora da rede interna iniciar
conexões TCP com máquinas dentro da rede. Se a rede estiver por trás de uma
implementação básica de NAT sem nenhuma opção de proxie carregada isso já seria
impossível. Esse tipo de firewall funciona com política aberta ou fechada,
definida no kernel, ou seja, não faz diferença se você colocou
IPFIREWALL_DEFAULT_TO_ACCEPT ou IPFIREWALL_DEFAULT_TO_DENY como padrão.

"SIMPLE" - Esse tipo de firewall é uma contradição. Apesar do nome


SIMPLE, ele é muito mais complexo que a definição CLIENT, e requer que o
usuário tenha algum conhecimento nos padrões RFC de Internet pra poder entender
suas definições de regras de firewall. Essa regra vai evitar spoofing (técnica
onde uma máquina se faz passar por outra, alterando seu endereçamento IP) não

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

permitindo a entrada de nenhum pacote que tenha um endereço de retorno igual ao


endereço de qualquer host dentro da rede interna. Vai bloquear todos os pacotes
endereçados como de redes privadas, conforme definido na RFC 1928, evitando o
tráfego pra dentro ou fora da rede, e vai bloquear ainda todas as redes não-
roteaveis, conforme definido no Internet-Drafts da IETF (disponível em
http://www.ietf.org/internet-drafts/draft-manning-dsua-03.txt). Esse tipo de
firewall vai permitir tráfego de e-mail, de WWW, de DNS, e NTP, e vai permitir
também pacotes fragmentados, e em relação às conexões TCP iniciadas por hosts
fora da rede, o firewall não vai apenas bloquear, como na definição CLIENT, vai
também logar todas essas tentativas.

"CLOSED" - Tecnicamente essa definição não é um conjunto de regras de


firewall, porque não adiciona nenhuma regra. Na verdade, aqui acontece tudo que
nós insistimos que você deve evitar, ou seja, estabelece uma política fechada,
negando todo e qualquer tráfego da rede (exceto o tráfego via lo0 que nós vimos
anteriormente que é controlado por padrão). Essa definição simplesmente
desabilita todos os serviços IP na rede, a não ser que no seu kernel você tenha
adicionado a regra de política aberta. Então, ajustar o firewall pra CLOSED vai
ser necessário em casos *extremos* onde você prefere (ainda que
temporariamente) tirar toda a sua rede de funcionamento. Ou seja, não defina
como padrão no rc.conf.

2.2.2. Tipos de Firewall Personalizado;

Se você decidiu estabelecer um conjunto de regras customizado, então é


recomendável que você especifique um arquivo, ao invés de um dos tipos de
firewall abordados acima. A maneira de se estabelecer esse tipo personalizado
de firewall é a mesma, utilizando a opção firewall_type no rc.conf, contudo,
basta indicar o caminho (path) pro seu arquivo de regras:

firewall_enable="YES"
firewall_type="/etc/rc.firewall.rules"

Dessa forma você vai poder definir sua própria configuração de firewall
no arquivo /etc/rc.firewall.rules, o qual será carregado sempre que seu
firewall for iniciado. Se você preferir ainda que seu firewall seja iniciado de
forma silenciosa, basta incluir no rc.conf:

firewall_quiet="YES"

O formato do seu conjunto de regras será apresentado de forma um


pouquinho diferente nesse arquivo, em relação ao que você encontra no
rc.firewall. O motivo é simples, o rc.firewall é um 'shell script' sh(1)
escrito de forma que possa rodar por si próprio, enquanto o arquivo que define
as suas regras personalizadas estão ali simplesmente para serem processadas
pelo ipfw(8). A principal diferença é que você não vai usar nada correspondente
à variável ${fwcmd} usada no rc.firewall. Simplesmente as regras.
Posteriormente, vamos construir um arquivo de regras próprio, e então vamos ver
isso passo-a-passo.

3. Sintaxe de regras básicas do Ipfw(8);

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

A sintaxe das regras de firewall no FreeBSD são simples. Qualquer regra


pode ser adicionada pelo console, com o comando ipfw(8). Antes de nos
aprofundarmos nas sintaxes das regras do ipfirewall(4), contudo, vamos
verificar como podemos listar as regras que estão ativas no momento.

3.1. Listando Regras Ativas;

A forma mais simples possível de se listar as regras ativas no


firewall:

root@eeviac~# ipfw list

Dessa forma, você vai estar listando todas as regras ativas no momento,
seguindo a ordem do número da regra. Por exemplo:

root@eeviac~# ipfw list


00101 deny log logamount 100 tcp from any to 192.168.1.0/24 12345
00102 deny log logamount 100 tcp from any to 192.168.1.0/24 21
00103 allow tcp from any any
65535 deny all from any to any

Dessa forma, ainda que, a regra número 00103 tenha sido adicionada
antes da regra 00101, a de número menor será mostra antes, porque a ordem das
regras também influi na forma como o ipfirewall(4) vai se comportar.

Pra mostrar a data e hora da última vez que um pacote coincidiu com uma
regra basta usar a opção timestamp do ipfw(8):

root@eeviac~# ipfw -t list


00101 Fri Sep 21 06:31:23 2001 deny log logamount 100 tcp from any to
192.168.1.0/24 12345
00102 Tue Sep 18 00:33:12 2001 deny log logamount 100 tcp from any to
192.168.1.0/24 21
00103 Sat Sep 22 19:12:15 2001 allow tcp from any any
65535 deny all from any to any

root@eeviac~# date
Sat Sep 22 19:12:24 GMT 2001

Ou seja, nesse caso, a última vez que a regra 00101 bloqueou um pacote
foi na madrugada do dia anterior, a regra 00102 bloqueou um pacote também aos
33 minutos de 2 dias atrás, e o último pacote permitido pelo firewall foi há 9
segundos. Detalhe no comando date posterior que ilustra a data corrente.

Por último, se nós queremos listar o número de vezes que um pacote


passou (ou foi bloqueado) por uma regra, e o número de bytes que esse tráfego
gerou, podemos fazer o seguinte:

root@eeviac~# ipfw -a list

ou

root@eeviac~# ipfw show

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

Os dois comandos vão apresentar as mesmas informações, dispostas da


mesma maneira. A primeira coluna é o número da regra, em ordem como ela é
verificada. A segunda coluna informa quantas vezes aquela regra coincidiu com
um pacote, seguido do (terceira coluna) número de bytes que trafegaram pela
regra, e finalmente a regra em sí. Existem algumas sintaxes curtas pra esses
comandos. Por exemplo, "ipfw s" tem o mesmo efeito que "ipfw show"; "ipfw l" o
mesmo que "ipfw list", etc.

3.2. Comandos básicos e suas funções;

A partir de agora nós vamos, gradualmente, analisarmos cada opção e


comandos disponíveis pra se construir um conjunto de regras de firewall. Por
enquanto não vamos abordar regras com as opções de stateful, ou seja, estaremos
trabalhando com regras stateless. Durante os nossos exemplos, não vamos estar
utilizando o programa de controle do firewall (o /sbin/ipfw), que deve preceder
cada um dos nossos comandos, caso estejamos configurando as regras de forma
manual, pelo console do FreeBSD. O padrão abordado é como deve ser quando
estamos trabalhando com um arquivo de regras pra ser passado pro ipfw(8) via
firewall_type="/caminho/pro/arquivo.firewall" no rc.conf.

add 1000 allow all from any to any

Esse é o exemplo mais simples de uma regra. Nós já encontramos a mesma


regra anteriormente, com uma única diferença, que era o número da regra.
Lembre-se que, na seção 2.1 quando nós discutimos sobre tipos de firewall
"OPEN" (aberto) nós trabalhamos com o parâmetro "pass", que é como ele foi
usado no rc.firewall. Bom, acontece que "pass", "allow" e "permit" são
sinônimos pro ipfirewall(4), eles tem o mesmo efeito, contudo as variações
permitem que o administrador fique o mais a vontade possível para escrever as
suas regras quase que de forma literal. Nessa regra, "all" (todos) os pacotes
vindos de "any" (qualquer) lugar para "any" (qualquer) destino são permitidos
("allow").

No ipfirewall(4), grande parte das vezes, sempre que um pacote combinar


com uma regra, o ipfirewall(4) pára de examinar as outras regras pra aquele
pacote, ou seja, a ordem como as regras são processadas no firewall do FreeBSD
são do tipo "first match wins" onde, a primeira constatação do pacote evita que
as outras sejam lidas. Por isso é extremamente importante estar atento a ordem
(número) das regras. Sob circunstâncias especiais as outras regras podem ser
procesadas.

Então, de forma geral, a sintaxe mais simples pro ipfw(4) é:

<comando> [<número da regra>] <ação> <protocolo> from <origem> to


<destino>

Os <comandos> mais importantes são "add" e "delete". Uma simples


tradução seria o suficiente pra explicar que "add" adiciona uma regra e
"delete" a exclui. O <número da regra> varia de 0 até 65535, e indica a ordem
que essas regras serão processadas no firewall, portanto a última regra sempre
define a política padrão do firewall no kernel. Mesmo se você tiver uma
política de firewall aberta (OPEN) definida no seu /etc/rc.conf, a última regra
vai sempre indicar a política do kernel. Isso é ótimo porque, como a ordem de
busca das regras para de processar ao encontrarem uma regra que combina com o

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

pacote, e se a penúltima regra é a de número 65000, definida pelo rc.firewall


pra permitir todo o tráfego da rede, então todo tráfego vai ser liberado, mesmo
que a última regra (65535) negue todos os pacotes, já que essa regra nunca vai
ser processada.

"<ação>" na sintaxe do ipfw(8) pode ser uma das seguintes:

"allow" | "pass" | "permit" | “accept” - Quando uma regra define essa


ação, sempre que um pacote combinar com essa regra, será permitido seu
roteamento pelo firewall, e o processamento das regras *pra esse pacote*
termina.

"deny" | "drop" - Qualquer pacote que combinar com uma regra cuja ação
seja "deny" ou "drop" são silenciosamente bloqueados pelo firewall, e o
processamento das regras *pra esse pacote* termina.

add 1100 deny all from any to any

Essa regra nega todos os pacotes vindos de qualquer origem e indo pra
qualquer destino.

"reset" - Quando um pacote encontra uma regra com essa ação, o pacote é
bloqueado, e o ipfirewall(4) tenta enviar um sinal (flag) de TCP Reset (RST)
pro endereço de origem do pacote. O processamento das regras *pra esse pacote*
termina. Como esse tipo de regra apenas se aplica pra pacotes TCP, o protocolo
especificado na regra deve ser "tcp", para que apenas tais pacotes sejam
processados por essa regra, e não todos (proto "all") os protocolos de pacotes
IP.

Vale notar que o uso do "reset" pode ser muito interessante pra enganar
ferramentas que escaneiam as redes (network scanners), já que normalmente podem
detectar um serviço por trás de uma porta filtrada, mesmo que ele esteja por
trás de um firewall de bloqueio. Por outro lado, se alguém estiver praticando
um ataque do tipo "network flood" em uma porta específica a qual o
ipfirewall(4) está configurado para responder com pacotes RST, isso duplicaria
o uso da sua banda de rede. Uma solução simples é bloquear, com uma regra
prévia o endereço da máquina que está agindo dessa forma, endereço esse obtido
de forma dinâmica por monitoramento.

add 1200 reset tcp from any to any

Essa regra 'precária' (risos) bloquearia todas as conexões TCP vindas


de qualquer destino, indo para qualquer origem, e responderia com um pacote RST
para cada uma delas.

"count" - Todos os pacotes que combinarem com uma regra cuja ação seja
"count", determinará que o ipfirewall(4) incremente o contagem de pacotes, ou
seja, a saída de "ipfw show" indicará mais uma ocorrência de pacotes nessa
regra. Motivos estatísticos óbvios. O processamento das regras do firewall
continuam a buscar por outras regras que combinem com os pacotes.

add 1300 count all from any to any


add 1310 count all from 200.230.50.0/24 to 192.168.1.0/24

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

Essa (primeira) regra incrementa o número de vezes que um pacote passou


pelo firewall, vindo de qualquer lugar e indo pra onde quer que seja. Já a
segunda regra conta quantos pacotes, dentre todos, estariam sendo enviados da
rede 200.230.50.0/24 (origem) pra rede 192.158.1.0/24 (destino). Uma observação
aqui: se o processamento das regras fosse terminado quando um pacote encontra
uma regra cuja ação seja "count", então, no exemplo acima a regra 1310 não
teria serventia alguma.

"skipto <número da regra>" - Todos os pacotes que combinem com uma


regra cuja ação seja "skipto <número>" vão fazer com que o ipfirewall(4)
continue processando esse pacote e buscando ocorrência nas regras que sejam de
ordem maior ou igual ao <número da regra> indicado pela ação.

add 1400 skipto 1800 all from 192.168.1.0/24 to any

Essa regra faria com que todo o tráfego vindo da rede 192.168.1.0/24 e
indo pra qualquer destino seja processado pelas regras a partir da regra de
número 1800

"reject" - Essa ação é pouco utilizada atualmente. Quando um pacote


combina com uma regra cuja ação seja "reject", então o ipfirewall(4) bloqueia
esse pacote e responde com uma mensagem ICMP do tipo "host unreachable", dando
a impressão que a máquina se encontra fora da rede. Essa é uma forma não
silenciosa de negar o tráfego pelo firewall, contudo, assim como a ação
"reset", essa ação também aumenta o uso da sua banda de rede.

3.3. Especificando Protocolos;

Protocolo (proto) em "protocolo" na sintaxe básica de uso do ipfw(8), é


o protocolo de comunicação que você quer que aquela regra combine. Definições
de protocolos do tipo "ip" ou "all" são especificações gerais que englobam
todos os protocolos. Os protocolos mais comuns são "icmp", "udp" e "tcp", mas a
relação de protocolos com os quais o ipfirewall(4) trabalha é enorme. Na
verdade são todos os protocolos possíveis de uma rede. Para uma lista completa
das possibilidades, fique a vontade:

root@eeviacbsd~# cat /etc/protocols

3.4. Especificando endereços de Origem e de Destino;

O endereço de destino e de origem de um pacote tem o mesmo formato em


uma regra de firewall. Eles podem ser um nome, definido no /etc/hosts e
resolvido por DNS, pode ser um endereço IP, um endereço de rede com máscara de
rede (bitmask/netmask) e, ainda podem definir uma ou várias portas, se o
protocolo for tcp ou udp. Usar nomes ou endereços IP é indiferente, basta
atentar ao fato que a resolução de nomes via DNS pode mudar sem seu
conhecimento prévio.

add 1000 allow all from minhamaquina to outramaquina


add 1100 deny all from 10.0.0.5 to any

A primeira regra permite todo o tráfego vindo da "minhamaquina" para a


"outramaquina", e a segunda regra nega toda conexão da máquina 10.0.0.5 para
qualquer outra estação. Sempre que um pacote coincidir com uma regra do

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

firewall, o processamento pra aquele pacote termina, e o pacote é permitido ou


negado, de acordo com a ação definida pela regra. Esse é um exemplo muito
simples de um filtro baseado em estações, ou “host-based filtering”, que filtra
de acordo com o destino ou origem do pacote. Um firewall por filtragem de redes
funciona de forma similar, distinguindo-se apenas a notação de redes, onde é
necessário definir a máscara de subrede (netmask) ou ainda o bitmask. Vejamos:

add 2000 allow all from 192.168.0.0/16 to any


add 2100 deny all from any to 10.0.0.0:255.0.0.0

A primeira regra permite todo o tráfego de pacotes vindo da rede cujo


conjunto de endereços IP começa em 192.168.0.0 até 129.168.255.255. A regra usa
uma máscara (bitmask) pra indicar a abrangência do endereçamento da rede. A
máscara em bits também conhecida como bitmask especifica quantos bits do
endereço de rede (192.168.0.0) devem permanecer o mesmo pra cada pacote. Nesse
caso, os primeiros 16 bits dos 32 bits do endereço vão continuar os mesmos.
Como os primeiros 16 bits são os primeiros dois octetos do endereçamento da
rede, então todos os endereços cuja origem seja a indicada nos dois primeiros
octetos (ou nos 16 bits iniciais), nesse caso a rede 192.168, serão permitidos
por essa regra.

A segunda regra tem uma função similar, utilizando as máscaras de rede.


A máscara de rede (netmask) indica quantos bits do endereço de rede deve ser
monitorado pelo regra do firewall. No exemplo acima, a segunda regra (número
2100) tem a máscara de rede 255.0.0.0. O primeiro octeto dessa regra é definido
como 'bits altos', ou seja, os primeiros 8 bits são 'bits altos', o que indica
pro firewall que apenas os pacotes cujos primeiros 8 bits do endereço da rede
devem ser filtrados. Como os primeiros 8 bits da rede é igual a 10, então todos
os pacotes cujo endereço de destino seja 10 no primeiro octeto (ou seja, toda a
faixa de 10.0.0.0 até 10.255.255.255) vão combinar com essa regra, e então
serão bloqueados, como indicado na ação da regra (deny).

O firewall do FreeBSD oferece ainda a possibilidade de inverter a


expressão apresentada na regra com o comando “not”. Por exemplo, para que o
ipfirewall(4) bloqueie todos os pacotes que não seja da estação 192.168.0.3:

add 1000 deny all from not 192.168.0.3

3.4.1. Uma introdução à Netmask e Bitmask;

O princípio básico que envolve máscaras de rede e bits de rede (netmask


e bitmask) são simples, mas frequentemente confundidos por pessoas que não
tenham muito conhecimento em redes, e ainda requer um pouco de noção de números
binários. É muito mais prático se nós trabalharmos com endereço IP em sua forma
binária, contudo, a confusão que existe entre os conceitos binários e decimais
costuma ser decisiva pra alguém sem muitos conhecimentos em rede. De qualquer
forma, para uma referência rápida, a seguinte tabela ilustra que faixa de
endereçamento IP corresponde a qual bitmask e respectivo netmask em uma classe
C de rede. Alguns breves exemplos de bitmask e netmask adicionais são
ilustradas, denotando algumas definições pra redes maiores.

Bitmask Netmask Total de Ips IPs Usáveis

32 255.255.255.255 1 1

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

31 255.255.255.254 2 1
30 255.255.255.252 4 2
29 255.255.255.248 8 6
28 255.255.255.240 16 14
27 255.255.255.224 32 30
26 255.255.255.192 64 62
25 255.255.255.128 128 126
24 255.255.255.0 256 254

...

22 255.255.192.0 16320 16318


20 255.255.128.0 32768 32766
16 255.255.0.0 65536 65534
12 255.128.0.0 8.388608+e6
8.388606+e6
8 255.0.0.0 256^3
(256^3)-2
0 0.0.0.0 (todos IPs) 256^4 (256^4)-2

Como você pode ver existe um padrão definido. O número de endereço


total de uma rede sempre sobra a partir da máscara que lhe foi atribuida, e o
número total de Ips disponíveis (que podem ser usados por estações) é sempre o
total disponível na rede menos 2 (total – 2). O motivo também é simples, para
cada rede/subrede existem dois endereços IP reservados para o endereço da rede
e para o endereço de broadcast da rede. O último octeto da máscara de rede
(netmask) começa com 255 e sempre se decrementa em valores múltiplos de 2,
enquanto o bitmask se decrementa em múltiplos de 1.

Vamos ver, de forma sucinta como usar a tabela acima. Vamos descobrir
então qual é a faixa de IPs que compõe uma subrede cujo endereço seja:

172.16.100.32/28

O primeiro detalhe ao qual atentamos é que o endereço da rede é


172.16.100.32, então sabemos que a subrede inicia nesse valor, ou seja, o
endereço de rede é 192.16.100.32. Então percebemos que o bitmask do endereço é
28. Isso quer dizer que todos os primeiros 28 bits do endereço são 'bits
altos', ou seja, são endereços que não mudam. Portanto, concluímos de forma
lógica que temos apenas 4 bits ajustados como 'bits baixos', já que um endereço
completo de rede tem 32 bits, e 28 são altos (conforme indicado pela bitmask)
subtraindo 28 de 32 restam-nos 4 bits (os bits baixos). Sabemos agora que
existem apenas 2 valores possíveis para cada bit, já que o endereçamento não
decimal é binário. Então elevamos dois (possibilidades binárias) à quatro
(bits): 2^4. Agora sim já temos o número de estações que aquele bitmask está
indicando: 2^4 = 16.

Agora basta somar: 172.16.100.32 + 16 = 172.16.100.48, portanto a faixa


de endereçamento IP varia de 172.16.100.32 até 172.16.100.48; Se olharmos na
tabela apresentada cima, veríamos que 16 endereços IP corresponde a um bitmask
de 28, que é o nosso caso. Dessa forma poderíamos ter evitado todo esse cálculo
matemático para encontrarmos o valor exato. Mas, vale lembrar que, nem sempre
essa tabela vai estar disponível pra você consultar, a menos que você a imprima
e ande com ela na carteira, portanto é muito mais valioso aprender como o
endereçamento funciona e aplicar os cálculos necessários. Aprenda uma vez e use

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

sempre.

3.4.2. Especificando Portas e Faixas de Portas;

Você pode também controlar o tráfego de conexões baseando-se em


filtragem de portas. Isso possibilita que você permita ou negue acesso a um
serviço em específico ao invés de controlar o tráfego das estações todas. A
definição das portas em uma regra de firewall com ipfw(8) é feita após a
declaração do endereço de origem ou do endereço de destino, simplesmente
definindo a porta após o endereço. Uma faixa de portas pode ser especificada
com um hífen, podem ser separadas por vírgula, ou ainda, em casos mais
elaborados, pode-se usar um netmask pra definir a faixa de portas. É importante
lembrar que você não pode definir “all” como protocolo na regra que especifica
portas, porque nem todos os protocolos trabalham com portas.

add 1000 allow tcp from any to 172.16.0.5 25


add 1100 allow tcp from any to 172.16.0.5 1021-1023
add 1200 allow tcp from any to 172.16.0.5 21,22,23
add 1300 deny udp from any to 192.168.0.5 1024:8

Na primeira regra, todos os pacotes TCP cujo destino é a porta 25 da


estação 172.16.0.5 são permitidos pelo firewall. Na segunda regra todas as
conexões TCP cujo destino seja qualquer porta da faixa 1021 até 1023 da estação
172.16.0.5 também são permitidas pelo ipfirewall(4). Na terceira regra, todos
os pacotes TCP destinados às portas 21, 22 ou 23 na estação 172.16.0.5 é
permitida. E, finalmente na quarta regra, todos os pacotes UDP destinados pra
faixa de portas de 1024 à 1028 na estação 172.16.0.5 são bloqueados. A
apresentação da faixa de portas na última regra é interessante, porque faz uso
de uma netmask pra declarar a mesma. Mas a matemática também é bem simples.
Como agora estamos tratando de Bitmask pra porta 1024, o valor pra ela é 10
bits, e como a máscara indica 8 bits, tiramos 8 possibilidades de 10, restando-
nos apenas 2 bits. Como o valor de cada bit é binário, elevamos os bits
disponíveis (2) aos valores possíveis (binário = 2): 2^2, então temos 4 portas
que compõe a faixa de endereçamento da porta 1024, ou seja, de 1024 até 1024+4
= 1024 até1028.

O uso de máscaras para definição de faixas de portas são raramente


usadas, mas são bem mais interessantes do que o uso de bitmask ou netmask pra
endereços IP, já que o número de bits de uma porta varia dependendo da porta em
questão. Por isso o uso de hífen é recomendado pra se definir uma faixa de
portas, e vírgulas quando se deseja definir várias portas em uma mesma regra.
Mas a declaração de máscaras para as portas indica que o firewall foi
construído por alguém que domina completamente as definições de endereçamento
de redes, e é estétitamente mais proveitoso.

4. Sintaxe de regras avançadas do ipfw(8);

Embora o overview anterior sobre as criações de regras do ipfw(8) seja


o bastante pra cobrir a maioria dos cenários e necessidades simples de um
firewall, ele se mostra solenimente curto pra muitas situações mais complexas,
como por exemplo, quando o sistema possui mais de uma interface de rede é
possível que se queira definir ações especiais para algumas combinações de
pacotes, ou então que se queira um maior controle sobre o direcionamento do

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

tráfego. Então, vamos expandir o modelo de sintaxe que estávamos trabalhando no


ipfw(8) para o seguinte:

<comando> [<número da regra>] <ação> [log [logamount <número>]] <proto>


from <origem> to <destino> [<interface-spec>] [<opções>]

Todas as opções entre colchetes fazem menção à novas funcionalidades


que iremos discutir nessa seção. Nós vamos inclusive cobrir uma nova "ação" que
não foi relatada anteriormente. A Sintaxe pode parecer inicialmente confusa,
mas nós vamos com calma, e montaremos as regras aos poucos.

4.1. A ação "unreach";

Primeiramente, vamos introduzir uma nova "ação":

"unreach <código>" - Qualquer pacote que combine com uma regra cuja
ação seja "unreach", serã respondido com um código 'ICMP unreach' (código ICMP
de indisponibilidade), e posteriormente a leitra do conjunto de regras será
terminada. As possibilidades de códigos pro 'ICMP unreach' pode ser indicada
por número ou por nome. Segue agora uma breve lista de 'ICMP unreach codes' (os
códigos em questão) e seus nomes correspondentes. Se você não sabe onde esses
códigos são utilizados, não tem porque você tentar usa-los:

net 0 net-prohib 9
host 1 host-prohib 10
protocol 2 tosnet 11
port 3 toshost 12
needfrag 4 filter-prohib 13
srcfail 5 host-precedence 14
net-unknown 6 precedence-cutoff 15
host-unknown 7
isolated 8

4.2. Controle de Interface e Fluxo;

Uma das mais importantes funcionalidades do ipfw(8), que não foi


comentada anteriormente na seção 3 desse documento é o controle de fluxo e de
interface, ou seja, a possibilidade de criar regras que verifiquem os pacotes
de acordo com uma interface em especial (aplicável quando você tem um sistema
com múltiplas interfaces de rede). Essas regras podem identificar de onde esses
pacotes estão vindo, e em que direção estão indo. Até agora o senso de direção
que nós adotamos simplesmente definia os endereços de origem e de destino, mas
usar apenas essas opções pra definir de onde um pacote está vindo ou pra onde
ele está indo via firewall não é muito confiável. Quando você quer filtrar
pacotes que estão apenas entrando ou saindo pela rede, as opções "in" e "out"
podem ser utilizadas com precisão. Ambas opções ("in" e "out") correspondem ao
campo "interface-spec" no modelo de sintaxe dado anteriormente, e normalmente,
são definidas próximas ao final de cada regra, antecedendo qualquer possível
opção extra. Dessa forma, quando decidirmos filtrar todos os pacotes vindos de
qualquer lugar e indo pra qualquer lugar, poderíamos definir:

add 1000 allow all from any to any in

Pra filtrar pacotes indo através de uma interface em particular,

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

podemos usar a opção literal "via", seguida do nome da interface. Dessa forma,
se estivermos usando uma placa de rede 3Com 3c59x PCI, sua interface será
"xl0". Pra filtrarmos qualquer pacote, vindos especialmente dessa interface,
com origem e destinos quaisqueres, o seguinte seria o suficiente:

add 1100 allow all from any to any in via xl0

Ou talvez, se você tiver um sistemas com múltiplas interfaces, e quiser


filtrar todos os pacotes vindos de qualquer lugar e indo pra qualquer lugar,
mas que esteja ao menos saindo via *alguma* interface, pode fazer o seguinte:

add 1200 allow all from any to any out via any

Você vai notar que, quando você listar as regras de firewall, as


entradas que estiverem usando "in" ou "out" combinadas com "via", não
apresentarão a utilização do "via" mas apresentará a citação "recv" ou "xmit",
dependendo da definição de um "in" ou um "out" respectivamente. Veja só:

root@eeviac~# ipfw add 7000 allow all from any to any out via xl0
root@eeviac~# ipfw list | grep 7000
07000 allow ip from any to any out xmit xl0
root@eeviac~#

Portanto, você pode usar "recv" ou "xmit" no lugar de "via" quando você
for criar alguma regra que faça uso de "in" e "out", contudo isso não é
preciso, o ipfirewall(4) distingui se a interface está recebendo o transmitindo
o dado, e, além do que, essa definição pode confundir usuários não experientes.

No geral, essas opções oferecem muito mais controle sobre o tráfego da


rede em um sistema de interfaces múltiplas, e qualquer outro sistema em geral,
visto que elas permitem a filtragem de pacotes específicos vindo para o
firewall, saindo por ele, e se deslocando através de uma interface
especificada.

4.3. Combinando tipos de pacotes ICMP e TCP específicos;

Pacotes ICMP, TCP e IP são apresentados em vários formatos distintos.


Esses tipos de pacotes são definidos por várias _flags_ (opções de
identificação). Nós podemos filtrar cada um desses tipos usando uma das
seguintes opções do ipfw(8), ao final de cada regra:

4.3.1. icmptypes (tipos icmp);

"icmptypes <tipo>" - Essa opção filtra o pacote ICMP do <tipo>


definido, e inverte a opção se uma '!' (exclamação) for devinida antes do
<tipo>, ou seja, todos os pacotes que não forem desse tipo serão combinados.
Existe, atualmente 15 tipos diferentes de pacotes ICMP que podem ser filtrados;
cada um é definido por um número. Você pode ainda especificar faixas de
'icmptypes' utilizando hífen ou separando-os por vírgula. Os 15 tipos de
pacotes ICMP são:

0 - Echo Reply (Resposta de Echo)


3 - Destination Unreachable (Destino Indisponível)
4 - Source Quench (Origem extinta)

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

5 - Redirect (Redireção)
8 - Echo Request (Pedido de Echo)
9 - Router Advertisement (SPAM de roteamento? :-))
10 - Router Solicitation (Pedido de Roteamento)
11 - Time-to-Live Exceeded (TTL Excedido)
12 - IP header bad (Cabeçalho IP malformado)
13 - Timestamp Request (Pedido de Timestamp)
14 - Timestamp Reply (Resposta de Timestamp)
15 - Information Request (Pedido de Informação)
16 - Information Reply (Resposta de Informação)
17 - Address Mask Request (Pedido de Máscara de Rede)
18 - Address Mask Reply (Resposta de Máscara de Rede)

Se você ficou curioso pra saber como esses tipos ICMP, especialmente o
tipo 3, correspondem aos códigos de indisponibilidade que podem ser criados com
a opção "unreach", então, saiba simplesmente que o tipo 3 identifica qualquer
um desses códigos, ou seja, todos. Usar filtros de pacotes ICMP é muito útil,
especialmente pra controlar ping; por exemplo, você pode permitir que qualquer
cliente dentro da sua rede interna pingue qualquer estação pra fora da rede,
enquanto você bloqueia que qualquer estação externa pingue o seu gateway, ou
qualquer outro cliente interno. As três regras a seguir definem isso
facilmente:

add 1000 allow icmp from any to any out icmptypes 8


add 1100 allow icmp from any to any in icmptypes 0
add 1200 deny icmp from any to any in icmptypes 8

A primeira regra permite que todos os pacotes icmp do tipo 8 (pedido de


echo) possam trafegar pra fora do firewall. A segunda permite que todos os
pacotes icmp do tipo 0 (resposta de echo) entrem pelo firewall, e a regra
seguinte bloqueia todos os pacotes icmp do tipo 8 de entrarem. Em resumo,
permite que qualquer cliente faça um pedido de echo pra fora, e permite a
entrada da resposta pra dentro do firewall, e não permite que ninguém de fora
faça um pedido de echo pra dentro do firewall, ou seja, todomundo protegido
pelo firewall pode pingar qualquer estação externa, mas ninguém de fora pode
pingar dentro. Naturalmente essas opções só podem ser definidas quando o
protocolo da regra for "icmp".

4.3.2. tcpflags, setup & established;

"tcpflags <flag>" - Essa opção filtra qualquer pacote TCP cujo


cabeçalho contenha alguma das flags (opções) identificadas. Uma definição
inversa também pode ser utilizada se colocarmos uma '!' (exclamação) antes da
<flag>, dessa forma filtrando todos os pacotes TCP que não possuam a <flag> em
questão. Veja as opções de 'flags':

fin - Request for connexion termination (pedido de


finalização da conexão)
syn - Request for connexion initiation (pedido de
inicialização da conexão)
rst - Reset Connexion (Redefinição da Conexão)
psh - Push Flag (opção Push)
ack - Acknowledgement (conhecimento, concordância com a
conexão)

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

urg - Indicate Urgent OOB data (indica um OOB de dados


urgentes)

A <flag> SYN é a mais interessante, visto que ela é enviada quando uma
conexão TCP é iniciada. Por ser tão importante, existe inclusive uma opção
separada do ipfw(8) dedicada especialmente pra definir pacotes TCP cujo
cabeçalho tenha a flag SYN ajustada. Essa opção se chama "setup". É claro que
só podemos trabalhar com a opção "setup" quando o protocolo indicado é o "tcp".

"setup" - Qualquer regra contendo essa opção vai filtrar todos os


pacotes TCP cujo cabeçalho indique a flag SYN ajustada. Dessa forma, se
quizermos simplesmente negar todos os pacotes TCP que estiverem entrando no
firewall com o cabeçalho SYN definido, temos duas opções:

add deny tcp from any to any in tcpflags syn

OU SIMPLESMENTE:

add deny tcp from any to any in setup

Em cada uma dessas regras, a mesma ação é tomada: todos os pacotes TCP
SYN vindos de qualquer (any) origem para qualquer (any) destino serão negados.
Vale a pena ilustrarmos a necessidade do protocolo ser "tcp" quando
trabalharmos essas regras.

"established" - Exatamente como existe uma opção especial que


identifica um pedido de inicialização de conexão TCP ("setup"), existe também
uma opção que identifica quando uma conexão já está estabelecida, ou seja, ja
foi iniciada. Pela grande importância de facilitar o controle de conexões TCP,
as opções "established" e "setup" foram disponibilizadas, dessa forma
oferecendo facilidade na criação de regras. Utilizando estas opções (ou mesmo
suas definições nativas correspondentes às "tcpflags") podemos ter inicialmente
um controle de conexões TCP mais simples. Essa é a base de implementações
"stateful" de um firewall. Vamos trabalhar com elas de forma mais detalhada
depois.

4.3.3. ipoptions;

"ipoptions <flag>" - Finalmente podemos trabalhar com alguns pacotes IP


específicos. A <flag> que define um tipo de pacote IP é nomeada SSRR (para:
Strict Source Route), LSRR (para: Loose Source Route), RR (para: Record Packet
Route), e TS (para: Timestamp). Se você não sabe pra que serve cada uma dessas
flags, então não haverá necessidade de construir regras que façam uso delas.

4.4. Reconhecendo Pacotes Fragmentados;

Pacotes fragmentados podem ser filtrados com a opção "frag" do ipfw(8).


Na grande maioria dos casos, os pacotes fragmentados devem ser bloqueados pelo
firewall. Receber um número grande de pacotes fragmentados pode indicar a
eminência de um ataque do tipo DoS (Denial of Service - ou Negação de Serviço).
Mesmo considerando que o FreeBSD, e a maioria dos outros sistemas UNIX de
verdade não são sucetíveis a esse tipo de ataque, os sistemas Windows são
frequentemente muito vulneráveis. Dessa forma, se você tem clientes Windows por
trás do firewall, dentro da sua rede, é recomendável bloquear pacotes

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

fragmentados pra protege-los.

Quando você for usar a opção "frag" pra filtrar (e bloquear) os pacotes
fragmentados, tem duas regrinhas básicas que você deve seguir. A primeira é que
você não pode usar "frag" quando também estiver usando a opção "tcpflags"; você
define qualquer pacote fragmentado, ou não define nenhum. A segunda: você
também não pode utilizar o "frag" se estiver especificando portas TCP ou UDP;
você bloqueia todos os pacotes fragmentados, não importando pra qual porta ou
serviço eles estejam sendo enviados. Dito isso, podemos facilmente definir uma
regra pra negar todos os pacotes fragmentados que estiverem entrando na rede:

add deny all from any to any in frag

4.5. Filtragem baeada em UID e GID;

Uma poderosa função que outros firewall (como o IPFilter) não possuem é
a filtragem de pacotes baseada em GID/UID. O Ipfirewall(4) tem a capacidade de
filtrar pacotes de acordo com o UID ou GID do dono do processo o qual originou
uma conexão. Por motivos lógicos só se pode filtrar pacotes que tenham sido
gerados por processos locais. As opções a serem utilizadas são "gid" ou "uid"
seguidos do GID/UID ou do nome do usuário/grupo que estivermos filtrando.

Um uso em potencial dessa função é restringir o número de IPs virtuais


em um servidor de shell. Se você quer se assegurar que um ou mais Hosts
Virtuais não poderão ser usados por ninguém mais que o dono do IP virtual, você
pode definir uma regra baseada em filtragem de UID, para que, dessa forma, todo
o tráfego do host virtual que não seja do próprio usuário seja bloqueado:

add allow tcp from any to 172.16.0.10 in


add allow tcp from 172.16.0.10 to any out uid patrick
add deny tcp from 172.168.0.10 to any

Essas regras permitem que apenas o usuário 'patrick' vai poder utilizar
a alias de IP (Apelido de IP, IP-Alias ou IP vhost) 172.168.0.10 pra
estabelecer conexões TCP pra fora da rede. Ninguém mais será permitido pendurar
Bots, Clientes de IRC ou qualquer outra coisa que precise estabelecer conexão
TCP (quase tudo) nesse endereço IP. O protocolo UDP também pode ser usado para
filtragem de pacotes baseada em UID/GID, contudo nenhum outro protocolo fora
esses dois podem.

Outra utilização possível pra UID/GID seria habilitar limitação de uso


de banda para cada usuário, ao invés de limitar pra cada estação ou rede. Por
exemplo, você pode definir um grupo de usuários que tenham contas rápidas de
FTP, definindo uma regra pro GID em questão, e em contrapartida ter um grupo de
usuários de shell que não precisam de muita banda. Vamos ilustrar outras
limitações de bandas definidas por GID posteriormente, quando estivermos
cobrindo o "traffic shaping" com ipfirewall(4).

Por motivos de segurança, talvez seja necessário voce logar o tráfego


de rede de um usuário em particular, e nesse caso o filtro baseado em UID/GID
também viria bem a acalhar. Na verdade sempre que se queira definir um
comportamente distinto do firewall com base no usuário que acessa o serviço, o
UID/GID do ipfw(8) sempre vem bem a acalhar. Uma pequena dica é sempre definir
as regras baseadas em UID/GID antes das outras regras, visto que o

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

ipfirewall(4) termina a verificação da lista das regras quando um pacote


combina com alguma das regras em uso. Isso garante desempenho e evita que se
bloqueie ou permita um pacote antes de verificar qual usuário originou o
tráfego.

5. Logs (Logging);

5.1. Propriedades de Logs;


As vantagens de manter os logs do firewall ativo são óbvias. A
possibilidade de verificar posteriormente quais conexões foram negadas, de que
endereços elas vieram, pra que rede ou estação elas estavam indo, se o conteúdo
dos pacotes eram fragmentados (indicantivo de muitos ataques de negação de
serviço – DoS), enfim, possibilita saber onde as conexões estão sendo feitas,
por quem e quando. Em especial, os logs de firewall são importantes pra
rastrear crackers ou pessoas má intencionadas.

Mas logar também tem o seu lado negativo, se você não for cuidadoso.
Dependendo do tipo de dado que você está logando você pode se perder com a
abundância de mensagens, e também utilizar muito espaço em disco pros arquivos
de logs. Ataques de negação de serviço que tendem a sobrecarregar discos
rígidos é um dos tipos mais antigos de atividade má intencionada, e por
incrível que pareça ainda é sinônimo de perigo pra administradores imprudentes.
Por isso a importância de se definir que tipos de regras serão logadas.
Normalmente logar pacotes permitidos de serviços públicos (como WWW) não é uma
boa indéia, visto que o próprio serviço (servidor WWW) também mantém logs das
atividades de acesso, e a frequência de pacotes em um serviço como esse é muito
grande.

Por outro lado, o que a maioria dos novos administradores que


experimentam quando eles habilitam o ipfirewall(4) pra logar, é o seu terminal
abarrotado com mensagens sobre a atividade de pacotes. Esse pequeno
inconveniente é o resultado da combinação de:

- estar logando regras que combinam com pacotes muito frequentes;


- não ter desabilitado logs pro console e pros terminais de root
(péssima idéia);
- não estar controlando limite de logs com o IPFIREWALL_VERBOSE_LIMIT;

5.2. Configurações de Logs do sistema;

5.2.1. Opções do Kernel;

Pra habilitar os logs do ipfirewalll(4) no FreeBSD, você tem que


incluir ao menos as seguintes opções no kernel (não se esqueça de iniciar seu
sistema com o novo kernel após a compilação do mesmo):

options IPFIREWALL_VERBOSE

Você ainda pode habilitar a seguinte opção:

options IPFIREWALL_VERBOSE_LIMIT=#

Nós já mencionamos essas opções anteriormente, quando estavamos revendo

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

a ativação do firewall. Essa segunda opção do kernel limita o número de


mensagens consecutivas enviados ao sistema de logs do FreeBSD, o syslogd(8),
quando dada regra do firewall é ativada. Portanto, quando você aciona essa
opção no kernel, o número de mensagens consecutivas relacionada a uma conexão
em particular é limitada ao valor (número) específico. Considere o seguinte:

options IPFIREWALL_VERBOSE_LIMIT=10

Com essa entrada definida no seu kernel, apenas 10 mensagens


consecutivas a respeito de determinada conexão serão logadas no syslogd(8), e
todas as outras ocorrências seriam identificadas sob uma expressão genérica
como por exemplo:

Jan 29 03:26:55 meuservidor last message repeated 45 times

Normalmente essas mensagens são logadas em /var/log/messages além de


serem impressas no console do sistema também. Se você quiser modificar esse
comportando do syslogd(8), você terá que editar o /etc/syslog.conf. O
syslog.conf(5) oferece uma flexibilidade considerável em relação à configuração
sobre as formas com que o syslogd(8) vai tratar as mensagens do sistema. O
limite definido pra IPFIREWALL_VERBOSE_LIMIT fica à critério do administrador,
mas valores acima de 10 já proporciona um tráfego alto de mensagens em
servidores muito requisitados. Mas se você quer definir um arquivo separado pra
logar tudo de forma distinta, ao invés de simplesmente logar no arquivo padrão
(/var/log/messages), isso pode ser feito também, e ainda, se você julgar ter
espaço em disco o bastante pra trabalhar com rotacionamento de logs (Log
Rotation) você não precisa definir a opção de limite de verbosidade no Kernel.

5.2.2. Configurando o syslog(8).

Você pode configurar o syslogd(8) pra logar as atividades do


ipfirewall(4) em um arquivo separado, seguindo três passos relativamente
simples:

1) Crie o seu novo arquivo de log para o ipfw(8) e, como


alternativa, crie também o diretório de logs que você achar conveniente. Vamos
assumir então que você quer que todos os logs relativos ao ipfirewall(4) sejam
armazenados em /var/log/ipfw/ipfw.log. Dessa forma você vai ter que criar o
diretório em questão (/var/log/ipfw) e em seguida o arquivo de log (ipfw.log)
sob tal diretório, pra isso vai utilizar o comando touch(1):

eksffa@eeviac~# mkdir /var/log/ipfw && touch /var/log/ipfw/ipfw.log


eksffa@eeviac~#

Tenha certeza que o diretório e arquivo em questão não tenham


permissões de leitura pra outros usuários senão o dono do arquivo, por questões
óbvias de segurança.

2) Configure o syslog.conf(5) pra enviar todas as mensagens


relativas ao ipfirewall(4) pro arquivo /var/log/ipfw/ipfw.log. A forma mais
fácil de fazer isso é adicionar as seguintes linhas no final do syslog.conf(5):

!ipfw
*.* /var/log/ipfw/ipfw.log

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

Atente pra usar <TAB> (tecla tab) nesse arquivo ao invés de espaços
simplesmente. Mesmo assumindo que usar “tabs” não é obrigatório no FreeBSD pro
arquivo /etc/syslog.conf, é de bom costume fazê-lo, caso você trabalhe também
com outros UNIX, cuja maioria não aceita espaços no syslog.conf(5). Portanto
mesmo você podendo ignorar a mensagem de advertência no início do
/etc/syslog.conf, é sempre bom manter o bom hábito seguro de usar o
syslog.conf(5) da forma indicada por ele.

Você vai reparar que as mensagnes do tipo "last messages repeated #


times" (ou seja: últimas mensagens repetidas # vezes) serão também logadas,
além desse arquivo, pra qualquer outro cujo syslog.conf(5) aponte as seguintes
entras:

*.err, kern.debug, *.notice

E ainda, o console também irá receber todas essas mensagens, como


definido na linha:

*.err;kern.debug;auth.notice;mail.crit /dev/console

Lembre-se que o console na verdade é apenas o ttyv0 (ALT+F1). Os


consoles virtuais e pseudo terminais se comportarão de forma distinta em
relação à mensagens. Por padrão as seguintes linhas definirão quando as
mensagens forem enviadas pra outros terminais:

*.err root
*.notice;news.err root
*.alert root
*.emerg *

As linhas *.err e *.notice irão logar mensagens do kernel e também as


exibirão no terminal onde o usuário especificado estiver logado. Note que o
usuário em questão é o 'root', então, como por padrão você não deve logar como
root a toa, o usuário root será sempre alertado. Não se recomenda de forma
alguma que essas linhas sejam comentadas, informações de log para o root e pro
terminal são extremamente importantes pra se manter atento a qualquer coisa
errada que estiver acontecendo com o servidor. Se por bom senso você costuma
estar muito logado com outro usuário que não seja o root, também é considerável
configurar o syslogd(8) pra alertar o seu usuário.

Então vamos resumir o que deve ser feito quando você for configurar
seus logs pelo arquivo de configuração syslog.conf(5):
Insira a linha com “!ipfw” e indique o caminho pra onde as informações
referentes às atividades do Firewall devem ser logadas.
Não altere as mensagens que serão enviadas ao usuário Root se ele estiver
logado. Indique os mesmos alertas pra um usuário que você usa com mais
frequência.

3) Envie um sinal de reinicialização pro processo do syslogd(8). A


forma mais fácil é usando o comando:

eksffa@eeviac~# killall -HUP syslogd


eksffa@eeviac~#

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

5.2.3. Configuração do newsyslog(8) pra fazer Rotação (ou


Rotacionamento) de Logs (log rotation);

Agora que o ipfirewall(4) está configurado pra logar todas suas


atividades, você deveria pensar seriamente em configurar o newsyslog.conf(5) de
forma a garantir que o newsyslog(8) vá rotacionar os logs do ipfirewall(4), ou,
como alternativa, optar por algum outro mecanismo de rotacionamento de logs.
Pra se ter uma boa noção de todas as configurações possíveis do
newsyslog.conf(5) é recomendado que você leia a página de manual (man
newsyslog.conf) do arquivo. Essa é uma poderosa ferramenta de logs, mas não tem
porque nós explicarmos ela aqui, isso é tarefa pra um capítumo sobre
administração do sistema FreeBSD, pro nosso caso de Firewall específico a
seguinte entrada deve ser o bastante:

/var/log/ipfw/ipfw.log 600 10 * $W0D2 Z

Essa linha pode ser adicionada no final do arquivo newsyslog.conf(5). A


primeira entrada é um tanto quanto óbvia, ela indica qual arquivo vai ser
rotacionado. A segunda indica os bits de permissões pros arquivos rotacionados.
A terceira parte é o número de arquivo de logs que se deseja manter
rotacionando até que o mais antigo seja apagado. O seguinte é o tamanho do
arquivo quando ele deve ser rotacionado, não estamos usando essa opção. A
quintar parte é quando (tempo) nós devemos rotacionar o arquivo, e finalmente a
última opção, é uma opção especial. Como você já deve ter concluído, rotação de
logs são definidas por dois critérios: tamanho ou data. No nosso caso, nós
indicamos que queremos que o arquivo de log seja rotacionado às duas da manhã
de todo domingo, não importando o tamanho do arquivo de log. Depois definimos
(a última opção especial, “Z”) que o arquivo deve ser comprimido com gzip(1)
sempre que rotacionar, e definimos que vamos manter um histórico arquivado de
10 semanas. Se você deseja manter seus logs por mais que 10 semanas basta
alterar o valor 10 pra qualquer um que você queira. Ou o ideal, criar uma
rotina que faça backup em uma máquina separada (um LogHost) a cada 10 semanas,
ou então gravar seus Logs em CD ou qualquer outra mídia barata e de grande
capacidade quando for necessário.

Uma vez configurado, o newsyslog.conf(5) vai cuidar do rotacionamento


dos logs do ipfirewall(4). O newsyslog.conf(5) é ativado pelo cron(8) do
FreeBSD, e por isso não precisa de um Daemon rodando, consequentemente você não
tem que reiniciar nenhum processo. Você pode criar seu próprio script pra
rotacionar logs ou usar de terceiros, com tanto que você confie. De qualquer
forma é bom decidir uma maneira de controlar o crescimento dos logs dentro do
seu sistema. Lembre-se, não existe nada que o cron(8) e um script não possa
fazer nesse caso.

5.3. Configuração de Log nas Regras;

Uma vez que tudo esteja pronto pra utilizar as funções de logs do
ipfirewall(4), vamos começar a definir quais regras nós queremos logar quando
elas forem filtradas. Existem dois parâmetros básicos pra usarmos em conjunto
com nossas regras pra definirmos que queremos logar *aquela* regra. Vejamos:

"log" – É o parâmetro mais comum. Toda vez que uma regra que for
definida o “log” for acionada, então a ação definida (“action”) por aquela

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

regra será logada todas as vezes que um pacote coincidir a regra. Por isso tome
muito cuidado pra não defnir “log” pra uma regra que a terão pacotes
frequentementes assimilados a ela, como por exemplo:

add 0500 allow log all from any to any

Essa é uma regra que permite todo o tráfego de todos os tipos de


pacotes de todas as redes pra todas as redes, então imagine a frequência de
informações que serão logadas sempre que cada pacote for permitido pelo seu
firewall. Esse tipo de regra pode facilmente proporcionar problemas pro seu
disco local ;-)

Por outro lado, definir “log” pra uma regra geral de negação é uma
pedida considerável:

add 65000 deny log all from any to any

Essa regra é mais considerável, porque é uma das últimas, em uma


política clara de firewall do tipo “CLOSED” ou seja, tudo que deve ser
permitido já o foi nas regras anteriores que suponhamos existir, portanto nos
interessa manter logs das conexões negadas. Além do que o número da regra é
6500, o que, em relação à regra anterior (500) é muito mais seletiva, visto que
é uma das últimas regras a serem checadas. Preste muita atenção pra escolher
quais regras você quer logar e quais você não quer.

"logamount <número>" - Esse parâmetro em seguida ao “log” define o


número máximo de vezes que uma regra vai ser logada. Esse parâmetro é análogo à
entrada de limite de verbosidade no kernel, e da muito mais controle ao
administrador que pode, por exemplo, definir um número baixo pra uma
determinada regra, e zerar a mesma uma vez ao dia, dessa forma só deixando de
logar o período que um possível ataque ocorrer. Essa definição é possível no
FreeBSD 4.x, FreeBSD 2.2.x e FreeBSD série 3 acina de 3.4.x. Nas versões
anteriores à 3.4 no FreeBSD 3.x o padrão do “logamount” era 10.

Sempre que uma regra é logada, as informações geradas pra tal pacote
são:

- Data & Hora


- Número da Regra
- Ação
- Endereços IP do Destino & Origem
- Portas de Origem & Destino
- Direção do Fluxo
- A Device onde o tráfego aconteceu.

Por definição, uma regra de firewall sua, quando logada, deve parecer
com o seguinte:

Oct 09 18:59:31 SuaMaquina /kernel: ipfw: 65000 Deny TCP


172.16.0.1:62307 192.168.0.1:23 in via xl0

6. Introdução à filtragem 'Stateless' e 'Stateful' de pacotes;

A filtragem de pacotes do tipo 'Statefull' e 'Stateless' são dois


termos frequentemente encontrados em discussões cujo assunto seja ipfilter(4) e

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

ipfirewall(4). O modo de filtragem 'Stateless' tende a tratar cada pacote


roteado pelo firewall como pacotes individuais, que não tenham associação
alguma com qualquer outro tráfego que também estiver passando pela dada
interface do firewall. Esse tipo de filtragem é o mais comum e o mais fácil de
implementar, e tem vantagens efetivas quando se pretende:

- filtrar pacotes corrompidos (fragmentados)


- filtrar pacotes de protocolos específicos (icmp, udp, igmp, etc)
- fazer um firewall baseado em host (ou seja filtrando de acordo com o
destino e/ou origem do pacote)

Já uma filtragem do tipo 'Stateful' é mais complexa de ser


implementada; esse tipo de filtro trata o tráfego como sendo composto de
determinadas conexões, ou seja os pacotes pertencem a uma dada conexão, negada
ou permitida, e não trata pacotes como individuais. Toda a comunicação através
de qualquer protocolo usa números de sequência que indicam em que ordem os
pacotes serão lidos em um socket(2). Esse é o primeiro princípio básico das
informações que um firewall 'Stateful' precisa conhecer. O segundo é que,
conexões orientadas à protocolos como TCP, geram tráfego de pacotes especiais
que indicam o início de uma conexão (SYN) e o fim da mesma (FIN). Esse ponto
também é essencial a um firewall do tipo 'Stateful'. No geral, você deve:

- saber à que estado pertence uma conexão (iniciada, não iniciada, em


negociação, terminada, etc)
- ser capaz de determinar se uma conexão esta se comportando de forma
esperada, com procedimentos validos, ou se ela está se comportando de forma
indevida. Você deve ser capaz de filtrar os pacotes que se comportarem de forma
indevida.

Um firewall do tipo 'Stateful' cria regras dinâmicas pras conexões que


estiverem em andamento, e elimina essas regras quando a conexão foi terminada.
Isso permite ficarmos atento de forma mais inteligente às atividades da rede.
Por outro lado um firewall do tipo 'stateful' são incapazes de filtrar cada
pacote individualmente, exatamente pelo fato dele criar regras dinâmicas
especiais que permitem uma conexão em sua totalidade, examinando se o
comportamento dessa conexão está aceitável. Em compensação, é muito fácil
juntar regras de firewall do tipo 'stateful' e do tipo 'stateless' em um mesmo
firewall, dependendo apenas do quanto o administrador do sistema é bom. E
normalmente administradores de FreeBSD já são muito bons por natureza, portanto
podem se beneficiar dos dois tipos de firewall.

Quase todas as regras que nós apresentamos anteriormente eram


'stateless'. As unicas excessões foram as regras a respeito das opções
"tcpflags," "setup," e "established" que permitiam que nós checassemos o estado
de uma conexão TCP. Vamos então usar uma combinação dessas regras pra um
primeiro exemplo prático de regras 'stateful'. Antes um pouquinho de história.
Esse tipo de verificação primitiva de estado de conexão (tcpflags, etc) existe
no ipfirewall(4) faz muito tempo, contudo essas opções eram as únicas, o que
fazia a capacidade do ipfirewall(4) de criar regras 'stateful' muito limitada.
Por isso anteriormente à versão 4.x do FreeBSD o ipfirewall(4) era chamado de
tipicamente 'stateless', enquanto o ipfilter era a opção 'stateful' disponível.
A partir do FreeBSD 4.0 o ipfirewall(4) foi habilitado a trabalhar com
funcionalidades 'stateful' mais extensivas, e mais desenvolvimento a respeito
disso está em andamento no ipfirewall(4).

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

6.1. Configurações 'Stateful' Iniciais;

Pro nosso primeiro exemplo, vamos estar usando as características mais


básicas e conhecidas do ipfirewall(4) pra tratar filtragem 'stateful'. A
maioria dos administradores mais atentos que costumam ler as regras de firewall
pré definidas no /etc/rc.firewall, costumaram fazer largo uso das funções
“setup” e “established”, que compõe a maiora das regras nesse arquivo. Mesmo
essas regras podendo ser usadas exclusivamente pra controlar conexões TCP de
forma 'stateful', o que demonstra certa limitação, vamos criar no nosso
primeiro exemplo um conjunto simples de regras que filtram conexões ao serviço
SSH de forma 'stateful':

add 1000 allow tcp from any to any established


add 2000 allow tcp from any to any 22 in setup

Vamos assumir que estamos usando uma política de firewall fechado (ou
seja, firewall_type no /etc/rc.conf não está definido como “OPEN” e não existe
a entrada IPFIREWALL_DEFAULT_TO_ACCEPT no kernel do sistema). Nesse caso, as
duas regras anteriores vão permitir o roteamento dos pacotes desejados. A regra
número 1000 vai permitir todos os pacotes que sejam parte de uma conexão TCP já
estabelecida, e então a verificação das regras subsequentes vai cessar para
aqueles pacotes. Se, por outro lado algum pacote não fizer parte de uma conexão
iniciada, a regra 1000 não será assumida, e então a verificação passa pra regra
seguinte. Na regra número 2000, se o pacote for do tipo TCP SYN, e for
destinado à porta 22 (serviço SSH), a regra vai permitir que ele seja roteado.
Nesse caso, pacotes TCP SYN iniciam uma conexão TCP, por isso a importância de
deixa-los passar. Os pacotes subsequentes relacionados ao serviço SSH serão
permitidos pela regra 1000, já que eles farão parte de uma conexão já
estabelecida. Você pode experimentar uma configuração parecida usando
'stateless':

add 1000 allow tcp from any to any out


add 2000 allow tcp from any to any 22 in

Nesse exemplo, todos os pacotes saindo pelo firewall, vindos de


qualquer fonte pra qualquer destino serão permitidos, e todos os pacotes
entrando pela porta 22 também serão permitidos. Nesse caso você vai perceber
que as regras não ficam monitorando os pacotes TCP pra verificarem de que tipo
eles são, se são de inicialização de uma conexão ou de uma conexão já
estabelecida, e em contra-partida permitem que todos os pacotes TCP saiam pelo
firewall ou entrem pela porta 22, sem verificar que pacotes são esses.

Essa é a essência de um firewall do tipo 'stateful' utilizando “setup”


e “stablished”: Deixa passar pedidos de inicialização de conexões de um serviço
(porta) específico, e depois da conexão estar estabelecidade permite que todo o
tráfego funcione normalmente.

Vamos dar uma olhada em um exemplo memos simples, que envolve conexões
ssh, email, FTP e DNS pra rede 172.16.0.0/27:

add 1000 allow tcp from any to any established


add 2000 allow tcp from any to 172.16.0.0/27 21,22,25 setup
add 3000 allow udp from 172.16.0.0/27 to any 53
add 3100 allow udp from any 53 to 172.16.0.0/27

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

Nesse exemplo, o pedido de inicio de conexão (usando “setup”) é


permitido pras portas 21, 22, 25 (FTP, SSH e SMTP respectivamente) quando os
pacotes são destinados à rede 172.16.0.0. Consequentemente todas as conexões
TCP estabelecidas serão permitidas na regra anterior. As regras 3000 e 3100
permitem pacotes UDP pra porta 53 de outros hosts, e permite pacotes UDP vindos
da porta 53 de qualquer lugar entrarem pelo firewall. Essas duas últimas regras
são 'stateless'. A porta 53 é a porta onde o serviço de nomes (DNS) roda. A
regra 1000 deve ser “from any to any” porque os pacotes TCP de conexões já
estabelecidas devem ser permitidas vindo de qualquer origem pra qualquer
destino. Lembre-se sempre que existe o fluxo em duas direços, os pacotes vindos
de algum lugar e as suas respostas pra outro lugar.

Vamos analizar um caso especial: FTP. Se você fosse fazer um firewall


cujas regras fossem exclusivamente 'stateless', você teria que manter todas as
portas entre a 1024 e a 65000 abertas. O motivo é simples, o protocolo FTP é um
protocolo revoltadinho que estabelece suas conexões em qualquer porta não
reservada, ou seja qualquer porta acima da 1024. Uma solução não muito prática
é liberar as portas 21 e 22 de forma 'stateless' e forçar seus clientes FTP a
estabelecerem conexões exclusivamente não-passivas (FTP Modo Passivo). O
problema é que nem todos os seus clientes (como os que usam Windows por
exemplo) tem muita noção de FTP a ponto de coloca-lo em modo nãp-passivo, por
mais simples que isso seja. Nesse caso, portanto, permitimos a inicialização de
uma conexão na porta 21 (onde todas as requisições FTP iniciam) e
posteriormente permitimos o roteamento de pacotes pertencentes à essa conexão
por qualquer porta (utilizando “stablished”). Essa é a forma mais eficiente de
se controlar FTP via firewall, e essa prática pode ser adotada pra outros
serviços que tenham comportamente similar a esse.

6.2. Configurações 'Stateful' Avançadas;

Como já foi dito, configurações de firewall 'stateful' usando apenas


“setup” e “established” são muito limitadas. Exatamente por permitir controle
de conexões stateful apenas sobre o protocolo TCP, essa filtragem é a mais
simples existente. Desde a versão 4.0 do FreeBSD, o ipfirewall(4) adotou
características 'stateful' baseada em ótimos argumentos; agora pode-se
controlar conexões TCP, UDP e ICMP de forma 'stateful', além de outros tipos de
pacotes, usando o que nós chamamos de regras dinâmicas.

Regras dinâmicas é uma característica recente do ipfirewall(4) no


FreeBSD 4.x; como seu próprio nome sugeste, são regras dinâmicamente criadas
pra conexões independentes. Cada regra dinâmica depois de um certo período de
tempo sem serem utilizadas são descarregadas. O tempo que uma conexão TCP leva
pra ser terminada pode ser controlada por inúmeras variávels do sysctl(8), ou
seja, de certa forma um conjunto de regras monitora não somente o início de uma
conexão, mas também quando essa conexão é terminada, e ajusta suas ações de
acordo a configuração utilizada.

Uma opção e um comando são utilizados pra controlar esse comportamente


'stateful' avançado:

"keep-state" – Quando um pacote é combinado com uma regra que tenha


essa opção ajustada, então uma regra dinâmica é iniciada.

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

"check-state" - Esse comando define que a verificação das regras pelo


firewall vai primeiro checar as regras dinâmicas. Se não existir uma regra com
esse comando em todo o conjunto de regras do seu firewall, ai as regras
dinâmicas serão verificadas no momento em que a opção “keep-state” for
definida. Se uma regra com esse comando combinar com um pacote, a verificação
das regras é terminada, do contrário a verificação continua.

Vamos então voltar ao nosso exemplo anterior, onde tínhamos regras


destinadas à permitir apenas conexões SSH, mas dessa vez vamos usar regras mais
avançadas de 'stateful':

add 1000 check-state


add 2000 allow tcp from any to any 22 in setup keep-state

Só lembrando, essa regra presume que a política do seu firewall seja


fechada. Nas regras acina, a primeira regra faz com que o ipfirewall(4)
verifique as regras dinâmicas. Se o pacote não pertence a nenhuma conexão já
estabelecida (ou seja, não fazem parte de nenhuma regra dinâmica) então a
verificação continua na regra 2000, onde, se o pacote for do tipo TCP SYN
entrando pela porta 22 (SSH), aí a função “keep-state”
ordena a criação de uma regra dinâmica, que será sempre verificada na
constatação da regra 1000. Todos os outros pacotes seriam bloqueados pela sua
regra padrão de firewall fechado.

Bom, nós já havíamos trabalhado com regras desse tipo utilizando as


outras funções de 'stateful' e também utilizando 'stateless'. Agora, essa nossa
nova abordagem, utilizando a opção “keep-state” e o comando “check-state”
proporciona algumas vantagens sobre as outras configurações de firewall. Antes,
a opção “stablished” permitia a ocorrência de qualquer pacote TCP vindo de uma
conexão TCP previamente estabelecida, ainda que esse pacote fosse spoofado e
não fosse um pacote legítimo dessa conexão TCP. A expressão “spoof” define um
tipo de pacote que traz consigo informações de origem manipulada, ou seja o
pacote não legítimo se faz passar por um pacote que na verdade não é ele. É uma
técnica não muito simples e que pode ser evitada de várias formas, uma delas é
a verificação pelo firewall. Nessa nossa nova abordagem, cada regra dinâmica é
criada para uma conexão específica entre duas pontas (dois hosts) e suas
respectivas portas, ou seja, um pacote TCP spoofado poderia manipular seu
endereço de destino e de origem, mas não manipularia a porta (a não ser com
muita sorte) onde a conexão foi efetivada, e onde a conexão TCP legítima está
sendo mantida. Dessa forma a regra 1000 (“check-state”) falha, não permitindo o
roteamento do pacote, e posteriormente a regra seguinte (2000) também falharia,
a não ser que o pacote fosse do tipo TCP SYN, e dessa forma o pacote é negado
pra regra final da política padrão fechada do firewall.

Resumindo, os critérios que definem a permissão ou não de um pacote


passando por uma regra dinâmica são:

- Protocolo
- Endereço & Porta IP
- Destino & Porta IP
- Tempo da regra esgotado

Como já foi dito, a regra dinâmica é descarregada depois de certo tempo


sem ser utilizada. Dependendo de como uma regra dinâmica é utilizada, podemos
definir um período fixo de tempo até que a regra se esgote. Esse tempo de

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

duração pra cada tipo de regra dinâmica pode ser verificado utilizando as
variáveis corretas do sysctl(8). Posteriormente podemos modificar esses
valores. Eis a listagem dos valores padrões dessas variáveis do sysctl:

eksffa@eeviac~# sysctl -a | grep 'dyn.*lifetime'


net.inet.ip.fw.dyn_ack_lifetime: 300
net.inet.ip.fw.dyn_syn_lifetime: 20
net.inet.ip.fw.dyn_fin_lifetime: 20
net.inet.ip.fw.dyn_rst_lifetime: 5
net.inet.ip.fw.dyn_short_lifetime: 5
eksffa@eeviac~#

A primeira variável do sysctl(8) indica que o tempo de vida padrão pra


cada regra dinâmica que use um pacote do tipo TCP ACK é 300 segundos. A
variável seguinte indica que o tempo de vida de uma regra dinâmica cujo pacote
seja TCP SYN é 20 segundos. Na regra seguinte, 20 segundos também de vida pra
regras com pacotes TCP FIN. Depois 5 segundos de vida pras regras que
encontrarem pacotes do tipo TCP RST ou outros pacotes (UDP, ICMP, etc),
conforme indica as duas últimas variáveis do sysctl(8).

Vamos usar um exemplo pra demonstrar como isso funciona na prática:

1) – Uma conexão TCP legítima é iniciada da máquina 172.16.0.1 na porta


1234 pra porta 22 do servidor 192.168.0.1 que fica por trás do firewall. Esse
pedido de inicialização de conexão se consiste de um pacote de sincronização
TCP, ou seja, um TCP SYN.

2) – A regra 1000 do firewall faz com que o ipfirewall(4) verifique as


regras dinâmicas, onde ele não vai encontrar nenhuma regra referente à pacotes
TCP vindos de 72.15.0.1:1234 para 192.168.0.1:22.

3) – A regra 2000 é verificada e combinada, então o “keep-state” ordena


que se crie uma regra dinâmica pras conexões TCP entre as
máquinas172.16.0.1:1234 e 192.168.0.1:22, e que essa regra tenha um tempo de
vida de 20 segundos (que é o padrão pra pacotes TCP SYN).

4) – Depois de um segundo, um pacote TCP ACK é enviado pro servidor


192.168.0.1:22 em resposta ao pacote TCP ACK enviado pro cliente, pra confirmar
o pedido de uma conexão TCP.

5) – Em seguida o pacote vai encontrar a regra 1000 do firewall de


novo, que vai verificar pelas regras dinâmicas e encontrar uma regra cujo tempo
de vida não tenha terminado, e que esteja permitindo o roteamento dos pacotes
cujo IP e porta de origem sejam conhecidos, assim como IP e porta do destino.
Dessa forma a regra dinâmica permite que o pacote trafegue com segurança pelo
firewall.

6) – Um pacote TCP ACK spoofado, vindo de um possível ataque que, em


circunstâncias normais danificaria os recursos de rede de uma máquina Windows
não preparada, que estivesse por trás do firewall.

7) – A regra 1000 verifica as regras dinâmicas e encontra o pacote


spoofado com IP e portas de destino que pertencem a uma regra dinâmica
existente, contudo o IP e porta pra onde o pacote deve voltar não corresponde
ao da regra (porque foi gerado de forma randômica pelo ataque). Dessa forma a

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

regra 1000 falha, e a filtragem pelo firewall continua pra regra seguinte.

8) – A regra seguinte (2000) verifica que o pacote não é do tipo TCP


SYN, então não define regra dinâmica praquele pacote.

9) – Consequentemente o pacote é bloqueado pela regra padrão do


firewall que é do tipo fechado.

No nosso primeiro exemplo de regra 'stateful' esse pacote spoofado


teria sido aceito, porque a regra que continha “established” como dependência
teria sido cumprida, pois aceitava todo pacote com um destino em particular,
que tivesse ao menos a 'flag' ACK definida, e o pacote Spoofado cumpriria esse
critério. Já a regra dinâmica criada exclusivamente para as duas pontas em
comunicação, verificou pela porta de origem e consequente resposta da conexão,
informação que é gerada aleatóriamente, ou seja, não existe uma forma lógica de
se manipular. Esses são exemplos e rasões primários, contudo poderosos em
relação à vantagens das operações avançadas de 'stateful' do ipfirewall(4).
Esse tipo de vantagem o IPFilter também possui.

No exemplo anterior poderíamos ter assumido um ataque diferente se o


pacote spoofado fosse do tipo TCP SYN, mas antes de explicarmos isso, vamos dar
uma olhada em um tipo de ataque popular utilizando TCP SYN, ataque esse
conhecido como SYN FLOODs.

Pacotes TCP SYN spoofados são usados com muita frequência em taques de
rede. A ação mais comum desse tipo de ataque consiste em enviar inúmeros
pacotes TCP SYN (SYN FLOODs) pra uma determinada estação na rede, de modo que
toda a conexão fique em estado de espera, por estarem esperando suas respostas
em fila. Dessa forma o tráfego de rede controlado pelo kernel fica saturado,
evitando o roteamento de novas conexões legítimas. Mesmo considerando que o
Stack TCP/IP do FreeBSD é desenvolvido de forma à eliminar randomicamente
conexões TCP que estiverem em fila de espera de forma inativa, esse tipo de
ataque pode ser devastador dependendo da política de eliminação das filas
adotado no sistema (via sysctl(8)) e dependendo também da largura de banda da
rede. Vamos assumir que, se os pacotes TCP SYN chegarem ao servidor de forma
muito rápida, eles vão fazer pedidos falsos de conexões de forma mais rápida do
que eles podem ser eliminados da fila, não sobrando recursos o suficiente pra
tratarmos todas as conexões legítimas que também estiverem chegando.

Os primeiros pontos em questão, relacionado à esse tipo de ataque, é a


velocidade do ataque e velocidade com que esses pacotes podem chegar até o
servidor (definido por quão larga seja a banda do atacante) e depois a
velocidade e poder de processamento do servidor que está processando os pacotes
que estão chegando pelo Stack TCP/IP. Felizmente, nós estamos trabalhando com
FreeBSD, e o Stack TCP/IP do FreeBSD é mais poderoso do que o de qualquer outro
sistema, sejam até mesmo Unix, Linux, ou alguns outros BSD Unix. De qualquer
forma, dependendo do número de atacantes ao mesmo tempo, e da largura da banda
dos mesmos, essa velocidade nem sempre é o bastante.

Como podemos concluir na nossa ilustração prévia de um ataque TCP ACK


Spoofado, qualquer outro ataque com pacotes de qualquer tipo, SYN ou ACK
também seriam evitados pelo Firewall, porque cada novo pacote com porta de IP
randomicamente criada não encontraria uma regra dinâmica que o permitisse. Mas
de qualquer forma devemos ficar muito atentos em relação ao número de regras
dinâmicas que poderíamos abrir por pacotes TCP SYN spoodados. Mesmo tendo

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

certeza que o Stack TCP/IP do FreeBSD não seria sobrecarregado por tantas
tentativas de conexões, a criação das regras dinâmicas do ipfirewall(4)
poderiam ser saturadas, de forma a colocar pacotes em espera. A melhor forma de
evitar isso é diminuindo o tempo de vida das regras dinâmicas iniciadas por
pacotes TCP SYN, utilizando sysctl(8), como foi mostrado anteriormente, e
ainda, aumentar o número máximo de regras dinâmicas, através de uma outra
variável do sysctl(8):

net.inet.ip.fw.dyn_max: 1000 (default)

Como o seu firewall 'stateful' em plena atividade, você pode verificar


quantas regras dinâmicas existem criadas no exato momento, verificando a
variável do sysctl(8):

net.inet.ip.fw.dyn_count

A melhor forma de evitar que pacotes spoofados utilizem todas as suas


regras dinâmicas é evitar que qualquer máquina fora da sua rede inicie uma
conexão TCP. Isso pode ser feito facilmente com as seguintes regras, assumindo
que a rede 192.168.0.0/27 está por trás do firewall:

add 1000 check-state


add 2000 allow tcp from 192.168.0.0/27 to any out setup \
keep-state

Dessa forma só os pacotes TCP SYN que saírem pelo seu firewall poderão
ser roteados, ou seja, os pedidos que entrarem serão automaticamente negados.
Esse é o mesmo tipo de proteção que o NAT e proxies transparentes de forma
geral oferecem pras máquinas internas.

Até agora nós trabalhamos essencialmente com regras 'stateful' que


manipulavam conexões TCP. É claro, não é pra menos, conexões TCP representam a
grande maioria do tráfego gerado em rede, contudo você se lembra que nós
comentamos que o ipfirewall(4) poderia manipular também filtragem 'stateful' de
outro protocolos. Bom, então de uma olhada nas regras que nós usamos pra
permitir que nossos clientes internos pudessem pingar qualquer máquina pra fora
da rede, enquanto ninguém poderia nos pingar, quando estudamos a seção
referente ao “icmptypes”. Agora vamos fazer a mesma coisa usando "check-state"
e "set-state":

add 1000 check-state


add 2000 allow icmp from any to any out icmptypes 8 keep-state

Já podemos entender facilmente essa regra, que cria uma regra dinâmica
pra cada pedido de echo que nossas estações internas façam pra fora. Quando a
resposta chega ela é permitida pela regra dinâmica que estabeleceu a conexão
entre as duas pontas, e se alguém de fora tenta pingar uma máquina interna, a
regra padrão nega essa ação. O protocolo ICMP usa a variável
net.inet.ip.fw.dyn_short_lifetime do sysctl(8). Se a resposta do ping demorar
mais que 5 segundos pra chegar a regra vai ser descarregada e o pacote não vai
poder ser roteado. Se você considera que as respostas de ping levarão mais que
5 segundos pra acontecer, então você, como administrador da rede deve elevar o
valor da variável no sysctl(8). De qualquer forma a maioria dos atrasos de rede
levam menos de 1 segundo, a não ser que seja IRC ;-)

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

A regra 2000 ainda poderia ter definido uma faixa de rede com permissão
pra fazer o ping, caso existisse mais de uma rede por trás do firewall, e
apenas uma delas poderiam pingar máquinas externas. Na verdade escolhemos a
regra assim porque é a forma que mais se aproxima do nosso exemplo inicial de
controle do ping.

6.3. Anatomia de uma Regra Dinâmica;

Vamos dar uma olhada na saída que você devei encontrar quando listar as
regras dinâmicas de um firewall 'stateful' no seu FreeBSD:

00100 allow ip from any to any via lo0


00200 deny ip from any to 127.0.0.0/8
01000 check-state
02000 allow tcp from any to any keep-state
65535 deny ip from any to any
## Dynamic rules:
02000 9 1255 (T 54, # 0) ty 0 tcp, 192.168.0.1 2007 <-> 204.71.200.245
80

Nós já conhecemos as regras estáticas apresentadas, contudo, essa é a


primeira vez que nós estamos encontrando uma regra dinâmica listada pelo nosso
firewall. Vamos examina-la com mais atenção:

A primeira citação de uma regra dinâmica é o número da regra estática


que a gerou, no nosso caso, a regra número 2000, que tem a opção “keep-state”
ajustada, conforme aprendemos anteriormente. A segunda parte é o número de
vezes que aquela regra foi utilizada, ou seja o número de vezes que um pacote
saiu pelo firewall através daquela regra, ou o número de incidências da regra,
seguido do número total de bytes que os pacotes que passaram por aquela regra
rotearam. Entre parênteses encontramos o valor “T” que indica o “timeout” (o
tempo de vida) daquela regra, em segundos. Nesse caso ainda existem 54 segundos
de vida para essa regra. A cerquilha (#) indica o número da regra, nesse caso
essa é a nossa regra número 0. O 'ty 0' indica o tipo de regra dinâmica em
questão. Os tipos de regras correspondem ao fluxo do roteamento de pacotes
através daquela regra, ou seja, se ela permite apenas tráfego da origem pro
destino, do destino pra origem, ou se a regra é bidirecional. No nosso caso
temos apenas um tipo indicado, que é o padrão: bidirecional. Podemos verificar
essa afirmação visualmente, indicado pelo símbolo “<->” entre a Porta/IP de
origem e de destino. Depois do tipo da regra dinâmica podemos constatar o
protocolo que a regra ta usando, seguidos do IP/porta de origem, o símbolo de
fluxo dos pacotes (no caso “<->”) e finalmente o IP/porta do destino da
conexão.

Mesmos depois que uma regra dinâmica foi descarregada, você ainda pode
lista-la com o comando “ipfw list”, contudo a regra inativa vai ter um valor de
tempo de vida (“T”) igual a zero (T 0, #). Uma vez descarregada, a regra não
vai mais aceitar pacotes, simplesmente porque ela não existe mais, até que a
mesma regra seja reiniciada, ou ressucitada pela mesma entrada “keep-state” da
regra que a originou inicialmente. Uma vez descarregadas, as regras também
podem ser substituídas por novas regras dinâmicamente ativadas. A não ser que
todas as regras dinâmicas continuem em pleno uso, elas serão continuamente
substituídas por novas regras, especialmente se o número de regras dinâmicas
alcançou o máximo permitido pelas variáveis do sysctl(8).

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

Veja o seguinte exemplo de listagem das regras do ipfw(8):

00100 0 0 allow ip from any to any via lo0


00200 0 0 deny ip from any to 127.0.0.0/8
01000 0 0 check-state
02000 462 71516 allow tcp from any to any keep-state
65000 186 16464 deny ip from any to any
65535 56146 6054724 allow ip from any to any
## Dynamic rules:
02000 125 22084 (T 300, # 48) ty 0 tcp, 200.210.70.151 1180 <->
200.210.42.45 22
02000 31 1828 (T 217, # 55) ty 0 tcp, 200.210.70.151 1176 <->
200.210.42.45 21
02000 15 1372 (T 0, # 58) ty 0 tcp, 200.210.70.151 1174 <->
200.210.42.45 22

Não vamos comentar a listagem acima, cabe a você entender o que está
acontecendo com o firewall. Note que existe conexões cujo tempo de vida já se
esgotou, e ainda assim a mesma foi listada.

Bom, quando você começar usar regras 'stateful' em grande escala, você
vai perceber o quanto a saída de um comando pra listar as regras do ipfw(8) vão
se tornar perturbadoras, devido ao enorme número de regras dinâmicas criadas. O
ipfw(8) lista todas as regras dinâmicas, mesmo que já descarregadas pra
oferecer controle total do firewall ao administrador, contudo nem sempre você
quer analisar as regras dinâmicas, e apenas as estáticas, já que são essas que
criam as dinâmicas. Nesse caso uma solução óbvia do mundo Unix seria:

eksffa@eeviac~# ipfw list | grep -v '[<->#]'

Ou se você quer analisar com cuidado todas as regras, sejam estáticas


dou dinâmicas, uma solução é utilizar um paginador:

eksffa@eeviac~# ipfw list | less

OU

eksffa@eeviac~# ipfw list | more

7. Traffic Shape (controle de tráfego);

Controle de Tráfego (Traffic Shaping) se refere à possibilidade de


controlar todo o roteamento de pacotes pelo seu firewall de diversas maneiras,
entre as quais as mais importantes são: limitação de banda, atrasos no
roteamento (delays), criação de filas de fluxo, entre outros. Ele permite que
você controle a intensidade, direção e disponibilidade do tráfego. Até agora a
gente entendia como controlar roteamento, a escolha e definição de políticas de
permissões ou restrições de acesso; agora controlar tráfego passa a significar
mais do que simplesmente filtrar quem e quando pode acessar determinado
serviço, rede e/ou estações. A inclusão do dummynet(4) no FreeBSD possibilitou
um controle de tráfego extensivo, funcionalida essa que o IPFilter também não
pode oferecer.

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

Todo gerenciamento mais rudimentar de uma rede, em relação à sua infra


estrutura básica de tráfego e roteamento pode ser implementado utilizando-se
ipfirewall(4) e dummynet(4). Existem apenas duas restrições: probabilidade de
ocorrências e a utilização de regras dinâmicas. Nenhuma regra de 'Traffic
Shapping' pode ser criada de forma dinânica, simplesmente porque é inviável, em
relação à performance, a verificação da capacidade de banda, atrasos e filas de
fluxo em cada regra à ser criada de forma não estática.

7.1. Probabilidade de Ocorrências (Probability Matching).

O ipfirewall(4) possui uma ferramenta incrivelmente funcional pra


auditar e testar uma rede. Essa ferramenta permite que o administrador simule a
restrição de pacotes de forma aleatória sob várias taxas de probabilidade. Essa
ferramenta estatística faz uso da opção “prob” nas regras do firewall, opção
essa, seguida de um número entre 0 e 1, o qual corresponde à probabilidade
estatística dos pacotes que serão liberados pelo firewall. Dessa forma, uma
probabilidade 0.9 (indicada pelo comando “prob 0.9”) vai permitir o tráfego de
90% dos pacotes que passaram por aquela regra, da mesma forma que uma “prob
0.1” permitirá apenas 10% de probabilidade. Segue então uma pequena extensão da
sintaxe do ipfw(8) que nós estávamos acostumados:

<comando> [<no. regra>] [prob <prob_ocorrencia>] <acão> [log


[logamount <número>]] <proto> from <origem> to <destino>
[<interface-spec>] [<opcoes>]

Por exemplo, se nós quisermos restringir 20% dos pedidos de echo (echo
requests) do ICMP, poderíamos usar a seguinte regra:

add 1000 prob 0.8 allow icmp from any to any in icmptypes 8

Podemos também querer negar 50% dos pacotes TCP SYN pro servidor web,
dessa forma simulando um tráfego pesado na interface ep0. Faríamos da seguinte
forma:

add 1000 prob 0.5 allow tcp from any to any in setup via ep0

A utilização de probabilidade de ocorrências é uma função nativa do


ipfirewall(4).

7.2. Dummynet;

Todas as outras funcionalidades pra se implementar Traffic Shapping


requer o uso do dummynet(4), que foi incorporado na versão 2.2.8 do FreeBSD.
Pra isso precisamos adicionar uma opção ao nosso Kernel:

options DUMMYNET

Depois de compilado o nosso kernel com mais essa opção (além das opções
típicas do ipfirewall(4)), o administrador do sistema vai poder especificar a
criação de túneis (chamados “pipes”) pra controle do tráfego. Um túnel nada
mais é do que uma regra de Traffic Shapping que controla o roteamento,
canalizando as informações que posteriormente irão trafegar por endereços
específicos de rede. A criação desses túneis é feita com o comando “pipe” do
ipfw(8). O tráfego é redirecionado à esses tuneis por meio do comando “pipe

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

<pipe #>” no ipfw(8). Vamos então criar um túnel simples:

pipe 10 config bw 100Kbit/s

Note que, assim como nas regras de firewall, o “pipe” é apenas mais uma
ação pro ipfw(8), exatamente como “add” ou “delete”, portanto antes de cada
comando é feita uma chamada ao ipfw(8) (/sbin/ipfw pipe 10... por exemplo).

Esse túnel simples que criamos logo acima vai limitar o fluxo de
informações pra uma velocidade máxima de 100 Kilobits por segundo. Existem
várias maneiras distintas de indicarmos as medidas de velocidade de tráfego:
bit/s, Byte/s, Kbit/s, Kbyte/s, Mbit/s, Mbyte/s. Cada túnel de limitação de
banda deve usar a opção “bw” (de bandwidth – banda).

Uma outra maneira de controlar tráfego é usar a opção “delay” que força
um atraso na comunicação, simulando o que se conhece como “lag” do sistema:

pipe 10 config delay 100

O valor que segue a opção “delay” é o tempo de atraso que nós


desejamos, definido em milisegundos. Nesse exemplo todo o tráfego roteado
através desse túnel terá um atraso de 100ms.
Existe ainda a possibilidade de proporcionarmos uma taxa de perca de
pacotes, função essa igual à “prob” que comentalos logo acima. Por exemplo, pra
conseguirmos uma taxa de 20% de pacotes perdidos (equivalente a “prob 0.8”)
podemos criar o seguinte túnel:

pipe 10 config plr 0.2

"plr" significa "packet loss rate" (taxa de perca de pacotes), portanto


o valor indica à que taxa os pacotes não serão roteados, oposto da opção “prob”
do ipfw(8), que indica a taxa dos pacotes que serão roteados. Pra evitar
qualquer confusão com a utilização de “prob” ou ®plr”, aconselhamos que o
administrador assuma uma escolha pessoal entre as duas possibilidades. Ambas
são igualmente efetivas, e co-existem porque a primeira é nativa do
ipfirewall(4) enquanto a segunda faz parte do dummynet(4).

7.2.1. Filas de Túneis (Pipe Queues);

Bom, a necessidade seguinte é definir o tamanho das filas dos túneis


gerados, especialmente se a MTU da interface de rede em questão é relativamente
grande. A MTU de uma 'device' de rede define o tamanho máximo que um pacote vai
ter naquela interface. MTU = Maximum Transmission Unit, ou Unidade Máxima de
Transmissão. Pra se obter o valor da MTU em uma interface de rede é necessário
o uso do ifconfig(8):

eksffa@eeviac~# ifconfig xl0


xl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 192.168.0.1 netmask 0xffffffe0 broadcast 192.168.0.31
ether 00:70:18:d4:a4:ac
media: 10baseT/UTP (10baseT/UTP <half-duplex>)
supported media: 10base5/AUI 10baseT/UTP <full-duplex>
10baseT/UTP
<half-duplex> 10baseT/UTP

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

eksffa@eeviac~#

Verificamos portanto que na interface xl0 em questão, a MTU da placa de


rede é 1500 (bytes). Por padrão esse valor é comum entre as placas de rede.

As filas são utilizadas pelos túneis pra forçar as limitações e atrasos


de banda. Elas podem ser configuradas especificando-se o seu temanho em
“Kbytes” ou por “slots”. Cada 'slot' corresponde a um pacote, ou seja definir
que uma fila tem 10 'slots' significa que aquela fila vai suportar apenas 10
pacotes simultâneos. O tamanho máximo de cada pacote, por ser definido pela MTU
da interface, equivale a multiplicação do mesmo pelo número de pacotes na fila,
ou seja se você criar uma fila (queue) com 10 'slots', o tamanho dela será 10 x
1500 bytes, portanto 15Kbytes.

É importante entender a definição de tamanho das filas (queue) porque o


padrão pra cada fila é 50 'slots', que pode ser muito pra determinadas
interfaces de rede com MTU grande e pouca banda disponível. O padrão 50 'slots'
foi definido por ser o tamanho médio de uma fila nas devices de rede.
Normalmente esse valor é o ideal, contudo quando se tem uma banda pequena, a
requisição pelas interfaces é maior do que o tráfego possível na rede, isso
gera gargalo e consequente atrasos na rede. Façamos o seguinte então: vamos
criar um túnel em uma rede que simule a velocidade máxima de um modem de 56K:

pipe 10 config bw 56Kbit/s

... mas não vamos definir uma MTU menor pra device, com o ifconfig(8),
nem vamos diminuir o tamanho da fila (queue), que seria nossa melhor opção. A
fila pros pacotes então seria 1500 bytes (12000 bits) x 50, ou seja, 600Kbits
de fila. Pra um túnel que esta limitando a banda à 56Kbit por segundo, levaria
aproximadamente 10.7 segundos pra uma fila de 600Kbit ser preenchida. Esse é um
atraso inaceitável pra por o tráfego em andamento. Pra evitar esse tipo de
problema é recomendável ajustar manualmente o tamanho das filas (queue), em
'slots' que é mais fácil pra uma comparação com o padrão (que sabemos ser 50)
ou em ®Kbits” que é uma melhor atribuição à quantidade de dados. A segunda
opção é a melhor, porque além de ser um valor mais compreensível, o uso de
'slots' requer que o administrador também defina o valor pra MTU da interface,
utilizando o ifconfig(8), já que esse valor equivale à variável de
multiplicação no tamanho da queue (fila). Lembre-se, quanto menor a banda
disponível, menor deve ser a fila. No nosso exemplo acima, uma configuração
rasoável pra fila seria:

pipe 10 config bw 56Kbit/s queue 5Kbytes

7.2.2. Máscaras de Túneis (Pipe Masks);

Uma poderosa característica dos túneis é permitir múltiplas filas por


fluxo. Por exemplo, imagine que você tenha várias máquinas atrás do seu
firewall, e você quer limitar a banda pra 100Kbits/s pra cada máquina, ou seja,
não vai agregar um valor somatório à banda pra todas as máquinas, vai definir
individualmente a banda. Existem duas formas de se fazer isso, a mais óbvia e
primeira conclusão que um administrador tomaria seria criar túneis e regras
individuais pra cada máquina, com o ipfw(8). Mas agora considere que você pode
definir máscaras pra identificar um subconjunto de estações que pertencem ao
mesmo túnel, exatamente como netmasks e bitmasks identificam subconjuntos de

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

estações que pertencem a mesma rede.

As máscaras podem ser de seis tipos distintos:

"dst-ip" – máscara pro IP de destino do pacote que esta sendo enviado


pelo túnel.
"src-ip" – máscara da origem
"dst-port" – máscara da porta de destino
"src-port" – máscara pra porta de origem
"proto" – máscara do protocolo
"all" - máscara geral, que especifica todos os bits nos campos (dst-ip,
src-ip, etc) como importantes e válidos.

Por exemplo, vamos assumir a mesma idéia anterior de uma rede atrás de
um firewall onde cada estação deve ter uma banda de 100Kbit/s. Se nós
simplesmente direcionarmos todo o tráfego pra um túnel, o valor do tráfego será
a somatória de todas as estações, e não valores individuais. Pra utilizar
máscaras pras estações às quais o tráfego deve ser separado por filas
específicas, dessa maneira limitando a banda de forma separada, faremos o
seguinte:

pipe 10 config mask src-ip 0x000000ff bw 100Kbit/s queue 10Kbytes


pipe 20 config mask dst-ip 0x000000ff bw 100Kbit/s queue 10Kbytes
add 1000 add pipe 10 all from 192.168.0.0/16 to any out via <device>
add 2000 add pipe 20 all from 192.168.0.0/16 to any in via <device>

No primeiro instante as definições acima parecem confusas,


especialmente porque essa também é a primeira vez que nós incluimos as regras
do ipfw(8) pra direcionar os pacotes pros túneis. Assumimos que apenas a
definição dos túneis sem o direcionamento com ipfw(8) não faz mais sentido. No
túnel (pipe) 10 nós criamos uma limitação de banda de 100Kbit/s e fila de
10Kbytes pro endereço de origem do nosso conjunto de estações. O túnel (pipe)
20 definiu os mesmos valores de bandas e fila (queue) pro nosso conjunto de
endereços de destinos. A regra 1000 definiu que todo o tráfego entre a nossa
rede sairia pelo túnel 10, e a regra 2000 definiu que todo o tráfego entre a
nossa rede interna entraria pelo túnel 20, sempre (nas duas regras) o tráfego
ocorreria pela interface <device>.

Existem dois motivos pra termos túneis pra entrada e pra saída do
tráfego, mas uma delas nós vamos discutir posteriormente. A primeira questão
que deve nos prender atenção no momento é que cada túnel define uma máscara
diferente. O túnel 10 define a máscara 0x000000ff pros endereços de origem,
simplesmente porque a regra 1000 direciona todo o tráfego que sai (out) pela
rede interna, ou seja a máscara *deve* fazer menção ao endereço de origem,
porque cada origem faz diferença quando queremos filas distintas pra cada
estação que origina o fluxo. Da mesma forma o tráfego que está chegando (in)
deve ser separado em filas (queue) disntas de acordo com cada endereço de
destino.

Você deve ter percebido que nós especificamos as máscaras em


hexadecimal ao invés de decimal nos túneis. As duas notações funcionam
perfeitamente. As máscaras pros túneis funcionam exatamente da mesma forma que
as 'netmasks', mas a utilização delas se torna muito mais clara quando nós
percebemos que sua aplicação é definida de forma reversa, se comparadas. Quando
nós utilizamos 'netmask' nós estamos dividindo a rede em subgrupos, de forma

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

que os bits iniciais são os bits altos, ou seja, os bits imutáveis da subrede.
Aqui nós definimos os bits altos como os últimos bits da máscara, porque cada
túnel roteia os dados de trás pra frente em relação à rede. O valor em
hexadecimal que nós especificamos corresponde à mascara decimal 0.0.0.255. Bem
simples portanto: o último octeto indica que apenas uma estação será atribuída
por fila (256 menos 255 = 1). Dessa forma é atribuida uma fila específica por
controle de banda pra cada endereço de estação com número distinto (no seu
último octeto). É claro que estamos supondo aqui que a rede em questão não
deverá ter mais que 254 estações, mas caso existam, a máscara deverá ser
redefinida. Então se você quer definir 254^2 estações na rede que o firewall
vai estar controlando, aí a máscara teria que ser 0.0.255.255 (0000ffff). Isso
define que qualquer endereço com um único bit diferente entre os dois últimos
octetos (ou seja os 16 últimos bits baixos) deverá ter sua própria fila de
pacotes.

7.2.3. Remanejamento de Pacotes por Túneis (Packet Reinjection);

Em 99% dos casos, assim que um pacote é direcionado à um túnel (pipe),


é a configuração definida pro túnel que toma parte do pacote, e nesse momento a
busca nas regras termina, como de costume no ipfirewall(4). Contudo você pode
forçar que o pacote seja reinjetado (ou remanejado) no firewall, a partir da
regra seguinte, mesmo depois de ter sido direcionado pro túnel. Pra fazer isso
basta desativar a seguinte opção no sysctl(8):

net.inet.ip.fw.one_pass: 1

Essa opção é booleana. Só pra constar ;-)

8. Fluxo do Tráfego pelo Firewall.

Vamos lembrar que as regras que não especificam se o pacote deve ser
examinado na entrada ou saída pelo firewall (usando as opções “in” e “out”),
serão sempre verificadas pro tráfego de entrada *E* de saída. Isso implica em
algumas consequências. Quando uma regra redireciona o tráfego pra um túnel sem
usar “in” ou “out”, a regra será duplicada, um túnel pros pacotes que saem e um
pros que entram. Outra coisinha, quando as regras não são definidas por
interface (usando “via”) todas as regras são aplicadas à todas as interfaces,
mesmo se definidos entrada e saída (“in”, ”out”), simplesmente porque, imagine
seu gateway com múltiplas interfaces de rede, uma pra rede verdadeira
(Internet) e duas pra redes internas. Todo tráfego definido como “in” é o que
entra pelas interfaces pra máquina firewall, ou seja, se vem da internet pro
gateway, ENTRA pelo firewall; Se vem das redes locais pro gateway, ENTRA pelo
firewall. Uma breve ilustração:

_________
|
|
REDE INTERNA <== (OUT) | | (IN) <== INTERNET
REDE INTERNA ==> (IN) | | (OUT) ==> INTERNET
| ________ |
firewall

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

Devemos também notar os conceitos de half-duplex e de full-duplex pras


conexões. Se o tráfego de entrada e saída são direcionaos pro mesmo túnel,
então ele vai adotar um coportamento half-duplex, simplesmente porque o túnel
não pode rotear o tráfego em ambas as direções ao mesmo tempo. Se você esta
trabalhando com conexões de rede que sejam full-duplex portanto é sempre
recomendado criar túneis distintos, pro tráfego que entra e pro que sai, dessa
forma podendo rotear as duas direções ao mesmo tempo. Eis a segunda rasão que
nós estávemos devendo pra se ter duas regras, uma pra controlar cada direção de
fluxo.

Apêndice A: Exemplos de Configurações de Firewall;

Vamos ilustrar aqui alguns cenários onde é necessário implementar um


firewall. Cada um é exemplificado com regras de firewall e uma explicação breve
de como a regra funciona. Nos nossos exemplos vamos adotar a rede
12.18.123.0/24 como a local, xl0 será a interface de rede externa e xl1 será a
interna.

P) Como eu bloqueio pings externos, mas permito que eu possa pingar


qualquer estação externa?

R) A solução Stateful. As regras dinâmicas pros pacotes ICMP usam as


definiçoes do net.inet.ip.fw.dyn_short_lifetime no sysctl(8), que é de 5
segundos de vida pra cada regra. A vantagem da solução Stateful é que as
respostas de echo são permitidas apenas das máquinas que você pingou.

add 1000 deny icmp from any to 12.18.123.0/24 in via xl0 icmptypes 8
add 1010 check-state
add 1020 allow icmp from 12.18.123.0/24 to any out via xl0 icmptypes 8
keep-state
add 1030 deny icmp from any to any

O motivo pra regra de negação antes da regra com check-state é que as


regras dinâmicas são bi-direcionais, ou seja, os pedidos de echo podem vir de
estações externas que serão permitidos, durante a vida últil da regra. Por isso
filtramos os pings externos antes de verificarmos as regras dinâmicas.

A solução Stateless. A vantagem é que sobrecarrega menos o firewall,


porque existe um número menor de regras à serem processadas; mas, elas
sobrecarregam o firewall quando não existem muitas ocorrências de tentativas de
pings, então a vantagem de uma solução ou outra depende de uma análise da
frequência que os pings ocorrem.

add 1000 deny icmp from any to 12.18.123.0/24 in via xl0 icmptypes 8
add 1010 allow icmp from 12.18.123.0/24 to any out via xl0 icmptypes 8
add 1020 allow icmp from any to 12.18.123.0/24 in via xl0 icmtypes 0

Outra desvantagem da solução Stateless é que ela vai sempre aceitar


respostas de echo (Echo Reply) de qualquer estação, enquando a solução Stateful
permite resposta apenas das estações que foram pingadas.

P) Como eu bloqueio que as redes privadas, conforme definidas na RFC

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.
IPFW­HOWTO
 

1918, sejam roteadas pra dentro ou pra fora da minha rede?

R)

add 1000 deny all from 192.168.0.0/16 to any via xl0


add 1010 deny all from any to 192.168.0.0/16 via xl0
add 1020 deny all from 172.16.0.0/12 to any via xl0
add 1030 deny all from any to 172.16.0.0/12 via xl0
add 1040 deny all from 10.0.0.0/8 to any via xl0
add 1050 deny all from any to 10.0.0.0/8 via xl0

O) Como eu posso forçar a limitação de taxas de cada estação na minha


rede de forma individual? Eu quero forçar um limite de UpStream de 64Kbit por
segundo e DownStream de 384 Kbit por segundo pra cada estação; ainda, quero
também evitar que qualquer estação externa inicie conexões com as estações na
minha rede, dessa forma ninguém vai poder rodar nenhum tipo de servidor.

R) Essa é a solução adotada em uma universidade:

pipe 10 config mask src-ip 0x000000ff bw 64kbit/s queue 8Kbytes


pipe 20 config mask dst-ip 0x000000ff bw 384kbit/s queue 8Kbytes
add 100 deny icmp from any to 12.18.123.0/24 in via xl0 icmptypes 8
add 110 check-state
add 1000 pipe 10 all from 12.18.123.0/24 to any out via xl0
add 1100 pipe 20 all from any to 12.18.123.0/24 in via xl0
add 1200 allow tcp from 12.18.123.0/24 to any out via xl0 setup keep-
state
add 1200 allow udp from 12.18.123.0/24 to any out via xl0 keep-state
add 1300 allow icmp from 12.18.123.0/24 to any out icmptypes 8 keep-
state
add 65535 deny all from any to any

http://www.freebsdbrasil.com.br
Reprodução integral ou parcial permitida desde que as fontes originais sejam mencionadas.

Вам также может понравиться