História do SSH: do telnet ao OpenSSH
Descubra como o ataque de 1995 em Helsínquia levou ao SSH, com a linha do tempo verificada de telnet e rlogin até ao OpenSSH e aos padrões pós-quânticos.
Onde começa a história do SSH
A história do SSH começa com palavras-passe roubadas. Antes de 1995, iniciar sessão numa máquina Unix remota significava usar telnet ou rlogin, e ambos enviavam a palavra-passe pela rede como texto legível. Qualquer pessoa que conseguisse monitorizar o tráfego podia lê-la. No início da década de 1990, isso já acontecia em grande escala.
O SSH foi a resposta de uma pessoa a esse problema. Foi escrito em 1995 e disponibilizado gratuitamente. Desde então, o protocolo foi reconstruído uma vez, e o programa que quase toda a gente utiliza atualmente é um fork de outro fork. As datas abaixo são importantes, porque cada etapa foi uma resposta a uma falha específica.
O que o telnet e o rlogin realmente enviavam
O Telnet é definido na RFC 854, publicada em maio de 1983 por Jon Postel e Joyce Reynolds. O documento descreve uma sessão de terminal transportada por TCP e não inclui qualquer tipo de encriptação. Cada byte que escreve, incluindo a palavra-passe, é transmitido como bytes em texto simples que qualquer dispositivo no caminho pode ler.
O rlogin surgiu no Berkeley Unix e foi documentado mais tarde na RFC 1282 (BSD Rlogin, B. Kantor, dezembro de 1991). Acrescentou algo pior do que uma palavra-passe legível: confiança baseada no host. Era possível configurar um servidor para aceitar logins de um host identificado pelo nome sem exigir qualquer palavra-passe. A RFC inclui uma secção chamada "A Cautionary Tale" que afirma: "Bypassing password authentication from trusted hosts opens ALL the systems so configured when just one is compromised." Também observa que a confiança é baseada nos nomes dos hosts. Por isso, o comprometimento do DNS (domain name system) ou um endereço falsificado consegue contornar esse mecanismo.
Ambos os projetos eram adequados à rede em que foram criados. A Ethernet inicial era um meio partilhado: todas as máquinas de um segmento recebiam todas as tramas e deviam ignorar as que não lhes eram destinadas. Uma máquina que deixasse de as ignorar, que é o significado de modo promíscuo, via o tráfego das outras máquinas. Junte-se uma universidade que fornecia contas shell a milhares de estudantes, e uma única conta comprometida podia tornar-se num coletor de palavras-passe de todo um departamento.
O comunicado de 1994 que não veio com uma correção
Em 3 February 1994, a CERT publicou o comunicado CA-94:01, "Ongoing Network Monitoring Attacks". O comunicado informou que intrusos tinham capturado informações de acesso de dezenas de milhares de sistemas em toda a Internet. A ferramenta utilizada colocava a interface de rede em modo promíscuo e registava o início de cada nova sessão telnet, rlogin e FTP. Essa parte contém o nome de utilizador e a palavra-passe.
A CERT recomendou que os sites alterassem a palavra-passe de todas as contas acessíveis pela rede. Quando essa recomendação é analisada à luz dos protocolos, o problema fica claro: a nova palavra-passe atravessa a mesma rede em texto simples na primeira vez que é utilizada. Não existia uma correção dentro do telnet ou do rlogin, porque nenhum dos dois protocolos tinha um mecanismo onde a pudesse aplicar.
Por que um ataque de captura de tráfego em Helsínquia deu origem ao SSH
Em 1995, a rede da Universidade de Tecnologia de Helsínquia foi atingida por um ataque de captura de palavras-passe do tipo descrito pelo CERT. Tatu Ylönen, investigador da universidade, escreveu uma substituição e disponibilizou-a como freeware em julho de 1995. Chamou-lhe Secure Shell.
Dois princípios de conceção foram fundamentais. A sessão era cifrada, por isso um intruso que monitorizasse o segmento não obtinha informações úteis. O servidor também provava a sua identidade com uma chave, permitindo ao cliente confirmar se tinha contactado a máquina correta. Essa era a vulnerabilidade que a confiança no nome do host do rlogin deixava aberta.
A adoção também aumentou porque os comandos correspondiam aos que os utilizadores já introduziam. ssh substituía rsh e rlogin, enquanto scp substituía rcp. A mudança exigia adaptar um hábito, não alterar um fluxo de trabalho. No final de 1995, a base de utilizadores tinha atingido aproximadamente 20,000 utilizadores em cinquenta países. Em dezembro desse ano, Ylönen fundou a SSH Communications Security para desenvolver e comercializar o software.
De uma versão gratuita a um produto comercial
À medida que o SSH se tornou um negócio, a licença do código-fonte mudou. As versões posteriores passaram a incluir termos que limitavam o que outras pessoas podiam fazer com o código, e a última versão que qualquer pessoa podia reutilizar livremente foi a ssh 1.2.12. Não havia nada de inadequado nisso. Isso significava apenas que a versão do SSH sobre a qual o resto do mundo podia trabalhar deixou de evoluir, enquanto o desenvolvimento continuava num local que esse mundo não podia acompanhar. As licenças determinam que código sobrevive, um padrão sobre o qual vale a pena ler em como o licenciamento de código aberto moldou a infraestrutura moderna.
Por que o OpenBSD criou um fork do OpenSSH em 1999
No início de 1999, Björn Grönvall voltou à última versão livre e começou a corrigir os erros nela existentes. A versão dele chamava-se OSSH e falava apenas o protocolo SSH 1.3.
O projeto OpenBSD adotou o OSSH e reescreveu-o. Segundo o próprio projeto, Theo de Raadt, Niels Provos, Markus Friedl, Bob Beck, Aaron Campbell e Dug Song fizeram o trabalho de limpar, auditar e ampliar o código. O resultado foi o OpenSSH 1.2.2, incluído no OpenBSD 2.6 em 1 December 1999.
Por que um fork criado por um pequeno projeto de sistema operativo acabou presente em quase todas as máquinas? Por causa do que o OpenBSD precisava dele. O OpenBSD disponibiliza um sistema base auditado, concebido para ser seguro na configuração predefinida. Por isso, o acesso remoto encriptado tinha de fazer parte desse sistema base, sob uma licença sem restrições. Código auditado sob uma licença sem restrições era precisamente o que todos os outros fornecedores de sistemas operativos também queriam. Damien Miller, Philip Hands e outros começaram quase imediatamente um ramo portátil. É daí que vem o p numa versão como 10.5p1. O OpenBSD desenvolve a versão limpa, e o ramo portátil acrescenta a integração necessária para os restantes sistemas. A forma como o Unix se dividiu nos sistemas que usamos atualmente explica por que essa integração é necessária.
O suporte para a segunda versão do protocolo veio depois. O OpenSSH 2.0 foi incluído no OpenBSD 2.7 em 15 June 2000.
Por que SSH-2 é um protocolo novo, e não apenas um aumento de versão
O SSH-1 protegia a integridade do fluxo cifrado com CRC-32, uma soma de verificação concebida para detetar erros de transmissão, não para resistir a um atacante. Em 1998, Ariel Futoransky e Emiliano Kargieman, da CORE SDI, demonstraram as consequências. Com os modos de cifra CBC ou CFB e uma verificação CRC-32, um atacante que conheça apenas 16 bytes do texto simples pode inserir texto cifrado à sua escolha que o recetor aceita como legítimo. Isto permite executar comandos no servidor.
A falha estava no protocolo, por isso não podia ser corrigida sem quebrar a compatibilidade. Em vez disso, as implementações incluíram um detetor no ficheiro chamado deattack.c, que tentava reconhecer o ataque enquanto este ocorria. Em fevereiro de 2001, descobriu-se que o detetor também continha um integer overflow, CVE-2001-0144, que permitia a execução remota de código contra servidores e clientes que tinham a correção instalada. Um design que não pode ser reparado acumula patches, e os patches trazem os seus próprios bugs.
O SSH-2 foi definido num grupo de trabalho do IETF chamado secsh e publicado como RFCs em janeiro de 2006: a arquitetura no RFC 4251, a camada de transporte no RFC 4253, a autenticação de utilizadores no RFC 4252 e a camada de ligação no RFC 4254. A divisão em camadas é a parte importante, porque cada camada pode ser substituída de forma independente. Grande parte do restante desta história consiste nessa substituição.
Destacam-se duas alterações. A integridade passou de CRC-32 para um HMAC (código de autenticação de mensagens baseado em hash) protegido por uma chave derivada de um segredo partilhado. Assim, um atacante que não consiga calcular o MAC não pode falsificar um pacote. A negociação de chaves também passou para Diffie-Hellman. No SSH-1, o cliente escolhia a chave da sessão e enviava-a cifrada com as chaves RSA do servidor. Assim, qualquer pessoa que obtivesse posteriormente essas chaves privadas podia decifrar uma sessão gravada. O Diffie-Hellman deriva um segredo novo para cada sessão. Esse segredo nunca é transmitido. Por isso, gravar o tráfego agora e obter a chave do host mais tarde não revela nada. Esta propriedade chama-se forward secrecy.
O SSH-2 não tem compatibilidade ao nível do protocolo com o SSH-1. Por isso, o número mudou, em vez de apenas mudar a parte decimal.
Por que o SSH-1 foi removido em vez de corrigido
A remoção ocorreu em três versões do OpenSSH. A versão 7.0, em 11 August 2015, desativou o protocolo 1 por padrão no momento da compilação. A versão 7.4, em 19 December 2016, removeu o suporte do servidor. A versão 7.6, em 3 October 2017, também eliminou o lado cliente, juntamente com as respetivas opções de configuração e documentação.
Manter o protocolo como opção para equipamento antigo teria sido a escolha mais conveniente, mas o detetor de CRC-32 explica por que essa opção foi recusada. O overflow só era alcançável porque o código do protocolo 1 estava incluído na compilação e encontrava-se num caminho que a maioria dos administradores considerava inativo nos seus sistemas. Código incluído numa versão pode ser alcançado. Código eliminado não pode.
Por que a primeira ligação SSH avisa sobre a chave do host
A encriptação garante que o tráfego é privado. Não garante quem está na outra extremidade. Se um atacante se posicionar no caminho e responder em vez do seu servidor, terá uma sessão perfeitamente encriptada com o atacante. Isto é um ataque machine-in-the-middle. O SSH resolve este problema com uma chave de host: o servidor prova que possui a parte privada de um par de chaves, e o cliente compara essa chave com a que registou anteriormente. Se quiser conhecer o funcionamento da própria ligação, consulte o que acontece quando abre uma ligação SSH.
Na primeira ligação não existe uma ligação anterior. Por isso, o cliente não tem nada para comparar e tem de lhe perguntar:
The authenticity of host 'vps.example.com (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:BQ0Qs2jVXhH2lPZ2rM0aQ0mQ8f9pQ0m3nH0oQ1bYqkE.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?Responder yes armazena essa chave em ~/.ssh/known_hosts. Em todas as ligações seguintes, o cliente compara a chave com o valor armazenado. Se houver uma diferença, é apresentada a mensagem mais grave que o programa tem:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!A interpretação correta desse primeiro aviso é que o protocolo está a admitir o seu único momento fraco. A confiança na primeira utilização significa que a primeira ligação só é tão segura quanto a rede através da qual foi feita. É possível eliminar essa lacuna. Leia a impressão digital na consola do seu fornecedor ou no log de compilação do servidor antes de estabelecer a ligação. Publique-a no DNS como um registo SSHFP (RFC 4255), mas isto só é útil se utilizar DNSSEC. Outra opção é assinar as chaves de host com a sua própria autoridade certificadora (CA), para que os clientes confiem na CA e não em cada chave individual. Na prática, a maioria das pessoas aceita o aviso sem o verificar. É importante reconhecer isso.
Como as chaves públicas substituíram as palavras-passe
A autenticação por chave pública existe desde as primeiras versões do SSH, mas demorou anos até se tornar o procedimento normal. O mecanismo é assimétrico: o cliente prova que possui uma chave privada ao assinar um desafio, e a chave privada nunca sai do cliente. Uma palavra-passe funciona ao contrário. Embora o SSH a transporte dentro do canal cifrado, o servidor recebe o segredo real. Por isso, um servidor comprometido ou hostil acaba por guardar algo que pode reutilizar contra si noutros locais.
A segunda razão é aritmética. Qualquer servidor com a porta 22 aberta num endereço público recebe tentativas de início de sessão automatizadas continuamente, e uma palavra-passe é uma sequência que pode ser adivinhada. Uma chave não pode ser adivinhada na prática. Definir PasswordAuthentication no elimina toda essa categoria de ataques, razão pela qual aparece em todas as listas de verificação de hardening. Também remove o recurso de fallback que antes permitia recuperar quando uma chave falhava. Por isso, aprenda a distinguir os vários erros que apresentam todos Permission denied (publickey) antes de ser você a ficar sem acesso. Viver sem palavras-passe também significa acumular chaves, e um agente que tenha uma dúzia delas oferece cada uma pela ordem até o servidor atingir o limite de tentativas e terminar a ligação. Esse é o motivo pelo qual um início de sessão pode falhar com Too many authentication failures mesmo quando a chave correta está carregada. A geração e a rotação de chaves são abordadas em Noções básicas sobre a gestão de chaves SSH, e as definições do lado do servidor em hardening do SSH num VPS.
Por que a lista de algoritmos SSH continua a mudar
Um protocolo em camadas permite retirar algoritmos sem criar um protocolo novo. O OpenSSH tem usado essa liberdade de forma consistente, e as datas das versões mostram o ritmo.
O Ed25519 chegou ao OpenSSH 6.5 em 30 January 2014, juntamente com a cifra chacha20-poly1305 e um formato de chave privada protegido por bcrypt. As assinaturas Ed25519 derivam deterministicamente o nonce de cada assinatura, pelo que um gerador de números aleatórios fraco no momento da assinatura não consegue expor a chave privada. Foi exatamente assim que chaves privadas DSA e ECDSA foram recuperadas em incidentes reais.
O DSA seguiu o caminho oposto. O OpenSSH 7.0 desativou ssh-dss chaves de host e de utilizador em tempo de execução em 2015, porque o algoritmo está limitado a uma chave privada de 160 bits e ao SHA-1. A versão 9.8, em 1 July 2024, desativou o DSA em tempo de compilação. A versão 10.0, em 9 April 2025, removeu-o, nas palavras do projeto, "completando o processo de descontinuação iniciado em 2015". Dez anos entre a desativação e a remoção.
O RSA não desapareceu, mas o seu formato de assinatura antigo desapareceu. O OpenSSH 8.8, em 26 September 2021, deixou de aceitar por predefinição assinaturas RSA feitas com SHA-1. As notas da versão indicam claramente o motivo: o SHA-1 está quebrado do ponto de vista criptográfico, e era possível obter colisões de prefixo escolhido por menos de USD 50,000. Se alguma vez encontrou sign_and_send_pubkey: no mutual signature supported ao ligar-se a um servidor antigo, esta é a alteração em causa. A sua chave está correta. O algoritmo de assinatura solicitado pelo outro lado é que não está.
O mesmo processo está agora a ocorrer com a troca de chaves, desta vez antes de a ameaça existir. O tráfego capturado hoje pode ser armazenado e desencriptado anos mais tarde por quem obtiver primeiro um computador quântico capaz, pelo que o acordo de chaves teve de mudar antes de existir uma máquina desse tipo. O OpenSSH 9.0, em 8 April 2022, tornou uma troca de chaves híbrida a predefinição: sntrup761x25519-sha512@openssh.com combina um algoritmo pós-quântico com a troca X25519, pelo que o resultado não é mais fraco do que a parte clássica se o novo algoritmo não cumprir o esperado. O OpenSSH 9.9, em 19 September 2024, adicionou mlkem768x25519-sha256, baseado no ML-KEM (module lattice key encapsulation mechanism), normalizado pelo NIST em 2024. O OpenSSH 10.0 tornou-o a predefinição para o acordo de chaves, e a página pós-quântica do projeto explica o motivo. O OpenSSH 10.1, em 6 October 2025, começou a emitir um aviso quando o outro lado não o suporta:
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded.Esse aviso está ativo por predefinição e é controlado pela opção WarnWeakCrypto em ssh_config. O significado prático desse aviso e o que fazer com um servidor que o ativa são explicados em as predefinições pós-quânticas da troca de chaves SSH.
O que este histórico significa para o servidor à sua frente
O comando que você digita mudou muito pouco desde 1995. Quase tudo o que existe por baixo dele foi substituído: a verificação de integridade, a troca de chaves, os algoritmos de assinatura e a própria base de código. Isso só foi possível porque cada substituição terminava com uma remoção deliberada, e cada remoção fazia algo deixar de funcionar para alguém.
Por isso, a segurança do seu SSH é determinada principalmente pela versão. Os padrões incorporam as decisões sobre quais algoritmos são oferecidos, quais são recusados e quais avisos são exibidos. Um servidor antigo continua oferecendo tudo o que a sua versão ainda permitia e continuará negociando uma versão inferior para atender a um cliente antigo. Em agosto de 2026, a versão atual é o OpenSSH 10.5, publicado em 11 de agosto de 2026. A distância entre essa versão e a versão instalada em uma máquina que ninguém atualiza há três anos indica a dimensão do problema. Verificar isso faz parte dos dez primeiros minutos em um novo VPS.
FAQ
Quem criou o SSH e porquê?
Tatu Ylönen, investigador da Helsinki University of Technology, escreveu o SSH em 1995, depois de um ataque de captura de palavras-passe na rede da universidade. As ferramentas de início de sessão remoto da época, telnet e rlogin, enviavam as palavras-passe pela rede como texto legível. Por isso, qualquer pessoa que monitorizasse um segmento partilhado recolhia as credenciais à medida que passavam. Ele lançou o programa como freeware em julho de 1995. No final desse ano, o programa tinha aproximadamente 20,000 utilizadores em cinquenta países. Em dezembro de 1995, fundou a SSH Communications Security.
Qual é a diferença entre SSH-1 e SSH-2?
São protocolos diferentes, sem compatibilidade ao nível do formato transmitido. O SSH-1 era um protocolo monolítico que usava CRC-32 para garantir a integridade. O cliente enviava uma chave de sessão cifrada com as chaves RSA do servidor. O SSH-2 separa o trabalho em camadas de transporte, autenticação e ligação (RFCs 4251 a 4254, janeiro de 2006). Usa um HMAC para garantir a integridade e deriva as chaves de sessão com Diffie-Hellman. Assim, o tráfego capturado continua privado mesmo que a chave do host seja roubada posteriormente. O SSH-1 foi removido do OpenSSH por fases. O processo terminou na versão 7.6, em outubro de 2017.
Por que motivo o OpenSSH substituiu a implementação original do SSH?
O desenvolvimento da implementação original passou para um produto comercial com uma licença restritiva. A última versão que podia ser reutilizada livremente foi a ssh 1.2.12. No início de 1999, Björn Grönvall recuperou essa versão como OSSH. A equipa do OpenBSD criou um fork do OSSH chamado OpenSSH, que foi incluído no OpenBSD 2.6 em 1 de dezembro de 1999. O OpenBSD precisava de código auditado com uma licença sem restrições para o seu sistema base. Essas duas características permitiram que todos os outros sistemas operativos distribuíssem a mesma implementação através da variante portable.
Por que motivo o SSH pergunta pela chave do host na primeira ligação?
Porque o cliente nunca viu esse servidor antes e não tem nenhuma chave com a qual possa comparar a chave recebida. A cifragem, por si só, não distingue um servidor legítimo de uma máquina colocada no caminho da ligação. Por isso, o SSH identifica os servidores pela chave e regista o que recebeu em ~/.ssh/known_hosts. Na primeira ligação, não existe um valor armazenado para comparar. É por isso que o cliente pergunta ao utilizador. Compare a impressão digital com uma obtida na consola do fornecedor ou no próprio servidor. Trate qualquer mensagem posterior REMOTE HOST IDENTIFICATION HAS CHANGED como um evento real até conseguir explicá-la.
Por que motivo chaves SSH antigas deixam de funcionar depois de uma atualização?
Porque o OpenSSH descontinua algoritmos segundo um calendário publicado. As chaves DSA (ssh-dss) foram desativadas por predefinição no OpenSSH 7.0, em 2015, e removidas definitivamente no OpenSSH 10.0, em 9 de abril de 2025. As chaves RSA continuam a funcionar. No entanto, as assinaturas feitas com SHA-1 foram desativadas por predefinição no OpenSSH 8.8, em setembro de 2021. Ao ligar-se a um servidor antigo, isto aparece como sign_and_send_pubkey: no mutual signature supported. Uma chave Ed25519, disponível desde o OpenSSH 6.5, em janeiro de 2014, evita ambos os problemas.