[OpenBSD]

[Anterior: Tradução do Endereço de Rede (NAT)] [Conteúdo] [Próximo: Atalhos na Criação de Regras]

PF: Redirecionamento (Port Forwarding)


Conteúdo


Introdução

Quando você utiliza NAT no seu escritório, você tem a Internet inteira disponível para todas as suas máquinas. Mas e se você tiver uma máquina atrás do gateway NAT que precisa ser acessada de fora? É aqui que entra o redirecionamento. Redirecionamento permite enviar tráfego para uma máquina atrás do gateway NAT.

Vejamos um exemplo:

rdr on tl0 proto tcp from any to any port 80 -> 192.168.1.20

Esta linha redireciona o tráfego TCP na porta 80 (servidor web) para uma máquina na rede com endereço 192.168.1.20. Portanto, mesmo que 192.168.1.20 esteja atrás do gateway dentro da rede, ela se torna acessível ao mundo externo.

A parte from any to any da linha rdr acima pode ser muito bem utilizada. Se você souber quais endereços ou subredes devem ter acesso ao servidor na porta 80, pode restringi-los assim:

rdr on tl0 proto tcp from 27.146.49.0/24 to any port 80 -> \
   192.168.1.20

Isto irá redirecionar somente a subrede especificada. Perceba que isso implica que você pode redirecionar diferentes hosts para máquinas diferentes atrás do gateway. O que pode ser muito útil. Por exemplo, você pode fazer com que usuários em lugares remotos acessem seus próprios computadores desktop usando a mesma porta e endereço IP no gateway desde que você saiba de que endereço IP eles se conectarão.

rdr on tl0 proto tcp from 27.146.49.14 to any port 80 -> \
   192.168.1.20
rdr on tl0 proto tcp from 16.114.4.89 to any port 80 -> \
   192.168.1.22
rdr on tl0 proto tcp from 24.2.74.178 to any port 80 -> \
   192.168.1.23

Uma faixa de portas também pode ser redirecionada dentro da mesma regra:

rdr on tl0 proto tcp from any to any port 5000:5500 -> \
   192.168.1.20
rdr on tl0 proto tcp from any to any port 5000:5500 -> \
   192.168.1.20 port 6000
rdr on tl0 proto tcp from any to any port 5000:5500 -> \
   192.168.1.20 port 7000:*

Estes exemplos mostram portas 5000 a 5500 inclusive, sendo redirecionadas para 192.168.1.20. Na regra #1, a porta 5000 é redirecionada para 5000, 5001 para 5001, etc. Na regra #2, toda a faixa de portas é redirecionada para a porta 6000. E na regra #3, a porta 5000 é redirecionada para 7000, 5001 para 7001, etc.

Redirecionamento e Filtragem de Pacotes

NOTA: Pacotes traduzidos ainda devem passar pelo sistema de filtragem e serão bloqueados ou permitidos, com base nas regras de filtragem definidas.

A única exceção a regra é quando a palavra-chave pass é usada na regra rdr. Neste caso, os pacotes redirecionados passarão direto pelo sistema de filtragem: as regras de filtragem não serão avalidas para estes pacotes. É um atalho para evitar a adição de regras de filtragem pass para cada regra de redirecionamento. Pense nisso como uma regra rdr normal (sem a palavra-chave pass) associada a uma regra de filtragem pass com a palavra-chave keep state. Contudo, caso queira habilitar opções de filtragem mais específicas, como synproxy, modulate state, etc, você ainda precisará usar regras pass dedicadas, já que estas opções não se encaixam em regras de redirecionamento.

Também fique ciente de que, como a tradução ocorre antes da filtragem, o sistema de filtragem verá os pacotes traduzidos como eles ficam após a alteração de seu endereço IP e/ou porta de destino terem sido alterados pela regra rdr. Considere o cenário:

Regra de Redirecionamento:

rdr on tl0 proto tcp from 192.0.2.1 to 24.65.1.13 port 80 \
   -> 192.168.1.5 port 8000

Pacote antes da regra rdr ser processada:

Pacote após a regra rdr ter sido processada:

O sistema de filtragem vê o pacote IP como ele se encontra após ter sido feita a tradução.

Implicações de Segurança

Redirecionamento possui implicações de segurança. Fazer um furo no firewall para permitir tráfego para a rede interna protegida, cria um risco de comprometimento da máquina. Caso o tráfego seja transmitido para um servidor web interno por exemplo, e uma vulnerabilidade seja descoberta no servidor ou num script CGI rodando no servidor web, a máquina pode ser comprometida por um intruso na Internet. De lá, o intruso tem uma porta aberta para a rede interna, numa máquina que tem permissão de passar pelo firewall.

Estes riscos podem ser minimizados mantendo-se os sistemas acessados externamente confinados numa rede separada. Essa rede é geralmente chamada de Zona Desmilitarizada (DMZ) ou Rede de Serviços Privada (PSN). Dessa forma, caso o servidor web seja comprometido, os efeitos podem ser limitados à rede DMZ/PSN pela filtragem cuidadosa do tráfego que terá permissão de entrar e sair da DMZ/PSN.

Redirecionamento e Reflexão

Geralmente, regras de redirecionamento são usadas para transferir pedidos de conexão da Internet para um servidor local com endereço IP privado na rede interna, ou LAN como:
server = 192.168.1.40

