[OpenBSD]

[Anterior: Redundância de Firewall com CARP e pfsync] [Conteúdo]

PF: Exemplo: Firewall para Casa ou Pequeno Escritório


Conteúdo


O Cenário

Neste exemplo, o PF está em execução em uma máquina OpenBSD agindo como firewall e gateway NAT para uma pequena rede em casa ou no escritório. O objetivo geral é prover acesso à Internet para a rede interna e acesso limitado ao firewall de conexões provenientes da Internet, e ainda disponibilizar para acesso externo um servidor Web localizado na rede interna. Este documento guia-o através da 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. Esses computadores são estações de trabalho usadas para navegar na Internet, ler mensagens de correio eletrônico, usar programas de bate-papo virtual, etc., exceto COMP3, que também roda um pequeno servidor Web. A rede interna usa o bloco de rede 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 a cabo com a Internet 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.

O Objetivo

Os Objetivos são:

Preparação

Este documento assume que a máquina OpenBSD tenha sido corretamente configurada para funcionar como roteador, incluindo a configuração de endereços IP, conectividade com a Internet e a definição das variáveis do sysctl(3) net.inet.ip.forwarding e/ou net.inet6.ip6.forwarding para "1". Também é necessário que você tenha ativado o PF usando pfctl(8) ou definindo a variável apropriada em /etc/rc.conf.local.

O Conjunto de Regras

A seguir um passo a passo através do conjunto de regras que realizarão os objetivos descritos acima.

Macros

As seguintes macros são definidas para facilitar a leitura e manutenção do conjunto de regras:
int_if="xl0"

tcp_services = "{ 22, 113 }"
icmp_types = "echoreq"

comp3="192.168.0.3"

A primeira linha define a interface de rede interna onde a filtragem acontecerá. Definindo aqui, se precisarmos mover esse sistema para outra máquina com hardware diferente, podemos alterar apenas essa linha e o resto das regras continuarão utilizáveis. (Para este exemplo, a interface externa vai ser tratada usando o egress grupo de interface. Isto é definido automaticamente em qualquer interface segurando uma rota padrão, neste caso, fxp0). A segunda e terceira linha 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 do PPPoE, então filtragem e NAT devem acontecer na interface pppoe0 e não na interface egress (fxp0).

Opções

As duas opções seguintes são responsáveis pela definição da resposta padrão para regras de filtragem block e pelo "ativamento" do registro de estatísticas para a interface externa:
set block-policy return
set loginterface egress

Todo sistema Unix possui uma interface "loopback". Esta é uma interface de rede virtual que é utilizada por aplicativos para conversarem entre si dentro do sistema. No OpenBSD, a interface loopback é a lo(4). É recomendado desabilitar qualquer filtragem nas interfaces loopback; use set skip para fazer isso.

set skip on lo
Note que nós estamos usando skip para todas as interfaces lo, dessa maneira nós podemos mais tarde adicionar interfaces loopback adicionais e não precisamos nos preocupar em alterar essa parte do nosso arquivo de regras.

Firewall Rules

Vamos iniciar as regras para suportar o uso de ftp-proxy(8) para que osclientes de FTP local possam se conectar a servidores de FTP na internet. Isso funciona por inserir dinamicamente regras quando uma conex&aatilde;o ftp é feita. Isso é usando um anchor:
anchor "ftp-proxy/*"

Agora adicionamos a regra necessária para desviar as conexões para que eles sejam visto por ftp-proxy(8):

pass in quick on $int_if inet proto tcp to any port ftp \
    divert-to 127.0.0.1 port 8021

Esta regra irá interceptar liga¸ões de FTP para a porta 21 e desviá-las para uma instância ftp-proxy(8) em execução na porta 8021 e, através do uso de palavra-chave -quick, pacotes combinando não serão novamente verificadas em relação ao resto do conjunto de regras Se os usuários se conectem a servidores FTP em outras portas, então uma lista deve ser usado para especificar a porta de destino, por exemplo: to any port { 21, 2121 }.

Note-se que tanto a regra anchor eo ftp-proxy(8) de desvio precisam ser localizados antes de qualquer match, regras de NAT ou o proxy-ftp(8) não vai funcionar como esperado.

