Linux e ferramentas de desenvolvimento
Bash básico para trabalho de segurança
Aprenda pipes, redirecionamento, variáveis, laços, códigos de saída e set -euo pipefail, e use isso para contar logins falhos e gerar hashes.
Como funcionam as chaves SSH de host e de usuário, por que Ed25519 com senha de proteção é o padrão e como proteger o login em uma VM de laboratório.
SSH (Secure Shell) é o protocolo que a maioria das pessoas usa para entrar em servidores Linux, máquinas virtuais de laboratório e hospedagens de Git. Ele abre um shell sobre um canal criptografado, e o mesmo canal pode copiar arquivos ou fazer encaminhamento de portas. Ele tem três funções. Criptografa o tráfego para que ninguém no caminho da rede consiga ler. Prova ao servidor quem você é. Prova a você quem é o servidor.
As chaves fazem a segunda função sem mandar uma senha pela rede. Uma senha pode ser adivinhada ou roubada por phishing. Um par de chaves funciona de outro jeito. O servidor guarda só a metade pública. Para entrar, o seu cliente assina um desafio com a metade privada, e o servidor confere a assinatura. A chave privada nunca sai da sua máquina.
O SSH não protege você em alguns casos, e eles importam tanto quanto o protocolo. Se o seu próprio computador estiver comprometido, um malware rodando com o seu usuário pode ler o arquivo da chave privada ou pedir ao agente que assine coisas por você. Se a chave privada for roubada e a senha dela for fraca, o atacante pode tentar adivinhá-la offline. Se você aceitar a identidade de um servidor sem conferir, pode estar falando com alguém que não é o servidor.
O SSH usa dois tipos diferentes de chave, e as pessoas costumam confundi-los.
Chaves de host identificam o servidor. Cada servidor SSH tem uma ou mais, normalmente guardadas em /etc/ssh/ssh_host_*_key. A parte privada fica no servidor. A parte pública é apresentada a todo cliente que se conecta. Na primeira vez que o seu cliente a vê, ele salva a chave em known_hosts. Nas conexões seguintes, uma chave de host diferente dispara um aviso.
Chaves de usuário identificam você. Você gera o par na sua própria máquina. A chave privada fica com você. A chave pública vai para o servidor, em ~/.ssh/authorized_keys da conta que você quer usar.
A diferença tem consequências práticas. Copiar a sua chave privada para um servidor entrega a esse servidor, e a quem puder lê-la, o material necessário para agir como você em todo lugar onde a chave é confiável. Ignorar um aviso de chave de host significa que você pode enviar sua senha ou seus comandos a um impostor.
O OpenSSH suporta vários tipos de chave. RSA ainda funciona, mas chaves RSA novas devem ter pelo menos 3072 bits, e as linhas de chave pública ficam longas. Chaves Ed25519 são curtas, rápidas de verificar e padronizadas para SSH na RFC 8709. O OpenSSH 9.5 e as versões seguintes já usam Ed25519 como padrão no ssh-keygen. Para uma chave de laboratório, Ed25519 é a escolha certa, a menos que um sistema que você precisa acessar aceite só um tipo mais antigo.
A senha de proteção (passphrase) criptografa o arquivo da chave privada no disco. Sem ela, quem copiar o arquivo pode usar a chave. Com ela, o atacante precisa do arquivo e da senha. Isso protege contra os acidentes mais comuns: um backup enviado para o lugar errado, uma chave deixada em pasta compartilhada, um arquivo sincronizado por engano com a nuvem. A senha não ajuda depois que a chave é carregada em um agente e um malware roda como você. Use uma senha longa, guarde-a em um gerenciador de senhas e mantenha uma cópia do arquivo da chave em um lugar seguro.
A RFC 4253 descreve a camada de transporte. Em linhas gerais, uma conexão passa por estas etapas:
known_hosts. Se o host for novo, o cliente mostra a impressão digital e pede que você a confirme.authorized_keys, envia um desafio. Seu cliente assina o desafio com a chave privada, e o servidor confere a assinatura.Repare de onde vem a confiança. A etapa 3 trata do servidor. A etapa 4 trata de você. Se você pular a conferência da impressão digital na etapa 3, o restante do processo continua funcionando para quem atendeu a chamada.
Uma impressão digital é um hash curto de uma chave pública. O OpenSSH mostra impressões SHA256 por padrão. Duas pessoas podem comparar a impressão digital para confirmar que têm a mesma chave pública, sem ler a chave inteira em voz alta.
Os comandos abaixo foram executados em um Windows 11 com OpenSSH 9.9p2 (ssh -V), no Git Bash. A chave era uma cópia de teste criada só para esta observação, com senha vazia, para que a saída pudesse ser mostrada aqui. A sua chave real terá outra impressão digital.
ssh-keygen -t ed25519 -C 'lab-key' -f ./lab_ed25519 -N ''
ssh-keygen -lf ./lab_ed25519.pubSaída observada:
256 SHA256:2BAyZTrHADdiG1FNwfCwb/fC5vSVZPwfGnZjRaaExc4 lab-key (ED25519)ssh-keygen -lvf mostra a mesma impressão digital com uma figura aleatória. A figura ajuda a notar uma mudança, mas o texto da impressão digital é o que você compara.
Você precisa de uma máquina virtual ou instância na nuvem que seja sua e que você controle, com um servidor OpenSSH rodando e uma conta que possa usar sudo. Uma VM local no VirtualBox ou no Hyper-V serve. Uma instância pequena na nuvem que você paga e pode apagar também serve. Não execute estes passos em uma máquina que pertença a outra pessoa.
ssh-keygen -t ed25519 -C 'lab-key' -f ~/.ssh/lab_ed25519Quando pedido, digite uma senha de proteção longa. O comando cria dois arquivos: lab_ed25519 (privada) e lab_ed25519.pub (pública). Só o arquivo .pub deve sair da sua máquina.
ssh-keygen -lf ~/.ssh/lab_ed25519.pubAnote esta impressão digital, ou pelo menos os primeiros caracteres. Você vai compará-la depois.
chmod 600 ~/.ssh/lab_ed25519No Linux e no macOS, o ssh recusa uma chave privada que outros usuários conseguem ler. No Windows, o OpenSSH confere as ACLs do arquivo, e não os bits de modo do Unix. Nesta máquina Windows, o chmod 600 rodou sem erro, mas o ls -l continuou mostrando -rw-r--r-- depois. Não presuma que os bits de modo mudaram ali. Se o ssh reclamar de permissões no Windows, inspecione o arquivo com icacls e remova o acesso de outras contas.
ssh-copy-id -i ~/.ssh/lab_ed25519.pub seuusuario@sua-vm-de-laboratorioEsta é a única vez em que você digita a senha da conta de propósito. O comando acrescenta a chave pública em ~/.ssh/authorized_keys na VM.
A primeira conexão com a VM também mostra uma impressão digital da chave de host. Compare-a com a real. Na VM, rode:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubSe as duas impressões digitais baterem, digite yes. Se não baterem, pare. Descubra o motivo antes de continuar. A diferença pode significar que você reinstalou a VM, ou que alguém está no meio do caminho entre você e ela.
Este passo não foi executado aqui, porque nenhuma VM estava disponível nesta máquina. Por isso os comandos dos passos 4 a 6 aparecem sem saída. Você pode conferir cada um na sua VM.
ssh -i ~/.ssh/lab_ed25519 seuusuario@sua-vm-de-laboratorioO cliente pede a senha de proteção da chave, e não a senha da conta. Se aparecer um shell, a chave funciona. Mantenha esta sessão aberta para o próximo passo.
Na VM:
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sshd -t && sudo systemctl restart sshA linha do sed substitui a linha PasswordAuthentication, esteja ela comentada ou não. O sshd -t confere a sintaxe da configuração e interrompe a sequência se houver erro. O systemctl restart ssh aplica a mudança. No Fedora e em outras distribuições da família RHEL, o serviço se chama sshd, então use esse nome.
Três problemas são comuns aqui:
/etc/ssh/sshd_config inclui arquivos de /etc/ssh/sshd_config.d/, e vale o primeiro valor lido para cada palavra-chave. Confira o valor que o sshd realmente usa:sudo sshd -T | grep -i '^passwordauthentication'Depois da mudança, a saída deve ser passwordauthentication no. Se ainda disser yes, encontre o arquivo que define o valor e corrija ali.
sed só edita uma linha que já existe. Se não houver linha PasswordAuthentication, vale o padrão, e a página de manual do sshd_config(5) diz que o padrão é yes. Acrescente a linha você mesmo:echo 'PasswordAuthentication no' | sudo tee -a /etc/ssh/sshd_configDepois, teste da sua máquina se o login por senha é recusado:
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password seuusuario@sua-vm-de-laboratorioA conexão deve falhar com uma mensagem de permissão negada. Faça essa conferência você mesmo, na VM que você controla. Ela não foi executada nesta máquina.
Digitar a senha de proteção em cada conexão cansa. O ssh-agent mantém a chave já descriptografada na memória durante a sua sessão, então você digita a senha uma vez.
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/lab_ed25519
ssh-add -lO ssh-add -l lista as impressões digitais que o agente tem carregadas. Nesta máquina Windows, o ssh-add -l rodou sem um agente ativo e mostrou Could not open a connection to your authentication agent., com código de saída 2. No Windows, isso é feito pelo serviço OpenSSH Authentication Agent. Inicie esse serviço pelo console de Serviços ou por um PowerShell como administrador. É uma mudança no seu sistema, então faça você mesmo e só se quiser o agente rodando.
O agente é cômodo e também é alvo. Quem conseguir falar com o socket do agente enquanto você está logado pode pedir a ele que assine coisas. Por isso, evite o encaminhamento de agente (ssh -A) para hosts em que você não confia por completo. Um usuário root no host remoto pode usar o agente encaminhado. Se precisar chegar a uma máquina privada por um bastion, use um jump host:
ssh -J seuusuario@bastion seuusuario@vm-privadaO cliente guarda as chaves de host em ~/.ssh/known_hosts, uma linha por host e tipo de chave. As linhas podem ser embaralhadas (hash) se você definir HashKnownHosts yes, o que esconde os nomes dos hosts de quem ler o arquivo.
Para procurar um host:
ssh-keygen -F sua-vm-de-laboratorioPara remover uma entrada depois de reconstruir a VM e obter uma nova chave de host:
ssh-keygen -R sua-vm-de-laboratorioFaça isso só quando souber o motivo da mudança da chave. Uma chave de host alterada é um alerta, não um incômodo. Apagar a entrada antiga sem conferir a nova impressão digital ensina você a ignorar o próximo alerta, e o próximo pode ser real.
.pub vai para servidores, hospedagens de Git ou outras pessoas.authorized_keys..pub em authorized_keys.~/.ssh deve ser 700 e authorized_keys deve ser 600. Modos mais abertos podem fazer o sshd ignorar a chave. Olhe os logs do sshd quando um login por chave falhar.lab_ed25519 para o laboratório e outra chave para o GitHub.yes.ssh-copy-id duas vezes não causa dano, mas acrescentar a mesma chave à mão várias vezes torna o arquivo difícil de auditar. Remova as chaves que você não usa mais.Depois que o laboratório funcionar, alguns passos deixam o uso diário mais seguro e organizado.
~/.ssh/config. Dê um apelido a cada host, defina o IdentityFile e acrescente IdentitiesOnly yes, para que o cliente ofereça só a chave que você escolheu. Assim ele não testa todas as chaves do agente em cada servidor.ssh-keygen -t ed25519-sk. A parte privada não pode ser copiada para fora do dispositivo. Confira a sua versão do OpenSSH e o suporte antes de depender disso.ssh-keygen e do sshd_config descrevem todas as opções que você vai encontrar. A RFC 4253 explica a camada de transporte, e a RFC 8709 trata do Ed25519 no SSH.Se permissões e donos de arquivos ainda forem novidade para você, leia antes o artigo anterior sobre permissões de arquivos no Linux. O próximo artigo trata de redes Docker isoladas para laboratórios, que ajudam a manter o tráfego do laboratório longe da sua rede do dia a dia.
ssh-keygen(1): https://man.openbsd.org/ssh-keygensshd_config(5): https://man.openbsd.org/sshd_configLinux e ferramentas de desenvolvimento
Aprenda pipes, redirecionamento, variáveis, laços, códigos de saída e set -euo pipefail, e use isso para contar logins falhos e gerar hashes.
Linux e ferramentas de desenvolvimento
Donos, grupos, bits rwx, chmod, umask e setuid no Linux, com laboratório que testa o acesso de outro usuário e procura modos arriscados.
Linux e ferramentas de desenvolvimento
GitHub para iniciantes: a diferença entre Git e GitHub, os termos básicos, um exercício local com Git e como checar um projeto antes de rodá-lo.