Uma tabela é usada para armazenar endereços IPv4 e/ou IPv6. Pesquisas
em tabelas são muito rápidas, consumindo menos memória e tempo de
processamento do que as listas. Por
esta razão, uma tabela é ideal para armazenar grandes números de
endereços já que o tempo de pesquisa numa tabela com 50,000 endereços
é apenas ligeiramente maior do que para uma contendo 50 endereços. Tabelas podem
ser usadas das seguintes maneiras:
endereços de destino em opções route-to, reply-to e
dup-to nas regras de filtragem.
Tabelas são criadas tanto no
pf.conf ou utilizando o
pfctl(8).
Configuração
No pf.conf, tabelas são criadas usando a diretiva table.
Os atributos a seguir podem ser especificados para cada tabela:
const - o conteúdo da tabela não pode ser alterado, uma vez que
ela tenha sido criada. Quando este atributo não é especificado, o
pfctl(8) pode ser usado para adicionar ou remover endereços da tabela
a qualquer momento, mesmo quando o sistema estiver usando
securelevel(7) no nível dois ou maior.
persist - faz com que o kernel mantenha a tabela em memória
mesmo quando nenhuma regra faça referência a mesma. Sem esse atributo, o kernel
removerá a tabela automaticamente quando a última regra referenciando a tabela
for removida.
block in on fxp0 from { <rfc1918>, <spammers> } to any
pass in on fxp0 from <goodguys> to any
Endereços também podem ser especificados usando o modificador de negação
dessa forma:
table <goodguys> { 192.0.2.0/24, !192.0.2.5 }
A tabela goodguys agora casará com todos endereços na rede
192.0.2.0/24 exceto 192.0.2.5.
Note que nomes de tabelas são sempre colocados entre < >.
Tabelas também podem ser populadas via arquivos texto contendo listas
de endereços IP e redes:
table <spammers> persist file "/etc/spammers"
block in on fxp0 from <spammers> to any
O arquivo /etc/spammers deve conter uma lista de endereços IP
e/ou blocos de rede CIDR,
um por linha.
Qualquer linha começando com # é tratado como comentário e ignorada.
Manipulando com pfctl
Tabelas podem ser manipuladas em tempo real usando o
pfctl(8). Por
exemplo, para adicionar entradas a tabela <spammers> criada acima:
# pfctl -t spammers -T add 218.70.0.0/16
Caso a tabela <spammers> ainda não exista ela será criada.
Para listar os endereços na tabela:
# pfctl -t spammers -T show
O argumento -v também pode ser usado com -Tshow
para mostrar estatísticas para cada entrada da tabela. Para remover
endereços de uma tabela:
# pfctl -t spammers -T delete 218.70.0.0/16
Para mais informaçoes sobre manipulação de tabelas com pfctl,
por favor leia a página de manual
pfctl(8).
Especificando Endereços
Além de especificar hosts por endereço, eles também podem ser
referenciados pelo nome de host. Quando o nome de host é resolvido para
um endereço IP, todos os endereços IPv4 e IPv6 resultantes são
inseridos na tabela. Endereços IP também podem ser inseridos na
tabela especificando-se um nome de interface válido ou a
palavra-chave self.
A tabela conterá então todos endereços IP atribuídos aquela
interface ou à máquina respectivamente (incluindo endereço de loopback).
Uma limitação ao se especificar endereços é que 0.0.0.0/0 e
0/0 não funcionarão em tabelas.
A alternativa é escrever esse endereço manualmente ou fazer uso de uma
macro.
Pesquisa de Endereços
Uma pesquisa de endereço numa tabela retornará a entrada que combine mais
precisamente com o endereço. Isso permite a criação de tabelas como:
block in on dc0 all
pass in on dc0 from <goodguys> to any
Qualquer pacote chegando em dc0 terá seu endereço de origem
comparado com a tabela <goodguys>:
172.16.50.5 - a entrada mais próxima é 172.16.0.0/16; o pacote
casa com a tabela e será aceito
172.16.1.25 - a entrada mais próxima é !172.16.1.0/24; o
pacote casa com uma entrada na tabela, mas essa entrada é uma negação
(usa o modificador "!"); portanto o pacote não casa com a tabela e
será bloqueado
172.16.1.100 - casa exatamente com 172.16.1.100; o pacote casa com a
tabela e será aceito
10.1.4.55 - não combina com nenhuma entrada na tabela, portanto
será bloqueado