Agora vamos passar para algumas regras o match. Por si só, a regra match não determina se ou não o pacote é permitido passar. Em vez disso, os pacotes que atendam essa regra terá os parâmetros lembrado, pois eles vão ser usados ​​em qualquer regras pass que lidam com estes pacotes.

Isto é powerful: parâmetros tais como NAT ou queueing pode ser aplicado a certas classes de pacote e, em seguida, as permissões de acesso pode ser definida separadamente.

Para fazer NAT para toda a rede interna a seguinte regra match é usada:

match out on egress inet from !(egress:network) to any nat-to (egress:0)

Neste caso, o "!(egress:network)" pode ser facilmente substituído por um "$int_if:network", mas se você adicionou várias interfaces internas, você teria que adicionar mais regras de NAT, enquanto que com esta estrutura, NAT serão tratadas em todas as interfaces protegidas.

Já que o endereço IP na interface externa é atribuído dinamicamente, parênteses são colocados ao redor da interface de tradução para que o PF note quando o endereço mudar. O sufixo :0 é usado para que, se a interface external tenha multiplos endereços, somente o primeiro endereço é usado para a tradução.

Por fim, o protocolo familiar inet (IPv4) é ​​especificado. Isso evita traduzir quaisquer pacotes inet6 (IPv6), que podem ser recebidos.

Agora as regras para controlar as permissões de acesso. Inicia com o bloqueio padrão:

block in log

Nesse ponto todo o tráfego tentando entrar em uma interface será bloqueado, mesmo os da interface de rede interna. Estes pacotes também seram registrados. As regras seguintes abrem o firewall de acordo com os objetivos descritos acima, e abrem também quaisquer interfaces virtuais que se façam necessárias.

Tenha em mente que o pf pode bloquear o tráfego que entra e sai de uma interface. Para simplificar sua vida, você pode escolher fazer a filtragem de tráfego em apenas uma direção em vez de bloquear entrada e saída. Em nosso caso optamos por filtrar o tráfego de entrada, mas uma vez filtrada a entrada não tentaremos obstruir sua saída, portanto faremos o seguinte:

pass out quick

Ao utilizar quick, os pacotes de saída pode evitar, ser verificado contra as seguintes regras, melhorando o desempenho.

É bom usar também a proteção contra falsificações:

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 egress inet proto tcp from any to (egress) \
   port $tcp_services

Especificar 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 do conjunto de regras. Serviços UDP também podem ser abertos com a criação de uma macro $udp_services e a adição de uma regra de filtragem, similar a anterior, que especifique proto udp.

A próxima regra pega qualquer tentativa por alguém na Internet para conectar a porta TCP 80 no firewall. Tentativas legítimas para acessar esta porta serão de usuários que tentam acessar o servidor da rede web. Estas tentativas de conexão devem ser redirecionados para COMP3:

pass in on egress inet proto tcp to (egress) port 80 rdr-to $comp3

Tráfego ICMP precisa ser permitido:

pass in inet proto icmp all icmp-type $icmp_types

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 essa regra se aplica a todas as 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. Essa não é necessariamente uma suposição válida; um conjunto de regras muito mais restritivo pode ser apropriado para muitos ambientes.

pass in on $int_if

Tráfego TCP, UDP e ICMP pode sair do firewall com destino à Internet de acordo com a linha "pass out" anterior. A informação de estado das conexões é mantida de forma que pacotes que retornam passarão pelo firewall.

O Conjunto de Regras Completo

# 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 egress

set skip on lo

# FTP Proxy rules

anchor "ftp-proxy/*"

pass in quick on $int_if inet proto tcp to any port ftp \
   divert-to 127.0.0.1 port 8021
 
# match rules

match out on egress inet from !(egress:network) to any nat-to (egress:0)

# Regras de filtragem
block in log
pass out quick

antispoof quick for { lo $int_if }

pass in on egress inet proto tcp from any to (egress) \
   port $tcp_services

pass in on egress inet proto tcp to (egress) port 80 rdr-to $comp3

pass in inet proto icmp all icmp-type $icmp_types

pass in on $int_if

[Anterior: Redundância de Firewall com CARP e pfsync] [Conteúdo]


[voltar] www@openbsd.org
$OpenBSD: example1.html,v 1.16 2013/05/03 05:53:48 ajacoutot Exp $