rdr on $ext_if proto tcp from any to $ext_if port 80 -> $server \
   port 80

Mas quando a regra de redirecionamento é testada por um cliente na LAN, ela não funciona. O motivo é que as regras de redirecionamento se aplicam apenas a pacotes que passam pela interface especificada (no exemplo a interface $ext_if). Conectar-se ao endereço externo do firewall de um host na LAN, contudo, não significa que os pacotes passarão por sua interface externa. A pilha TCP/IP no firewall compara o endereço de destino do pacote chegando com seus próprios endereços e aliases e detecta conexões para ela mesma tão logo tenham passado pela interface interna. Estes pacotes não passam fisicamente pela interface externa, e a pilha TCP/IP não simula essa passagem de forma alguma. Portanto, o PF nunca verá estes pacotes na interface externa, e a regra de redirecionamento, especificando a interface externa, não se aplicará.

Adicionar uma segunda regra de redirecionamento para a interface interna também não produz o efeito desejado. Quando um cliente local se conecta ao endereço externo do firewall, o pacote inicial do handshake TCP atinge o firewall pela interface interna. A regra de redirecionamento é aplicada e o endereço de destino é substituído pelo do servidor interno. O pacote é transferido de volta pela interface interna e chega ao servidor interno. Mas o endereço de origem no pacote não foi alterado, contendo ainda o endereço local do cliente, portanto o servidor envia suas respostas diretamente ao cliente. O firewall nunca vê as respostas, ficando sem chance de reverter a tradução apropriadamente. O cliente então recebe respostas de um endereço IP de onde ele nunca esperava, e por isso descarta os pacotes. O handshake TCP falha e a conexão não pode ser estabelecida.

Mas ainda assim, geralmente é necessário que os clientes na LAN se conectem ao servidor interno da mesma forma que os clientes externos, e que o façam de maneira transparente. Existem várias soluções para este problema:

Split-Horizon DNS

É possível configurar servidores DNS para responder a pesquisas de clientes locais de maneira diferente das pesquisas externas, de forma que clientes locais receberão o endereço interno do servidor durante a resolução de nomes. Eles irão, portanto, se conectar diretamente ao servidor local, e o firewall não tem envolvimento. Isso reduz o tráfego local, já que os pacotes não precisarão passar pelo firewall.

Movendo o Servidor Para uma Rede Local Separada

Acrescenteando mais uma interface de rede ao firewall e movendo o servidor local da rede cliente para uma rede dedicada (DMZ) permite o redirecionamento de conexões de clientes locais da mesma maneira que o redirecionamento de conexões externas. O uso de redes separadas tráz diversas vantagens, incluindo melhora na segurança devido ao isolamento do servidor e dos clientes locais. Caso o servidor (que em nosso caso é acessível pela Internet) seja comprometido, ele não terá acesso direto aos hosts locais, porque todas as conexões devem agora passar pelo firewall.

Proxy TCP

Um proxy TCP genérico pode ser configurado no firewall, escutando na porta para ser transferido ou recebendo conexões redirecionadas na interface interna para a porta onde ele esteja ouvindo. Quando um cliente local se conecta ao firewall, o proxy aceita a conexão, estabelece uma segunda conexão com o servidor interno e transfere dados entre as duas conexões.

Proxies simples podem ser criados usando-se inetd(8) e nc(1). A entrada /etc/inetd.conf a seguir cria um socket escutando no endereço de loopback (127.0.0.1) na porta 5000. As conexões são encaminhadas ao servidor 192.168.1.10 na porta 80.

127.0.0.1:5000 stream tcp nowait nobody /usr/bin/nc nc -w \
   20 192.168.1.10 80

A regra de redirecionamento a seguir transfere conexões na porta 80 na interface interna para o proxy

rdr on $int_if proto tcp from $int_net to $ext_if port 80 -> \
   127.0.0.1 port 5000

Combinação de RDR e NAT

Com uma regra NAT adicional na interface interna, a tradução de endereço que estava faltando no cenário acima pode ser remediada.

rdr on $int_if proto tcp from $int_net to $ext_if port 80 -> \
   $server
no nat on $int_if proto tcp from $int_if to $int_net
nat on $int_if proto tcp from $int_net to $server port 80 -> \
   $int_if

Isso fará com que o pacote inicial do cliente seja traduzido novamente quando retornar através da interface interna, substituindo o endereço de origem do cliente pelo endereço interno do firewall. O servidor interno irá responder para o firewall, que pode então reverter ambas as regras de tradução NAT e RDR ao transferir o pacote para o cliente. Esta construção é um tanto complexa, pois cria dois estados separados para cada conexão refletida. Deve-se tomar muito cuidado para evitar que a regra NAT atinja outro tráfego, por exemplo conexões originadas de hosts externos (através de outros redirecionamentos) ou o próprio firewall. Perceba que a regra rdr acima fará com que a pilha TCP/IP receba pacotes na interface interna com endereço de destino dentro da rede interna.

De preferência, deve-se utilizar uma das soluções apresentadas anteriormente.

[Anterior: Tradução do Endereço de Rede (NAT)] [Conteúdo] [Próximo: Atalhos na Criação de Regras]


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