SSD Nodes Learn 🎉 VPS desde $5.50/mês
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-21

FTP passivo: como liberar as portas no firewall

O login funciona, mas a listagem trava por timeout. Defina um intervalo de portas passivas e libere exatamente esse intervalo no firewall, inclusive atrás de NAT.

Por que o FTP aceita o login, mas a listagem do diretório fica bloqueada

O modo passivo do FTP falha num firewall porque o FTP usa duas conexões TCP, não uma. A conexão com a porta 21 transporta o login e os comandos. Por isso, o nome de utilizador e a palavra-passe são aceites, e o firewall parece estar configurado corretamente. A primeira ls precisa então de uma segunda conexão numa porta diferente. O firewall não permite essa conexão. Por isso, o cliente fica à espera até ocorrer um timeout.

A correção consiste em definir um intervalo fixo de portas para essas conexões de dados e criar uma regra no firewall que permita o mesmo intervalo. Um servidor atrás de NAT (network address translation) precisa de uma configuração adicional para anunciar o endereço correto. Os connection tracking helpers costumavam fazer este trabalho automaticamente. Atualmente, já não o fazem. É importante saber o motivo antes de copiar um guia antigo.

O canal de controlo e o canal de dados

O FTP (protocolo de transferência de ficheiros) está especificado na RFC 959 e é anterior tanto ao NAT como à firewall com estado. Uma sessão abre uma ligação de controlo para a porta TCP 21 e mantém-na aberta durante toda a sessão. Os comandos são enviados em texto simples. As respostas regressam com um código de três dígitos e uma linha de texto. Essa ligação nunca transporta o conteúdo dos ficheiros.

Cada elemento de dados usa a sua própria ligação TCP: uma para uma listagem de diretório (LIST), uma para cada transferência de ficheiro (RETR), e uma para cada carregamento (STOR). A ligação é aberta, usada uma vez e fechada. A autenticação ocorre inteiramente no canal de controlo, pelo que uma falha no caminho de dados apresenta sempre o mesmo sintoma: início de sessão bem-sucedido, seguido de uma espera indefinida. Se o cliente apresentar uma resposta 230 e depois parar durante a listagem, o problema está no canal de dados, não nas credenciais.

Modo ativo: o servidor liga-se de volta ao cliente

No modo ativo, o cliente escolhe uma porta, fica à escuta nessa porta e informa o servidor sobre onde se deve ligar:

PORT 192,168,1,50,195,80

Os primeiros quatro números são o endereço IP do cliente. Os dois últimos são a porta, codificada como dois bytes: 195 * 256 + 80 = 50000. Em seguida, o servidor abre a ligação de dados a partir da sua própria porta 20 para a porta 50000 no cliente.

Do ponto de vista do cliente, essa ligação é de entrada e não solicitada, pelo que a firewall do cliente a bloqueia. Se o cliente estiver atrás de um router doméstico, o endereço no comando PORT será privado e o servidor não conseguirá alcançá-lo. Foi no modo ativo que o FTP ganhou a reputação de não funcionar.

Modo passivo: o cliente abre ambas as ligações

O modo passivo inverte a ligação de dados. O cliente envia PASV e o servidor responde com um endereço e uma porta próprios:

227 Entering Passive Mode (203,0,113,10,195,80)

A codificação é a mesma, por isso o cliente liga-se a 203.0.113.10 na porta 50000. O cliente passa a abrir ambas as ligações. É por isso que o modo passivo funciona através de NAT no lado do cliente e que todos os clientes atuais o tentam primeiro.

O problema mudou de lugar, mas não desapareceu. A ligação de entrada não solicitada chega agora ao seu servidor, numa porta alta que muda a cada transferência. Essa firewall é sua, por isso o problema também é seu.

EPSV (modo passivo estendido, RFC 2428) segue a mesma ideia, mas usa uma resposta mais simples:

229 Entering Extended Passive Mode (|||50000|)

