30.4. IPFW

O IPFW é um firewall stateful para o FreeBSD, que suporta tanto o IPv4 como o IPv6. Ele é composto de vários componentes: o processador de regras de filtro de firewall do kernel e seu recurso integrado de contabilidade de pacotes, o recurso de registro em log, NAT, o dummynet(4) traffic shaper, um recurso de forward, um recurso de bridge e uma habilidade ipstealth.

O FreeBSD fornece um conjunto de regras de exemplo em /etc/rc.firewall que define vários tipos de firewall para cenários comuns para ajudar usuários iniciantes a gerar um conjunto de regras apropriado. O IPFW fornece uma poderosa sintaxe que os usuários avançados podem usar para criar conjuntos de regras personalizados que atendam aos requisitos de segurança de um determinado ambiente.

Esta seção descreve como ativar o IPFW, fornece uma visão geral de sua sintaxe de regra e demonstra vários conjuntos de regras para cenários comuns de configuração.

30.4.1. Ativando o IPFW

O IPFW está incluído na instalação base do FreeBSD como um módulo carregável do kernel, o que significa que um kernel customizado não é necessário para ativar o IPFW.

Para aqueles usuários que desejam compilar estaticamente o suporte ao IPFW em um kernel personalizado, veja Seção 30.4.6, “Opções do Kerne para o IPFW.

Para configurar o sistema para ativar o IPFW no momento da inicialização, adicione firewall_enable="YES" ao /etc/rc.conf:

# sysrc firewall_enable="YES"

Para usar um dos tipos de firewall padrão fornecidos pelo FreeBSD, adicione outra linha que especifique o tipo:

# sysrc firewall_type="open"

Os tipos disponíveis são:

  • open: passa todo o tráfego.

  • client: protege apenas esta máquina.

  • simple: protege toda a rede.

  • closed: desativa completamente o tráfego IP, exceto na interface de loopback.

  • workstation: protege apenas esta máquina usando regras stateful.

  • UNKNOWN: desativa o carregamento de regras de firewall.

  • filename: caminho completo do arquivo que contém o conjunto de regras do firewall.

Se firewall_type estiver definido como client ou simple, modifique as regras padrão encontradas em /etc/rc.firewall para se adequar a configuração do sistema.

Observe que o tipo filename é usado para carregar um conjunto de regras customizado.

Uma maneira alternativa de carregar um conjunto de regras personalizado é definir a variável firewall_script para o caminho absoluto de um script executável que inclui comandos IPFW. Os exemplos usados ​​nesta seção assumem que o firewall_script está definido como /etc/ipfw.rules:

# sysrc firewall_script="/etc/ipfw.rules"

Para habilitar o registro em log por meio do syslogd(8), inclua esta linha:

# sysrc firewall_logging="YES"

Atenção:

Somente regras de firewall com opção de log vão ser logadas. As regras padrão não contém essa opção e deve ser adicionada manualmente. Por isso é avisado que o conjunto de regras padrão é editado para logar. Em adição a isso, rotacionamento de log é desejado se os logs estiverem em um arquivo separado.

Não existe uma variável em /etc/rc.conf para definir os limites de log. Para limitar o número de vezes que uma regra é registrada por tentativa de conexão, especifique o número usando esta linha no /etc/sysctl.conf:

# echo "net.inet.ip.fw.verbose_limit=5" >> /etc/sysctl.conf

Para habilitar o registro através de uma interface dedicada chamada ipfw0, adicione esta linha ao /etc/rc.conf em vez disso:

# sysrc firewall_logif="YES"

Em seguida, use o tcpdump para ver o que está sendo registrado:

# tcpdump -t -n -i ipfw0

Dica:

Não há sobrecarga devido ao log, a menos que o tcpdump esteja anexado.

Depois de salvar as edições necessárias, inicie o firewall. Para ativar os limites de log agora, defina também o valor sysctl especificado acima:

# service ipfw start
# sysctl net.inet.ip.fw.verbose_limit=5

30.4.2. Sintaxe de Regras IPFW

