1. 1 PF o Firewall do OpenBSD Luiz Arthur
Atualmente as redes de computadores e sistema computacionais em gerais
tratam de informações vitais para inúmeras pessoas e/ou corporações.
Manter estas informações confidenciais, integras e disponíveis não é uma tarefa
de segurança muito fácil. Para tanto, torna-se fundamental o uso de Firewalls
para tentar manter o mínimo de segurança.
Existem vários Firewalls disponíveis no mundo, muitos proprietários e outros
não, mas um que merece destaque atualmente é o PF do OpenBSD.
O PF é o Firewall do Sistema Operacional OpenBSD, sendo que o OpenBSD é
considerado um dos Sistemas Operacionais mais seguros do mundo,
mantendo a incrível marca de apenas dois erros de segurança remotos em mais
de 10 anos (na instalação básica).
Mas por que usar o OpenBSD e o PF para proteger as informações de
uma rede? As razões são muitas, sendo algumas: do ponto de vista legal, já
que este Firewall é Open Source logo não precisa de licença para funcionar
em um ambiente computacional; financeiro já que a licença é livre de
pagamento, mas é claro que vai ter o custo da implantação do PF por um
profissional de segurança; e técnico já que este prove várias funcionalidades
ao Firewall e melhor ainda com alto nível de segurança.
2. 2 PF o Firewall do OpenBSD Luiz Arthur
O PF foi desenvolvido pelo Daniel Hartmeier e necessita do Sistema
Operacional OpenBSD para funcionar, mas também pode ser utilizado no
FreeBSD e NetBSD através do sistema de ports (gerenciador de pacotes). Tais
sistemas BSD tem mais de 25 anos de desenvolvimento sendo sucessores do
BSD de 1976 e do próprio UNIX, assim também são parecidos com o Linux (mas
não igual).
O OpenBSD é um Sistema Operacional obsecado por segurança, e tem
atualizações em um intervalo regular de 6 meses.
O código-fonte do OpenBSD passa por auditoria constante e sempre esta na
vanguarda quando o assunto é segurança, incorporando várias ferramentas de
segurança.
Por exemplo: O OpenBSD foi o primeiro a implementar IPSec; A equipe
OpenBSD também ajudou a desenvolver o OpenSSH, o que torna o OpenBSD
um sistema voltado a segurança por natureza.
O PF tem sido parte do Kernel GENERIC do OpenBSD desde o OpenBSD 3.0.
Versões anteriores do OpenBSD usavam um pacote diferente para firewall/NAT
que não é mais suportado.
3. 3 PF o Firewall do OpenBSD Luiz Arthur
PF então é o Firewall de um dos Sistemas Operacionais mais seguros do mundo
e é responvel pelas seguintes funcionalidades:
● Filtragem de pacotes (Firewall) bem como controle de estados das conexões
TCP/IP;
● Monitorar e rearranjar fragmentos de pacotes de diversas formas fazendo
normalização e condicionando tráfego TCP/IP;
● Fazer tradução de Endereços de Rede (NAT), bem como redirecionar
conexões;
● Realizar controle de banda e priorização de pacotes;
● Autenticação de usuários.
Requisição de Hardware para o OpenBSD e o PF
A documentação do OpenBSD traz todas as arquiteturas suportadas (pode
ser encontrado no diretório /pub/OpenBSD/versão/HARDWARE, troque versão
pela versão do OpenBSD), bem como todos os hardwares periféricos
suportados. Mas o OpenBSD pode suportar uma vasta gama de hardwares.
O OpenBSD pode ser instalado em arquitetura: i386, Sparc, Sparc Ultra,
Alpha, etc.
4. 4 PF o Firewall do OpenBSD Luiz Arthur
O OpenBSD suporta a grande maioria dos dispositivos IDE's, SCSI, PCI,
ISA, etc.
Quanto a processador o PF não utilizam muita carga, é possível executa-lo em
uma CPU com 20MHz, é claro que um pouco mais de CPU nunca faz mal a
ninguém.
O uso de CPU na verdade vai depender de vários fatores tal como:
● A velocidade da rede que o firewall é conectado: Por exemplo, uma rede
de 10Mbps ficará muito bem com um Pentium de 100MHz;
● Tamanho e complexidade das regras: Todos os pacotes são combinados
com todas as regras do Firewall;
● Executar softwares adicionais: O ciclo de clock de uma CPU pode ser
consumida rapidamente com a adição de software de rede (FTP DNS, HTTP,
,
etc.) então cuidado;
Então levando em conta alguns itens anteriores, podemos concluir que um
Firewall com requisitos básicos em uma rede de 100Mbps deve ter um
processador de 200MHz.
5. 5 PF o Firewall do OpenBSD Luiz Arthur
Quanto a memória, o mínimo é 32 MB, caso seja utilizado NAT o recomendável
é 64 MB, e com o uso de Proxy (squid) é necessário 128 MB ou mais.
Já o espaço em disco, a instalação mínima não deve utilizar mais de 1GB, mas
se a máquina mantiver IDS, ou proxys, deve haver muito mais espaço em disco.
Depois de instalar o OpenBSD podemos passar a configuração do sistema.
Configurando o OpenBSD
Como o OpenBSD não é um Sistema Operacional muito convencional, vamos
dar uma breve olhada em algumas configurações de administração de Sistemas
Operacionais referentes ao OpenBSD.
Configuração de Rede
Com certeza qualquer administrador de Firewall deve saber como configurar a
rede de seu próprio Firewall.
Para configurar as interfaces de rede faz-se uso do ifconfig, o comando é
basicamente o mesmo de qualquer sistema UNIX-Like. As interfaces de
redesgeralmente levam o nome do fabricante.
6. 6 PF o Firewall do OpenBSD Luiz Arthur
Então, caso se queira ver todas as interfaces de rede do sistema basta
executar o comando:
# ifconfig -a
Para se configurar uma placa Ethernet com um IP 172.20.0.100 e máscara
classe C podemos usar o comando:
# ifconfig ne3 172.20.0.100 netmask 255.255.255.0
Para configurar mais de um IP em uma mesma interface de rede podemos
usar o comando:
# ifconfig ne3 alias 10.0.0.1
As configurações feitas via ifconfig são voláteis, caso as configurações devam
ser mantidas depois do boot, devemos editar o arquivo /etc/hostname.nome,
onde nome é o nome da interface de rede, em nosso caso de exemplo a ne3,
então:
# cat /etc/hostname.ne3
inet 172.20.0.100 255.255.255.0 NONE
inet 10.0.0.1 255.255.255.0 NOME
Com este arquivo temos a placa de rede ethernet chamada de ne3 com dois IPs,
172.20.0.100 e 10.0.0.1.
7. 7 PF o Firewall do OpenBSD Luiz Arthur
Configurando Gateway Padrão
O gateway padrão do host pode ser configurado no arquivo /etc/mygate, cujo
conteúdo deve ser apenas o endereço IP do roteador padrão, exemplo:
# cat /etc/mygate
172.20.0.1
Ou utilizando o comando route, para adicionar a rota padrão, tal como:
# route add default 172.20.0.1
Servidor de Nomes (DNS)
Já o servidor de nomes é dado através do arquivo /etc/resolv.conf, onde
podemos por exemplo passar como servidor primário de DNS o host 172.20.0.1
e como servidor secundário o host 200.203.233.10 e o conteúdo pode ser:
#cat /etc/resolv.conf
nameserver 172.20.0.1
nameserver 200.203.233.10
8. 8 PF o Firewall do OpenBSD Luiz Arthur
Configuração via DHCP
Configurações via servidor DHCP podem ser obtidas com o comando dhclient
e o nome da interface, exemplo:
# dhclient ne3
Ou colocando-se a opção dhcp no arquivo de configuração
/etc/hostname.nome, em nosso exemplo com a interface ne3, podemos
executar o comando:
# echo “dhcp” /etc/hostname.ne3
Reiniciando as configurações de redes
Estes comando fazer a configuração básica da parte de rede do host com
OpenBSD, para aplicar as alterações nos arquivos de configuração de rede
podemos usar o script /etc/netstart, tal como:
# sh /etc/netstart
9. 9 PF o Firewall do OpenBSD Luiz Arthur
Configurando rotas para redes e hosts
É possível também configurar rotas para outras redes ou hosts com o comando
route, por exemplo o primeiro comando adiciona rota para uma rede:
# route add 192.168.0.0 -netmask 255.255.255.0 192.168.0.254
ou
# route add 192.168.0.0/24 192.168.0.254
Para adicionar uma rota para um host:
# route add 192.168.255.1 172.20.0.1
Para ver as tabelas de rotas podemos usar o comando:
# route show
Já para deletar rotas substitua a opção add por delete no comando route, por
exemplo:
# route delete 192.168.0.0 -netmask 255.255.255.0
10. 10 PF o Firewall do OpenBSD Luiz Arthur
Iniciando serviços de redes
Para iniciar serviços de rede no OpenBSD, podemos utilizar o inetd ou chamar
os servidores de forma standalone, através do nome do servidor:
# httpd
# sshd
Para iniciar os servidores HTTP (apache) e SSH (OpenSSH) respectivamente.
Status de serviços de redes
Já para ver os serviços de rede em execução podemos usar o comando netstat,
tal como:
# netstat -a -p tcp
Para ver os serviços TCP Neste caso serão apresentados tanto serviços IPv4
.
(inet) quanto os IPv6 (inet6) , para filtrar somente os IPv4 por exemplo
podemos usar o comando:
# netstat -a -p tcp -f inet
Para ver os serviços via UDP é só substituir o -p tcp por -p udp.
11. 11 PF o Firewall do OpenBSD Luiz Arthur
Também é interessante ver as rotas pelo comando netstat, para isto podemos
executar:
# netstat -r -f inet
Neste caso serão apresentadas as rotas IPv4. Para IPv6 troque -f inet por -f
inet6.
Caso seja necessário associar a porta aberta para o servidor e o PID
(Process ID), para por exemplo reiniciar o processo ou desligá-lo, faz-se
necessário o uso do comando fstat. Mas este comando vai lhe trazer várias
saídas o que vai deixar a tarefa difícil, para melhorar a busca podemos usar o
comando grep, para filtrar a buscar. Por exemplo, para buscar por todos os
processo TCP, executamos:
#fstat | grep tcp
root sshd 15851 5* internet stream tcp 0xd2308324 172.20.0.100:22 <-- 172.20.0.2:58775
root sendmail 27708 4* internet stream tcp 0xd2319c80 127.0.0.1:25
root sendmail 27708 5* internet6 stream tcp 0xd2319e10 [::1]:25
root sendmail 27708 6* internet stream tcp 0xd2308004 127.0.0.1:587
root sendmail 27708 7* internet6 stream tcp 0xd2308194 [::1]:587
root sshd 26462 4* internet6 stream tcp 0xd2319960 *:22
root sshd 26462 5* internet stream tcp 0xd2319af0 *:22
root inetd 19439 4* internet stream tcp 0xd2319000 *:113
root inetd 19439 5* internet6 stream tcp 0xd2319190 *:113
root inetd 19439 8* internet stream tcp 0xd2319320 *:13
root inetd 19439 9* internet6 stream tcp 0xd23194b0 *:13
root inetd 19439 10* internet stream tcp 0xd2319640 *:37
root inetd 19439 11* internet6 stream tcp 0xd23197d0 *:37
12. 12 PF o Firewall do OpenBSD Luiz Arthur
Na saída do comando anterior, por exemplo, o processo sendmail (servidor de
email) está associado a porta 25 e tem como PID o número 27708.
Assim, com esta informação podemos desligar o servidor de email, por exemplo,
usando o comando:
# kill 27708
Já para que o processo sendmail seja reiniciado, par ler os arquivos de
configuração por exemplo, podemos usar o comando:
# kill -s 1 27708
Assim, com estes comando podemos fazer as tarefas básicas para um Firewall,
mas é importante salientar que alguns comandos tal como o ifconfig são
bem abrangentes (e bem diferentes de Sistemas como o Linux) dando até a
possibilidade de criar um Cluster de Firewalls. Então vale a pena se
aprofundar na configuração do OpenBSD.
13. 13 PF o Firewall do OpenBSD Luiz Arthur
Instalando pacotes de aplicações
Instalar aplicações é fundamental para qualquer Sistema Operacional, no
OpenBSD a instalação pode se dar via Internet ou através dos CD's de
instalação. Por incrível que parece a instalação de pacotes no OpenBSD é muito
simples, para tanto podemos baixar as aplicações em sites como:
http://www.openbsd.org/4.3_packages/i386.html, no qual é destinado a
arquitetura i386 para o OpenBSD 4.3.
Porém a forma mais simples de instalar pacotes é via Internet para tanto
podemos executar o comando:
# export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/4.3/packages/i386/
Que irá dizer de onde baixar os pacotes. Para tornar o processo mais simples
coloque o comando anterior dentro do arquivo /etc/profile. Já que caso isto não
seja feito o comando em questão deverá ser realizado toda vez que o sistema
for reinicializado.
Após esta configuração é só executar o comando pkg_add para instalar o
pacotes, por exemplo:
# pkg_add -v bash
Este comando irá baixar da Internet o shell bash e irá instalar no OpenBSD.
14. 14 PF o Firewall do OpenBSD Luiz Arthur
Outros comando relacionados a instalação são: pkg_delete e pkg_info.
Configuração de interface de rede em Bridge
O OpenBSD pode trabalhar tal como um switch Ethernet, com isto é possível
fazer um Firewall invisível. Um Firewall Bridge pode ter várias placas de
rede, mas normalmente só tem duas, de foma que o tráfego de rede passe por
estas duas interfaces.
Uma Bridge pode ser criada com o comando brconfig, por exemplo para criar
uma Bridge entre as interfaces de rede rl0 e rl1 executamos o seguinte
comando:
# brconfig ponte add rl0 add rl1 up
Assim, criamos uma Bridge chamada ponte, este nome serve para gerenciar a
Bridge, e por exemplo, adicionar mais uma placa de rede, exemplo:
# brconfig ponte add ne3
Tais configurações são voláteis, para se tornar presente no próximo boot, é
necessário colocar as configurações no arquivo /etc/bridgename.*.
15. 15 PF o Firewall do OpenBSD Luiz Arthur
Mas antes de implementar Bridges é necessário ter-se em mente alguns fatores:
● Não são todas as placas de redes que suportam o modo bridge;
● As placas na bridge trabalharam no modo promíscuo, o que exigirá mais
CPU; quando for fazer as regras no PF lembre-se que os pacotes são
comparados em todas as interfaces da Bridge;
● A Bridge irá redirecionar todos os protocolos, IP IPX, etc. A menos que se
,
use o comando blocknoip no arquivo /etc/bridgename.*;
● A máquina pode ficar invisível na rede o que dificulta a administração, já
que não tem IP para acessar.
Níveis de Segurança
O OpenBSD permite que o administrador defina diferentes níveis de segurança
(securelevels), e para determinar que ações administrativas são permitidas ou
não.
Os níveis de segurança são: -1, 0, 1 e 2, sendo que quanto mais alto o nível,
menor privilégio do administrador da máquina tem. Para mudar o nível de
segurança, é necessário executar o comando:
# sysctl -w kern.securelevel=2
16. 16 PF o Firewall do OpenBSD Luiz Arthur
Para tornar o securelevel permanente é necessário alterar o arquivo
/etc/rc.securelevel. Depois disto para alterar o nível de segurança faz-
se necessário o boot do sistema no modo single, comando:
boot> boot -s
Para o Firewall é um dos melhores níveis é o 2 que não permite alterações
de regras no Firewall.
Note que isto é ótimo para segurança, mas dificulta muito a administração da
Firewall. Lembre-se quanto mais seguro o sistema menos flexível e amigável.
Iniciando os trabalhos com o Firewall PF
Depois instalar e de ver algumas configurações básicas do Sistema Operacional
OpenBSD, podemos finalmente iniciar com as configurações e gerenciamento
do Firewall propriamente dito.
O arquivo /etc/pf.conf e o comando pfctl
O PF é um Firewall composto de políticas e regras (ruleset), tais regras no PF
são escritas em texto puro e por padrão são armazenadas no arquivo
/etc/pf.conf, mas tais regras podem residir em outro arquivo, bastando
configurar o sistema para ler tal arquivo.
17. 17 PF o Firewall do OpenBSD Luiz Arthur
As regras no arquivo /etc/pf.conf (ou qualquer outro arquivo, com regras do
PF) são gerenciadas e interpretadas pelo comando pfctl, o qual checa a
sintaxe das regras do arquivo antes de carregar essas regras na memória.
Assim, para carregar as regras do arquivo padrão basta executar o comando:
# pfctl -f /etc/pf.conf
O arquivo com as regras do PF é dividido em seções, que devem
obrigatoriamente serem respeitadas. Ou seja, caso estas seções não sigam a
ordem correta haverá erro de sintaxe no carregamento das regras. Portanto a
ordem do arquivo /etc/pf.conf deve ser:
● Macros: Variáveis definidas pelo usuário, que podem armazenar endereços
IP, nomes de interface de rede, etc;
● Tabelas: Uma estrutura usada para armazenar listas de endereços IP;
● Opções: Várias opções de controle do funcionamento do PF;
● Scrub: Reprocessamento de pacotes para normalização e desfragmentação;
● Filas: Fornece controle de banda e priorização de pacotes;
● Tradução: Controla NAT (Network Address Translation) e
redirecionamento de pacotes;
● Regras de Filtragem: Permite selecionar pacotes para filtragem ou
bloqueá-los conforme chegam nas interfaces.
18. 18 PF o Firewall do OpenBSD Luiz Arthur
Com exceção de macros e tabelas, cada seção deve aparecer nesta ordem no
arquivo de configuração, contudo nem todas seções precisam existir para
determinadas configurações de Firewall.
No arquivo com regras do PF as linhas em branco são ignoradas, e linhas
começando com # são tratadas como comentários.
Habilitando o PF
Mesmo depois de carregar o PF com o comando pfctl -f não quer dizer que o
PF esteja ativo, para ativar o PF faz-se necessário o comando:
# pfctl -e
O comando anterior ativa (enable) o Firewall PF tornando válida suas regras,
para desativar o Firewall basta usar o mesmo comando com a opção -d, tal
como:
# pfctl -d
Com o comando anterior, as regras do Firewall não valeriam mais, pois o PF foi
desativado. Estes comandos são voláteis.
19. 19 PF o Firewall do OpenBSD Luiz Arthur
Para deixar o PF habilitado durante o processo de inicialização do sistema
faz-se necessário configurar duas variáveis no arquivo /etc/rc.conf:
pf=YES
pf_rules=/etc/pf.conf
Sendo que a opção pf=YES habilita o PF no boot e se deixada como “NO” o PF
estará desabilitado após o boot. Já a opção pf_rules indica o arquivo que
contém as configurações/regras do PF.
Algumas opções úteis do comando pfctl
Após o boot, o gerenciamento do PF pode ser feita usando o programa pfctl.
Alguns exemplos de comandos e opção uteis do pfctl, são:
# pfctl -nf /etc/pf.conf Analisa o arquivo, mas não o carrega;
# pfctl -Nf /etc/pf.conf Carrega apenas as regras NAT do arquivo;
# pfctl -Rf /etc/pf.conf Carrega apenas as regras de filtragem do arquivo;
# pfctl -sn Mostra as regras de NAT;
# pfctl -sr Mostra as regras de filtragem;
# pfctl -ss Mostra a tabela de estado das conexões;
# pfctl -si Mostra status de filtragem e contadores;
# pfctl -sa Mostra TUDO o que pode ser mostrado.
20. 20 PF o Firewall do OpenBSD Luiz Arthur
Normalização/regularização de pacotes
Não são todos os pacotes enviados pela Internet que são bem formados, e
isto pode causar problemas para hosts ou roteadores que não podem tratar tais
pacotes problemáticos, por exemplo, fragmentação de pacotes TCP/IP Tal .
problema pode ser causado por acidente ou propositalmente.
Ataques de fragmentação, por exemplo, podem ser utilizados para passar
através de Firewalls, deixar mais lento o sistema de detecção de intrusão de
redes (NIDS) ou que este não reconheça a assinatura do ataque já que os
pacotes estão fragmentados, causar problemas de negação de servições (DoS),
etc.
A solução para este problema pode ser capturar os pacotes antes que este
cheguem ao seu destino final, por exemplo, no firewall e rearranjar tais
pacotes de forma que estes estejam "bem formados" quando atingirem o host
de destino ou a rede final. Assim, o NIDS pode verificar de forma mais correta
se o pacote corresponde ou não a uma assinatura.
Implementando normalização de pacotes com o Scrub
O processo de normalização implementado pelo PF é chamado de scrubbing.
Que é aplicado em todos os pacotes que combinem com as regras de scrub
(scrub rules).
21. 21 PF o Firewall do OpenBSD Luiz Arthur
As regras de scrub são avaliadas pelo PF antes do tratamento de pacotes
(Bandwidth Shaping), redirecionamento (Packet Redirection) e regras de
filtragem de pacotes (Packet Filtering).
As regras de scrub podem tanto ser aplicadas em pacotes que entram na
rede local, quanto a pacotes que saem da rede local em direção a
Internet. É claro que normalizar todos os pacotes vai gerar um custo ao
sistema (carga na CPU, memória, etc). Assim, é preciso verificar se o sistema
vai normalizar todos os pacotes ou apenas os que entram em sua rede.
Sintaxe das regras de Scrub
As regras de scrub tem uma sintaxe muito simples. Cada regra inicia com a
palavra scrub, seguido por:
● A direção in ou out. Que específica se as regras combinarão com os pacotes
que entram in ou os que saem out;
● Se o pacotes será registrado log, opcional;
● O nome das interfaces que a normalização será aplicada, também é
opcional e pode ser omitida caso a regra se aplique a todas as interfaces;
● Especificação da família de endereços de redes usados, inet para IPv4 e
inet6 para IPv6. Atualmente fragmentos IPv6 são despresados.
● Endereços dos hosts de origem/destino ou all se a regra se aplica a
todos os hosts.
22. 22 PF o Firewall do OpenBSD Luiz Arthur
Opções de regras de Scrub
Existem duas maneiras de refinar as regras de scrub, com as opções gerais do
Firewall PF e com as opções de regras do scrub.
Opções do gerais do PF que ajudam o Scrub
A opção limit frags n determina os limites de uso de memória para o PF
normalizar pacotes. Isto específica quanto de memoria o PF pode usar para
armazenar pacotes fragmentados. O valor padrão é aceitar 5000 fragmentos,
mas é possível ajustar para baixo ou para cima, este valor. Valores menores
irão descartar mais conexões, mas usará menos memória do sistema. Porém,
o uso de muita valores altos podem consumir muita memória e pode ser
usado para ataques de DoS. Assim, o administrador tem que chegar a uma
média sobre o que é melhor para o seu sistema. Um exemplo de opção do PF:
set limit frags 30000
Neste exemplo, é aceito até 30000 fragmentos na memória. É possível checar
estes limites com o seguinte comando:
#pfctl -s memory
23. 23 PF o Firewall do OpenBSD Luiz Arthur
Outra importante opção do PF é timeout frag, que diz ao PF quanto tempo
deve ser armazenado um fragmento antes de ser apagado da memória.
Opções de regras de normalização com o Scrub
A normalização de pacotes podem fazer uso das seguintes opções de scrub:
- fragment reassemble - reorganiza pacotes fragmentados. Esta opção é
tida como padrão, então pode ser omitida. Esta opção armazena em buffer,
pacotes fragmentados que chegam e os reconstrói em pacotes completos antes
de passa-los para o sistema de filtragem. A vantagem é que regras de filtragem
devem lidar apenas com pacotes completos, ignorando fragmentos. A
desvantagem é o aumento do uso de memória para armazenar os fragmentos.
Esta também é a única opção fragment que funciona com NAT.
- fragment crop - Descarta fragmentos duplicados e elimina
sobreposições. Diferentemente de fragment reassemble, os fragmentos não
são armazenados em buffer, mas passados adiante assim que chegam.
- fragment drop-ovl - bloqueia todos os fragmentos de pacotes
duplicados assim como seus fragmentos futuros. Essa opção é mais
agressiva que o fragment crop, e pode resultar em mais conexões
bloqueadas, mas é mais segura. Se você não está usando um NIDS, então esta
opção pode ser usada ao invés da opção fragment reassemble.
24. 24 PF o Firewall do OpenBSD Luiz Arthur
- max-mss m - configura o tamanho máximo de segmento (Maximum
Segment Size) para pacotes que combinam com m bytes. Pacotes que combinem
com esta regra do scrub deverá ter o MSS menor ou igual ao valor passado
em m. A prática geralmente mostra que quanto maior o MSS melhor a
performance da rede, mas nem sempre isto é verdade. Caso seja desejado a
alteração do MTU isto é possível através do comando ifconfig.
- min-ttl n - configura o tempo de vida (TTL - Time-to-Live) mínimo para os
pacotes que combinarem com a regra scrub, ou seja, o número máximo de hops.
Então é possível, por exemplo, aumentar o TTL dos pacotes, em uma rede
corporativa muito grande, mas tome cuidado com esta opção, pois os pacotes
podem entrar em loop eterno, por exemplo.
- no-df - Limpa o bit de não fragmente (DF - don't-fragment) do protocolo
IP Assim, os pacotes podem ser fragmentados ao longo do caminho da origem
.
ao fim. Esta opção é desejada para enviar pelo scrub pacotes NFS ou outros
pacotes que tem o bit DF marcados. Quando esta opção é usada, é oportuno
usar a opção random-id.
- random-id - sobrescreve o campo de identificação do pacote IP com
valores aleatórios. Alguns hackers utilizam tal campo para identificar
máquinas atrás de NAT's. Evitando assim, que hackers identifiquem o
layout de uma rede local. Porém esta técnica só pode ser usada em pacotes que
saem da rede out.
25. 25 PF o Firewall do OpenBSD Luiz Arthur
- reassemble tcp - normaliza conexões TCP Ao usar scrub reassemble tcp
.
uma direção in/out não deve ser especificada. As seguintes normalizações são
realizadas: Nenhum lado da conexão pode reduzir seu TTL IP. Isso é feito
para proteger contra um atacante enviando pacotes de forma que cheguem ao
Firewall, afetem a informação de estado da conexão, e expire antes de atingir o
host de destino. O TTL de todos pacotes é aumentado para o maior valor
possível para a conexão; Modula timestamps TCP em cabeçalhos de
pacotes para um número aleatório. Isso pode impedir um observador de
deduzir a quanto tempo a máquina está ligada ou saber quantos hosts existem
atrás de um gateway NAT.
Exemplos de scrub:
set limit frags 10000
Limita o número de fragmentos na memória para 10000.
scrub out on $ext_if all random-id
Trata todos os pacotes saindo pela interface externa e sobrescreve a
identificação do IP com um valor aleatório.
26. 26 PF o Firewall do OpenBSD Luiz Arthur
scrub in on $ext_if all no-df min-ttl 100 max-mss 1460
fragment reassemble
Trata pacotes entrando pela interface externa, limpando o bit DF do IP,
marcando o TTL para 100, o MSS para 1460, usando a remontagem de
fragmento.
scrub out on $ext_if all no-df min-ttl 10 max-mss 1460 fragment crop
Trata pacotes saindo da interface externa limpando o DF do IP marcando TTL
,
para 10, MSS para 1460 descartando fragmentos duplicados, mas não guarda
fragmentos em buffer.
scrub in on $ext_if from $src_ad to $dmz_ad no-df min-ttl 100
max-mss 1460 fragment drop-ovl
Trata pacotes entrando na interface externa tentando chegar a DMZ, limpando
o DF, sentando TTL em 10, o MSS para 1460 usando fragment drop-ovl, ou
seja, barrando fragmentos duplicados e todos os fragmentos subseqüentes,
lembre-se que este irá barrar mais conexões.
27. 27 PF o Firewall do OpenBSD Luiz Arthur
Como achar quem esta enviando pacotes mal formados
Para achar a fonte dos pacotes mal formados utilize os logs gerados pelo scrub
mais as ferramentas traceroute ou traceroute6. Achando esta possível fonte
de pacotes mal formados, a próximo passo pode ser enviar um email para o
administrador deste roteador ou rede.
NAT - mascarando e redirecionando pacotes
Network Address Translation (NAT) é um método para redirecionar ou
mascarar pacotes entre redes (forwarding) alterando endereços e portas dos
pacotes. O serviço de NAT é muito importante para manter uma rede segura, já
que com este é possível esconder o layout de uma rede. No PF o NAT trabalha
tanto com o IPv4 quanto com o IPv6 apesar do IPv6 não necessitar do NAT
teoricamente.
Aplicações seguras
Um endereço IP válido em hosts de uma rede IP é um perigo. Pois, o host pode
ser acessado diretamente a Internet, e o atacante pode usar estes endereços
para fazer um mapeamento das máquinas de uma dada rede, espionando
pacotes, parando a rede ou desabilitando a comunicação. Mas é claro que em
alguns casos o uso de endereços IPs válidos é inevitável.
28. 28 PF o Firewall do OpenBSD Luiz Arthur
O NAT fornece um nível de proteção contra este tipo de ataque, mencionado
anteriormente.
Por exemplo, ao invés de expor um servidor DNS ou HTTP direto na Internet,
é possível dar um endereço público para o Firewall e deixar os servidores com
endereços não válidos na Internet, e o Firewall irá fazer o redirecionamento
e mascaramento dos pacotes.
Assim, o único ponto de acesso a Internet é o Firewall e este deve estar
bem protegido por filtragem de pacotes, e tal filtragem permite apenas que o
usuário vindo da Internet acessem APENAS os serviços de DNS e HTTP já que
,
o Firewall pode estar bloqueando todo o resto.
Isto evita que os atacantes vindos da Internet explorem outras
vulnerabilidades (portas abertas no sistema). Fora que dentro de seu sistema
você pode utilizar outro esquema de portas para o serviço tal como usar
HTTP na porta 8080 ao invés da 80, isto também ajuda a manter a
segurança do sistema.
Outro uso do segurança do NAT é escondendo o número real de hosts de
sua LAN atrás de um único endereço IP (o do Firewall). É claro que esta técnica
acaba causando alguns atrasos na rede. Porém, existem técnicas para descobrir
máquinas dentro de uma rede com NAT, porém a opção random-id pode ajudar
a evitar este problema.
29. 29 PF o Firewall do OpenBSD Luiz Arthur
E é claro o NAT resolve um grande problema da Internet, que é a falta
de endereços IPv4 válidos na Internet atual, já que o NAT permite que
várias máquinas acessem a Internet através de um único endereço IP válido.
Uma variação da técnica NAT é a bi-direcional NAT. A regra binat
estabelece o mapeamento um para um (1:1) entre um endereço IP
interno e um endereço externo. O binat pode ser usado, por exemplo, para
disponibilizar um servidor web na rede interna que possua seu próprio IP
externo. Conexões vindas da Internet para esse endereço serão traduzidas para
o endereço interno e as conexões do servidor web (como pesquisas DNS) serão
traduzidas para o endereço externo. Portas TCP e UDP nunca são alteradas por
regras binat como acontece com regras NAT.
Configurações de NAT podem ser usadas com IPv6. Hosts atrás do NAT
devem usar o endereço FEC0/10 através do FEFF/10 (site-local) como definido
no RFC 2373. Assim com o OpenBSD e o PF, é possível redirecionar tráfegos
IPv4 e IPv6.
É preciso deixar claro que com o uso do IPv6 o NAT não teria mais razão
de existir, já que este resolve o problema de endereçamento, e cada máquina
na Terra terá o seu próprio endereço IP válido. Porém, o NAT mesmo com o
IPv6 provavelmente terá o seu lugar ao sol, por exemplo, em alguns casos
será necessário mesmo no IPv6 fazer redirecionamento de pacotes; ou
implementar soluções de balanceamento de carga, dentre outras.
30. 30 PF o Firewall do OpenBSD Luiz Arthur
Problemas ocasionados pelo NAT
Trabalhar com NAT pode gerar alguns problemas em uma rede, tal como, NAT
geralmente causa problemas em VPNs porque algumas soluções de VPN
checam a integridade dos pacotes e essas VPN iram descartar os pacotes
depois de descobrir que estes tiveram seus endereços alterados. É claro que
algumas soluções de VPN não tem este problema.
Outro problema é a má cooperação entre NAT e bridge. Isto é causado pelo
fato da bridge fazer mudanças nos pacotes antes do PF e isto confunde o PF. A
solução natural para isto é usar máquinas separadas, uma para o NAT outra
para a bridge.
Regras de NAT no PF
São três tipos de regras de NAT:
● nat - traduz (mascará) endereços internos em um único endereço externo;
● rdr - redirecionamento de endereços e portas;
● binat - tradução bidirecional entre um endereço interno e um endereço
externo.
Para usar NAT, faz-se necessário primeiro habilitar o roteamento (forwarding)
no kernel do OpenBSD.
31. 31 PF o Firewall do OpenBSD Luiz Arthur
Habilitação de roteamento no Firewall
Caso se deseje utilizar o PF como Firewall entre duas redes é necessário
habilitar o roteamento entre redes, este processo também é necessário para ser
fazer NAT. Para tornar o OpenBSD um roteador permante (processo de boot) é
necessário alterar o arquivo /etc/sysctl.conf e descomentando a seguinte
linha:
net.inet.ip.forwarding=1
Porém se o OpenBSD iniciou com a opção forwarding=0, será necessário
reiniciar o computador ou executando o comando sysctl com a opção de
roteamento. Então caso seja necessário ativar o roteamento, sem reiniciar o
computador, deve-se usar o comando sysctl. Exemplo:
# sysctl net.inet.ip.forwarding=1
Para desativar basta marcar a opção net.inet.ip.forwarding=0, isto pode ser
necessário, por exemplo, caso haja um ataque de DoS vindo de redes externas
para a rede interna, sem fazer roteamento o ataque para no roteador, não
comprometendo a segurança da redes privada, mas é claro que parando o
acesso a estas redes através deste roteador.
32. 32 PF o Firewall do OpenBSD Luiz Arthur
Diferente da filtragem de pacotes, as regras de redirecionamento são
aplicadas usando "a primeira regra que combinar vence". Assim, é
sempre melhor colocar as regras mais específicas primeiro e as regras
mais genéricas depois.
Escondendo hosts atrás de um único endereço com regras de NAT
As regras de NAT faz a tradução de endereços hosts internos (com endereços
privados), de forma que estes saiam para uma outra rede (normalmente a
Internet) usando uma única interface com um único endereço IP.
O NAT permite o mascaramento de pacotes porque o Firewall mantém
um registro de quem enviou o que e onde, e por isso é possível devolver a
resposta do pacote ao host correto.
Para manter está relação entre pacotes e suas origens no NAT é necessário uma
tabela ordenada e marcação de pacotes para a Internet. Essa marcação
permite que atacantes deduzam quantos hosts estão atrás de um
Firewall. Isto também é usado por algumas empresas de DSL para saber se
seus usuários estão usando NAT e caso seja proibido está prática, a empresa
pode pelalizar o usuário. O PF pode dificulta esta detecção com o uso da
Normalização de pacotes.
33. 33 PF o Firewall do OpenBSD Luiz Arthur
As regras de NAT tem a seguinte sintaxe:
● no - Diz ao PF para não aplicar a tradução de endereços. Isto serve para
desligar o NAT em certas circunstâncias. Opcional;
● nat - Está palavra é obrigatória;
● pass - Opcional, quando usado o pacote é enviado ao destino sem passar
pelas regras de filtragem de pacotes.
● on – E o nome da interface de rede ou uma lista de interfaces, é
necessário dizer ao PF qual interface cada regra de NAT se aplica;
● O nome da família de endereço IP. É possível inet para IPv4 ou inet6
para IPv6, esta opção é obrigatória caso o alvo (depois do ->) tenha mais
que uma família de endereços, isto acontece quando usamos tanto IPv6
quando IPv4;
● Especificações de Protocolo;
● Endereço de origem do host e portas. Esses são endereços e portas que
espera-se fazer NAT;
● Tag marker (Marcação) - É possível marcar os pacotes que passam pelo
NAT para que sejam checados quando este possuem marcação (uma string).
Opcional;
● Endereços de host e portas do host de destino;
● Endereços externos usados pelo NAT;
34. 34 PF o Firewall do OpenBSD Luiz Arthur
● Opções de Pool. Relacionado a controle de banda e balanceamento de
carga;
● Opção static-port. Está é opcional, quando usada diz para que não seja
feita mudanças nas portas de origem. Isto pode ajudar algumas VPNs,
que tem problemas com NAT.
Exemplos do uso de redirecionamento e mascaramento:
# Interface externa para a Internet
ext_if = "ne1"
# Endereço publico IPv4
ext_ad = "64.0.0.1/32"
# Endereços IPv4 privados, uso na rede interna.
prv_ad = "10.1.1.0/24"
#Protocolos a serem submetidos ao NAT
nat_proto = "{tcp, udp, icmp}"
nat on $ext_if inet proto $nat_proto from $prv_ad
to any -> $ext_ad
No exemplo a “” na penúltima linha significa a quebra de linha, ou seja, o
comando continua na linha de baixo, isto será usado em vários comandos.
Caso tenhamos duas redes, privadas:
# Faixa da rede privada 2.
prv2_ad = "192.168.2.0/24"
nat on $ext_if inet proto $nat_proto from {$prv_ad, $prv2_ad}
to any -> $ext_ad
35. 35 PF o Firewall do OpenBSD Luiz Arthur
As regras de NAT permitem usamos no e ! para negar nomes de interfaces ou
endereços de hosts. Isto é muito útil assim é possível que um dado segmento da
rede não se comunique com outro, por exemplo:
no nat on $ext_if inet proto $nat_proto from $prv_ad to $prv2_ad
no nat on $ext_if inet proto $nat_proto from $prv2_ad to $prv_ad
nat on $ext_if inet proto $nat_proto from {$prv_ad, $prv2_ad}
to any -> $ext_ad
Bem nem tudo são rosas com o NAT, surge um problema com as trocas de
portas de origem para usar-se o NAT, as 65535 portas que aparentemente
são muitas para uma única máquina, podem não ser para uma rede
inteira usando um NAT. A solução para isto é usando-se dois ou mais IPs na
interface externa, por exemplo. No OpenBSD isto é feito com um alias no
arquivo /etc/hostname. Então, podemos escrever duas regras de NAT separadas
para os dois endereços de redes em dois diferentes segmentos de redes:
# Novo endereço privado para a rede externa.
ext2_ad = "64.0.0.2/32"
nat on $ext_if inet proto $nat_proto from $prv_ad to any -> $ext_ad
nat on $ext_if inet proto $nat_proto from $prv2_ad to any -> ext2_ad
36. 36 PF o Firewall do OpenBSD Luiz Arthur
Porém, se não for possível adquirir mais um endereço IP público, pode-se
tentar dividir o espaço de portas entre os segmentos de LANs:
nat on $ext_if inet proto $nat_proto from $prv_ad
to any -> $ext_ad port 10000:20000
nat on $ext_if inet proto $nat_proto from $prv2_ad
to any -> $ext2_ad port 20001:30000
Outro problema é determinar a porta de origem. O PF faz isto de forma
aleatória o que não é desejável em algumas aplicações, então é possível
resolver isto com um proxy nat:
nat on $ext_if inet proto $nat_proto from $prv_ad port 22
to any -> $ext_ad port 8022
E se tivermos que mapear portas uma-para-uma, 1024 para 1024, 30000 para
30000, etc, podemos então usar uma (*):
nat on $ext_if inet proto $nat_proto from $prv_ad port 1024:65535
to any -> $ext_ad port 1024:*
37. 37 PF o Firewall do OpenBSD Luiz Arthur
É possível também desligar modificações nas portas de destino em regras
NAT com a opção static-port no final da regra:
nat on $ext_if inet proto $nat_proto from $prv_ad port 22
to any -> $ext_ad static-port
ou:
nat on $ext_if inet proto $nat_proto from $prv_ad
to any -> $ext_ad static-port
Regras de NAT são frequentemente utilizadas junto com regras de
filtragem de pacotes, e podem passar ou serem liberadas depois do
redirecionamento:
nat on $ext_if inet proto tco from $prv_ad to any -> ($ext_if)
block out on $ext_if inet proto tcp from ($ext_if) to any port 25
Assim, tudo que passa pelo NAT na porta na porta 25 para hosts externos é
bloqueado, mas é possível fazer a mesma coisa em uma única regra:
nat pass on $ext_if inet proto tcp from $prv_ad
to any port != 25 -> ($ext_if)
38. 38 PF o Firewall do OpenBSD Luiz Arthur
Outra importante ferramenta para filtrar regras de NAT com as de
filtros são os tags. Porém, regras de tag e pass não se misturam, assim se for
usado os dois o tag não será usado.
As regras de NAT podem ser escritas de forma dinâmica enquanto o PF é
executado, para tanto é necessário usar ancoras (anchors).
Redirecionamento de pacotes para outros endereços e portas (rdr)
Regras rdr são escritas usando a seguinte sintaxe:
● no - Diz ao para o PF não fazer o redirecionamento. Isto é usado para
selecionar o que não deve ser redirecionado e é normalmente usado em
casos bem específicos. Opcional;
● rdr - Diz que é uma regra de redirecionamento, sendo esta palavra
obrigatória;
● pass - É opcional e quando usada diz que a regra não precisa passar pelas
regras de filtragem de pacotes;
● on - O nome da interface ou uma lista de interfaces. É necessário dizer ao
pf a qual interface cada regra rdr será aplicada;
● inet ou inet6 - Nome da família de endereços IP Este é obrigatório se for
.
aplicado o alvo ->;
● Especificações de protocolo.
39. 39 PF o Firewall do OpenBSD Luiz Arthur
● Endereços e portas dos hosts. São endereços e portas para o
redirecionamento;
● marcação - Tag marker. É possível marcar o pacote para uma verificação
extra com a palavra tag seguida de uma string de identificação. Opcional;
● Endereços e portas dos Hosts alvo. São endereços e portas para onde os
pacotes serão direcionados
● Opções de Poll - Pool options. Para controle de banda e balanceamento
de carga.
Regras rdr redirecionam pacotes de uma porta para outra. Um clássico
exemplo, ao invés de deixar um servidor HTTP exposto direto na Internet com
um IP válido, é possível colocar ele atrás de um Firewall, que ouve a porta 80 e
redireciona para a porta 8080 do servidor na rede DMZ.
Este cenário é possível com as seguintes regras:
ext_if = "ne1"
ext_ad = "64.0.0.1/32"
www_ad = "192.168.2.100/32"
rdr on $ext_if inet proto tcp from any to $ext_ad
port 80 -> $www_ad port 8080
40. 40 PF o Firewall do OpenBSD Luiz Arthur
Com esta regra todos pacotes usando o protocolo TCP (proto tcp) chegando ao
Firewall pela interface externa (on $ext_if) com o endereço 64.0.0.1/32,
originados por qualquer origem (from any) e destinados ao servidor HTTP
ouvindo na porta 80 (to $ext_ad port 80) serão redirecionadas ao servidor na
DMZ 192.168.2.100/32 na porta 8080 (-> $www_ad port 8080).
Esta regra na prática só servirá para conexões vinda da rede externa, e
portanto não funcionará para uma LAN, assim é necessário outra regra para
que a LAN acesse o servidor HTTP.
prv_if = "ne2"
prv_ad = "p.p.p.p/24"
www_ad = "w.w.w.w/32"
rdr on $prv_if inet proto tcp from $prv_ad to $ext_ad port 80
-> $www_ad port 8080
Tais regras podem ser escritas em uma única através de chaves:
rdr on {$ext-if, $prv_if} inet proto tcp from any to $ext_ad
port 80 -> $www_ad port 8080
Tal regra será divida em duas regras distintas e pode ser vista com o comando:
#pfctl -s nat
41. 41 PF o Firewall do OpenBSD Luiz Arthur
Forçando todo mundo a usar um Web Cache
Muitas vezes é desejável redirecionar o fluxo da rede local para um Web
Cache antes que este sai para a Internet, assim é possível agilizar os acessos a
páginas comuns, ou filtrar alguns conteúdos na Camada de Aplicação. Para isto
a seguinte regra é possível:
ch_ad = "192.168.2.254/32"
rdr on $prv_if inet proto tcp from $prv_ad to any port 80
-> $ch_ad port 3128
Neste exemplo, o servidor Web Cache está ouvindo na porta 3128. Esta técnica
força todo mundo da rede interna a passar pelo servidor Web Cache.
Caso alguma máquina não deva passar pelo Web Cache, é possível usar o
modificador no tal como:
boss_ad "192.168.0.5/24"
no rdr on $prv_if inet proto tcp from $boss_ad to any port 80
rdr on $prv_if inet proto tcp from $prv_ad to any port 80
-> $ch_ad port 1080
Note que com o no a parte da regra com o -> não é necessária.
Sempre faça exceções ANTES das regras de NAT, ou as exceções não
iram ser aplicadas.
42. 42 PF o Firewall do OpenBSD Luiz Arthur
Outro modificador muito usado é o !, que nega valore:
rdr on ! ne1 inet proto tcp from ! 200.0.0.1/32 to ! e.e.e.e/32 port
80 -> d.d.d.d/32 port 8080
Sendo que esta regra redireciona todos os pacotes IPv4 TCP chegando em
qualquer interface exceto a ne1 vindos de qualquer endereço exceto
200.0.0.1/32 e destinado a qualquer endereço exceto 9.2.2.2/32.
NAT bidirecional - binat
A última das três regras NAT é a binat. A qual liga um endereço externo
público a um endereço interno privado. A sintaxe para o binat seria:
● no: diz ao PF para não aplicar o binat para um dado endereço. Opcional;
● binat: Palavra obrigatória;
● pass: Opcional, e é utilizada quando deseja-se que a regra não passe pela
verificação de filtro de pacotes;
● on: Nome da interface em que ocorre o binat. Está é obrigatória;
● inet ou inet6: Diz se usa IPv4 ou IPv6. Esta parte é requerida se o
endereço (colocado depois de ->) expande-se para mais que uma família de
endereços (IPv4 ou IPv6);
● Especificações de protocolos;
43. 43 PF o Firewall do OpenBSD Luiz Arthur
● Endereços Internos. Este é o endereço do host interno que você deseja
fazer o mapeamento bidirecional;
● Tag Marker - É possível marcar os pacotes que atravessam o binat para
uma checagem dupla através do tag seguido de uma string. Opcional;
● Endereço externo. É o endereço externo que será aplicado o binat.
Essas regras são similares ao rdr, mas não permitem um refinamento
gradual para controle, em particular controle de portas.
As regras binat seriam assim:
binat on $ext_if inet proto tcp from 192.168.1.37 to
any -> $ext_ad_1
binat on $ext_if inet proto tcp from 192.168.1.54 to
any -> $ext_ad_2
Nas regras a cima todos os endereços internos podem ter seus próprios
endereços externos. Isto pode ser usado da mesma forma para interfaces
externas.
Quanto as regras de NAT lembre-se de duas coisas:
● Não tente redirecionar pacotes para a mesma interface, isto não irá
funcionar;
● Não redirecione nada para a interface local do Firewall (127.0.0.1), por que
isso cria um risco em potencial de segurança.
44. 44 PF o Firewall do OpenBSD Luiz Arthur
Filtro de Pacotes
Regras de filtro de pacotes, está presente no /etc/pf.conf e são examinadas
depois das regras de Scrub e NAT. Há três tipos de filtro de pacotes:
- block - Bloqueia pacotes;
- pass - Permite a passagem de pacotes;
- antispoof - uma regra especial para bloqueio.
A sintaxe das regras de filtro são parecidas com as de NAT mas permitem um
melhor refinamento:
● block ou pass: Ação aplicada ao pacote, no caso ou bloqueia ou passa.
Palavra obrigatória;
● in ou out: direção do pacotes, ou está entrando ou saindo. Palavra
obrigatória;
● log ou log-all: Diz para registrar pacotes, este é opcional;
● quick: Diz para não continuar procurando por regras caso o pacote combine
com esta. Está palavra é opcional;
● Nomes da interface: É opcional, mas raramente é omitida;
● Opções de roteamento: Essa opção é usada para refinar rotas de pacotes,
logging, etc. Opcional.
● Família do Endereço: Se IPv4 inet ou IPv6 inet6. Opcional.
45. 45 PF o Firewall do OpenBSD Luiz Arthur
● Nomes de protocolos: Parte opcional;
● Endereço IP de origem e porta de origem: Cada uma pode ser usada
separadas ou juntas e são opcionais;
● Endereço IP de destino e porta de destino. Assim como as de origem são
opcionais.
● Opções: Parte Opcional.
Um monte de palavras/opções de configurações são possíveis, nós iremos
iniciar com as mais comuns e depois veremos as mais raras.
Block ou Pass?
As palavras block e pass estarão presentes em praticamente todas as regras
de filtragem.
Para bloquear todas os pacotes que estão entrando e saindo use:
block in all
block out all
O oposto, ou seja, para permitir a passagem de todos os pacotes:
pass in all
pass out all
No primeiro caso tudo estará negado, nenhum pacote entra ou sai no Firewall.
Já no segundo caso todos os pacotes podem sair e entrar no Firewall.
46. 46 PF o Firewall do OpenBSD Luiz Arthur
As regras do slide anterior, podem ser utilizada como políticas. As políticas
geralmente são:
● Bloquear tudo o que não for estritamente permitido;
● Liberar o que não for bloqueado;
Uma configuração muito recomendada para filtro de pacotes é a de
"Bloquear tudo o que não for estritamente permitido". As regras seriam:
block in all
block out all
Essas regras tornam o ambiente muito seguro, já que todo o tráfego está
primeiramente bloqueado e somente abrir (pass) rotas que são absolutamente
necessárias depois. Isto permite que as regas sejam simples e objetivas, o que
facilita dentre outras coisas depurar o que entre e sai do Firewall.
Diferente das regras de NAT, onde a primeira regra que combina com o
pacote vence! As regras de Filtros de Pacotes são avaliadas até que o
final das regras e a última que combinar vence. Supondo se você tem
quatro hosts e deseja fazer NAT para três, você necessita usar a regra no nat
antes da regras nat que permite o NAT dos outros três micros. Mas, as coisas
são diferentes nas regras de Filtro de Pacotes, se é desejável bloquear a saída
de pacotes para um dado host na LAN, precisa-se colocar tal regra (block)
depois das regras que permitem a passagem (pass) dos demais.
47. 47 PF o Firewall do OpenBSD Luiz Arthur
Resposta para quem envia os pacotes (drop, return-icmp, return-icmp2,
return-rst, return)
O block nega todos os pacotes que combinarem com a regra sem enviar
qualquer tipo de notificação de volta para o host que enviou o pacotes
originalmente. A prática de não enviar nenhuma resposta para hosts
bloqueados, por que assim não gasta-se recurso do Firewall com este tipo de
resposta, além do que alguns hacker utilizam pacotes de resposta de
pacotes bloqueados para, por exemplo, descobrir o Sistema Operacional do
Firewall, ou fazer um ataque DoS.
Mas em alguns casos pode existir a necessidade de respostas de
bloqueio, tal como testes, ou controle da rede interna. Essas respostas podem
ser enviando mensagens ICMP destination-unreachable para hosts que tenham
suas mensagens bloqueadas.
Por exemplo, o servidor de email Sendmail, em uma respota ICMP irá esperar
um ICMP na porta 113 (auth), o que caso não chegue, terá de esperar o time
out expirar para completar a conexão. Mas isto pode ser feito de forma elegante
com as seguintes regras:
48. 48 PF o Firewall do OpenBSD Luiz Arthur
# Bloqueia conexões entrando pela porta 113 (auth) e retorna uma
mensagem ICMP destination-unreachable
block return-icmp in quick on $ext_if proto tcp from any to
$ext_ad port auth
# permite a entrada de conexões para a porta 25 (smtp)
pass in quick on $ext_if from any to $ext_ad port smtp
O retorno de mensagens ICMP podem trabalhar com IPv4 return-icmp ou IPv6
,
com return-icmp6. É possível adicionar palavra-chaves tal como números ou
nomes para identificar mensagens ICMP específicas, isto é opcional e só é
requerido em casos especiais, tais mensagens podem ser vistas nos manuais
icmp(4) e icmp6(4).
Outra possibilidade é responder os pacotes com conexões TCP RST
(Reset). Isto pode ser obtido com a opção return-rst, o qual pode ser seguido
por um número inteiro definindo o TTL (time to live), por exemplo:
block return-rst in quick on $ext_if proto tcp from any to
$ext_ad port auth
ou:
block return-rst (ttl 100) quick in on $ext_if proto tcp from any
to $ext_ad port auth
A opção return-rst é aplicável apenas para conexões TCP.
49. 49 PF o Firewall do OpenBSD Luiz Arthur
A opção return, retornar RST para conexões TCP e destination-
unreachable para ICMP e UDP. Por exemplo:
block return quick in on $ext_if from any to $ext_ad
Para finalizar, é possível mudar o block para este funcionar tal como o
return, isto é possível mudando a política de com (set block-policy return).
Exemplo:
set block-policy return
block drop in quick on $ext_if proto tcp from any to $ext_ad
port auth
Todas as opções mostradas nesta sessão são opcionais e não funcionam com
uma bridge.
Entrada (in) e Saída de pacotes (out)
Existem duas direções de fluxos de pacotes que são possíveis para o filtro de
pacotes: in ou out. Estas direções são conhecidas por causar algumas
confusões, especialmente quando o Firewall é equipado com mais que uma
placa de rede e quando regras de NAT são usadas com regras de filtro de
pacotes.
50. 50 PF o Firewall do OpenBSD Luiz Arthur
A chave para entender quando um pacote combina com a direção in (a
entrada de pacotes) ou out (a saída de pacotes) é lembrar que essas direções
são relativas ao próprio Firewall. Então um pacote casa com as direções nos
seguintes casos:
● Se um pacote é enviado de um host externo para o firewall, ele combinará
com regras de in (entrada) na interface externa do Firewall;
● Quando um pacote é enviado pelo próprio Firewall, este pacote combina
com a saída (out) na interface externa;
● De forma semelhante, pacotes enviados de hosts da rede internar para o
Firewall destinados para os hosts externos iram combinar com regras de
entrada (in) na interface conectada no segmento da rede interna e com
regras de saída (out) na interface externa do Firewall.
Como registrar ou não os pacotes (log, log-all)
É possível dizer ao PF para registrar (log) pacotes que combinam com uma
dada regra, usando a interface pflog0. Assim, estes serão escolhidos pelo
pflogd(8) e armazenados nos arquivos de logs presentes no diretório
/var/log.
51. 51 PF o Firewall do OpenBSD Luiz Arthur
Para iniciar o registro de pacotes, é preciso usar as opções log ou log-all. A
diferença entre as duas formas (log e log-all) está relacionada com os
módulos de estados (keep state) do Firewall.
No log são feitos registros somente a abertura de estados dos pacotes,
enquanto o log-all registra todos os pacotes. Então se você usa filtro de
pacotes stateful e espera capturar todos os pacotes é necessário usar log-all,
do contrário use log.
É possível ainda usar a opção dup-to usada para duplicar pacotes e
envia-los para diferentes interfaces, para que os pacotes posam ser
armazenados, ouvidos e analisados de formar diferentes.
Terminando a comparação de regras mais cedo (quick)
Diferente das regras de NAT (nat, binat, rdr), que são processadas usando o
método "a primeira regra que combina vence" as regras de filtro de
pacotes utilizam o método "a última que combina vence".
Assim, caso tenha-se 100 linhas de filtragem de pacotes todas essas linhas
devem ser analisadas, mesmo que seja a primeira regra a ser aplicada. Mas isto
pode ser mudado usando a opção quick, quando esta opção é utilizada o PF irá
executar tal regra (caso combine com o pacote) e não irá continuar
combinando com as demais. Isto ajuda a preservar algum tempo de
processamento.
52. 52 PF o Firewall do OpenBSD Luiz Arthur
A opção quick pode ser adicionada depois de log ou log-all ou na ausência
desses, depois de in ou out, exemplo:
pass in log-all quick on $ ext_if proto tcp from any to $ext_ad
port 80
ou:
pass in quick on $ext_if proto tcp from any to $ext_ad port 80
Tome muito cuidado com a opção quick pois esta pode modificar de forma
radical um Firewall, assim tome cuidado principalmente quando se usar
ancoras (anchors).
Nomes de interfaces de rede
O nome das interfaces é dado depois da opção on, veja os exemplos a seguir:
block in on $ext_if
block in log-all on $ext_if
block in log_all quick on $ext_if
Se você não sabe o nome da interface, é possível verificar isto na saída dos
comandos dmesg ou ifconfig.
53. 53 PF o Firewall do OpenBSD Luiz Arthur
Opções de roteamento (fastroute, reply-to, route-to, dup-to)
Geralmente os pacotes examinados pelo PF são roteados de acordo com as
entradas das tabelas de rotas presentes no firewall, o que é desejável na
maioria dos casos. É possível checar as rotas com o seguinte comando:
$ route show ou $ netstat -r
Porém, algumas vezes é desejável tomar um caminho secundário como
rota ou duplicar os pacotes para que estes sejam enviados a um IDS ou para
propósitos de registro (log).
Assim, as seguintes opções são permitidas para influenciar no roteamento:
● fastroute: usa a tabela de rotas;
● route-to: usa um caminho alternativo para roteamento. Assim, a rota é a
interface descrita depois da opção route-to. O nome da interface pode ser
seguido por um endereço IP do host que deve receber os pacotes, os dois
devem estar entre parenteses, exemplo:
pass in on $ext_if route-to (int_if $int_ad) all
pass in on $ext_if route-to $inet_if all
54. 54 PF o Firewall do OpenBSD Luiz Arthur
● dup-to: cria uma cópia de cada pacote que combinar com a regra, sendo
que o pacote será roteado pela tabela de roteamento padrão e uma cópia do
pacote será repassado para outra interface indicada depois da opção dup-
to. O nome da interface pode ser seguida de um endereço IP sendo que tal
,
host irá receber uma cópia do pacote, deve se colocar a interface e IP em
parenteses assim como na opção anterior.
● reply-to: Replica a rota de pacotes que combinaram com alguma regra,
utilizando para isto os estados do Firewall (keep state, modulate state).
Isto irá implementar um roteamento simétrico, e será muito útil caso exista
mais que uma interface para uma dada rede, dois links de Internet, por
exemplo.
A opção dup-to)é muito usada para configurar um pacote para ser logado ou
repassado para um sistema de detecção de intrusão. Uma regra simples é:
pass in on $ext_if dup-to $log_if all
pass out on $ext_if dup-to $log_if all
É sempre aconselhável deixar a máquina que tratam logs de forma isolada, pois
esta exige muito da rede, mas é claro que isto vai requerer mais uma interface
para este segmento da rede.
55. 55 PF o Firewall do OpenBSD Luiz Arthur
As opções dup-to, reply-to e route-to pode ser seguidas por um grupo de
endereços (pools) e das opções bitmask, random, round-robin, source-
hash, static-port, que são opções de balanceamento de carga.
Famílias de Enderereços IP's: IPv4 e IPv6
O PF pode filtrar pacotes com endereços IPv4 e IPv6. Sendo possível selecionar
a versão do endereço IP com as opções inet para IPv4 ou inet6 para IPv6.
Se a rede ira suportar apenas IPv4, as seguintes regras podem ser utilizadas:
block in quick inet6 all
block out quick inet6 all
ou:
block in all
pass in inet all
pass out inet all
56. 56 PF o Firewall do OpenBSD Luiz Arthur
Protocolos suportados pelo PF
O PF faz filtragem pelo nome ou número dos protocolos. Isto é feito
adicionando-se a opção proto seguido pelos nomes ou números dos protocolos,
sendo que esses nomes ou números podem ser vistos no arquivo
/etc/protocols.
Por exemplo, se espera-se receber apenas pacotes TCP, use essa regra:
pass in quick on $ext_if proto tcp
Quase todos os serviços populares usam TCP Assim, algumas pessoas
.
simplesmente bloqueiam todo tráfego UDP mas isto deve ser feito com cuidado,
,
já que é necessário ter ciência de que não é mesmo necessário o uso de pacotes
UDP em sua rede.
Para sabe qual protocolo é usado em qual serviço, olhe o arquivo
/etc/protocols ou recorra ao site:
http://www.iana.org/assignments/protocol-numbers.
57. 57 PF o Firewall do OpenBSD Luiz Arthur
Endereços de origem (from, any, all)
O filtro de endereços de origens são usados para bloquear dois tipos de
pacotes: aqueles originados de endereços de hosts que são válidos na rede; E
endereços de hosts não são válidos, vindos de hosts que estão tentando
enganar (spoofed) a rede fazendo se passar por outros hosts.
As seguintes regras bloqueiam pacotes que tentam enganar a rede com
um endereço de origem "falsos" enviados de hosts da rede externa e tentando
chegar ao Firewall por interfaces também externas:
$block_ads = {10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16,
224.0.0.0/4, 240.0.0.0/5, 127.0.0.0/8, 0.0.0.0}
block in quick on $ext_if from $block_ads
Existem duas opções de atalhos que podem ser usadas para especificar uma
larga faixa de IP's. Uma é any que quando colocada depois do from ou to quer
dizer qualquer endereço. Então from any de qualquer endereço de origem e
to any para qualquer endereço de destino.
58. 58 PF o Firewall do OpenBSD Luiz Arthur
O segundo atalho é a opção all (qualquer origem e qualquer destino) que
substitui from any to any, assim as seguintes regras são iguais:
block in on $ext_if from any to any
block in on $ext_if all
Note que se você usar from é obrigatório o uso do to, e vice-versa.
Porta de Origem (port)
Para um refinamento maior na filtragem de pacotes é possível especificar a
porta de origem. A porta aparece depois do endereço IP de origem e usada pela
opção port, exemplo:
block in on $ext_if proto tcp from any port 80
A porta 80 é equivalente a (port = 80).
Outra possibilidade é o uso de operadores, que são: <, >, <=, >=, !=, <> e
><, o slide a seguir mostra uma vasta possibilidades para os operadores.
59. 59 PF o Firewall do OpenBSD Luiz Arthur
#bloqueia pacotes destinados a porta 80
block in on $ext_if proto tcp from any to $dmz_www_ad port = 80
#boqueia pacotes destinados para todas as portas exeto a 80
block in on $ext_if proto tcp from any to $dmz_www_ad port != 80
#bloqueia todos os pacotes destinados para portas menores que 80
block in on $ext_if proto tcp from any to $dmz_www_ad port < 80
#bloqueia pacotes destinados para portas menores e iguais a porta 80
block in on $ext_if proto tcp from any to $dmz_www_ad <= 80
#bloqueia pacotes destinados as portas maior que 80
block in on $ext_if proto tcp from any to $dmz_www_ad port < 80
#bloqueia pacotes destinados para portas maiores e iguais a 80
block in on $ext_if proto tcp from any to $dmz_www_ad port >= 80
#bloqueia pacotes destinados a portas maior que 80 e menor que 1024
block in on $ext_if proto tcp from any to $dmz_www_ad port 80 ><
1024
#bloqueia pacotes destinados a portas menores que a porta 80 e maior
#que 1024
block in on $ext_if proto tcp from any to $dmz_www_ad port
80 <> 1024
60. 60 PF o Firewall do OpenBSD Luiz Arthur
Só é possível usar portas a princípio com os protocolos TCP ou UDP
então é necessário usar a opção proto para indicar o protocolo. Caso contrário
o comando pfctl irá acusar erro ao carregar as regras.
O número de porta e o nome dos serviços desta porta podem ser obtidos no
arquivo /etc/services ou na página:
http://www.iana.org/assignments/port-numbers
Sistema Operacional (os)
A partir do OpenBSD 3.4 é possível descobrir o Sistema Operacional de
quem está enviando mensagens para o Firewall, isto é feito através de uma
base de dados (fingerprint) armazenada no arquivo /etc/pf.os. Este arquivo é
de texto puro com uma entrada por linha. O figerprint pode usar três campos:
nome do sistema operacional, versão e subtipo/patchlevel.
Para usar esta características adicione a opção os seguido pelos parâmetros de
fingerprint depois do número da porta, ou depois do endereço IP quando não
for especificado porta. Por exemplo, se você procura conexões vindo de
máquinas com o Sistema Operacional Microsoft Windows, escreva:
pass in on $ext_if proto tcp from any os "Windows"
61. 61 PF o Firewall do OpenBSD Luiz Arthur
Uma regra mais específica poderia ser para o Windows 2000, segue:
pass in on $ext_if proto tcp from any os "Windows 2000"
Mas é possível especificar mais ainda, como por exemplo filtrar pacotes com o
Microsoft Windows 2000 com o Service Pack 4 (SP4) aplicado, segue o
exemplo:
pass in on $ext_if proto tcp from any os "Windows 2000 SP4"
Em caso de duvidas sobre o sistema operacional e seus parâmetros, tal como
usar "Windows SP4", teste com o seguinte comando:
# pfctl -f ./test-os
Quando o pfctl encontra algo parecido no /etc/pf.os será apresentada a
saída:
pass in on ne1 prot tcp from any os "Windows 2000 SP4"
Se não for encontrando:
pass in on ne1 proto tcp from any os "nomatch"
62. 62 PF o Firewall do OpenBSD Luiz Arthur
Sempre cheque se as regras de (os) resolve a assinatura que você especificou,
pois algumas vezes o resultado pode não o esperado, desta forma fique ciente:
● Fingerprinting de sistema operacionais não é uma ciência exata, então use
como cuidado;
● Só é possível usar esta técnica com conexões TCP assim a opção (proto
,
tcp) é requerida;
Quando se adiciona regras com os o PF vai automaticamente carregar o
/etc/pf.os na memória, é possível ver isto com o comando: # pfctl -so;
● Para combinar uma regra com um Sistema Operacional desconhecido em
/etc/pf.os, é possível usar o parâmetro "unknown", exemplo:
pass in on ne1 proto tcp from any os "unknown"
É possível alterar a base de dados padrão /etc/pf.os, usando o seguinte:
set fingerprints "/etc/pf.os-special-modifications"
63. 63 PF o Firewall do OpenBSD Luiz Arthur
Endereços IP's de destino (to, any, all)
A filtragem de endereços IP's de destino é tipicamente usada para passar
pacotes destinados a endereços que possuem servidores ativos, for exemplo:
pass in on $ext_if from any to $dmz_www_ad
As regras são semelhantes ao endereço de origem.
Porta de destino (port)
Assim, como o endereço IP de destino este é usado para especificar um serviço
que esteja "listen" (ouvindo), e também é semelhante a porta de origem, segue
exemplos:
pass in on $ext_if proto tcp from any to $ext_www_ad
port $ext_www_port
pass in on $ext_if proto tcp from any to $ext_www_ad
port $ext_smtp_port
pass in on $ext_if proto tcp from any to
$ext_www_ad port $ext_ftp_port
64. 64 PF o Firewall do OpenBSD Luiz Arthur
Controle de acesso para usuários ou grupos (user, group)
O PF possui a habilidade de filtrar pacotes baseado no nome de usuários ou
grupos de usuários através do socket dos pacotes recebidos. Os usuários ou
grupos podem ser especificados por IDs ou nomes. Exemplo:
pass out on $ext_if proto {tcp, udp} from any to any user joe
keep state
pass out on $ext_if proto {tcp, udp} from any to any
user > 1000 group admin keep state
No caso de conexões saindo o ID do usuário ira combinar com o usuário que irá
abrir a conexão com o Firewall. Para conexões entrando, o ID do usuário será o
ID que abriu o socket no Firewall. Não é possível combinar regras com nomes
de usuários que estão passando (forward) pelo firewall com NAT, neste caso
usuários e grupos podem combinar com regras usando o nome (unknown). Neste
caso as operações permitidos são = e !=.
Usuários e grupos podem ser somente utilizados com os protocolos TCP e UDP.
Outra aplicação para usuários e grupos (user/group) é descrito no capítulo 12,
Usando authpf.
65. 65 PF o Firewall do OpenBSD Luiz Arthur
Flags TCP (flags)
Cabeçalhos TCP possuem um campo chamado flags o qual permite
implementar regras de controle para o processo de estabelecimento,
manutenção e fechamento de conexões.
As flags são importantes do ponto de vista da segurança, pois alguns ataques
abusam do three-way-hadshake e outros flags para implementar ataques, por
exemplo, do tipo DoS.
O OpenBSD trata os seguintes flags:
● S: simboliza o flag SNY sincroniza números de seqüências;
● A: simboliza o flag ACK ou acknowledge, usado para confirmação;
● R: representa o flag RST, ou reinicia;
● F: representa o flag FIN, ou final;
● P: representa o flag PUSH, ou empure, usado para enfiar os dados antes que
o buffer TCP seja atingido;
● U: representa o flag URG ou ponteiro de urgência, usado para indicar dados
que precisam ser enviados fora da seqüência de stream TCP;
● E: representa o ECE-Echo específico para notificação de congestionamento
usando echo;
● W: representa o CWR, ou janela para redução de congestionamento.
66. 66 PF o Firewall do OpenBSD Luiz Arthur
A sintaxe para o uso de filtro com flags é a seguinte: a opção flags seguida de
duas listas separadas por uma "/"; A primeira lista são de flags que serão
verificados e devem estar ativos e a segunda lista são as flags que serão
verificados e podem ou não estar ativos. Exemplo:
# FIN deve estar ativa, e o resto é ignorado
block in proto tcp all flags F/F
# FIN deve não deve esta ativo, o resto é ignorado
block in proto tcp all flags /F
# FIN deve estar ativo, o resto deve estar desativado
block in all flags F
# FIN deve estar ativo, e o ACK deve estar desativado, o resto é
# ignorado
block in all flags F/FA
# FIN e ACK devem estar desativados, o resto é ignorado
block in all flags /FA
A opção (flags) só pode ser utilizado com o protocolo TCP.
67. 67 PF o Firewall do OpenBSD Luiz Arthur
Pacotes ICMP
Pacotes ICMP geram mensagens sobre a rede, mas podem ser utilizados para
alguns tipos de ataques, então este tipo de pacote também deve ser tratado
com cuidado.
No PF pacotes ICMPv4 são apicados com a opção icmp-type, enquanto ICMP
IPv6 são tratados com a opções ipv6-icmp-type. Ambas opções são seguidas
de um número que identifica a mensagem ICMP separados com a opção (code).
,
Por exemplo, se você espera que o Firewall receba e responda requisições do
ping, então implemente a seguinte regra:
pass in inet proto icmp icmp-type 8 code 0 keep state
O equivalente IPv6:
pass in inet6 proto icmpv6 icmpv6-icmp-type 8 code 0 keep state
68. 68 PF o Firewall do OpenBSD Luiz Arthur
Filtro Stateful (keep state, modulate state, synproxy state)
O PF implementa filtragem de pacotes stateful, sendo então capaz de controlar
estados de conexão. Um filtro stateful possui as seguintes vantagens:
● Fazer os processamentos de pacotes de forma mais rápida;
● Fazer conjuntos de regras mais simples;
● Manter as conexões mais seguras.
O conceito básico por trás de um Firewall stateful é simples. Quanto os
primeiros pacotes de uma conexão chegam ao Firewall, este cria uma tabela
de conexões e adiciona a conexão em questão. Caso a conexão seja aceita
pelo Firewall todos os pacotes subseqüentes desta conexões serão
comparadas primeiramente a esta tabela de conexões já aceita, isto agiliza o
processamento de pacotes no filtro. Então quando um pacote chega ao Firewall
primeiro o pacote é submetido a uma comparação a tabela stateful caso já
esteja liberado tal conexão o pacote passa sem ser processado pelo filtro de
pacotes, caso o pacote não esteja nesta lista de conexões já permitidas no
stateful este pacote deve ser submetido as regras de filtragem normalmente.
Firewalls stateful decidem se um pacote pertence ou não a uma conexão
através do número de seqüência armazenados no cabeçalhos TCP A inspeção
.
stateful é ativada pela opção (keep state) colocada no final da regra de
filtragem. Exemplo:
pass out on $ext_if proto tcp all keep state
69. 69 PF o Firewall do OpenBSD Luiz Arthur
As informações sobre uma conexão são removidas após as conexões serem
fechadas via TCP ou depois que o tempo de resposta de pacotes TCP expirem
(caso a conexão caia, por exemplo), isto ajuda a controlar a memória usada por
este recurso.
De toda forma quando usa-se regras nat/binat/rdr, já se está usando o
filtro stateful de forma automática.
As regras a seguir permite que qualquer pacote TCP criem estados quando um
pacote estiver saindo do Firewall. Mas para pacotes entrando no Firewall,
somente pacotes TCP destinados a porta 80 podem criar estados:
pass in proto tcp all port 80 keep state
pass out proto tcp all keep state
Se você espera limitar que apenas pacotes com o flag SYN criem estados use a
opção flags S/SA:
pass in proto tcp all port 80 flags S/SA keep state
pass out proto tcp all flags S/SA keep state
Apenas conexões TCP possuem controle de conexões de estados
implementados em nível de protocolo, porém no PF os protocolos UDP e
ICMP que não possuem por natureza estados, podem usar deste
artificio.
70. 70 PF o Firewall do OpenBSD Luiz Arthur
Com pacotes UDP um conjunto de endereços IP de origem, destinos,
bem como portas de origem e destino são usadas para criar uma idéia
de estados.
Para conexões ICMP, são implementadas diferentes formas de artifícios
para se manter estados, ou seja, tudo depende do código da mensagem
ICMP. Por exemplo, mensagens ICMP de erro normalmente referente a pacotes
TCP ou UDP, assim o PF compara o pacote ICMP com os estados estabelecidos
dos pacotes UDP ou ICMP Assim regras de controle de estados para este tipo
.
de mensagem podem ser criadas de forma única.
Mas alguns tipos de mensagens ICMP tem que ter suas regras separadas, tal
como o ping:
pass out inet proto icmp all icmp-type echoreq keep state
Os números iniciais de seqüência podem ser usados para ataques em
Firewalls to tipo stateful, já que alguns Sistemas Operacionais mantem
este número de seqüência de forma previsível. O PF pode prevenir estes
ataques com a regra modulate state. Para ativar este modulo use o modulate
state ao invés do keep state:
pass in proto tcp all port 80 flags S/SA modulate state
pass out proto tcp all flags S/SA keep modulate state
71. 71 PF o Firewall do OpenBSD Luiz Arthur
A vantagem de usar o modulate state está no aumento no nível de segurança
aplicado pelo uso de números de seqüência randômico usado para as
conexões que combinem com as regras de filtragem.
Mas lembre-se o modulate state pode somente ser usado com conexões TCP.
Para outras conexões (UDP e ICMP) use o keep state.
Outra variante do filtro stateful é o SYNPROXY a idéia por trás deste é
completar as conexões TCP usando o handshake. As regras synproxy
state implementa as características do keep state e modulate state e
somente trabalha com conexões TCP:
pass in proto tcp all port 80 flags S/SA synproxy state
Regras de synproxy previne ataques to tipo SYN floods.
O comportamento dos estados podem ser controlados com opções globais
aplicáveis a todas as regras, ou com opções locais aplicáveis a apenas uma
regra. Essas opções são: limits states e timeout.
A opção limit states indica o tamanho da memória que vai ser usado pelo
PF para armazenar estados, esta opção pode prevenir ataques de DoS.
72. 72 PF o Firewall do OpenBSD Luiz Arthur
Você pode alterar estes limites, mas para deixar sem limite você devera
remover a opção (set limit states) do arquivo /etc/pf.conf e reiniciar o
Firewall.
A opção timeout ajusta o tempo que espera uma conexão. Essas regras
somente se aplicada a pacotes que combinem com conexões stateful.
Exemplos:
#1 - Marca o tempo de espera para conexões para 20 segundos depois
# de receber o primeiro pacote
set timeout tcp.first 20
#2 - Marca o tempo de espera de conexões stateful para 20 segundos
# depois de receber o primeiro pacote do host que inicializa esta
# conexão, se a conexão é estabelecida todos os pacotes da conexão
# reiniciam a conexão para 10 a cada vez que chegam.
set timeout tcp.first 20
set timeout tcp.established 10
#3 - O mesmo que o exemplo 2, mas as regras estão em uma mesma linha
set timeout {tcp.first 20, tcp.established 10}
73. 73 PF o Firewall do OpenBSD Luiz Arthur
Os exemplos anteriores são bem agressivos, já que se a conexão não é
estabelecida em 20 segundos ela será bloqueada. Com o exemplo 2 é
adicionado ainda uma regra que diz que o Firewall deve receber pacotes da
conexão em no mínimo de 10 em 10 segundos caso contrário a conexão será
bloqueada.
O protocol.connectionstate pode assumir os seguintes valores:tcp.first;
tcp.opening; tcp.established; tcp.closing; tcp.finwait; tcp.closed.
Essas configurações são estáticas (você precisa recarregar as regras para
alterar esses valores), mas você pode utilizar o adaptive:
● adaptive.start - quando o número de estados excede esse valor, o PF
inicia uma escala linear para todos os valores de timeout;
● adaptive.end - quando o número de estados excede esse valor, o PF seta
todas os timeouts para 0.
A forma usada para a escala linear utiliza os seguintes valores:
adaptive.start, adaptive.end e o número de estados armazenados na
memória:
((adaptive.end)- número de estados) / ((adaptive.end) -
(adaptive.start)) = scaling factor
74. 74 PF o Firewall do OpenBSD Luiz Arthur
Então se marcarmos as opções a seguir (isto pode ser feito globalmente ou
localmente):
set timeout {adaptive.start 5000, adaptive.end 20000}
e o número de estados é 8500, o valor de timeout irá ser escalado para baixo
com o seguinte valor:
(20000 - 8500) / (20000 - 5000) = 11500/15000 = 0.77 ou 77%
É possível controlar outros protocolos também, tal como UDP e ICMP mas o
,
número de estados é limitado: udp.first;udp.single;udp.multiple;
icmp.first; icmp.error; other.first; other.single; other.multiple.
A opção other capta todos os protocolos que não o TCP UDP ou ICMP
, .
A última opção de timeout é o interval que específica o intervalo de que o
estado expira. Exemplo:
set timeout interval 20
set timeout frags 20
75. 75 PF o Firewall do OpenBSD Luiz Arthur
Cada keep state ou modulate state pode ter suas próprias opções, que são:
● max: n - O número máximo de estados concorrentes que pode ser criados
para esta regra;
● timeout: Valores para estados criados com esta regra.
Essas regras são algo como:
pass in proto tcp all port 80 flags S/SA modulate state
(max 1000, tcp.established 120, tcp.slosing 10)
Rótulos (label)
Rótulos são usados para marcar regras de forma que o PF mantenha
estatísticas separadas. Você pode ver estas estatísticas com o pfctl. Um
rotulo é adicionado com a opção label seguido de um texto para identificar o
rotulo. Os rótulos são as últimas opções de uma regra:
pass in on rl0 all label "incoming"
pass out on rl0 all label "departing"
Para ver as estatísticas use:
#pfctl -s labels
76. 76 PF o Firewall do OpenBSD Luiz Arthur
Regras antispoof
O spoofing de endereços de origem é usado para passar pacotes pelo Firewall
através da interface de rede externa para a rede interna como se fosse um
pacote vindo da rede interna, exemplo, um pacote vindo da Internet com o
endereço da rede Privada (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).
Para ajudar nesta tarefa existem regras anti-spoof, isto é feito no PF com a
opção antispoof, com a seguinte sintaxe:
● antispoof: opção obrigatória;
● log: registra o pacote, e é opcional;
● quick: tal como o quick nas demais regras;
● for: permite dizer qual interface será gerada regras anti-spoof, está é
requerida;
● inet ou inet6: Indica se IPv4 ou IPv6, está é opcional.
Exemplo:
antispoof for ne1
77. 77 PF o Firewall do OpenBSD Luiz Arthur
Regras de filtragem para pacotes redirecionados
Quando for filtrar pacotes redirecionados, a principal coisa a se lembrar quando
você projetar suas regras para usar NAT ou redirecionamento de
porta/interface, é fazer as regras de filtragem para comparar com os pacotes
depois do NAT ou do redirecionamento, ou você vai ter muita dor de cabeça
depurando sua implementação.
Regras de encaminhamento são muito simples (entrando e saindo são
qualificados em relação ao Firewall):
● Regras rdr: Pacotes enviados por outros hosts, são comparadas com regras
block in ou pass in na mesma interface da regra rdr, exemplo:
rdr on $prv_if proto tcp from $prv_ad to any port 80 -> $ch_ad
port 8080
pass in on $prv_if proto tcp from $prv_ad to $ch_ad port 8080
No exemplo anterior, todos os pacotes enviados da rede privada para a porta 80
para qualquer endereço são redirecionados para o endereço $ch_ad na porta
8080.
78. 78 PF o Firewall do OpenBSD Luiz Arthur
● Regras nat: Pacotes enviados de hosts NATiados mostram-se como pacotes
saindo (out) do Firewall pela interface usada na regra de NAT. O endereço
de origem e a porta de origem são alteradas para a interface do Firewall.
Então são comparadas por regras block out ou pass out naquela
interface, exemplo:
nat on $ext_if from $prv_ad to any -> $ext_ad
pass out on $ext_if proto tcp from $ext_ad to any
● Regras binat: Pacotes enviados por hosts internos aparecem como pacotes
de saída out na interface que usa regras binat. O endereço de origem é
alterado para o endereço externo usado na regra binat. Então, são
comparados por regras block out ou pass out na interface usada na regra
binat. Pacotes enviados por hosts externos aparecem como pacotes
entrando no Firewall (in) pela interface usada no binat. Assim, os
endereços de destino são alterados para os endereços internos usados pela
regra de binat. Então combinam com regras block in ou pass
in.Exemplo:
binat on $ext_if from $workstation_int to any -> $workstation_ext
pass in on $ext_if proto tcp from any to $workstation_int
pass out on $ext_if proto tcp from $workstation_ext to any
79. 79 PF o Firewall do OpenBSD Luiz Arthur
- reassemble tcp - normaliza conexões TCP Ao usar scrub reassemble tcp
.
uma direção in/out não deve ser especificada. As seguintes normalizações são
80. 80 PF o Firewall do OpenBSD Luiz Arthur
- reassemble tcp - normaliza conexões TCP Ao usar scrub reassemble tcp
.
uma direção in/out não deve ser especificada. As seguintes normalizações são
81. 81 PF o Firewall do OpenBSD Luiz Arthur
Este material é retirado dos seguintes livros:
ARTYMIAK, Jacek. Building Firewalls with OpenBSD and PF. 2 Edição.
2003.
LUCAS, Michael W. Absolute OpenBSD: UNIX for Practical Paranoid. No Starch Press,
2003.
OPENBSD. OpenBSD Packet Filter. Disponível em:
www.openbsd.org/faq/pf/pt/index.html. Acessado em: 2007.
Todos os slides são apenas uma base para a disciplina e não dispensa a leitura
dos próprios livros para compreensão do assunto como um todo.