[OpenBSD]

[Anterior: Performance] [Conteúdo] [Próximo: Authpf: Shell de Usuário para Autenticação em Gateways]

PF: Problemas com FTP


Conteúdo


Modos FTP

FTP é um protocolo que data dos primórdios da Internet, quando esta era uma pequena a amigável coleção de computadores onde todo mundo se conhecia. Naquele tempo não havia necessidade de filtragem e altos requisitos de segurança. O FTP não foi desenvolvido para ser filtrado, atravessar firewalls, ou trabalhar com NAT.

Você pode usar FTP em dois modos: passivo e ativo. Geralmente, a escolha de modo passivo ou ativo é feita para determinar de quem será o problema com o firewall. Na verdade você precisará suportar ambos para deixar seus usuários contentes.

Com FTP ativo, quando um usuário se conecta ao servidor FTP remoto e solicita informações ou um arquivo, o servidor FTP abre uma nova conexão com o cliente para transferir os dados. Esta é a chamada conexão de dados. Para iniciar, o cliente FTP escolhe uma porta aleatória para receber a conexão de dados. O cliente envia o número da porta escolhida para o servidor FTP e fica esperando uma conexão nessa porta. Então o servidor FTP inicia a conexão com o endereço do cliente na porta escolhida e transfere os dados. Isto se torna um problema para usuários atrás de um gateway NAT tentando se conectar a servidores FTP. Por causa da forma como NAT funciona, o servidor FTP inicializa a conexão de dados se conectando ao endereço externo do gateway NAT na porta escolhida. A máquina fazendo NAT receberá o pedido, mas como não possui mapeamento para o pacote na tabela de estado, descartará o pacote sem entrega-lo ao cliente.

No modo FTP passivo (o modo padrão no cliente ftp(1) do OpenBSD), o cliente pede ao servidor que escolha uma porta aleatória para ouvir esperando a conexão de dados. O servidor informa ao cliente a porta escolhida e o cliente se conecta na porta para transferir os dados. Infelizmente, isto nem sempre é possível ou desejável, por causa da possibilidade do firewall em frente ao servidor FTP bloquear a conexão de dados. O ftp(1) do OpenBSD usa modo passivo por padrão; para forçar o modo ativo, use a opção -A para o ftp, ou defina modo passivo para "off" usando o comando "passive off" no prompt do "ftp>".

Client FTP Atrás de um Firewall

Como indicado anteriormente, FTP não se dá muito bem com NAT e firewalls.

Packet Filter fornece uma solução para esta situação redirecionando tráfego FTP para um servidor proxy FTP. Este processo age "guiando" o tráfego FTP através do gateway/firewall NAT. O proxy FTP usado pelo OpenBSD e PF é o ftp-proxy(8). Para ativa-lo, insira algo assim na seção NAT do pf.conf:

rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \
   port 8021

A explicação desta linha é: "Tráfego na interface interna é redirecionado para o servidor proxy nesta máquina que está ouvindo na porta 8021".

Espero que tenha ficado óbvio que o servidor proxy deve ter sido iniciado e estar rodando na máquina OpenBSD. Isso é feito adicionando a seguinte linha em /etc/inetd.conf:

127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy \
   ftp-proxy -n

Note que a opçao -n se faz necessária apenas caso a máquina OpenBSD esteja fazendo NAT. Agora envie um sinal 'HUP' ao inetd(8) para fazer com que ele releia seu arquivo de configuração. Uma forma de enviar o sinal 'HUP' é com o comando:

kill -HUP `cat /var/run/inetd.pid`

Você notará que o servidor ftp-proxy está ouvindo na porta 8021, a mesma porta onde a instruçao rdr está enviando tráfego FTP. A escolha da porta 8021 é arbitrária, de qualquer forma a 8021 é uma boa opção já que não é definida para nenhuma aplicação.

Neste ponto apenas conexões FTP em modo passivo funcionarão. Para habilitar conexões em modo ativo, a conexão ftp-data que o servidor FTP inicia deve passar pelo firewall. Infelizmente, a porta onde chega este pedido de conexão não pode ser previamente conhecida, apenas a faixa de portas em que ela pode estar. O que é sabido porém, é que a conexão será iniciada da porta 20 (porta ftp-data) e que o servidor ftp-proxy estará aceitando a conexão (e depois transmitirá os dados para o cliente). Já que o ftp-proxy roda como usuário proxy, a palavra-chave user pode ser usada na regra de filtragem.

pass in on $ext_if inet proto tcp from port 20 to ($ext_if) \
    user proxy flags S/SA keep state

Por favor note que a função do ftp-proxy(8) é ajudar clientes FTP atrás de um filtro PF; ele não é usado para lidar com servidor FTP atrás de um filtro PF.

PF "Auto-Protegendo" um Servidor FTP

Neste caso, PF está rodando no próprio servidor FTP ao invés de um firewall dedicado. Quando servindo uma conexão FTP passiva, FTP usará uma porta alta TCP aleatória para os dados. Por padrão, o servidor FTP nativo do OpenBSD ftpd(8) utiliza a faixa de portas de 49152 a 65535. Obviamente, esta faixa de portas deve ter permissão de passar pelas regras de filtragem, junto com a porta 21 (a porta de controle FTP):
pass in on $ext_if proto tcp from any to any port 21 keep state
pass in on $ext_if proto tcp from any to any port > 49151 \
   keep state

Perceba que se você quiser, pode restringir consideravelmente a faixa de portas. No caso do programa ftpd(8) do OpenBSD, isto é feito utilizando as variáveis sysctl(8) net.inet.ip.porthifirst e net.inet.ip.porthilast.

Servidor FTP Protegido por um Firewall PF Externo Fazendo NAT

Neste caso, o firewall deve redirecionar tráfego para o servidor FTP além de não bloquear as portas necessárias. Para o propósito da discussão, assumiremos que o servidor FTP em questão é novamente o servidor padrão do OpenBSD ftpd(8), usando a faixa de portas padrão.

Aqui está um pequeno conjunto de regras para realizar o serviço:

ftp_server = "10.0.3.21"

rdr on $ext_if proto tcp from any to any port 21 -> $ftp_server \
   port 21
rdr on $ext_if proto tcp from any to any port 49152:65535 -> \
   $ftp_server port 49152:65535

# entrada em $ext_if
pass in quick on $ext_if proto tcp from any to $ftp_server \
   port 21 keep state
pass in quick on $ext_if proto tcp from any to $ftp_server \
   port > 49151 keep state

# saída em $int_if
pass out quick on $int_if proto tcp from any to $ftp_server \
   port 21 keep state
pass out quick on $int_if proto tcp from any to $ftp_server \
   port > 49151 keep state

Mais Informações sobre FTP

Mais informações sobre filtragem FTP e funcionamento geral do FTP podem ser encontradas neste documento:

[Anterior: Performance] [Conteúdo] [Próximo: Authpf: Shell de Usuário para Autenticação em Gateways]


[voltar] www@openbsd.org
$OpenBSD: ftp.html,v 1.3 2005/11/18 20:48:47 jufi Exp $