Neste exemplo, PF está rodando numa máquina OpenBSD  agindo como firewall e gateway NAT para uma pequena rede em casa ou  escritório. O objetivo geral é prover acesso à  Internet para a rede interna e acesso limitado ao firewall pela Internet, e ainda disponibilizar para acesso externo um servidor web localizado na rede Interna. Este documento o  guiará na criação de um conjunto de regras para  esse fim.  
 A Rede
 A rede está configurada da seguinte forma:  
[ COMP1 ]    [ COMP3 ]
  |            |
---+------+-----+------- xl0 [ OpenBSD ] fxp0 --- ( Internet )
         |
     [ COMP2 ]
   Existem vários computadores na rede interna; o diagrama mostra apenas três, mas o número real é irrelevante.  Estes computadores  são estações de trabalho usadas para navegar na Internet,  ler email, chat, etc., exceto COMP3 que também roda um pequeno servidor  web. A rede interna usa a faixa de ips 192.168.0.0 / 255.255.255.0.  
 O firewall OpenBSD é um Celeron 300 com duas placas de rede:  uma 3com 3c905B (xl0) e uma Intel EtherExpress Pro/100  (fxp0). Ele possui uma conexão Internet a Cabo e faz NAT para  compartilhar o acesso com a rede interna. O endereço IP na  interface externa é atribuído dinamicamente pelo  Provedor de Acesso Internet.   
Objetivo
 Os Objetivos são: - Prover acesso irrestrito à Internet para a rede interna. 
- Usar "negar por padrão" como política padrão  de regras. 
- Permitir o seguinte tráfego vindo da Internet para o firewall:  - SSH (porta TCP 22): será utilizado para   manutenção remota do firewall.  
- Auth/Ident (porta TCP 113): utilizado por alguns   serviços como SMTP e IRC.  
- ICMP Echo Requests: o tipo de pacote ICMP usado pelo comando ping.  
 
- Redirecionar tentativas de conexão na porta 80 TCP (que  são tentativas de conexão a um servidor web) para o  computador COMP3. Também permitir trafego TCP porta 80 destinado a COMP3  através do firewall. 
- Logar estatísticas de filtragem na interface externa. 
- Por padrão, responder com um TCP RST ou ICMP Unreachable para  pacotes bloqueados. 
- Tornar as regras o mais simples possível, para facilitar a manutenção.
Preparação
 Este documento assume que o host OpenBSD tenha sido corretamente  configurado para funcionar como roteador, incluindo  configuração de endereços IP, conectividade com a  Internet e definição de variaveis 
net.inet.ip.forwarding e/ou 
net.inet6.ip6.forwarding para "
1". Também é necessário que você tenha ativado  o PF usando pfctl ou definindo a variável apropriada em 
/etc/rc.conf.local.  
 As regras
 A seguir um passo a passo através das regras que realizarão os  objetivos acima descritos.   Macros
 As seguintes macros são definidas para facilitar a leitura e  manutençao das regras:   ext_if="fxp0"
int_if="xl0"
tcp_services = "{ 22, 113 }"
icmp_types = "echoreq"
comp3="192.168.0.3"  
   As primeiras duas linhas definem a interface de rede onde a filtragem  acontecerá.  Definindo elas aqui, se precisarmos mover este sistema para outra máquina com hardware diferente, nós trocamos apenas estas duas linhas e o resto das regras  continuará a mesma.  A terceira e quarta linhas listam os números  de portas TCP dos serviços que serão abertos para a  internet (SSH e ident/auth) e os tipos de pacotes ICMP que  terão permissão de alcançar a máquina do  firewall.  Finalmente, a última linha define o endereço IP de COMP3.  
 Nota: Caso a conexão com a Internet necessite PPPoE, então, filtragem e NAT devem acontecer na interface  tun0 não em fxp0.   
Opções
 As duas opções seguintes definem a resposta padrão block para regras de filtragem, e fazem com que sejam logadas estatísticas de filtragem (statistics logging "on") para a  interface externa: 
  set block-policy return
set loginterface $ext_if  
   Todo sistema Unix possui uma interface "loopback". É uma interface de rede virtual que é utilizada por aplicações para conversarem entre si dentro do sistema. No OpenBSD, a interface loopback é lo. É recomendado desabilitar qualquer filtragem nas interfaces loopback. Usando set skip para isto. 
  set skip on lo  
 Note que nós estamos usando skip no grupo de interface  
