Tradução do Endereço de Rede (NAT) é uma forma de mapear toda uma rede
(ou redes) para apenas um endereço IP. NAT é necessário quando o
número de endereços IP atribuídos a você pelo seu Provedor de
Serviços Internet é menor que o número total de computadores para os quais
você quer prover acesso à Internet. NAT está descrito na
RFC 1631.
NAT permite você fazer uso dos blocos de endereços reservados
descritos na
RFC 1918,
"Address Allocation for Private Internets."
Tipicamente sua rede interna será configurada com endereços IP de
um ou mais blocos nessas redes. São eles:
10.0.0.0/8 (10.0.0.0 - 10.255.255.255)
172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
192.168.0.0/16 (192.168.0.0 - 192.168.255.255)
Um sistema OpenBSD fazendo NAT deve ter ao menos dois adaptadores de rede,
um para a Internet, e outro para a rede interna. O NAT irá traduzir
requisições da rede interna de forma que elas pareçam se originar
do sistema OpenBSD fazendo NAT.
Como Funciona o NAT
Quando um cliente na rede interna procura uma máquina na Internet,
ele envia pacotes IP destinados a esta máquina. Estes pacotes contém
toda a informação de endereçamento necessária para chegar a seu
destino. Informação pertinente ao NAT:
Endereço IP de orgigem (por exemplo, 192.168.1.35)
Porta de origem TCP ou UDP (por exemplo, 2132)
Quando o pacote passa pelo gateway NAT é alterado para que pareça ter
sido originado no próprio gateway. O gateway NAT registra então as
alterações feitas por ele em sua tabela de estado para que ele
possa a) reverter as alterações nos pacotes que retornam e b) certificar-se
de que os pacotes que retornam, cruzem o firewall sem serem bloqueados. Por exemplo,
as seguintes alterações devem ser feitas:
Endereço IP de origem: substituído pelo endereço externo do gateway
(por exemplo, 24.5.0.5)
Porta de origem: substituída por uma porta disponível no gateway
escolhida dinamicamente (por exemplo, 53136)
Nem a máquina interna e nem o host na Internet percebem esse trabalho de
tradução. Para a máquina interna, o sistema NAT é simplesmente um
gateway Internet. Para o host na Internet, os pacotes parecem vir diretamente
do sistema NAT; ele nem mesmo suspeita da existência da estação de
trabalho interna.
Quando o host na Internet responde aos pacotes da máquina interna, eles
serão endereçados ao IP externo do gateway NAT (24.5.0.5) na
porta da tradução (53136). O gateway NAT pesquisará então sua tabela
de estado para determinar se os pacotes em resposta casam com uma
conexão já estabelecida. Uma ocorrência única será encontrada
baseado na combinação endereço IP/porta que diz ao PF que os pacotes pertencem
a conexão iniciada pela máquina interna 192.168.1.35. O PF então
faz as alterações reversas feitas nos pacotes que
estabeleceram a conexão e transfere as respostas para a máquina interna.
A tradução de pacotes ICMP ocorre de maneira similar mas sem alteração
de porta de origem.
NAT e Filtragem de Pacotes
NOTA: Pacotes traduzidos ainda devem passar
pelo sistema de filtragem e serão aceitos ou bloqueados baseado nas regras
de filtragem definidas.
A única excessão a esta regra se dá quando
a palavra-chave pass é usada em uma regra nat.
O que fará com que os pacotes NATeados passem direto pelo sistema
de filtragem.
Saiba também que, como a tradução ocorre antes da filtragem, o
sistema de filtagem enxergará o pacote já traduzido para o
endereço IP e porta conforme explicado em Como Funciona o NAT.
IP Forwarding
Como o NAT é quase sempre usado em roteadores e gateways de rede,
provavelmente será necessário habilitar o IP forwarding para que
pacotes possam trafegar entre as interfaces de rede na máquina OpenBSD.
IP forwarding é habilitado usando o mecanismo
sysctl(3):
Estas linhas estão presentes, mas comentadas
(prefixadas por #). Remova o # e salve o arquivo.
O IP forwarding será habilitado quando a máquina for reiniciada.
Configurando NAT
A forma geral de regras NAT no arquivo pf.conf se parece com:
nat [pass] [log] on interface [af] from src_addr
[port src_port] to \ dst_addr [port dst_port] ->
ext_addr [pool_type] [static-port]
nat
A palavra-chave que inicia uma regra NAT.
pass
Faz com que pacotes traduzidos passem direto pelas regras de
filtragem.
log
Loga pacotes que combinem com a regra via
pflogd(8).
Normalmente apenas o primeiro pacote que combina será logado.
Para logar todos os pacotes, use log (all).
interface
O nome ou grupo da interface de rede onde os pacotes devem ser
traduzidos.
af
A família do endereço, inet para IPv4 ou
inet6 para IPv6. Normalmente o PF pode determinar essa
informação com base nos endereços de origem/destino.
src_addr
O endereço de origem (interno) dos pacotes que serão
traduzidos. O endereço de origem pode ser especificado como:
Um nome de domínio totalmente qualificado que será
resolvido pelo DNS quando as regras forem carregadas. Todos
endereços IP resultantes da pesquisa serão
substituídos nas regras.
O nome ou grupo de uma interface de rede. Qualquer número IP
atribuído à interface será usado quando a regra
for carregada.
O nome de uma interface de rede seguido por uma
/máscara (ex. /24). Cada endereço
IP na interface é combinado com a máscara para formar um
bloco de rede CIDR que é substituído na regra.
O nome ou grupo de uma interface de rede acompanhado de um dos
modificadores:
:network - substitui o bloco de rede CIDR (ex.,
192.168.0.0/24)
:broadcast - substitui o endereço de broadcast
(ex., 192.168.0.255)
:peer - substitui o endereço da outra ponta num
link ponto-a-ponto
Além disso, o modificador :0 pode ser adicionado
a um nome/grupo de interface ou a qualquer dos modificadores acima
para dizer ao PF para não incluir aliases de endereços
IP na substituição.
Esses modificadores também podem ser usados quando a interface
é colocada entre parênteses.
Exemplo: fxp0:network:0
Nome de domínio totalmente qualificado que será resolvido pelo
servidor DNS quando a regra for carregada.
O nome da interface de rede externa. Quaisquer endereços ip
atribuídos a interface serão substituídos nas regras quando forem
carregadas.
O nome da interface de rede externa entre parênteses
( ). Isso informa ao PF para atualizar a regra caso o
endereço da interface sofra alterações. É muito útil quando a
interface externa tem seu endereço IP atribuído via DHCP ou dial-up,
já que as regras não precisam ser recarregadas a cada alteração no
endereço.
O nome da interface de rede seguido de alguns destes modificadores:
:network - substitui um bloco de rede CIDR (ex.,
192.168.0.0/24)
:peer - é trocado pelo endereço IP da outra ponta num link
ponto-a-ponto
Além disso o modificador :0 pode ser incluído num nome de
interface ou em qualquer dos modificadores acima para indicar que o PF
não deve incluir endereços IP de aliases.
Estes modificadores também podem ser usados quando a interface está
entre parênteses.
Exemplo: fxp0:network:0
Informa ao PF para não traduzir a porta de origem em pacotes TCP e UDP.
O que pode nos levar a criação de uma regra básica equivalente:
nat on tl0 from 192.168.1.0/24 to any -> 24.5.0.5
Essa regra diz para fazer NAT na interface tl0 para quaisquer
pacotes vindos de 192.168.1.0/24 e substituir o endereço IP de origem para
24.5.0.5.
Embora a regra acima esteja correta, esta forma de uso não é recomendada.
A manutenção pode se tornar dificil porque caso algum endereço, na interface
externa ou interna seja alterado a linha também precisará ser alterada.
Faça a comparação com uma linha que facilita um pouco a
manutenção (tl0 é externa, dc0 interna):
nat on tl0 from dc0:network to any -> tl0
A vantatem deve ser clara: podemos alterar o endereço IP de qualquer
interface sem haver necessidade de se alterar a regra.
Ao especificar um nome de interface para a tradução de endereços como
acima, o endereço IP é determinado no carregamento do pf.conf,
e não em tempo real. Caso esteja usando DHCP para configurar sua interface
externa, isso pode se tornar um problema. Se o endereço atribuído for
alterado, o NAT continuará traduzindo pacotes com destino externo usando
o endereço IP antigo. O que fará com que as conexões parem de funcionar.
Para evitar esse problema, você pode dizer ao PF para atualizar o endereço
de tradução automaticamente, colocando o nome da interface entre parênteses:
nat on tl0 from dc0:network to any -> (tl0)
Este método funciona para tradução tanto de endereços IPv4 quanto IPv6.
Mapeamento Bidirecional (mapeamento 1:1)
Um mapeamento bidirecional pode ser estabelecido através do uso da
regra binat. A regra binat estabelece o
mapeamento um para um entre um endereço IP interno e um endereço
externo. Podendo 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.
binat on tl0 from $web_serv_int to any -> $web_serv_ext
Excessões em Regras de Tradução
Excessões às regras de tradução podem ser feitas usando-se a
palavra-chave no. Por exemplo, se o exemplo de NAT acima fosse alterado para:
no nat on tl0 from 192.168.1.208 to any
nat on tl0 from 192.168.1.0/24 to any -> 24.2.74.79
Então toda a rede 192.168.1.0/24 teria seus pacotes traduzidos para
o endereço externo 24.2.74.79 exceto o host 192.168.1.208.
Note que a primeira regra que casa vence; se for uma regra no,
o pacote não é traduzido. A palavra-chave no
pode também ser usada com regras binat e
rdr.
Verificando Status do NAT
O pfctl(8)
com a opção -s state é usado para
verificar as traduções NAT. Esta opção
listará todas sessões NAT ativas:
# pfctl -s state
fxp0 TCP 192.168.1.35:2132 -> 24.5.0.5:53136 -> 65.42.33.245:22 TIME_WAIT:TIME_WAIT
fxp0 UDP 192.168.1.35:2491 -> 24.5.0.5:60527 -> 24.2.68.33:53 MULTIPLE:SINGLE
Explicações (apenas a primeira linha):
fxp0
Indica a interface a qual o estado está vinculado. A palavra
self aparecerá caso o estado seja
floating.
TCP
O protocolo usado pela conexão.
192.168.1.35:2132
O endereço IP (192.168.1.35) da máquina na rede
interna. A porta de origem (2132) é mostrada após o
endereço. Este também é o endereço
substituído no cabeçalho IP.
24.5.0.5:53136
O endereço IP (24.5.0.5) e porta (53136) no gateway onde os
pacotes estão sendo traduzidos.
65.42.33.245:22
O endereço IP (65.42.33.245) e porta (22) onde a
máquina interna está se conectando.
TIME_WAIT:TIME_WAIT
Indica em qual estado o PF acredita que a conexão TCP esteja.