SSH — Secure Shell — é o protocolo pelo qual administradores, engenheiros de DevOps e sistemas automatizados se conectam a servidores remotos. Toda vez que um pipeline de CI/CD realiza um deploy em um servidor, toda vez que um engenheiro acessa uma instância na AWS, toda vez que um script transfere arquivos entre máquinas — o SSH está no meio.
Entender SSH não é apenas saber digitar um comando de conexão. É entender autenticação por chave, segurança de acesso, configuração de servidores e automação. Este artigo cobre tudo isso.
Conectando a um Servidor Remoto
A forma mais básica de conexão:
ssh usuario@192.168.1.100
Na primeira conexão, o SSH pergunta se o host é confiável — responde-se yes e a impressão digital do servidor é salva em ~/.ssh/known_hosts. Em conexões futuras, o SSH verifica se a impressão digital ainda é a mesma, protegendo contra ataques de intermediário.
Especificando uma porta diferente da padrão (22):
ssh -p 2222 usuario@192.168.1.100
Autenticação por Chave — O Jeito Certo
Autenticação por senha é conveniente, mas é o método mais vulnerável. Em ambientes profissionais, usa-se autenticação por par de chaves: uma chave privada que fica na máquina do usuário, e uma chave pública que é instalada no servidor.
Gerando o par de chaves:
ssh-keygen -t ed25519 -C "seu@email.com"
O algoritmo ed25519 é o recomendado atualmente — mais seguro e com chaves menores que o RSA. O parâmetro -C adiciona um comentário para identificar a chave.
O comando perguntará onde salvar a chave (aceitar o padrão ~/.ssh/id_ed25519) e se deseja uma passphrase — uma senha adicional que protege a chave privada mesmo que o arquivo seja roubado. Em ambientes de desenvolvimento pessoal é opcional; em ambientes corporativos é recomendada.
Dois arquivos são criados:
~/.ssh/id_ed25519 # Chave privada — NUNCA compartilhar
~/.ssh/id_ed25519.pub # Chave pública — pode ser copiada para servidores
Copiando a chave pública para o servidor:
ssh-copy-id usuario@192.168.1.100
Ou manualmente, caso ssh-copy-id não esteja disponível:
cat ~/.ssh/id_ed25519.pub | ssh usuario@192.168.1.100 \
"mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
A partir desse momento, a conexão acontece sem solicitar senha — o SSH usa a chave privada local para provar identidade ao servidor.
O Arquivo de Configuração SSH
Para quem gerencia múltiplos servidores, digitar o endereço IP e o usuário toda vez se torna impraticável. O arquivo ~/.ssh/config resolve isso:
Host servidor-web
HostName 192.168.1.100
User deploy
IdentityFile ~/.ssh/id_ed25519
Port 22
Host servidor-banco
HostName 192.168.1.200
User ubuntu
IdentityFile ~/.ssh/id_ed25519_banco
Port 2222
Host bastion
HostName 54.12.34.56
User ec2-user
IdentityFile ~/.ssh/aws_key.pem
Com essa configuração, a conexão se resume a:
ssh servidor-web
ssh servidor-banco
Transferindo Arquivos com SCP e rsync
SCP — cópia segura via SSH:
# Copia arquivo local para servidor remoto
scp arquivo.txt usuario@servidor-web:/home/usuario/
# Copia pasta inteira
scp -r pasta/ usuario@servidor-web:/home/usuario/
# Copia do servidor para local
scp usuario@servidor-web:/var/log/app.log ./logs/
rsync — mais eficiente para sincronização de diretórios, pois transfere apenas o que mudou:
# Sincroniza pasta local com servidor remoto
rsync -avz --progress ./app/ usuario@servidor-web:/var/www/app/
# Com exclusões
rsync -avz --exclude 'node_modules' --exclude '.git' \
./app/ usuario@servidor-web:/var/www/app/
O rsync é amplamente usado em scripts de deploy simples — antes da adoção massiva de containers, era o mecanismo principal de atualização de aplicações em servidores.
SSH Agent — Gerenciando Chaves com Passphrase
Quando a chave privada tem passphrase, o SSH solicita a senha a cada conexão. O ssh-agent resolve isso armazenando a chave desbloqueada na memória da sessão:
# Inicia o agente
eval "$(ssh-agent -s)"
# Adiciona a chave (pede a passphrase uma única vez)
ssh-add ~/.ssh/id_ed25519
# Lista chaves carregadas
ssh-add -l
A partir desse momento, todas as conexões SSH da sessão atual usam a chave sem solicitar passphrase novamente.
Boas Práticas de Segurança SSH em Servidores
Ao configurar um servidor que será exposto à internet, algumas mudanças no arquivo /etc/ssh/sshd_config são essenciais:
# Desabilita autenticação por senha — apenas chaves
PasswordAuthentication no
# Desabilita login direto como root
PermitRootLogin no
# Limita os usuários que podem conectar via SSH
AllowUsers deploy ubuntu
# Muda a porta padrão (dificulta varreduras automatizadas)
Port 2222
Após qualquer alteração no sshd_config, reinicia-se o serviço:
sudo systemctl restart sshd
Importante: antes de reiniciar, abre-se uma segunda sessão SSH para garantir que o acesso não foi bloqueado por um erro de configuração.
Um Cenário Real: Acesso a uma Instância EC2 na AWS
A AWS cria pares de chaves automaticamente ao lançar instâncias. O arquivo .pem baixado é a chave privada. O processo de conexão:
# Ajusta permissões da chave (obrigatório — SSH rejeita chaves muito abertas)
chmod 400 ~/.ssh/minha-chave-aws.pem
# Conecta à instância
ssh -i ~/.ssh/minha-chave-aws.pem ec2-user@54.12.34.56
Para facilitar, adiciona-se ao ~/.ssh/config:
Host meu-servidor-aws
HostName 54.12.34.56
User ec2-user
IdentityFile ~/.ssh/minha-chave-aws.pem
E a conexão se torna simplesmente:
ssh meu-servidor-aws
Referências para Aprofundamento
Documentação oficial
- OpenSSH Documentation — Manuais oficiais do OpenSSH, incluindo referências completas do
ssh,scp,ssh-keygenesshd_config. - SSH Academy — Base de conhecimento mantida pela empresa criadora do protocolo SSH. Cobre desde conceitos básicos até casos avançados de tunelamento e segurança.
Leitura técnica
- SSH Essentials — DigitalOcean — Tutorial abrangente da DigitalOcean cobrindo chaves, configuração de servidor e boas práticas de segurança.
- Connecting to GitHub with SSH — GitHub Docs — Guia oficial do GitHub para configurar autenticação SSH. Será usado diretamente no próximo módulo.
Prática
- Over The Wire: Bandit — níveis 13 a 17 — Esses níveis trabalham diretamente com SSH, chaves e conexões entre hosts. São os mais relevantes da série para este artigo.
- Linux Upskill Challenge — Dia 3 — O terceiro dia do desafio cobre exatamente acesso SSH a servidores reais na nuvem.
Exercícios
Exercício 1
O que acontece na primeira conexão a um servidor, quando o SSH pergunta se o host é confiável? Contra qual ataque esse mecanismo protege — e por que um aviso de impressão digital alterada nunca deve ser ignorado?
Ver resposta
✓ Resposta: Ao aceitar, o SSH grava a impressão digital do servidor em ~/.ssh/known_hosts. Em toda conexão seguinte ele compara a impressão apresentada com a guardada, e recusa a conexão se elas divergirem. É a defesa contra o ataque de intermediário: quem se coloca no meio do caminho fingindo ser o servidor tem outra chave de host, e a divergência denuncia a farsa. Por isso o aviso de mudança merece investigação — pode ser uma reinstalação legítima da máquina, mas pode ser exatamente o ataque que o mecanismo existe para detectar. Apagar a linha do known_hosts sem verificar é desligar o alarme sem olhar o motivo.
Exercício 2
No par de chaves, qual arquivo vai para o servidor e qual nunca sai da sua máquina? O que exatamente a autenticação por chave prova, e por que ela é mais segura que senha?
Ver resposta
✓ Resposta: A privada, ~/.ssh/id_ed25519, permanece na máquina do usuário. A pública, ~/.ssh/id_ed25519.pub, é copiada para o ~/.ssh/authorized_keys do servidor. Na conexão o servidor envia um desafio, o cliente o responde usando a chave privada e o servidor confere a resposta com a chave pública que já possui. O segredo nunca trafega pela rede e o servidor nunca precisa guardá-lo — se o servidor for comprometido, o atacante leva apenas chaves públicas, que não autenticam ninguém em lugar algum. Com senha, o segredo trafega e é armazenado dos dois lados.
Exercício 3
O ~/.ssh/config economiza digitação, mas o ganho não para aí. Que outro problema ele resolve para quem tem várias chaves diferentes?
Ver resposta
✓ Resposta: Ele amarra cada servidor à sua chave correta pelo IdentityFile. Sem isso, o SSH oferece as chaves disponíveis uma a uma até acertar — e servidores limitam o número de tentativas de autenticação. Com várias chaves no diretório, é perfeitamente possível ser recusado por exceder o limite mesmo possuindo a chave certa, porque ela foi oferecida tarde demais. O config elimina a tentativa e erro, e como scripts, rsync e ferramentas de deploy leem o mesmo arquivo, a configuração vale para toda a automação, não só para o comando digitado à mão.
Exercício 4
Quando escolher scp e quando escolher rsync? O que muda concretamente em um deploy repetido?
Ver resposta
✓ Resposta: O scp copia tudo, todas as vezes — serve para um arquivo pontual. O rsync compara origem e destino e transfere apenas o que mudou, com compressão (-z) e preservação de atributos (-a). Num deploy repetido a diferença é enorme: a primeira sincronização envia a aplicação inteira, e as seguintes enviam só os arquivos alterados, transformando minutos em segundos. Some a isso o --exclude 'node_modules' --exclude '.git', que impede o envio de diretórios que não têm o que fazer no servidor e que muitas vezes são maiores que a própria aplicação.
Exercício 5
Que problema o ssh-agent resolve? E por que o comando é eval "$(ssh-agent -s)", em vez de simplesmente ssh-agent -s?
Ver resposta
✓ Resposta: Quando a chave privada tem passphrase, o SSH pede a senha a cada conexão. O agente guarda a chave já desbloqueada na memória da sessão: o ssh-add pede a passphrase uma única vez e todas as conexões seguintes passam sem perguntar. Quanto ao eval: o ssh-agent -s sobe o agente e apenas imprime os comandos que definem SSH_AUTH_SOCK e SSH_AGENT_PID. Sem o eval, esse texto vai para a tela e as variáveis nunca são criadas — o agente existe, mas o shell não sabe como falar com ele. O eval executa a saída no shell atual, e é isso que conecta os dois.
Exercício 6
Por que abrir uma segunda sessão SSH antes de reiniciar o sshd? E o que PasswordAuthentication no e PermitRootLogin no protegem, cada um?
Ver resposta
✓ Resposta: Porque um erro no sshd_config pode tornar o servidor inacessível, e a sessão já aberta sobrevive ao restart — ela é a rede de segurança que permite desfazer a alteração. Se você fechar tudo e o restart quebrar o acesso, resta apenas o console físico ou o console do provedor de nuvem. Sobre as diretivas: PasswordAuthentication no encerra a força bruta de senha, que é a maior parte do tráfego automatizado contra a porta 22 — sem senha aceita, não há o que adivinhar. PermitRootLogin no obriga o atacante a acertar usuário e chave, e preserva o rastro de auditoria: cada pessoa entra com a própria conta e eleva privilégio via sudo, em vez de todos serem indistinguíveis como root.