Quando um pacote entra no firewall IPFW, ele é comparado com a primeira regra no conjunto de regras e avança uma regra por vez, movendo-se de cima para baixo em sequência. Quando o pacote corresponde aos parâmetros de seleção de uma regra, a ação da regra é executada e a pesquisa do conjunto de regras termina para esse pacote. Isto é conhecido como primeira combinação vence. Se o pacote não corresponder a nenhuma das regras, ele será pego pela regra padrão obrigatória IPFW de número 65535, que bloqueia todos os pacotes e os descarta silenciosamente. No entanto, se o pacote corresponder a uma regra que contenha as palavras-chave count, skipto ou tee, a pesquisa continuará. Consulte ipfw(8) para obter detalhes sobre como essas palavras-chave afetam o processamento de regras.

Ao criar uma regra IPFW, as palavras-chave devem ser escritas na seguinte ordem. Algumas palavras-chave são obrigatórias, enquanto outras são opcionais. As palavras mostradas em maiúsculas representam uma variável e as palavras mostradas em minúsculas devem preceder a variável que a segue. O símbolo # é usado para marcar o início de um comentário e pode aparecer no final de uma regra ou em sua própria linha. Linhas em branco são ignoradas.

CMD RULE_NUMBER set SET_NUMBER ACTION log LOG_AMOUNT PROTO from SRC SRC_PORT to DST DST_PORT OPTIONS

Esta seção fornece uma visão geral dessas palavras-chave e suas opções. Não é uma lista exaustiva de todas as opções possíveis. Consulte ipfw(8) para obter uma descrição completa da sintaxe de regra que pode ser usada ao criar regras IPFW.

CMD

Toda regra deve começar com ipfw add.

RULE_NUMBER

Cada regra é associada a um número de 1 até 65534. O número é usado para indicar a ordem do processamento da regra. Várias regras podem ter o mesmo número e, nesse caso, elas são aplicadas de acordo com a ordem em que foram adicionadas.

SET_NUMBER

Cada regra é associada a um número definido de 0 até 31. Os conjuntos podem ser desativados ou ativados individualmente, possibilitando adicionar ou excluir rapidamente um conjunto de regras. Se um SET_NUMBER não for especificado, a regra será adicionada no conjunto 0.

ACTION

Uma regra pode ser associada a uma das ações a seguir. A ação especificada será executada quando o pacote corresponder ao critério de seleção da regra.

allow | accept | pass | permit: essas palavras-chave são equivalentes e permitem pacotes que correspondem à regra.

check-state: verifica o pacote em relação à tabela de estados dinâmicos. Se uma correspondência for encontrada, execute a ação associada à regra que gerou essa regra dinâmica, caso contrário, vá para a próxima regra. Uma regra check-state não possui critério de seleção. Se nenhuma regra check-state estiver presente no conjunto de regras, a tabela de regras dinâmicas será verificada na primeira regra keep-state ou limit.

count: atualiza os contadores de todos os pacotes que correspondem à regra. A pesquisa continua com a próxima regra.

deny | drop: qualquer das duas palavras descarta silenciosamente os pacotes que correspondem a essa regra.

Ações adicionais estão disponíveis. Consulte ipfw(8) para detalhes.

LOG_AMOUNT

Quando um pacote corresponde a uma regra com a palavra-chave log, uma mensagem será registrada no syslogd(8) com nome SECURITY. O registro somente ocorre se o número de pacotes registrados para essa regra específica não exceder um LOG_AMOUNT especificado. Se nenhum LOG_AMOUNT for especificado, o limite será retirado do valor de net.inet.ip.fw.verbose_limit. Um valor de zero remove o limite de registro. Quando o limite for atingido, o registro em log poderá ser reativado, limpando o contador de registro ou o contador de pacotes para essa regra, usando ipfw resetlog.

Nota:

O registro é feito depois que todas as outras condições de correspondência de pacote foram atendidas e antes de executar a ação final no pacote. O administrador decide quais regras habilitar o log.

PROTO

