[Anterior: Redundância de Firewall com CARP e pfsync] [Conteúdo]
[ 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.
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.
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(4). É recomendado desabilitar qualquer filtragem nas interfaces loopback. Usando set skip para isto.
set skip on loNote 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 in
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/*"
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
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(8):
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.
# 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
|
[Anterior: Redundância de Firewall com CARP e pfsync] [Conteúdo]