A resposta não contém um endereço. O cliente reutiliza o endereço que já tem para a ligação de controlo. É isso que permite funcionar através de IPv6 e elimina toda uma classe de erros de NAT. O manual do curl indica que o curl normalmente tenta EPSV antes de PASV. A porta continua a ser escolhida em tempo de execução, por isso EPSV não altera as regras da firewall.

Por que uma regra normal de firewall não consegue permitir o canal de dados

Isso acontece porque o número da porta ainda não existe quando a regra é escrita. O servidor escolhe a porta para cada transferência. Com os valores predefinidos, o vsftpd documenta pasv_min_port e pasv_max_port como 0, ou seja, "usar qualquer porta". Assim, a ligação de dados pode chegar em qualquer porta acima de 1023. sudo ufw allow 21/tcp permite o canal de controlo e nada mais. Essa é exatamente a configuração que produz um login funcional e uma listagem que não funciona. Se o conceito de um serviço escutar numa porta fixa ainda não estiver claro, como funcionam as portas e os sockets de escuta no Linux explica os fundamentos.

Um firewall com estado acompanha as ligações, e o kernel pode aceitar uma nova ligação como RELATED de uma ligação existente. No FTP, isso exige que algum componente leia o fluxo de controlo e extraia a porta de uma linha 227 ou PORT. Por predefinição, nada faz isso.

Por que o helper de rastreamento de ligações FTP já não é a solução

O módulo do kernel nf_conntrack_ftp é o que os guias antigos indicam. Ele lê o canal de controlo em texto simples, encontra a porta anunciada e regista uma expectativa. Assim, a ligação de dados é aceite sem nenhuma regra que especifique a porta. Quatro aspetos mudaram desde que esses guias foram escritos.

A atribuição automática de helpers está desativada. A documentação do kernel define o sysctl nf_conntrack_helper como "0 - disabled (default)" e acrescenta: "If disabled it is required to set up iptables rules to assign helpers to connections." Carregar o módulo, por si só, não produz qualquer efeito.

Nos kernels atuais, essa opção já não existe. Execute sysctl net.netfilter.nf_conntrack_helper. Uma resposta sysctl: cannot stat /proc/sys/net/netfilter/nf_conntrack_helper: No such file or directory significa que o kernel já não tem atribuição automática de helpers para ativar. Se receber um número, a opção ainda existe e o seu valor predefinido é 0.

As interfaces de configuração de firewall também deixaram de recomendar esta abordagem. O man ufw-framework no Ubuntu 24.04 diz, sobre a linha IPT_MODULES em /etc/default/ufw: "Unconditional loading of connection tracking modules (nf_conntrack_*) in this manner is deprecated", e acrescenta que as regras de helpers "must be managed in via the RULES FILES". A documentação do firewalld descreve AutomaticHelpers em firewalld.conf como "Deprecated. This option is ignored and no longer used." Associar agora um helper exige escrever manualmente uma regra explícita com o destino CT. Isso dá mais trabalho do que a correção abaixo e deixa de funcionar assim que o TLS é ativado. iptables e nftables no Ubuntu explica onde essas regras estão efetivamente definidas.

O TLS elimina o fundamento desta abordagem. Um helper funciona ao ler o canal de controlo como texto. Quando esse canal é encriptado, o helper vê texto cifrado e não consegue encontrar a porta. Não existe uma correção para isso, e não deve existir: um middlebox capaz de ler o seu canal de controlo também é capaz de ler a sua palavra-passe.

Declare um intervalo de portas passivas no servidor

Todos os servidores FTP podem ser configurados para escolher as portas passivas a partir de um intervalo definido por si. Os nomes das opções variam, por isso consulte a documentação do servidor que utiliza.

vsftpd, em /etc/vsftpd.conf:

pasv_enable=YES
pasv_min_port=30000
pasv_max_port=30099

pasv_enable já assume YES por predefinição. As duas opções de portas assumem 0 por predefinição, o comportamento "usar qualquer porta" descrito acima. Aplique com sudo systemctl restart vsftpd e confirme depois que o serviço voltou a iniciar com systemctl status vsftpd. O vsftpd recusa iniciar quando não consegue analisar uma linha de configuração, em vez de a ignorar. Se o reinício falhar, consulte journalctl -u vsftpd -n 20 para encontrar a linha 500 OOPS: que identifica a opção que acabou de introduzir.