Este valor opcional pode ser usado para especificar qualquer nome ou número de protocolo encontrado no arquivo /etc/protocols.

SRC

A palavra-chave from deve ser seguida pelo endereço de origem ou por uma palavra-chave que represente o endereço de origem. Um endereço pode ser representado por any, me (qualquer endereço configurado em uma interface neste sistema), me6, (qualquer endereço IPv6 configurado em uma interface neste sistema), ou table seguido pelo número de uma tabela de consulta que contém uma lista de endereços. Ao especificar um endereço IP, ele pode ser seguido opcionalmente pela máscara ou pela máscara de sub-rede do CIDR. Por exemplo, 1.2.3.4/25 ou 1.2.3.4:255.255.255.128.

SRC_PORT

Uma porta de origem opcional pode ser especificada usando o número da porta ou um nome de /etc/services.

DST

A palavra-chave to deve ser seguida pelo endereço de destino ou por uma palavra-chave que represente o endereço de destino. As mesmas palavras-chave e endereços descritos na seção SRC podem ser usados ​​para descrever o destino.

DST_PORT

Uma porta de destino opcional pode ser especificada usando o número da porta ou um nome de /etc/services.

OPTIONS

Várias palavras-chave podem seguir a origem e o destino. Como o nome sugere, OPTIONS são opcionais. As opções comumente usadas incluem in ou out, que especificam a direção do fluxo de pacotes, icmptypes seguido pelo tipo de mensagem ICMP e keep-state.

Quando uma regra keep-state é correspondida, o firewall criará uma regra dinâmica que corresponda ao tráfego bidirecional entre os endereços e portas de origem e destino usando o mesmo protocolo.

O recurso de regras dinâmicas é vulnerável ao esgotamento de recursos de um ataque SYN-flood, o que abriria um grande número de regras dinâmicas. Para combater esse tipo de ataque com IPFW, use limit. Esta opção limita o número de sessões simultâneas verificando as regras dinâmicas abertas, contando o número de vezes que esta regra e a combinação de endereços IP ocorreram. Se essa contagem for maior que o valor especificado por limit, o pacote será descartado.

Dezenas de OPTIONS estão disponíveis. Consulte ipfw(8) para obter uma descrição de cada opção disponível.

30.4.3. Exemplo de Conjunto de Regras

Esta seção demonstra como criar um exemplo de script de conjunto de regras de firewall stateful chamado /etc/ipfw.rules. Neste exemplo, todas as regras de conexão usam in ou out para esclarecer a direção. Eles também usam via nome-da-interface para especificar a interface que o pacote está percorrendo.

Nota:

Ao criar ou testar um conjunto de regras de firewall, considere esta configuração temporária:

net.inet.ip.fw.default_to_accept="1"

Isso define a política padrão do ipfw(8) para ser mais permissiva do que o padrão deny ip from any to any, tornando um pouco mais difícil ficar bloqueado fora do sistema logo após a reinicialização.

O script de firewall começa indicando que é um script Bourne shell e limpa quaisquer regras existentes. Em seguida, ele cria a variável cmd para que ipfw add não precise ser digitado no início de cada regra. Ele também define a variável pif que representa o nome da interface que está conectada à Internet.

#!/bin/sh
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"
pif="dc0"     # interface name of NIC attached to Internet

As duas primeiras regras permitem todo o tráfego na interface interna e na interface de loopback:

# Change xl0 to LAN NIC interface name
$cmd 00005 allow all from any to any via xl0

# No restrictions on Loopback Interface
$cmd 00010 allow all from any to any via lo0

A próxima regra permite que o pacote passe se corresponder a uma entrada existente na tabela de regras dinâmicas:

$cmd 00101 check-state

O próximo conjunto de regras define quais conexões stateful os sistemas internos podem criar para hosts na Internet:

# Allow access to public DNS
# Replace x.x.x.x with the IP address of a public DNS server
# and repeat for each DNS server in /etc/resolv.conf
$cmd 00110 allow tcp from any to x.x.x.x 53 out via $pif setup keep-state
$cmd 00111 allow udp from any to x.x.x.x 53 out via $pif keep-state

