Você está na página 1de 35

V.0.

3br_pt
Se existirem perguntas ou comentários, por favor, envie-os para walt@erudi
tion.net. A versão mais recente desse documento vai estar sempre disponível em www.f
reebsd-howto.com. Os direitos de reprodução desse documento são reservados. Versão em po
rtuguês desse documento sob responsabilidade de Patrick Tracanelli (eksffa@freebsd
brasil.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 f
irewalls)
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
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 Reinj
ection)
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 r
ede 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 cui
dado na hora de ajustar o firewall (se você tem familiaridade com o ipf(8), por ex
emplo, 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 fi
rewalls 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 part
ir 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 estad
os 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 bloque
ado.
Um firewall costuma ser arquitetado de diversas formas, mas todas as man
eiras podem ser simplificadas com base em duas políticas de filtragem: aberto e fe
chado. 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 é de
sejado, ou seja, "abre tudo e bloqueia os indesejados". Já o firewall que segue um
a política fechada, faz o inverso, bloqueando todo o roteamento de pacotes, e libe
ra um a um o tráfego de conexões permitidas. Essa segunda implementação proporciona um f
irewall muito mais rígido, contudo sua configuração é bem mais trabalhosa, porque você pod
e 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 preve
r, 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 o
pções apropriadas no seu kernel através do seu arquivo de configurações, e compilar um nov
o 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 p
ra adicionar um firewall(4) com configurações básicas, contudo, a compilação estática propo
ciona, com pouca diferença, uma melhor performance, mas permite ainda que se adici
one 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 adicion
ar 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 segu
ir 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ê prest
ar 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 q
ue o firewall usa uma política padrão fechada. Se você simplesmente adicionar o ipfire
wall(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 pod
e ser evitada, mesmo considerando que não é recomendado acionar o ipfirewall(4) remo
tamente, tanto de forma estática quanto dinâmica.
Se, de qualquer maneira, você quiser carregar o ipfirewall(4) de um comput
ador remoto, então recomendados que se faça da seguinte forma:
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áfe
go da rede, ao invés de bloquea-lo, evitando assim que você perca a conexão com a máquin
a remota. De qualquer forma, é recomendável que se carregue o ipfirewall(4) dessa ma
neira 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 d
e 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 r
oteando os pacotes, ou seja, você não vai conseguir estabelecer uma conexão remota nov
amente 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 se
ja bloqueado pelo seu próprio firewall.
Pra você fazer isso, basta adicionar duas linhas no seu rc.conf, uma que v
ai acionar o firewall na inicialização da máquina, e outra pra definir o tipo de firew
all que vai ser iniciado. No caso firewall do tipo aberto (OPEN). Então basta adic
ionar 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 simplesme
nte 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 *nece
ssárias*, porque nós não vamos *precisar* do /etc/rc.firewall pra configurar uma polític
a aberta de firewall, porque essa política já vai ser iniciada por padrão no kernel. C
ontudo, ainda que você escolha definir uma política de firewall padrão no kernel, é inte
ressante 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âmi
ente, porque se eventualmente seu sistema for reinicializado, o módulo ipfw.ko não v
ai 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 aci
onar o firewall de forma estática no kernel, até o início da série 4.x do FreeBSD alguma
s dessas opções não podiam ser acionadas se não fosse de forma estática no kernel, mas nas
versões mais recentes foram definidas algumas variávies do kernel, mutáveis via sysc
tl(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 q
ue 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 logad


os para uma regra específica. Dessa forma, o syslogd(8) não será sobrecarregado com me
nsagens 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 alguma
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_VERB
OSE_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 sobr
e 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 esp
cas de roteamento de pacotes, e vamos tratar delas assim que começarmos a tratar e
ssas configurações.

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 é iniciad
o, 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 quan
do 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 pr
imeira 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 loca
l (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 co
rreta, onde o uso do /etc/rc.firewall via rc.conf é altamente recomendável. Se você fi
zer a opção por um script shell que carregue todas as suas regras e que seja executa
do sempre que o sistema iniciar, você deve ficar atento a essas e outras regras qu
e não devem faltar ao seu firewall.
Em seguida, quando você define um firewall do tipo "OPEN" (aberto) no rc.c
onf, 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 ker
nel. Se a política aberta é definida no kernel, a regra número 65535 vai ser automatic
amente carregada como "allow ip
from any to any" no lugar de "deny ip from any to any", posteriormente adicionan
do 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ê a
dicionou a política aberta (IPFIREWALL_DEFAULT_TO_ACCEPT) no kernel, e não quer perm
itir 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 regr
as e ver como o ipfirewall(4) do FreeBSD funciona, ou ainda, apenas bloquear alg
uns hosts específicos, e manter as suas configurações propícias às suas próprias regras, en
você pode seguramente pular pro nosso capíulo 3.
Contudo, se sua intenção é usar algum dos conjuntos de regras nativas já existen
tes 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 s
gunda é criar sua própria definição, com seu próprio conjunto de regras. Os autores do fir
ewwall nativo do FreeBSD, ipfirewall(4), recomendam o segundo caso, por duas rasõe
s 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 sinta
xe, se tornando mais experiente na definição de firewall, e ficando mais a vontade c
om 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 f
irewall, no caso você que está lendo esse documento. Se você preferir usar os conjunto
s 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 ger
encia 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 nenh
uma máquina que esteja fora da rede interna iniciar conexões TCP com máquinas dentro d
a rede. Se a rede estiver por trás de uma implementação básica de NAT sem nenhuma opção de
roxie 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 IPFI
REWALL_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 conhec
imento nos padrões RFC de Internet pra poder entender suas definições de regras de fir
ewall. Essa regra vai evitar spoofing (técnica onde uma máquina se faz passar por ou
tra, alterando seu endereçamento IP) não permitindo a entrada de nenhum pacote que t
enha um endereço de retorno igual ao endereço de qualquer host dentro da rede intern
a. Vai bloquear todos os pacotes endereçados como de redes privadas, conforme defi
nido na RFC 1928, evitando o tráfego pra dentro ou fora da rede, e vai bloquear ai
nda todas as redes não-roteaveis, conforme definido no Internet-Drafts da IETF (di
sponível em http://www.ietf.org/internet-drafts/draft-manning-dsua-03.txt). Esse t
ipo de firewall vai permitir tráfego de e-mail, de WWW, de DNS, e NTP, e vai permi
tir 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 tod
as 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 qual
quer tráfego da rede (exceto o tráfego via lo0 que nós vimos anteriormente que é control
ado 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, ajust
ar o firewall pra CLOSED vai ser necessário em casos *extremos* onde você prefere (a
inda 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 é recomen
dá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 arqui
vo /etc/rc.firewall.rules, o qual será carregado sempre que seu firewall for inici
ado. Se você preferir ainda que seu firewall seja iniciado de forma silenciosa, ba
sta 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 é sim
ples, 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 s
implesmente para serem processadas pelo ipfw(8). A principal diferença é que você não va
i 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);


A sintaxe das regras de firewall no FreeBSD são simples. Qualquer regra po
de ser adicionada pelo console, com o comando ipfw(8). Antes de nos aprofundarmo
s nas sintaxes das regras do ipfirewall(4), contudo, vamos verificar como podemo
s 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, se
guindo 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 d
a regra 00101, a de número menor será mostra antes, porque a ordem das regras também i
nflui na forma como o ipfirewall(4) vai se comportar.
Pra mostrar a data e hora da última vez que um pacote coincidiu com uma re
gra 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 19
2.168.1.0/24 12345
00102 Tue Sep 18 00:33:12 2001 deny log logamount 100 tcp from any to 19
2.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 minu
tos de 2 dias atrás, e o último pacote permitido pelo firewall foi há 9 segundos. Deta
lhe 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 fa
zer o seguinte:
root@eeviac~# ipfw -a list
ou
root@eeviac~# ipfw show
Os dois comandos vão apresentar as mesmas informações, dispostas da mesma mane
ira. 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 (t
erceira 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 d
isponíveis pra se construir um conjunto de regras de firewall. Por enquanto não vamo
s abordar regras com as opções de stateful, ou seja, estaremos trabalhando com regra
s 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 comand
os, caso estejamos configurando as regras de forma manual, pelo console do FreeB
SD. O padrão abordado é como deve ser quando estamos trabalhando com um arquivo de r
egras pra ser passado pro ipfw(8) via firewall_type="/caminho/pro/arquivo.firewa
ll" 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 a
nteriormente, 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 co
m o parâmetro "pass", que é como ele foi usado no rc.firewall. Bom, acontece que "pa
ss", "allow" e "permit" são sinônimos pro ipfirewall(4), eles tem o mesmo efeito, co
ntudo as variações permitem que o administrador fique o mais a vontade possível para e
screver 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 permit
idos ("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 seri
a 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 proces
sadas 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 s
eu /etc/rc.conf, a última regra vai sempre indicar a política do kernel. Isso é ótimo po
rque, como a ordem de busca das regras para de processar ao encontrarem uma regr
a que combina com o 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, semp
re que um pacote combinar com essa regra, será permitido seu roteamento pelo firew
all, 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 d
as 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 qu
alquer destino.
"reset" - Quando um pacote encontra uma regra com essa ação, o pacote é bloque
ado, e o ipfirewall(4) tenta enviar um sinal (flag) de TCP Reset (RST) pro ender
eço de origem do pacote. O processamento das regras *pra esse pacote* termina. Com
o 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 de
tectar 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 ti
po "network flood" em uma porta específica a qual o ipfirewall(4) está configurado p
ara responder com pacotes RST, isso duplicaria o uso da sua banda de rede. Uma s
olução simples é bloquear, com uma regra prévia o endereço da máquina que está agindo dessa
rma, 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 qua
lquer destino, indo para qualquer origem, e responderia com um pacote RST para c
ada uma delas.
"count" - Todos os pacotes que combinarem com uma regra cuja ação seja "coun
t", determinará que o ipfirewall(4) incremente o contagem de pacotes, ou seja, a s
aída de "ipfw show" indicará mais uma ocorrência de pacotes nessa regra. Motivos estatís
ticos ó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
Essa (primeira) regra incrementa o número de vezes que um pacote passou pe
lo firewall, vindo de qualquer lugar e indo pra onde quer que seja. Já a segunda r
egra conta quantos pacotes, dentre todos, estariam sendo enviados da rede 200.23
0.50.0/24 (origem) pra rede 192.158.1.0/24 (destino). Uma observação aqui: se o proc
essamento das regras fosse terminado quando um pacote encontra uma regra cuja ação s
eja "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 c
uja ação seja "skipto <número>" vão fazer com que o ipfirewall(4) continue processando e
sse 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 ind
o pra qualquer destino seja processado pelas regras a partir da regra de número 18
00
"reject" - Essa ação é pouco utilizada atualmente. Quando um pacote combina co
m uma regra cuja ação seja "reject", então o ipfirewall(4) bloqueia esse pacote e resp
onde com uma mensagem ICMP do tipo "host unreachable", dando a impressão que a máqui
na se encontra fora da rede. Essa é uma forma não silenciosa de negar o tráfego pelo f
irewall, contudo, assim como a ação "reset", essa ação também aumenta o uso da sua banda d
e rede.
3.3. Especificando Protocolos;
Protocolo (proto) em "protocolo" na sintaxe básica de uso do ipfw(8), é o pr
otocolo 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 pro
tocolos mais comuns são "icmp", "udp" e "tcp", mas a relação de protocolos com os quai
s o ipfirewall(4) trabalha é enorme. Na verdade são todos os protocolos possíveis de u
ma 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 po
r DNS, pode ser um endereço IP, um endereço de rede com máscara de rede (bitmask/netma
sk) e, ainda podem definir uma ou várias portas, se o protocolo for tcp ou udp. Us
ar nomes ou endereços IP é indiferente, basta atentar ao fato que a resolução de nomes v
ia 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 "ou
tramaquina", e a segunda regra nega toda conexão da máquina 10.0.0.5 para qualquer o
utra estação. Sempre que um pacote coincidir com uma regra do firewall, o processame
nto 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 ap
enas 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 conj
unto 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 c
onhecida como bitmask especifica quantos bits do endereço de rede (192.168.0.0) de
vem 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 d
ois octetos do endereçamento da rede, então todos os endereços cuja origem seja a indi
cada 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áscar
a de rede (netmask) indica quantos bits do endereço de rede deve ser monitorado pe
lo 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 o
s 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 (de
ny).
O firewall do FreeBSD oferece ainda a possibilidade de inverter a expres
são apresentada na regra com o comando not . Por exemplo, para que o ipfirewall(4) bl
oqueie 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 bitm
ask) são simples, mas frequentemente confundidos por pessoas que não tenham muito co
nhecimento em redes, e ainda requer um pouco de noção de números binários. É muito mais prá
ico se nós trabalharmos com endereço IP em sua forma binária, contudo, a confusão que ex
iste entre os conceitos binários e decimais costuma ser decisiva pra alguém sem muit
os 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 respecti
vo 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
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 últim
o octeto da máscara de rede (netmask) começa com 255 e sempre se decrementa em valor
es 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 en
tã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. Por
tanto, concluímos de forma lógica que temos apenas 4 bits ajustados como 'bits baixo
s', 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 a
gora que existem apenas 2 valores possíveis para cada bit, já que o endereçamento não de
cimal é 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 enco
ntrarmos 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álc
ulos necessários. Aprenda uma vez e use 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 por
tas. 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 fir
wall 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 especif
icada com um hífen, podem ser separadas por vírgula, ou ainda, em casos mais elabora
dos, pode-se usar um netmask pra definir a faixa de portas. É importante lembrar q
ue 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 1
72.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 permit
idas pelo ipfirewall(4). Na terceira regra, todos os pacotes TCP destinados às por
tas 21, 22 ou 23 na estação 172.16.0.5 é permitida. E, finalmente na quarta regra, tod
os 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 f
az uso de uma netmask pra declarar a mesma. Mas a matemática também é bem simples. Com
o agora estamos tratando de Bitmask pra porta 1024, o valor pra ela é 10 bits, e c
omo 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 valore
s possíveis (binário = 2): 2^2, então temos 4 portas que compõe a faixa de endereçamento d
a 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 d
e 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 in
dica 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 bas
tante 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 defin
ir ações especiais para algumas combinações de pacotes, ou então que se queira um maior co
ntrole sobre o direcionamento do 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 di
scutir nessa seção. Nós vamos inclusive cobrir uma nova "ação" que não foi relatada anterio
mente. A Sintaxe pode parecer inicialmente confusa, mas nós vamos com calma, e mon
taremos 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 indisponibilid
ade), e posteriormente a leitra do conjunto de regras será terminada. As possibili
dades 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 c
orrespondentes. Se você não sabe onde esses códigos são utilizados, não tem porque você ten
ar 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 sej
a, a possibilidade de criar regras que verifiquem os pacotes de acordo com uma i
nterface 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
ereços de origem e de destino, mas usar apenas essas opções pra definir de onde um pac
ote está vindo ou pra onde ele está indo via firewall não é muito confiável. Quando você qu
r 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 defi
nidas 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 ind
o 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, podemos u
sar 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 qua
isqueres, 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 filt
rar 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 qu
e 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 ipfirew
all(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 fi
ar 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 i
nverte a opção se uma '!' (exclamação) for devinida antes do <tipo>, ou seja, todos os p
acotes que não forem desse tipo serão combinados. Existe, atualmente 15 tipos difere
ntes de pacotes ICMP que podem ser filtrados; cada um é definido por um número. Você p
ode ainda especificar faixas de 'icmptypes' utilizando hífen ou separando-os por vír
gula. 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)
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 tip
o 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ódi
gos, ou seja, todos. Usar filtros de pacotes ICMP é muito útil, especialmente pra co
ntrolar ping; por exemplo, você pode permitir que qualquer cliente dentro da sua r
ede interna pingue qualquer estação pra fora da rede, enquanto você bloqueia que qualq
uer estação externa pingue o seu gateway, ou qualquer outro cliente interno. As três r
egras 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 pacot
es icmp do tipo 0 (resposta de echo) entrem pelo firewall, e a regra seguinte bl
oqueia todos os pacotes icmp do tipo 8 de entrarem. Em resumo, permite que qualq
uer cliente faça um pedido de echo pra fora, e permite a entrada da resposta pra d
entro 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 es
tação externa, mas ninguém de fora pode pingar dentro. Naturalmente essas opções só podem s
r 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 conte
nha alguma das flags (opções) identificadas. Uma definição inversa também pode ser utiliza
da se colocarmos uma '!' (exclamação) antes da <flag>, dessa forma filtrando todos o
s 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)
urg - Indicate Urgent OOB data (indica um OOB de dados urgente
s)
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 aju
stada. Essa opção se chama "setup". É claro que só podemos trabalhar com a opção "setup" qu
ndo o protocolo indicado é o "tcp".
"setup" - Qualquer regra contendo essa opção vai filtrar todos os pacotes TC
P cujo cabeçalho indique a flag SYN ajustada. Dessa forma, se quizermos simplesmen
te negar todos os pacotes TCP que estiverem entrando no firewall com o cabeçalho S
YN 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 vin
dos de qualquer (any) origem para qualquer (any) destino serão negados. Vale a pen
a ilustrarmos a necessidade do protocolo ser "tcp" quando trabalharmos essas reg
ras.
"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 qu
ndo 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 dispo
nibilizadas, dessa forma oferecendo facilidade na criação de regras. Utilizando esta
s opções (ou mesmo suas definições nativas correspondentes às "tcpflags") podemos ter inic
ialmente um controle de conexões TCP mais simples. Essa é a base de implementações "stat
eful" 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 S
ource 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 h
averá 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 g
rande maioria dos casos, os pacotes fragmentados devem ser bloqueados pelo firew
all. 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 qu
e 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 for
ma, se você tem clientes Windows por trás do firewall, dentro da sua rede, é recomendáve
l bloquear pacotes fragmentados pra protege-los.
Quando você for usar a opção "frag" pra filtrar (e bloquear) os pacotes fragme
ntados, tem duas regrinhas básicas que você deve seguir. A primeira é que você não pode us
ar "frag" quando também estiver usando a opção "tcpflags"; você define qualquer pacote f
ragmentado, ou não define nenhum. A segunda: você também não pode utilizar o "frag" se e
stiver especificando portas TCP ou UDP; você bloqueia todos os pacotes fragmentado
s, 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 filtra
gem de pacotes baseada em GID/UID. O Ipfirewall(4) tem a capacidade de filtrar p
acotes 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 processo
s locais. As opções a serem utilizadas são "gid" ou "uid" seguidos do GID/UID ou do no
me do usuário/grupo que estivermos filtrando.
Um uso em potencial dessa função é restringir o número de IPs virtuais em um ser
vidor de shell. Se você quer se assegurar que um ou mais Hosts Virtuais não poderão se
r usados por ninguém mais que o dono do IP virtual, você pode definir uma regra base
ada 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 c
onexões TCP pra fora da rede. Ninguém mais será permitido pendurar Bots, Clientes de I
RC 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 pa
ra cada usuário, ao invés de limitar pra cada estação ou rede. Por exemplo, você pode defi
nir um grupo de usuários que tenham contas rápidas de FTP, definindo uma regra pro G
ID em questão, e em contrapartida ter um grupo de usuários de shell que não precisam d
e muita banda. Vamos ilustrar outras limitações de bandas definidas por GID posterio
rmente, 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 b
em 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 ve
m bem a acalhar. Uma pequena dica é sempre definir as regras baseadas em UID/GID a
ntes das outras regras, visto que o ipfirewall(4) termina a verificação da lista das
regras quando um pacote combina com alguma das regras em uso. Isso garante dese
mpenho e evita que se bloqueie ou permita um pacote antes de verificar qual usuári
o 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 vie
ram, pra que rede ou estação elas estavam indo, se o conteúdo dos pacotes eram fragmen
tados (indicantivo de muitos ataques de negação de serviço DoS), enfim, possibilita sa
ber 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. Dependend
o do tipo de dado que você está logando você pode se perder com a abundância de mensagen
s, 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 ativi
dade má intencionada, e por incrível que pareça ainda é sinônimo de perigo pra administrad
ores imprudentes. Por isso a importância de se definir que tipos de regras serão log
adas. 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 a
cesso, 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 experiment
am quando eles habilitam o ipfirewall(4) pra logar, é o seu terminal abarrotado co
m 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éi
a);
- 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 a
o 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 a ativação
o firewall. Essa segunda opção do kernel limita o número de mensagens consecutivas env
iados 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 conse
cutivas 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 consecutiva
s 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 i
mpressas 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 fl
exibilidade 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 f
ica à 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 arqu
ivo padrão (/var/log/messages), isso pode ser feito também, e ainda, se você julgar te
r espaço em disco o bastante pra trabalhar com rotacionamento de logs (Log Rotatio
n) 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 alternativ
a, crie também o diretório de logs que você achar conveniente. Vamos assumir então que v
ocê quer que todos os logs relativos ao ipfirewall(4) sejam armazenados em /var/lo
g/ipfw/ipfw.log. Dessa forma você vai ter que criar o diretório em questão (/var/log/i
pfw) e em seguida o arquivo de log (ipfw.log) sob tal diretório, pra isso vai util
izar 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 leit
ura 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 relativ
as ao ipfirewall(4) pro arquivo /var/log/ipfw/ipfw.log. A forma mais fácil de faze
r isso é adicionar as seguintes linhas no final do syslog.conf(5):
!ipfw
*.* /var/log/ipfw/ipfw.log
Atente pra usar <TAB> (tecla tab) nesse arquivo ao invés de espaços simplesm
ente. 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 n
a 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
empre 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 ma
nter atento a qualquer coisa errada que estiver acontecendo com o servidor. Se p
or bom senso você costuma estar muito logado com outro usuário que não seja o root, ta
mbé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 log
s pelo arquivo de configuração syslog.conf(5):
Insira a linha com !ipfw e indique o caminho pra onde as informações referentes às ativi
dades do Firewall devem ser logadas.
Não altere as mensagens que serão enviadas ao usuário Root se ele estiver logado. Indi
que 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 form


a mais fácil é usando o comando:
eksffa@eeviac~# killall -HUP syslogd
eksffa@eeviac~#

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


gs (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 gara
ntir que o newsyslog(8) vá rotacionar os logs do ipfirewall(4), ou, como alternati
va, optar por algum outro mecanismo de rotacionamento de logs. Pra se ter uma bo
a noção de todas as configurações possíveis do newsyslog.conf(5) é recomendado que você lei
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 ent
rada 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 rotacionad
o. A segunda indica os bits de permissões pros arquivos rotacionados. A terceira p
arte é o número de arquivo de logs que se deseja manter rotacionando até que o mais an
tigo seja apagado. O seguinte é o tamanho do arquivo quando ele deve ser rotaciona
do, 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
tação de logs são definidas por dois critérios: tamanho ou data. No nosso caso, nós indica
mos que queremos que o arquivo de log seja rotacionado às duas da manhã de todo domi
ngo, não importando o tamanho do arquivo de log. Depois definimos (a última opção especi
al, Z ) que o arquivo deve ser comprimido com gzip(1) sempre que rotacionar, e defi
nimos que vamos manter um histórico arquivado de 10 semanas. Se você deseja manter s
eus logs por mais que 10 semanas basta alterar o valor 10 pra qualquer um que vo
cê queira. Ou o ideal, criar uma rotina que faça backup em uma máquina separada (um Lo
gHost) a cada 10 semanas, ou então gravar seus Logs em CD ou qualquer outra mídia ba
rata e de grande capacidade quando for necessário.
Uma vez configurado, o newsyslog.conf(5) vai cuidar do rotacionamento do
s 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 nad
a 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 filtr
adas. 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 regra será logada todas as vezes
ue um pacote coincidir a regra. Por isso tome muito cuidado pra não defnir log pra u
ma 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 log
adas 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á
el:
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 an
teriores que suponhamos existir, portanto nos interessa manter logs das conexões n
egadas. Além do que o número da regra é 6500, o que, em relação à regra anterior (500) é mu
mais seletiva, visto que é uma das últimas regras a serem checadas. Preste muita at
ençã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 d
vezes que uma regra vai ser logada. Esse parâmetro é análogo à entrada de limite de ver
bosidade no kernel, e da muito mais controle ao administrador que pode, por exem
plo, 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 v
ersõ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:6230
7 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 f
requentemente encontrados em discussões cujo assunto seja ipfilter(4) e ipfirewall
(4). O modo de filtragem 'Stateless' tende a tratar cada pacote roteado pelo fir
ewall como pacotes individuais, que não tenham associação alguma com qualquer outro tráf
ego que também estiver passando pela dada interface do firewall. Esse tipo de filt
ragem é 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 d
estino e/ou origem do pacote)
Já uma filtragem do tipo 'Stateful' é mais complexa de ser implementada; ess
e tipo de filtro trata o tráfego como sendo composto de determinadas conexões, ou se
ja 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ênc
ia que indicam em que ordem os pacotes serão lidos em um socket(2). Esse é o primeir
o princípio básico das informações que um firewall 'Stateful' precisa conhecer. O segund
o é que, conexões orientadas à protocolos como TCP, geram tráfego de pacotes especiais q
ue indicam o início de uma conexão (SYN) e o fim da mesma (FIN). Esse ponto também é ess
encial 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 espe
rada, 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 estiv
erem em andamento, e elimina essas regras quando a conexão foi terminada. Isso per
mite ficarmos atento de forma mais inteligente às atividades da rede. Por outro la
do um firewall do tipo 'stateful' são incapazes de filtrar cada pacote individualm
ente, 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. E
m compensação, é muito fácil juntar regras de firewall do tipo 'stateful' e do tipo 'sta
teless' em um mesmo firewall, dependendo apenas do quanto o administrador do sis
tema é bom. E normalmente administradores de FreeBSD já são muito bons por natureza, p
ortanto 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 "est
ablished" que permitiam que nós checassemos o estado de uma conexão TCP. Vamos então u
sar 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' mu
ito limitada. Por isso anteriormente à versão 4.x do FreeBSD o ipfirewall(4) era cha
mado 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 funcion
alidades 'stateful' mais extensivas, e mais desenvolvimento a respeito disso está
em andamento no ipfirewall(4).

6.1. Configurações 'Stateful' Iniciais;


Pro nosso primeiro exemplo, vamos estar usando as características mais básic
as 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 co
põe a maiora das regras nesse arquivo. Mesmo essas regras podendo ser usadas exclu
sivamente pra controlar conexões TCP de forma 'stateful', o que demonstra certa li
mitação, vamos criar no nosso primeiro exemplo um conjunto simples de regras que fil
tram 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 IPFIR
EWALL_DEFAULT_TO_ACCEPT no kernel do sistema). Nesse caso, as duas regras anteri
ores vão permitir o roteamento dos pacotes desejados. A regra número 1000 vai permit
ir todos os pacotes que sejam parte de uma conexão TCP já estabelecida, e então a veri
ficaçã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 t
ipo 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 impo
rtâ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 por
ta 22 também serão permitidos. Nesse caso você vai perceber que as regras não ficam moni
torando 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 pa
cotes são esses.
Essa é a essência de um firewall do tipo 'stateful' utilizando setup e stablish
ed : Deixa passar pedidos de inicialização de conexões de um serviço (porta) específico, e
epois da conexão estar estabelecidade permite que todo o tráfego funcione normalment
e.
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
Nesse exemplo, o pedido de inicio de conexão (usando setup ) é permitido pras p
ortas 21, 22, 25 (FTP, SSH e SMTP respectivamente) quando os pacotes são destinado
s à rede 172.16.0.0. Consequentemente todas as conexões TCP estabelecidas serão permit
idas 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 entr
arem pelo firewall. Essas duas últimas regras são 'stateless'. A porta 53 é a porta on
de o serviço de nomes (DNS) roda. A regra 1000 deve ser from any to any porque os pa
cotes 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 pac
otes vindos de algum lugar e as suas respostas pra outro lugar.
Vamos analizar um caso especial: FTP. Se você fosse fazer um firewall cuja
s 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 r
evoltadinho que estabelece suas conexões em qualquer porta não reservada, ou seja qu
alquer porta acima da 1024. Uma solução não muito prática é liberar as portas 21 e 22 de f
orma '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 o
s 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 in
icialização de uma conexão na porta 21 (onde todas as requisições FTP iniciam) e posterior
mente permitimos o roteamento de pacotes pertencentes à essa conexão por qualquer po
rta (utilizando stablished ). Essa é a forma mais eficiente de se controlar FTP via f
irewall, e essa prática pode ser adotada pra outros serviços que tenham comportament
e similar a esse.

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


Como já foi dito, configurações de firewall 'stateful' usando apenas setup e est
blished são muito limitadas. Exatamente por permitir controle de conexões stateful ap
enas sobre o protocolo TCP, essa filtragem é a mais simples existente. Desde a ver
são 4.0 do FreeBSD, o ipfirewall(4) adotou características 'stateful' baseada em ótimo
s 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 independen
tes. 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 control
ada por inúmeras variávels do sysctl(8), ou seja, de certa forma um conjunto de regr
as 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 'statef
ul' avançado:
"keep-state" Quando um pacote é combinado com uma regra que tenha essa opção a
justada, então uma regra dinâmica é iniciada.
"check-state" - Esse comando define que a verificação das regras pelo firew
all vai primeiro checar as regras dinâmicas. Se não existir uma regra com esse coman
do em todo o conjunto de regras do seu firewall, ai as regras dinâmicas serão verifi
cadas 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 c
ntinua.
Vamos então voltar ao nosso exemplo anterior, onde tínhamos regras destinada
s à permitir apenas conexões SSH, mas dessa vez vamos usar regras mais avançadas de 's
tateful':
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 re
gras dinâmicas. Se o pacote não pertence a nenhuma conexão já estabelecida (ou seja, não f
azem 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 sob
e as outras configurações de firewall. Antes, a opção stablished permitia a ocorrência de
alquer pacote TCP vindo de uma conexão TCP previamente estabelecida, ainda que ess
e pacote fosse spoofado e não fosse um pacote legítimo dessa conexão TCP. A expressão spo
of define um tipo de pacote que traz consigo informações de origem manipulada, ou sej
a 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 es
pecífica entre duas pontas (dois hosts) e suas respectivas portas, ou seja, um pac
ote TCP spoofado poderia manipular seu endereço de destino e de origem, mas não mani
pularia a porta (a não ser com muita sorte) onde a conexão foi efetivada, e onde a c
onexã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 é ne
gado 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 p
or 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 se
r utilizada. Dependendo de como uma regra dinâmica é utilizada, podemos definir um p
eríodo fixo de tempo até que a regra se esgote. Esse tempo de duração pra cada tipo de r
egra dinâmica pode ser verificado utilizando as variáveis corretas do sysctl(8). Pos
teriormente podemos modificar esses valores. Eis a listagem dos valores padrões de
ssas 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 i
ndica que o tempo de vida de uma regra dinâmica cujo pacote seja TCP SYN é 20 segund
os. 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 sysct
l(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 p
orta 22 do servidor 192.168.0.1 que fica por trás do firewall. Esse pedido de inic
ializaçã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 reg
ras 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 cri
e 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 pacot
es 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, q
ue 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 por
ta de origem sejam conhecidos, assim como IP e porta do destino. Dessa forma a r
egra 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 circuns
tâ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 regra 1000 falha, e a filtra
gem 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 é d
o 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 cu
mprida, pois aceitava todo pacote com um destino em particular, que tivesse ao m
enos 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 port
a 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 ipfirewal
(4). Esse tipo de vantagem o IPFilter também possui.
No exemplo anterior poderíamos ter assumido um ataque diferente se o pacot
e spoofado fosse do tipo TCP SYN, mas antes de explicarmos isso, vamos dar uma o
lhada em um tipo de ataque popular utilizando TCP SYN, ataque esse conhecido com
o 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 (S
YN FLOODs) pra uma determinada estação na rede, de modo que toda a conexão fique em es
tado de espera, por estarem esperando suas respostas em fila. Dessa forma o tráfeg
o de rede controlado pelo kernel fica saturado, evitando o roteamento de novas c
onexõ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 form
a inativa, esse tipo de ataque pode ser devastador dependendo da política de elimi
nação das filas adotado no sistema (via sysctl(8)) e dependendo também da largura de b
anda da rede. Vamos assumir que, se os pacotes TCP SYN chegarem ao servidor de f
orma 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 tratarm
os todas as conexões legítimas que também estiverem chegando.
Os primeiros pontos em questão, relacionado à esse tipo de ataque, é a velocid
ade do ataque e velocidade com que esses pacotes podem chegar até o servidor (defi
nido por quão larga seja a banda do atacante) e depois a velocidade e poder de pro
cessamento 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 Free
BSD é 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 a
o mesmo tempo, e da largura da banda dos mesmos, essa velocidade nem sempre é o ba
stante.
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 ev
itados pelo Firewall, porque cada novo pacote com porta de IP randomicamente cri
ada não encontraria uma regra dinâmica que o permitisse. Mas de qualquer forma devem
os ficar muito atentos em relação ao número de regras dinâmicas que poderíamos abrir por p
acotes TCP SYN spoodados. Mesmo tendo certeza que o Stack TCP/IP do FreeBSD não se
ria 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 me
lhor forma de evitar isso é diminuindo o tempo de vida das regras dinâmicas iniciada
s 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 sysc
tl(8):
net.inet.ip.fw.dyn_max: 1000 (default)
Como o seu firewall 'stateful' em plena atividade, você pode verificar qua
ntas regras dinâmicas existem criadas no exato momento, verificando a variável do sy
sctl(8):
net.inet.ip.fw.dyn_count
A melhor forma de evitar que pacotes spoofados utilizem todas as suas re
gras dinâmicas é evitar que qualquer máquina fora da sua rede inicie uma conexão TCP. Is
so pode ser feito facilmente com as seguintes regras, assumindo que a rede 192.1
68.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 rot
eados, ou seja, os pedidos que entrarem serão automaticamente negados. Esse é o mesm
o tipo de proteção que o NAT e proxies transparentes de forma geral oferecem pras máqu
inas internas.
Até agora nós trabalhamos essencialmente com regras 'stateful' que manipulav
am conexões TCP. É claro, não é pra menos, conexões TCP representam a grande maioria do trá
ego gerado em rede, contudo você se lembra que nós comentamos que o ipfirewall(4) po
deria manipular também filtragem 'stateful' de outro protocolos. Bom, então de uma o
lhada 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, quan
do estudamos a seção referente ao icmptypes . Agora vamos fazer a mesma coisa usando "c
heck-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 c
ada pedido de echo que nossas estações internas façam pra fora. Quando a resposta cheg
a 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 pro
tocolo ICMP usa a variável net.inet.ip.fw.dyn_short_lifetime do sysctl(8). Se a re
sposta do ping demorar mais que 5 segundos pra chegar a regra vai ser descarrega
da 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 ;-)
A regra 2000 ainda poderia ter definido uma faixa de rede com permissão pr
a 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 porq
ue é 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 regr
as 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 8
0
Nós já conhecemos as regras estáticas apresentadas, contudo, essa é a primeira v
ez 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,
o nosso caso, a regra número 2000, que tem a opção keep-state ajustada, conforme aprende
mos anteriormente. A segunda parte é o número de vezes que aquela regra foi utilizad
a, 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 i
ndica o timeout (o tempo de vida) daquela regra, em segundos. Nesse caso ainda exi
stem 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 e
m 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 d
estino pra origem, ou se a regra é bidirecional. No nosso caso temos apenas um tip
o 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 I
P/porta de origem, o símbolo de fluxo dos pacotes (no caso <-> ) e finalmente o IP/po
rta 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 p
acotes, simplesmente porque ela não existe mais, até que a mesma regra seja reinicia
da, ou ressucitada pela mesma entrada keep-state da regra que a originou inicialme
nte. 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 us
o, elas serão continuamente substituídas por novas regras, especialmente se o número d
e regras dinâmicas alcançou o máximo permitido pelas variáveis do sysctl(8).
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.4
5 22
Não vamos comentar a listagem acima, cabe a você entender o que está acontecen
do com o firewall. Note que existe conexões cujo tempo de vida já se esgotou, e aind
a assim a mesma foi listada.
Bom, quando você começar usar regras 'stateful' em grande escala, você vai per
ceber o quanto a saída de um comando pra listar as regras do ipfw(8) vão se tornar p
erturbadoras, devido ao enorme número de regras dinâmicas criadas. O ipfw(8) lista t
odas 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 ób
do mundo Unix seria:
eksffa@eeviac~# ipfw list | grep -v '[<->#]'
Ou se você quer analisar com cuidado todas as regras, sejam estáticas dou di
nâ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 q
uais 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 t
ego passa a significar mais do que simplesmente filtrar quem e quando pode acess
ar determinado serviço, rede e/ou estações. A inclusão do dummynet(4) no FreeBSD possibi
litou um controle de tráfego extensivo, funcionalida essa que o IPFilter também não po
de oferecer.
Todo gerenciamento mais rudimentar de uma rede, em relação à sua infra estrutu
ra 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 utiliz
açã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 capac
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 audita
r 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 est
atística faz uso da opção prob nas regras do firewall, opção essa, seguida de um número e
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 req
uests) 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, dess
a 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 req
uer 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
pfirewall(4)), o administrador do sistema vai poder especificar a criação de túneis (c
hamados 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 i
rão trafegar por endereços específicos de rede. A criação desses túneis é feita com o coman
ipe do ipfw(8). O tráfego é redirecionado à esses tuneis por meio do comando pipe <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 i
pfw(8), exatamente como add ou delete , portanto antes de cada comando é feita uma cham
ada ao ipfw(8) (/sbin/ipfw pipe 10... por exemplo).
Esse túnel simples que criamos logo acima vai limitar o fluxo de informações p
ra uma velocidade máxima de 100 Kilobits por segundo. Existem várias maneiras distin
tas de indicarmos as medidas de velocidade de tráfego: bit/s, Byte/s, Kbit/s, Kbyt
e/s, Mbit/s, Mbyte/s. Cada túnel de limitação de banda deve usar a opção bw (de bandwidth
nda).
Uma outra maneira de controlar tráfego é usar a opção delay que força um atraso n
omunicaçã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 e
milisegundos. Nesse exemplo todo o tráfego roteado através desse túnel terá um atraso d
e 100ms.
Existe ainda a possibilidade de proporcionarmos uma taxa de perca de pac
otes, 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 segui
nte 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),
e indica a taxa dos pacotes que serão roteados. Pra evitar qualquer confusão com a u
tilização de prob ou ®plr , aconselhamos que o administrador assuma uma escolha pessoal e
tre as duas possibilidades. Ambas são igualmente efetivas, e co-existem porque a p
rimeira é 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 M
TU de uma 'device' de rede define o tamanho máximo que um pacote vai ter naquela i
nterface. 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/U
TP
<half-duplex> 10baseT/UTP
eksffa@eeviac~#
Verificamos portanto que na interface xl0 em questão, a MTU da placa de re
de é 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 . C
ada '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áxi
mo 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 p
ra 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, con
tudo quando se tem uma banda pequena, a requisição pelas interfaces é maior do que o t
ráfego possível na rede, isso gera gargalo e consequente atrasos na rede. Façamos o se
guinte então: vamos criar um túnel em uma rede que simule a velocidade máxima de um mo
dem 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 1
0.7 segundos pra uma fila de 600Kbit ser preenchida. Esse é um atraso inaceitável pr
a 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
dos. 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, uti
lizando o ifconfig(8), já que esse valor equivale à variável de multiplicação no tamanho d
a 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 limita
r 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 fo
rmas de se fazer isso, a mais óbvia e primeira conclusão que um administrador tomari
a 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 subconj
untos de 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ún
el.
"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, sr
c-ip, etc) como importantes e válidos.
Por exemplo, vamos assumir a mesma idéia anterior de uma rede atrás de um fi
rewall onde cada estação deve ter uma banda de 100Kbit/s. Se nós simplesmente direcion
armos todo o tráfego pra um túnel, o valor do tráfego será a somatória de todas as estações
não valores individuais. Pra utilizar máscaras pras estações às quais o tráfego deve ser s
parado por filas específicas, dessa maneira limitando a banda de forma separada, f
aremos 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 por
que 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 direcionament
o 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 con
junto de endereços de destinos. A regra 1000 definiu que todo o tráfego entre a noss
a 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 p
ela 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 prende
r atenção no momento é que cada túnel define uma máscara diferente. O túnel 10 define a más
a 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 a
o endereço de origem, porque cada origem faz diferença quando queremos filas distint
as 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 in
vés de decimal nos túneis. As duas notações funcionam perfeitamente. As máscaras pros túnei
funcionam exatamente da mesma forma que as 'netmasks', mas a utilização delas se to
rna 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 sub
grupos, de forma 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 c
ada 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 úl
timo octeto indica que apenas uma estação será atribuída por fila (256 menos 255 = 1). D
essa 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á s
redefinida. Então se você quer definir 254^2 estações na rede que o firewall vai estar c
ontrolando, aí a máscara teria que ser 0.0.255.255 (0000ffff). Isso define que qualq
uer endereço com um único bit diferente entre os dois últimos octetos (ou seja os 16 últ
imos 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 confi
guração definida pro túnel que toma parte do pacote, e nesse momento a busca nas regra
s termina, como de costume no ipfirewall(4). Contudo você pode forçar que o pacote s
eja reinjetado (ou remanejado) no firewall, a partir da regra seguinte, mesmo de
pois 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 exami
nado na entrada ou saída pelo firewall (usando as opções in e out ), serão sempre verifi
pro tráfego de entrada *E* de saída. Isso implica em algumas consequências. Quando um
a regra redireciona o tráfego pra um túnel sem usar in ou out , a regra será duplicada,
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 in
erfaces, mesmo se definidos entrada e saída ( in , out ), simplesmente porque, imagine se
u gateway com múltiplas interfaces de rede, uma pra rede verdadeira (Internet) e d
uas pra redes internas. Todo tráfego definido como in é o que entra pelas interfaces p
ra 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

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


exões. Se o tráfego de entrada e saída são direcionaos pro mesmo túnel, então ele vai adota
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 sej
am full-duplex portanto é sempre recomendado criar túneis distintos, pro tráfego que e
ntra 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 ca
da 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 qual
quer 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 ap
enas 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 k
eep-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 d
inâ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 ext
ernos antes de verificarmos as regras dinâmicas.
A solução Stateless. A vantagem é que sobrecarrega menos o firewall, porque ex
iste um número menor de regras à serem processadas; mas, elas sobrecarregam o firewa
ll quando não existem muitas ocorrências de tentativas de pings, então a vantagem de u
ma 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 a
penas das estações que foram pingadas.
P) Como eu bloqueio que as redes privadas, conforme definidas na RFC 191
8, 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 form
a individual? Eu quero forçar um limite de UpStream de 64Kbit por segundo e DownSt
ream 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 pod
r 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-sta
te
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-stat
e
add 65535 deny all from any to any