ProFTPD, em proftpd.conf:

PassivePorts 30000 30099

A documentação do ProFTPD não define nenhum valor predefinido neste caso: sem a diretiva, o kernel escolhe a porta. A documentação também indica que, quando nenhuma porta do intervalo está livre, o servidor recorre a uma porta atribuída pelo kernel e regista uma mensagem. Um intervalo demasiado pequeno falha ocasionalmente em vez de falhar de forma clara, o que é muito mais difícil de diagnosticar. Utilize portas não privilegiadas, a partir de 1024.

O Pure-FTPd utiliza a opção -p first:last, documentada em man pure-ftpd como "Utilizar apenas portas no intervalo entre a primeira e a última, inclusive, para transferências em modo passivo", o que "torna o pure-ftpd mais compatível com filtros de pacotes". As versões empacotadas normalmente incluem essa opção num ficheiro de configuração. Consulte a documentação da sua distribuição para saber o nome do ficheiro, em vez de o tentar adivinhar.

De quantas portas precisa? De uma por cada ligação de dados ativa. Uma porta TCP fechada permanece em TIME_WAIT durante alguns minutos antes de poder ser reutilizada, por isso reserve várias vezes o pico esperado. Uma centena de portas é suficiente para alguns utilizadores. Um servidor público com muito tráfego precisa de muito mais.

Onde deve ficar o intervalo? Execute sysctl net.ipv4.ip_local_port_range primeiro. Numa instalação Ubuntu sem alterações, o resultado é 32768 60999, que corresponde às portas atribuídas pelo kernel para ligações de saída. Um intervalo passivo dentro dessa janela pode colidir com uma ligação de saída que já esteja a utilizar a porta, por isso mantenha o intervalo abaixo dela. 30000 a 30099 está disponível numa instalação predefinida. Verifique o seu próprio servidor em vez de confiar nesse valor.

Abrir o mesmo intervalo no firewall

O ufw escreve um intervalo com dois-pontos, e o manual indica que também pode ser usada uma lista ou um intervalo "para especificar várias portas; nesse caso, o protocolo é obrigatório":

sudo ufw allow 21/tcp
sudo ufw allow 30000:30099/tcp
sudo ufw status verbose

ufw status verbose deve agora listar as duas entradas. O mesmo comando sem /tcp é rejeitado com um erro que pede a indicação de tcp ou udp, porque o ufw não faz suposições. sintaxe das regras do ufw numa VPS explica o restante.

O firewalld escreve o intervalo com um hífen e precisa de um reload:

sudo firewall-cmd --permanent --add-service=ftp
sudo firewall-cmd --permanent --add-port=30000-30099/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

--add-service=ftp abre 21/tcp e solicita o helper ftp, que é o nome definido pela definição de serviço fornecida. Não abre o seu intervalo passivo. Por si só, deixa a situação exatamente como estava. zonas e serviços do firewalld numa VPS apresenta o contexto completo.

Com nftables diretamente, dentro da sua cadeia input:

tcp dport { 21, 30000-30099 } accept

Há mais um firewall a considerar: a maioria dos fornecedores executa um firewall de rede no painel de controlo, fora do sistema operativo. Se as regras no servidor parecerem corretas e os pacotes continuarem sem chegar, abra também o mesmo intervalo nesse firewall.

Informe o servidor do seu endereço público quando estiver atrás de NAT

Execute ip -4 addr show no servidor. Se o endereço da interface for aquele ao qual os clientes se ligam, ignore esta secção. Se a interface tiver um endereço privado (10.x, 172.16 a 172.31.x, 192.168.x) e a plataforma mapear um endereço público para esse endereço, o servidor não conhece o próprio endereço público. A documentação do vsftpd define o valor predefinido de pasv_address como "o endereço é obtido do socket ligado de entrada", portanto a resposta 227 contém o endereço privado e o cliente é enviado para um endereço que não consegue alcançar.