# Allow access to ISP's DHCP server for cable/DSL configurations.
# Use the first rule and check log for IP address.
# Then, uncomment the second rule, input the IP address, and delete the first rule
$cmd 00120 allow log udp from any to any 67 out via $pif keep-state
#$cmd 00120 allow udp from any to x.x.x.x 67 out via $pif keep-state

# Allow outbound HTTP and HTTPS connections
$cmd 00200 allow tcp from any to any 80 out via $pif setup keep-state
$cmd 00220 allow tcp from any to any 443 out via $pif setup keep-state

# Allow outbound email connections
$cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state
$cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state

# Allow outbound ping
$cmd 00250 allow icmp from any to any out via $pif keep-state

# Allow outbound NTP
$cmd 00260 allow udp from any to any 123 out via $pif keep-state

# Allow outbound SSH
$cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state

# deny and log all other outbound connections
$cmd 00299 deny log all from any to any out via $pif

O próximo conjunto de regras controla conexões de hosts da Internet para a rede interna. Ele começa negando pacotes tipicamente associados a ataques e, em seguida, permite explicitamente tipos específicos de conexões. Todos os serviços autorizados originados da Internet usam limit para evitar ataques de flood.

# Deny all inbound traffic from non-routable reserved address spaces
$cmd 00300 deny all from 192.168.0.0/16 to any in via $pif     #RFC 1918 private IP
$cmd 00301 deny all from 172.16.0.0/12 to any in via $pif      #RFC 1918 private IP
$cmd 00302 deny all from 10.0.0.0/8 to any in via $pif         #RFC 1918 private IP
$cmd 00303 deny all from 127.0.0.0/8 to any in via $pif        #loopback
$cmd 00304 deny all from 0.0.0.0/8 to any in via $pif          #loopback
$cmd 00305 deny all from 169.254.0.0/16 to any in via $pif     #DHCP auto-config
$cmd 00306 deny all from 192.0.2.0/24 to any in via $pif       #reserved for docs
$cmd 00307 deny all from 204.152.64.0/23 to any in via $pif    #Sun cluster interconnect
$cmd 00308 deny all from 224.0.0.0/3 to any in via $pif        #Class D & E multicast

# Deny public pings
$cmd 00310 deny icmp from any to any in via $pif

# Deny ident
$cmd 00315 deny tcp from any to any 113 in via $pif

# Deny all Netbios services.
$cmd 00320 deny tcp from any to any 137 in via $pif
$cmd 00321 deny tcp from any to any 138 in via $pif
$cmd 00322 deny tcp from any to any 139 in via $pif
$cmd 00323 deny tcp from any to any 81 in via $pif

# Deny fragments
$cmd 00330 deny all from any to any frag in via $pif

# Deny ACK packets that did not match the dynamic rule table
$cmd 00332 deny tcp from any to any established in via $pif

# Allow traffic from ISP's DHCP server.
# Replace x.x.x.x with the same IP address used in rule 00120.
#$cmd 00360 allow udp from any to x.x.x.x 67 in via $pif keep-state

# Allow HTTP connections to internal web server
$cmd 00400 allow tcp from any to me 80 in via $pif setup limit src-addr 2

# Allow inbound SSH connections
$cmd 00410 allow tcp from any to me 22 in via $pif setup limit src-addr 2

# Reject and log all other incoming connections
$cmd 00499 deny log all from any to any in via $pif

A última regra registra todos os pacotes que não correspondem a nenhuma das regras do conjunto de regras:

# Everything else is denied and logged
$cmd 00999 deny log all from any to any

30.4.4. Configurando o NAT

Contribuído porChern Lee.

O daemon embutido de NAT do FreeBSD, natd(8), funciona em conjunto com o IPFW para fornecer tradução de endereços de rede. Isso pode ser usado para fornecer uma solução de Compartilhamento de Conexão à Internet para que vários computadores internos possam se conectar à Internet usando um único endereço IP.

