[OpenBSD]

[Anterior: Redirecionamento de Tráfego (Port Forwarding)] [Conteúdo] [Próximo: Opções em Tempo de Execução]

PF: Atalhos na Criação de Regras


Conteúdo


Introdução

O PF oferece várias formas de simplificar regras. Alguns bons exemplos são através do uso de macros e listas. Além disso, a linguagem das regras, ou gramática, também oferece alguns atalhos para tornar as regras mais simples. Como uma regra geral, quanto mais simples as regras, mais fácil entender e manter.

Usando Macros

Macros são úteis porque são uma alternativa para se referenciar endereços, números de portas, nomes de interfaces, etc, em uma regra. O endereço IP de um servidor mudou? Sem problema, apenas atualize a macro; não é necessário sair alterando regras de filtragem que você teve tanto trabalho para aperfeiçoar as suas necessidades.

Um costume comum em regras PF é definir macros para cada interface de rede. Se em dado momento uma placa de rede precisar ser substituída por uma com driver diferente, por exemplo trocar uma 3Com por uma Intel, a macro pode ser atualizada e as regras de filtragem funcionarão como antes. Outro benefício é quando se usa as mesmas regras em diferentes máquinas. Certas máquinas podem ter placas de rede diferentes, e utilizar macros para defini-las permite usar as regras com o mínimo de edição. É prática recomendada usar macros para definir informações sujeitas a alteração como números de porta, endereços IP e nomes de interface.

# define macros para cada interface de rede
IntIF = "dc0"
ExtIF = "fxp0"
DmzIF = "fxp1"

Outra convenção comum é o uso de macros para definir endereços IP e blocos de rede. Isso reduz bastante o trabalho de manutenção de regras quando endereços IP são alterados.

# define nossas redes
IntNet = "192.168.0.0/24"
ExtAdd = "24.65.13.4"
DmzNet = "10.0.0.0/24"

Caso a rede interna for expandida ou mesmo reconfigurada em outro bloco de endereçamento IP, a macro pode ser atualizada:

IntNet = "{ 192.168.0.0/24, 192.168.1.0/24 }"

Uma vez recarregadas as regras, tudo funcionará como antes.

Usando Listas

Vejamos algumas regras para lidar com endereços especificados na RFC 1918, que simplesmente não podem ficar vagando na Internet, e quando são encontrados, provavelmente estão tentando causar algum problema:
block in  quick on tl0 inet from 127.0.0.0/8 to any
block in  quick on tl0 inet from 192.168.0.0/16 to any
block in  quick on tl0 inet from 172.16.0.0/12 to any
block in  quick on tl0 inet from 10.0.0.0/8 to any
block out quick on tl0 inet from any to 127.0.0.0/8
block out quick on tl0 inet from any to 192.168.0.0/16
block out quick on tl0 inet from any to 172.16.0.0/12
block out quick on tl0 inet from any to 10.0.0.0/8

Agora veja a simplificação:

block in  quick on tl0 inet from { 127.0.0.0/8, 192.168.0.0/16, \
   172.16.0.0/12, 10.0.0.0/8 } to any
block out quick on tl0 inet from any to { 127.0.0.0/8, \
   192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }

As regras foram reduzidas de oito linhas para apenas duas. Tudo fica melhor ainda quando se usa macros junto com listas:

NoRouteIPs = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
   10.0.0.0/8 }"
ExtIF = "tl0"
block in  quick on $ExtIF from $NoRouteIPs to any
block out quick on $ExtIF from any to $NoRouteIPs

Note que macros e listas simplificam o arquivo pf.conf, mas as linhas são expandidas em múltiplas regras pelo pfctl(8). Portanto, o exemplo acima é expandido na verdade para as seguintes regras:

