[Anterior: Performance] [Conteúdo] [Próximo: Authpf: Shell de Usuário para Autenticação em Gateways]
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>".
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.
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.
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
[Anterior: Performance] [Conteúdo] [Próximo: Authpf: Shell de Usuário para Autenticação em Gateways]