Para isso, a maquina FreeBSD conectada na internet deve atuar como um gateway. Esse sistema deve ter duas NICs, onde uma é conectada a internet e a outra conectada a LAN interna. Cada maquina conectada com a LAN deve estar associada a um endereço IP no espaço de rede privado, como definido pela RFC 1918, e ter o gateway padrão definido para um sistema natd(8) de endereço de IP interno.

Algumas configurações adicionais são necessárias para ativar a função NAT do IPFW. Se o sistema tiver um kernel personalizado, o arquivo de configuração do kernel precisa incluir a opção IPDIVERT juntamente com as outras opções IPFIREWALL descritas em Seção 30.4.1, “Ativando o IPFW.

Para ativar o suporte a NAT no momento da inicialização, isso deve estar no arquivo /etc/rc.conf:

gateway_enable="YES"		# enables the gateway
natd_enable="YES"		# enables NAT
natd_interface="rl0"		# specify interface name of NIC attached to Internet
natd_flags="-dynamic -m"	# -m = preserve port numbers; additional options are listed in natd(8)

Nota:

Também é possível especificar um arquivo de configuração que contenha as opções para passar para o natd(8):

natd_flags="-f /etc/natd.conf"

O arquivo especificado deve conter uma lista de opções de configuração, uma por linha. Por exemplo:

redirect_port tcp 192.168.0.2:6667 6667
redirect_port tcp 192.168.0.3:80 80

Para obter mais informações sobre esse arquivo de configuração, consulte natd(8).

Em seguida, adicione as regras de NAT ao conjunto de regras do firewall. Quando o conjunto de regras conter regras stateful, o posicionamento das regras de NAT é crítico e a ação skipto é utilizada. A ação skipto requer um número de regra para que ele saiba a qual regra saltar.

O exemplo a seguir se baseia no conjunto de regras do firewall mostrado na seção anterior. Ele adiciona algumas entradas adicionais e modifica algumas regras existentes para configurar o firewall com NAT. Ele começa adicionando algumas variáveis ​​adicionais que representam o número da regra para pular para, a opção keep-state e uma lista de portas TCP que serão usadas para reduzir o número de regras:

#!/bin/sh
ipfw -q -f flush
cmd="ipfw -q add"
skip="skipto 500"
pif=dc0
ks="keep-state"
good_tcpo="22,25,37,53,80,443,110"

A regra NAT de entrada é inserida após as duas regras que permitem todo o tráfego na interface interna e na interface de loopback e antes da regra check-state. É importante que o número de regra selecionado para esta regra NAT, neste exemplo 100, seja maior que as duas primeiras regras e menor que a regra check-state:

$cmd 005 allow all from any to any via xl0  # exclude LAN traffic
$cmd 010 allow all from any to any via lo0  # exclude loopback traffic
$cmd 100 divert natd ip from any to any in via $pif # NAT any inbound packets
# Allow the packet through if it has an existing entry in the dynamic rules table
$cmd 101 check-state

As regras de saída são modificadas para substituir a ação allow com a variável $skip, indicando que o processamento da regra continuará na regra 500. As sete regras tcp foram substituídas pela regra 125 porque a variável $good_tcpo contém as sete portas de saída permitidas.

# Authorized outbound packets
$cmd 120 $skip udp from any to x.x.x.x 53 out via $pif $ks
$cmd 121 $skip udp from any to x.x.x.x 67 out via $pif $ks
$cmd 125 $skip tcp from any to any $good_tcpo out via $pif setup $ks
$cmd 130 $skip icmp from any to any out via $pif $ks

As regras de entrada permanecem as mesmas, exceto a ultima regra que remove via $pif com intenção de casar com ambas regras de entrada e saida. A regra de NAT deve seguir essa ultima regra de saida, deve ter um numero maior que a ultima regra, e o numero da regra deve referenciar a ação skipto. Nesse conjunto de regras, o numero de regra 500 desvia todo pacote que casar com regra de saida do natd(8) para o processamento NAT. A proxima regra permite que todo pacote que esteja abaixo do processamento de NAT passe.

