[Anterior: Filtragem de Pacotes]
[Conteúdo]
[Próximo: Redirecionamento de Tráfego
("Port Forwarding")]
PF: Tradução do Endereço de Rede (NAT)
Conteúdo
Introdução
A Tradução do Endereço de Rede (NAT - "Network Address Translation") é
uma forma de mapear toda uma rede (ou redes) para apenas um endereço IP.
NAT é necessária quando o número de endereços IP atribuídos a você pelo
seu Provedor de Serviços de Internet é menor que o número total de
computadores para os quais você quer prover acesso à Internet.
NAT está descrita na
RFC 1631,
"The IP Network Address Translator (NAT)".
NAT permite que você faça uso dos blocos de endereços reservados
descritos na
RFC 1918,
"Address Allocation for Private Internets".
Tipicamente, sua rede interna é configurada com endereços IP de
um ou mais desses blocos de 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. A NAT
traduz as requisições da rede interna de forma que elas pareçam
se originar do sistema OpenBSD fazendo NAT.
Como Funciona a NAT
Quando um cliente na rede interna procura uma máquina na Internet,
ele envia pacotes IP destinados a essa máquina. Esses pacotes contêm
toda a informação de endereçamento necessária para chegar a seu
destino. Informação pertinente à NAT:
- Endereço IP de origem (por exemplo, 192.168.1.35)
- Porta TCP ou UDP de origem (por exemplo, 2132)
Quando o pacote passa pelo gateway NAT, ele é 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 estados 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 nem a máquina na Internet percebem esse trabalho
de tradução. Para a máquina interna, o sistema de NAT é simplesmente um
gateway de Internet. Para a máquina na Internet, os pacotes parecem vir
diretamente do sistema NAT; ele nem mesmo suspeita da existência da
estação de trabalho interna.
Quando a máquina na Internet responde aos pacotes da máquina interna,
eles são endereçados ao IP externo do gateway NAT (24.5.0.5) na porta
da tradução (53136). O gateway NAT então pesquisa na sua tabela de
estados para determinar se os pacotes de resposta correspondem a uma
conexão já estabelecida. Uma ocorrência única será encontrada
baseando-se na combinação endereço IP/porta, que diz ao PF que os
pacotes pertencem à 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 os pacotes de resposta para a
máquina interna.
A tradução de pacotes ICMP ocorre de maneira similar, mas sem alteração
da porta de origem.
IP Forwarding
Como a NAT é quase sempre usada 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):
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1 (se estiver usando IPv6)
Para que essa alteração seja permanente, as linhas a seguir devem ser
acrescentadas ao arquivo
/etc/sysctl.conf:
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
Essas linhas estão presentes, mas comentadas
(prefixadas por #). Remova o # e salve o arquivo.
O IP forwarding será habilitado quando a máquina for reinicializada.
Configuração da NAT
NOTA: Estas informações são relevantes apenas ao OpenBSD 4.7.
As configurações de NAT são significativamente diferentes nas versões mais atuais.
O uso de NAT é especificado através do uso do parâmetro opcional
nat-to atrelado a uma regra pass de saída.
Geralmente, em vez de ser definida diretamente numa regra
pass, uma regra de match é utilizada.
Quando um pacote é selecionado/marcado por uma regra match,
parâmetros (como o nat-to)presentes naquela regra são
armazenados e são aplicados ao pacote quando este pacote bate
com a regra de pass.
Isso permite que uma grande quantidade de pacotes seja gerenciada
por uma única regra match e então decisões específicas
podem ser aplicadas através de regras block ou pass.
Regras contidas no arquivo pf.conf teriam as seguintes sintaxes:
match out on interface [af] \
from src_addr to dst_addr \
nat-to ext_addr [pool_type] [static-port]
...
pass out [log] on interface [af] [proto protocol] \
from ext_addr [port src_port] \
to dst_addr [port dst_port]
- match
- Quando um pacote atravessa o conjunto de regras e corresponde a uma
regra match, os parâmetros opcionais especificados nesta
referida serão lembrados para uso futuro (é adicionada uma espécie
de etiqueta).
- pass
- Esta regra permite que o pacote seja transmitido.
Se o pacote foi previamente marcado por uma regra match de acordo com
os parâmetros especificados, eles serão aplicados a este pacote.
Regras pass podem ter seus próprios parâmetros; estes parâmetros tomam
prioridade sobre os parâmetros especificados em uma regra match.
- log
- Pacotes que corresponderam são registrados via
pflogd(8).
Normalmente, apenas o primeiro pacote que corresponde é registrado.
Para registrar todos os pacotes que corresponderam, use
log (all).
- interface
- O nome ou grupo da interface de rede onde os pacotes devem ser
transmitidos.
- af
- A família de endereços, inet para IPv4 ou
inet6 para IPv6. Normalmente o PF pode determinar essa
informação com base no(s) endereço(s) de origem/destino.
- protocol
- O protocolo (ex.: tcp, udp ou icmp) utilizado pelo pacote.
Caso src_port ou dst_port sejam especificados, o protocolo
DEVE ser informado.
- src_addr
- O endereço de origem (interno) dos pacotes que serão
traduzidos. O endereço de origem pode ser especificado como:
- Um endereço IPv4 ou IPv6 simples.
- Um bloco de rede
CIDR.
- Um nome de domínio totalmente qualificado que será resolvido pelo
DNS quando o conjunto de regras for carregado. Todos os endereços IP
resultantes da pesquisa serão substituídos na regra.
- O nome ou grupo de uma interface de rede. Quaisquer endereços IP
na interface serão substituídos quando a regra for carregada.
- O nome de uma interface de rede seguido de uma
/máscara (por exemplo, /24). Cada endereço
IP na interface é combinado com a máscara para formar um bloco de
rede CIDR que será substituído na regra.
- O nome ou grupo de uma interface de rede seguido de qualquer um
destes modificadores:
- :network - substitui o bloco de rede CIDR (por exemplo,
192.168.0.0/24)
- :broadcast - substitui o endereço de broadcast
(por exemplo, 192.168.0.255)
- :peer - substitui o endereço da outra ponta em um
link ponto a ponto
- Além disso, o modificador :0 pode ser acrescentado a um
nome/grupo de interface ou a qualquer um dos modificadores acima
para dizer ao PF para não incluir apelidos de endereços IP na
substituição.
Esses modificadores também podem ser usados quando a interface está
entre parêntesis.
Exemplo: fxp0:network:0
- Uma tabela.
- Qualquer um dos apresentados acima, mas negado usando o modificador
! ("não").
- Um grupo de endereços usando-se uma
lista.
- A palavra-chave any, indicando todos os endereços
- src_port
- A porta de origem no cabeçalho da Camada 4 do pacote. Portas
são especificadas como:
- Um número entre 1 e 65535
- Um nome de serviço válido de
/etc/services
- Um grupo de portas usando-se uma
lista
- Uma faixa:
- != (diferente de)
- < (menor que)
- > (maior que)
- <= (menor ou igual a)
- >= (maior ou igual a)
- >< (faixa)
- <> (faixa inversa)
- Os dois últimos são operadores binários (recebem dois
argumentos) e não incluem os argumentos na faixa.
- : (faixa inclusiva)
- O operador de faixa inclusiva também é um operador binário
e inclui os argumentos na faixa.
A opção port geralmente não é usada em regras nat
porque o objetivo geralmente é fazer NAT de todo o tráfego,
independente da(s) porta(s) sendo utilizada(s).
- dst_addr
- O endereço de destino dos pacotes a serem traduzidos.
Ele é especificado da mesma forma que o endereço de origem.
- dst_port
- A porta de destino no cabeçalho da Camada 4 do pacote. Essa porta
é especificada da mesma forma que a porta de origem.
- ext_addr
- O endereço externo (de tradução) do gateway NAT em que os pacotes
serão traduzidos. O endereço externo pode ser especificado como:
- Um endereço IPv4 ou IPv6 simples.
- Um bloco de rede
CIDR.
- Um nome de domínio totalmente qualificado que será resolvido pelo
servidor DNS quando a regra for carregada.
- O nome de uma interface ou de um grupo de interfaces da rede externa.
Quaisquer endereços IP atribuídos à interface serão substituídos
na regra quando for carregada.
- O nome de uma interface ou de um grupo de interfaces da rede externa entre parêntesis
( ). Isso informa ao PF para atualizar a regra caso o(s)
endereço(s) da interface sofra(m) alterações. É muito útil quando a
interface externa tem seu endereço IP atribuído via DHCP ou discada,
pois o conjunto de regras não precisa ser recarregado toda vez que
o endereço mudar.
- O nome de uma interface ou de um grupo de interfaces de rede,
seguidos de um destes modificadores:
- :network - substitui o bloco de rede CIDR (por exemplo,
192.168.0.0/24)
- :peer - substitui o endereço IP da outra ponta em um
link ponto a ponto
- Além disso, o modificador :0 pode ser acrescentado a um
nome/grupo de interfaces ou a qualquer um dos modificadores acima para
indicar que o PF não deve incluir apelidos de endereços IP na
substituição.
Esses modificadores também podem ser usados quando a interface está
entre parêntesis.
Exemplo: fxp0:network:0
- Um grupo de endereços usando-se uma
lista.
- pool_type
- Especifica o tipo de grupo de endereços a
usar para tradução.
- static-port
- Informa ao PF para não traduzir a porta de origem em pacotes TCP e
UDP.
Isso nos levaria à criação de regras básicas similares como estas:
match out on tl0 from 192.168.1.0/24 to any nat-to 24.5.0.5
pass on tl0 from 192.168.1.0/24 to any
ou você poderia simplesmente usar algo como:
pass out on tl0 from 192.168.1.0/24 to any nat-to 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
por 24.5.0.5.
Embora a regra acima esteja correta, essa forma de uso não é
recomendada.
A manutenção pode se tornar difícil, 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):
pass out on tl0 from dc0:network to any nat-to tl0
A vantagem 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
mostrado 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, a NAT continua traduzindo pacotes saindo do
firewall usando o endereço IP antigo. Isso faz 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êntesis:
pass out on tl0 from dc0:network to any nat-to (tl0)
Esse 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 do parâmetro
binat-to.
Uma regra com binat-to estabelece um mapeamento de um para um (1:1)
entre um endereço IP interno e um endereço IP externo.
Isso pode ser útil, por exemplo, para fornecer acesso a um servidor web
interno de modo que ele tenha seu próprio endereço IP externo.
Conexões vindas da Internet, destinadas aquele endereço, serão
transmitidas ao IP interno do servidor web e as conexões originadas
internamente pelo servidor web (tais como consultas de DNS) serão
repassadas com o endereço IP externo.
Portas de protocolos TCP e UDP nunca serão alteradas com o uso de
binat-to, da forma como são alteradas se você usar regras de
nat.
Exemplo:
web_serv_int = "192.168.1.100"
web_serv_ext = "24.5.0.6"
pass on tl0 from $web_serv_int to any binat-to $web_serv_ext
Exceções em Regras de Tradução
Se você necessita fazer tradução de grande parte do tráfego, mas prover
exceções à alguns casos, assegure-se de que as exceções sejam gerenciadas
por uma regra de filtro que não contenha o parâmetro nat-to.
Por exemplo, se o exemplo de NAT repassado anteriormente for
modificado para se parecer com isto:
pass out on tl0 from 192.168.1.0/24 to any nat-to 24.2.74.79
pass out on tl0 from 192.168.1.208 to any
Então toda a rede 192.168.1.0/24 teria seus pacotes traduzidos para
o endereço externo 24.2.74.79, exceto a máquina 192.168.1.208.
Verificação do Status da NAT
O
pfctl(8)
com a opção -s state é usado para verificar as traduções
NAT ativas.
Essa opção lista todas as 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 da 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. Esse 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 a 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 a 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.
[Anterior: Filtragem de Pacotes]
[Conteúdo]
[Próximo: Redirecionamento de Tráfego
("Port Forwarding")]
www@openbsd.org
$OpenBSD: nat.html,v 1.15 2013/02/25 08:23:50 ajacoutot Exp $