SSH: Conectando e Gerenciando Servidores Remotos

[61] SSH: Conectando e Gerenciando Servidores Remotos

SSH na prática: verificação de host com known_hosts, autenticação por par de chaves ed25519, o arquivo ~/.ssh/config, transferência de arquivos com scp e rsync, ssh-agent para chaves com passphrase e o endurecimento do sshd_config.
DevOps

9 min de leitura

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-keygen e sshd_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

Prática

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.

Comentários

Mais em DevOps

Introdução ao Terraform: Infraestrutura que Você Pode Versionar
Introdução ao Terraform: Infraestrutura que Você Pode Versionar

O problema dos snowflake servers e a infraestrutura que se pode versionar: o…

Protegendo Branches e Revisando Código com Pull Requests
Protegendo Branches e Revisando Código com Pull Requests

Pull Requests e proteção de branch: as regras que tornam a revisão…

Grafana: Dashboards e Alertas que Fazem Sentido
Grafana: Dashboards e Alertas que Fazem Sentido

Dashboards que respondem perguntas em vez de acumular gráficos…