$cmd 499 deny log all from any to any
$cmd 500 divert natd ip from any to any out via $pif # skipto location for outbound stateful rules
$cmd 510 allow ip from any to any

Neste exemplo, as regras 100, 101, 125, 500 e 510 controlam a tradução de endereços dos pacotes de saída e de entrada para que as entradas na tabela de estado dinâmico sempre registrem o endereço de IP privado da LAN .

Considere um navegador Web interno que inicialize uma nova sessão HTTP pela porta 80. Quando o primeiro pacote de saída entra no firewall, ele não corresponde à regra 100 porque ele está saindo e não entrando. Ele pula a regra 101 porque este é o primeiro pacote e ainda não foi inserido na tabela de estados dinâmicos. O pacote finalmente corresponde à regra 125 pois é uma conexão de saída em uma porta permitida e tem um endereço IP de origem da LAN interna. Ao combinar essa regra, duas ações ocorrem. Primeiro, a ação keep-state adiciona uma entrada à tabela de estados dinâmicos e a ação especificada, skipto rule 500, é executada. Em seguida, o pacote passa pelo NAT e é enviado para a Internet. Este pacote faz o seu caminho para o servidor web de destino, onde um pacote de resposta é gerado e enviado de volta. Este novo pacote entra no topo do conjunto de regras. Ele corresponde à regra 100 e tem seu endereço de destino IP mapeado de volta para o endereço interno original. Em seguida, ele é processado pela regra check-state, é encontrado na tabela como uma sessão existente e é liberado para a LAN.

No lado da entrada, o conjunto de regras deve negar pacotes inválidos e permitir apenas serviços autorizados. Um pacote que corresponde a uma regra de entrada é postado na tabela de estados dinâmicos e o pacote é liberado para a LAN. O pacote gerado como resposta é reconhecido pela regra check-state como pertencente a uma sessão existente. Em seguida, ele é enviado para a regra 500 para passar pelo NAT antes de ser liberado para a interface de saída.

30.4.4.1. Redirecionamento de Portas

A desvantagem com natd(8) é que os clientes da LAN não estão acessíveis na Internet. Os clientes na LAN podem fazer conexões de saída para o mundo, mas não podem receber conexões diretas. Isso é um problema ao tentar executar serviços de Internet em uma das máquinas clientes da LAN. Uma forma simples de contornar isso é redirecionar as portas selecionadas da Internet na máquina natd(8) para um cliente da LAN.

Por exemplo, um servidor IRC é executado no cliente A e um servidor Web é executado no cliente B. Para que isso funcione corretamente, as conexões recebidas nas portas 6667 (IRC) e 80 (HTTP) devem ser redirecionadas para as respectivas máquinas.

A sintaxe para o -redirect_port é a seguinte:

     -redirect_port proto targetIP:targetPORT[-targetPORT]
                 [aliasIP:]aliasPORT[-aliasPORT]
                 [remoteIP[:remotePORT[-remotePORT]]]

No exemplo acima, o argumento deve ser:

    -redirect_port tcp 192.168.0.2:6667 6667
    -redirect_port tcp 192.168.0.3:80 80

Isto redireciona as portas TCP para as máquinas clientes da LAN.

Intervalos de portas podem ser indicados com -redirect_port. Por exemplo, tcp 192.168.0.2:2000-3000 2000-3000 redirecionaria todas as conexões recebidas entre as portas 2000 e 3000 para as portas 2000 a 3000 no cliente A.

Estas opções podem ser usadas ao executar diretamente o natd(8), colocado na opção natd_flags="" no /etc/rc.conf, ou informado através de um arquivo de configuração.

Para mais opções de configuração, consulte natd(8).

30.4.4.2. Redirecionamento de Endereços