O FileZilla identifica este caso exatamente assim:

Server sent passive reply with unroutable address. Using server address instead.

O FileZilla corrige o problema e prossegue. Muitos outros clientes não o fazem. Tentam ligar-se a 10.0.0.5 e ficam bloqueados.

O curl também oculta o problema, o que é relevante se o curl for a sua ferramenta de teste. O manual indica que --ftp-skip-pasv-ip "está ativado por predefinição (adicionado na versão 7.74.0)", portanto o curl ignora o endereço na resposta 227 e reutiliza o endereço da ligação de controlo. Uma transferência que funciona com o curl pode continuar a falhar num cliente gráfico por este único motivo.

Defina o endereço explicitamente. O vsftpd aceita pasv_address=203.0.113.10, além de pasv_addr_resolve=YES (predefinição NO), se preferir escrever um nome de anfitrião. O ProFTPD aceita MasqueradeAddress, que pode receber um endereço, um nome DNS ou um nome de interface. O Pure-FTPd aceita -P, documentado para o caso em que "o servidor está atrás de um dispositivo de mascaramento (NAT)". EPSV evita todo o problema porque a respetiva resposta não tem um campo de endereço, mas não pode depender disso, porque é o cliente que decide qual comando enviar.

O que muda com TLS

FTPS é FTP sobre TLS (segurança da camada de transporte). O cliente liga-se à porta 21 como habitualmente, envia AUTH TLS para proteger o canal de controlo e, em seguida, envia PROT P para encriptar também o canal de dados. O FTP simples envia a palavra-passe pela rede como texto legível. Por isso, se tiver de manter o FTP, use FTPS. O vsftpd é distribuído com ssl_enable definido como NO por predefinição.

Daqui resultam duas consequências. Nenhum auxiliar de controlo de ligações pode funcionar. Este é o ponto anterior visto pelo lado oposto. Além disso, sudo tcpdump -nAi any 'tcp port 21' já não mostra a resposta 227. Quando precisar de saber que endereço e porta o servidor anunciou, consulte o log do próprio servidor em vez do tráfego da rede.

Testar a alteração a partir do exterior

Execute estes comandos noutra máquina. Testar a partir do próprio servidor ignora a firewall que está a tentar corrigir.

sudo ss -ltnp | grep :21
curl -v --disable-epsv --user ftpuser:secret ftp://example.com/
nc -vz example.com 30000

ss deve mostrar o daemon FTP a escutar na porta 21. Nenhum processo escuta no intervalo passivo enquanto o servidor está inativo, porque esses sockets são criados para uma transferência e fechados depois dela.

--disable-epsv força o curl a usar o caminho PASV, que é o que expõe o problema do endereço. O trace mostra a resposta do servidor e, em seguida, o endereço e a porta para os quais o curl estabelece a ligação:

< 227 Entering Passive Mode (203,0,113,10,117,52)

117 * 256 + 52 = 30004, dentro do intervalo declarado. Um endereço privado nessa linha significa que pasv_address não está definido. Uma porta fora do seu intervalo significa que o servidor nunca leu a alteração de configuração. Verifique se editou o ficheiro utilizado pelo serviço em execução.

nc responde por si só à questão da firewall. Um Connection refused imediato significa que o pacote chegou ao servidor e não encontrou nada a escutar, que é o resultado correto para uma porta passiva inativa: a regra funciona. Uma espera até nc desistir significa que algo descartou o pacote silenciosamente. Trata-se de uma firewall, seja a do servidor, seja a do painel do seu fornecedor. Essa distinção é a mesma descrita em recusada versus tempo esgotado no SSH e aplica-se a todas as portas.

Ainda deve usar FTP?