lo inteiro, desta maneira nós podemos, mais tarde, adicionar interfaces loopback adicionais e não precisamos nos preocupar em alterar esta parte do nosso arquivo de regras.  
 Scrub
 Não há razão para não utilizar scrubbing,  recomendado para todo tráfego entrante, portanto aplicamos a  regra com uma simples linha: 
  scrub in  
   Tradução do Endereço de Rede (NAT)
 Para fazer NAT para toda a rede interna a seguinte regra nat será usada:   nat on $ext_if from !($ext_if) to any -> ($ext_if)  
   O "!($ext_if)" pode ser substituído por  "$int_if" neste caso, mas caso você tenha  várias interfaces precisará adicionar mais regras  NAT, ao passo que, com esta estrutura o NAT será feito em  todas as interfaces protegidas.  
 Já que o endereço IP da interface externa é  atribuído dinamicamente, parênteses devem ser colocados  em volta da interface, assim o PF notará qualquer  alteração no endereço.  
 Como queremos que o proxy FTP funcione, adicionaremos uma âncora NAT também:  
  nat-anchor "ftp-proxy/*"  
    Redirecionamento
 As primeiras regras de redirecionamento necessárias são  para o ftp-proxy  assim, clientes FTP na rede interna local, poderão se conectar  a servidores FTP na Internet. 
  rdr-anchor "ftp-proxy/*"
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021  
   Note que esta regra funcionará apenas com conexões  destinadas à porta 21. Caso usuários se conectem a servidores FTP em outras portas,  então uma lista deve ser utilizada para especificar as portas  de destino, por exemplo: from any to any port { 21, 2121 }.  
 As últimas regras de redirecionamento pegam qualquer tentativa  de conexão vinda da Internet em direção à  porta 80 TCP no firewall. Tentativas de conexões legítimas nesta porta  serão de usuários tentando acessar o servidor web da rede. Estas conexões devem ser redirecionadas para COMP3:  
  rdr on $ext_if proto tcp from any to any port 80 -> $comp3  
   Regras de Filtragem
 Agora as regras de filtragem. Começando com negar por  padrão:   block in
 
   Neste ponto todo tráfego tentando entrar em uma interface  será bloqueado, mesmo estes da interface de rede interna. As regras seguintes abrem o firewall de acordo com os objetivos acima  descritos, bem como quaisquer interfaces virtuais que se façam  necessárias.  
 Tenha em mente que o pf pode bloquear tráfego entrando e saindo  de uma interface. Para simplificar sua vida você pode escolher fazer a filtragem de tráfego em apenas uma direção ao invés de  bloquear entrada e saída. Em nosso caso optamos por filtrar tráfego entrando na interface,  uma vez filtrada a entrada, não tentaremos obstruir sua  saída, portanto faremos o seguinte:  
  pass out keep state  
   Precisamos ter uma âncora  para o ftp-proxy:  
  anchor "ftp-proxy/*"  
   É bom usar também a proteção antispoof:  
  antispoof quick for { lo $int_if }  
   Agora abrimos as portas usadas pelos serviços que estarão disponíveis para a Internet. Primeiro, o tráfego que é destinado ao firewall em si:  
  pass in on $ext_if inet proto tcp from any to ($ext_if) \
port $tcp_services flags S/SA keep state  
   Especificando as portas na macro $tcp_services simplifica a abertura de serviços adicionais para a Internet através da simples edição da macro e recarregamento das regras. Serviços UDP também podem ser abertos com a  criação de uma macro $udp_services e  adição de uma regra de filtragem similar à  anterior, que especifique proto udp.  
 Além de ter uma regra rdr que redireciona o  tráfego do servidor web para COMP3, ainda PRECISAMOS permitir a passagem do tráfego através do firewall: 
  pass in on $ext_if inet proto tcp from any to $comp3 port 80 \
 flags S/SA synproxy state  
   Para aumentar um pouco a segurança, faremos uso de TCP SYN Proxy com intuito de  proteger o servidor web.  
 Tráfego ICMP precisa ser permitido: 
  pass in inet proto icmp all icmp-type $icmp_types keep state  
   Similar à macro $tcp_services, a macro  $icmp_types pode ser facilmente editada para alterar os tipos  de pacotes ICMP que terão permissão de passar pelo  firewall. Note que esta regra se aplica a todas interfaces de rede.  
 Agora o tráfego deve passar "de" e "para" a interface interna. Assumiremos que os usuários da rede interna sabem o que  estão fazendo e não nos causarão problemas.  Esta  não é necessariamente uma suposição  válida; um conjunto de regras muito mais restritivo pode ser  apropriado para muitos ambientes. 
  pass in quick on $int_if  
   Tráfego TCP, UDP e ICMP pode sair do firewall com destino  à Internet de acordo com a regra "pass out keep state" anterior. A informação de estado das conexões é  mantida de forma que pacotes que retornam passarão pelo firewall.   
O Conjunto Completo de Regras
   # macros
ext_if="fxp0"
int_if="xl0"
tcp_services="{ 22, 113 }"
icmp_types="echoreq"
comp3="192.168.0.3"
# opções
set block-policy return
set loginterface $ext_if
set skip on lo
# scrub
scrub in
# nat/rdr
nat on $ext_if from !($ext_if) -> ($ext_if:0) 
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
rdr on $ext_if proto tcp from any to any port 80 -> $comp3
# regras de filtragem
block in
pass out keep state
anchor "ftp-proxy/*" 
antispoof quick for { lo $int_if }
pass in on $ext_if inet proto tcp from any to ($ext_if) \
   port $tcp_services flags S/SA keep state
pass in on $ext_if inet proto tcp from any to $comp3 port 80 \
   flags S/SA synproxy state 
pass in inet proto icmp all icmp-type $icmp_types keep state
pass quick on $int_if