Redirecionamento de endereços é útil se mais de um endereço IP estiver disponível. Cada cliente da LAN pode receber seu próprio endereço IP externo pelo natd(8), que reescreverá os pacotes de saída dos clientes da LAN com o endereço IP externo apropriado e redirecionará todo o tráfego recebido naquele endereço IP específico de volta para o cliente da LAN específico. Isso também é conhecido como NAT estático. Por exemplo, se o endereço IP 128.1.1.1, 128.1.1.2, e 128.1.1.3 estiverem disponíveis, 128.1.1.1 pode ser usado pelo natd(8) como o endereço IP de saída externa, enquanto 128.1.1.2 e 128.1.1.3 são encaminhados de volta para os clientes da LAN A e B.

A sintaxe -redirect_address é a seguinte:

-redirect_address localIP publicIP
localIPO endereço IP interno do cliente da LAN.
publicIPO endereço IP externo correspondente ao cliente da LAN.

No exemplo, esse argumento seria:

-redirect_address 192.168.0.2 128.1.1.2
-redirect_address 192.168.0.3 128.1.1.3

Como o -redirect_port, esses argumentos são inseridos na opção natd_flags="" no /etc/rc.conf, ou passados ​​através de um arquivo de configuração. Com o redirecionamento de endereço, não há necessidade de redirecionamento de porta, pois todos os dados recebidos em um determinado endereço IP são redirecionados.

Os endereços IP externos na máquina natd(8) devem estar ativos e com alias na interface externa. Consulte rc.conf(5) para mais informações.

30.4.5. O Comando IPFW

O ipfw pode ser usado para adicionar ou excluir regras únicas e manuais ao firewall ativo enquanto ele estiver em execução. O problema com o uso desse método é que todas as alterações são perdidas quando o sistema é reinicializado. Recomenda-se, em vez disso, gravar todas as regras em um arquivo e usar esse arquivo para carregar as regras no momento da inicialização e substituir as regras de firewall em execução no momento em que o arquivo for alterado.

O ipfw é uma maneira útil para se exibir as regras de firewall em execução na tela do console. O recurso de contabilidade IPFW cria dinamicamente um contador para cada regra que case com cada pacote que corresponde à regra. Durante o processo de teste de uma regra, listar a regra com seu contador é uma maneira de determinar se a regra está funcionando conforme o esperado.

Para listar todas as regras em execução em sequência:

# ipfw list

Para listar todas as regras em execução com um registro de data e hora de quando a última vez em que a regra foi utilizada:

# ipfw -t list

O próximo exemplo lista as informações contábeis e a contagem de pacotes das regras correspondentes, junto com as próprias regras. A primeira coluna é o número da regra, seguido pelo número de pacotes e bytes correspondidos, seguidos pela própria regra.

# ipfw -a list

Para listar regras dinâmicas além das regras estáticas:

# ipfw -d list

Para mostrar também as regras dinâmicas expiradas:

# ipfw -d -e list

Para zerar os contadores:

# ipfw zero

Para zerar os contadores apenas para a regra com o número NUM:

# ipfw zero NUM

30.4.5.1. Mensagens de Log do Firewall

Mesmo com o recurso de geração de log ativado, o IPFW não irá gerar nenhum log de regras por conta própria. O administrador do firewall decide quais regras no conjunto de regras serão logadas e adiciona a palavra-chave log a essas regras. Normalmente, apenas as regras de bloqueio são logadas. É costume duplicar a regra ipfw default deny everything com a palavra-chave log incluída como a última regra no conjunto de regras. Dessa forma, é possível ver todos os pacotes que não correspondem a nenhuma das regras do conjunto de regras.

O log é uma espada de dois gumes. Se não houver cuidado, uma abundância de dados de log ou um ataque DoS pode encher o disco com arquivos de log. As mensagens de log não são gravadas apenas no syslogd, mas também são exibidas na tela do console do root e logo se tornam irritantes.