block in  quick on tl0 inet from 127.0.0.0/8 to any
block in  quick on tl0 inet from 192.168.0.0/16 to any
block in  quick on tl0 inet from 172.16.0.0/12 to any
block in  quick on tl0 inet from 10.0.0.0/8 to any
block out quick on tl0 inet from any to 10.0.0.0/8
block out quick on tl0 inet from any to 172.16.0.0/12
block out quick on tl0 inet from any to 192.168.0.0/16
block out quick on tl0 inet from any to 127.0.0.0/8

Como pode ver, a expansão do PF é puramente uma conveniência para quem escreve e mantém o arquivo pf.conf, não uma simplificação das regras processadas pelo pf(4).

Macros podem ser usadas para definir mais do que endereços e portas; elas podem ser usadas em qualquer lugar num arquivo de regras PF:

pre = "pass in quick on ep0 inet proto tcp from "
post = "to any port { 80, 6667 } keep state"

# Classe do David
$pre 21.14.24.80 $post

# Casa do Nick
$pre 24.2.74.79 $post
$pre 24.2.74.178 $post

Expande para:

pass in quick on ep0 inet proto tcp from 21.14.24.80 to any \
   port = 80 keep state
pass in quick on ep0 inet proto tcp from 21.14.24.80 to any \
   port = 6667 keep state
pass in quick on ep0 inet proto tcp from 24.2.74.79 to any \
   port = 80 keep state
pass in quick on ep0 inet proto tcp from 24.2.74.79 to any \
   port = 6667 keep state
pass in quick on ep0 inet proto tcp from 24.2.74.178 to any \
   port = 80 keep state
pass in quick on ep0 inet proto tcp from 24.2.74.178 to any \
   port = 6667 keep state

Gramática do PF

A gramática do PF é bem flexível, o que permite grande flexibilidade na construção de regras. PF pode até mesmo deduzir certas palavras, o que significa que elas não precisam ser declaradas explicitamente numa regra, e a ordem de construção é relaxada, de forma que não se faz necessário memorizar uma sintaxe precisa.

Eliminação de Palavras-Chave

Para definir uma política "negar por padrão", duas regras são utilizadas:

block in  all
block out all

Isso pode ser reduzido para:

block all

Quando a direção não é especificada, PF assume que a regra se aplica a pacotes movendo em ambas as direções.

De maneira similar, as cláusulas "from any to any" e "all" podem ser deixadas de lado numa regra, por exemplo:

block in on rl0 all
pass  in quick log on rl0 proto tcp from any to any port 22 keep state

pode ser simplificada como:

block in on rl0
pass  in quick log on rl0 proto tcp to port 22 keep state

A primeira regra bloqueia todo tráfego entrante de pacotes vindos de qualquer lugar em rl0 para qualquer lugar, e a segunda regra aceita tráfego TCP com destino à porta 22 em rl0.

Simplificação de Return

Regras usadas para bloquear pacotes e responder com TCP RST ou ICMP Unreachable podem ficar assim:

block in all
block return-rst in proto tcp all
block return-icmp in proto udp all
block out all
block return-rst out proto tcp all
block return-icmp out proto udp all

Ou podem ser simplificadas como:

block return

Quando PF encontra a palavra return, ele é inteligente o bastante para enviar a resposta apropriada, ou nenhuma resposta, dependendo do protocolo do pacote sendo bloqueado.

Ordenação de Palavras

A ordem em que as palavras-chave são especificadas na maioria dos casos é bem flexível. Por exemplo, uma regra escrita assim:

pass in log quick on rl0 proto tcp to port 22 \
   flags S/SA keep state queue ssh label ssh

Também pode ser escrita assim:

pass in quick log on rl0 proto tcp to port 22 \
   queue ssh keep state label ssh flags S/SA

Variações similares também funcionarão.

[Anterior: Redirecionamento de Tráfego (Port Forwarding)] [Conteúdo] [Próximo: Opções em Tempo de Execução]


[back] www@openbsd.org
$OpenBSD: shortcuts.html,v 1.7 2007/12/01 10:39:11 tobias Exp $