Para trabalho novo, não. O SFTP (protocolo de transferência de ficheiros por SSH) funciona dentro de uma única ligação SSH na porta 22. Não existe um segundo canal, um intervalo passivo, uma configuração de NAT ou um daemon adicional para proteger, porque o OpenSSH já fornece essa funcionalidade. sftp user@example.com funciona num sistema onde nunca configurou um serviço de transferência de ficheiros. Para fornecer ficheiros a alguém e nada mais, sshd_config usa ForceCommand internal-sftp juntamente com ChrootDirectory. Esse diretório deve pertencer a root e não pode ser gravável pelo utilizador, caso contrário o sshd recusa a sessão e regista uma linha bad ownership or modes for chroot directory.

O FTP continua a ser útil quando a outra parte não pode mudar. Scanners e impressoras multifunções vêm com firmware que fala FTP e nada mais. Equipamento laboratorial e industrial usa frequentemente uma imagem fixa que ninguém irá recertificar. Parceiros comerciais disponibilizam um destino FTPS e não irão adicionar um protocolo para um único fornecedor. Em cada um desses casos, o intervalo passivo e a regra de firewall correspondente são todo o trabalho necessário, e FTPS, não FTP simples, é a versão a utilizar. O desenho com dois canais é uma decisão de 1985 que agora funciona num mundo que nunca foi previsto para ele, uma história abordada em a história dos protocolos de transferência de ficheiros.

FAQ

Porque é que o FTP inicia sessão, mas a listagem do diretório fica bloqueada?

O início de sessão usa apenas a ligação de controlo na porta 21, que a firewall permite. A listagem do diretório precisa de uma segunda ligação TCP noutra porta, e essa ligação está bloqueada. Declare um intervalo de portas passivas no servidor FTP e abra o mesmo intervalo na firewall. A listagem será concluída. Uma listagem bloqueada é um problema do canal de dados, nunca um problema da palavra-passe.

Que portas tenho de abrir para o modo passivo do FTP?

A porta 21 para o canal de controlo, além do intervalo que configurou para as ligações de dados passivas. Não existe um intervalo padrão, porque é você que o escolhe. Um intervalo como 30000 a 30099 funciona: dimensione-o de acordo com o número máximo de transferências simultâneas e mantenha-o fora do intervalo de portas de saída do kernel, que pode consultar com sysctl net.ipv4.ip_local_port_range. Se o seu fornecedor disponibilizar uma firewall de rede no painel de controlo, abra também o mesmo intervalo nesse local.

Ainda preciso de nf_conntrack_ftp?

Não. Num kernel atual, também não pode depender desse módulo. A atribuição automática de helpers está desativada por predefinição. Nos kernels recentes, a opção net.netfilter.nf_conntrack_helper foi removida, pelo que sysctl indica que o ficheiro não existe. O manual do ufw considera obsoleto o carregamento incondicional desses módulos, e o firewalld ignora AutomaticHelpers completamente. Um helper também tem de ler o canal de controlo como texto simples. Por isso, deixa de funcionar assim que ativa FTPS. Declare um intervalo de portas passivas.

Porque é que o meu cliente FTP indica que a resposta passiva contém um endereço não encaminhável?

O servidor respondeu a PASV com o endereço que vê na sua própria interface, e esse endereço é privado. Isto acontece quando a plataforma associa um endereço público a um endereço privado. Defina explicitamente o endereço público: pasv_address no vsftpd, MasqueradeAddress no ProFTPD ou -P no Pure-FTPd. O FileZilla contorna o problema reutilizando o endereço ao qual já se ligou e regista "Using server address instead". É por isso que alguns clientes continuam a funcionar apesar da configuração incorreta, enquanto outros ficam bloqueados.

Devo usar FTPS ou SFTP?

Use SFTP quando controla as duas extremidades: existe uma única ligação SSH na porta 22, não há nenhum canal de dados adicional para abrir e o serviço já está em execução. FTPS é FTP sobre TLS. Por isso, mantém o modelo de dois canais e todos os problemas de firewall associados. Escolha FTPS quando a outra extremidade não aceitar mais nenhum protocolo. Não use FTP simples através da internet, porque a palavra-passe atravessa a rede como texto legível.