A opção do kernel IPFIREWALL_VERBOSE_LIMIT=5 limita o número de mensagens consecutivas enviadas para o syslogd(8), referente à correspondência de pacotes de uma regra dada. Quando esta opção está ativada no kernel, o número de mensagens consecutivas relativas a uma regra específica é limitado ao número especificado. Não há nada a ganhar com 200 mensagens de log idênticas. Com essa opção definida como cinco, cinco mensagens consecutivas referentes a uma regra específica seriam registradas no syslogd e as mensagens consecutivas idênticas restantes seriam contadas e postadas no syslogd com uma frase assim:

last message repeated 45 times

Todas os pacotes logados são escritos por padrão no arquivo /var/log/security, que é definido no /etc/syslog.conf.

30.4.5.2. Criando um Script de Regras

Os usuários mais experientes do IPFW criam um arquivo contendo as regras e as codificam de maneira compatível com sua execução como um script. A principal vantagem de fazer isso é que as regras de firewall podem ser atualizadas em massa sem a necessidade de reinicializar o sistema para ativá-las. Este método é conveniente para testar novas regras, pois o procedimento pode ser executado quantas vezes forem necessárias. Sendo um script, a substituição simbólica pode ser usada para valores usados ​​frequentemente para serem substituídos em várias regras.

Este script de exemplo tem a sintaxe compatível com shells sh(1), csh(1), e tcsh(1). Campos de substituição simbólicos são prefixados com um sinal de dólar ($). Campos simbólicos não possuem o prefixo $. O valor para preencher o campo simbólico deve ser colocado entre aspas duplas ("").

Inicie o arquivo de regras assim:

############### start of example ipfw rules script #############
#
ipfw -q -f flush       # Delete all rules
# Set defaults
oif="tun0"             # out interface
odns="192.0.2.11"      # ISP's DNS server IP address
cmd="ipfw -q add "     # build rule prefix
ks="keep-state"        # just too lazy to key this each time
$cmd 00500 check-state
$cmd 00502 deny all from any to any frag
$cmd 00501 deny tcp from any to any established
$cmd 00600 allow tcp from any to any 80 out via $oif setup $ks
$cmd 00610 allow tcp from any to $odns 53 out via $oif setup $ks
$cmd 00611 allow udp from any to $odns 53 out via $oif $ks
################### End of example ipfw rules script ############

As regras não são importantes, pois o foco deste exemplo é como os campos de substituição simbólica são preenchidos.

Se o exemplo acima estiver no arquivo /etc/ipfw.rules, as regras podem ser recarregadas pelo seguinte comando:

# sh /etc/ipfw.rules

/etc/ipfw.rules pode estar localizado em qualquer lugar e o arquivo pode ter qualquer nome.

A mesma coisa pode ser realizada executando esses comandos manualmente:

# ipfw -q -f flush
# ipfw -q add check-state
# ipfw -q add deny all from any to any frag
# ipfw -q add deny tcp from any to any established
# ipfw -q add allow tcp from any to any 80 out via tun0 setup keep-state
# ipfw -q add allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state
# ipfw -q add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state

30.4.6. Opções do Kerne para o IPFW

Para compilar estaticamente o suporte ao IPFW em um kernel personalizado, consulte as instruções em Capítulo 8, Configurando o kernel do FreeBSD. As seguintes opções estão disponíveis para o arquivo de configuração do kernel personalizado:

options    IPFIREWALL			# enables IPFW
options    IPFIREWALL_VERBOSE		# enables logging for rules with log keyword to syslogd(8)
options    IPFIREWALL_VERBOSE_LIMIT=5	# limits number of logged packets per-entry
options    IPFIREWALL_DEFAULT_TO_ACCEPT # sets default policy to pass what is not explicitly denied
options    IPFIREWALL_NAT		# enables in-kernel NAT support
options    IPFIREWALL_NAT64		# enables in-kernel NAT64 support
options    IPFIREWALL_NPTV6		# enables in-kernel IPv6 NPT support
options    IPFIREWALL_PMOD		# enables protocols modification module support
options    IPDIVERT			# enables NAT through natd(8)

Nota:

O IPFW pode ser carregado como um módulo do kernel: as opções acima são compiladas por padrão como módulos ou podem ser configuradas em tempo de execução usando parâmetros configuráveis.

All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.