Como configurar múltiplos hosts e bastions no SSH config

1. Introdução ao SSH config e seus benefícios

O arquivo ~/.ssh/config é a central de comando para qualquer profissional que lida com múltiplos servidores. Em vez de decorar endereços IP, portas e usuários, você define aliases e parâmetros que tornam a conexão tão simples quanto ssh dev-server.

A estrutura básica é composta por blocos Host, que definem um alias e seus parâmetros associados. Cada bloco pode conter diretivas como HostName, User, Port, IdentityFile, entre outras. O SSH config lê esses blocos em ordem e aplica o primeiro que corresponde ao nome do host digitado.

Os benefícios são claros: automação de conexões, redução de erros de digitação, centralização de configurações de segurança e a possibilidade de gerenciar dezenas de servidores com poucas linhas. Para ambientes com múltiplos bastions, o SSH config é praticamente obrigatório.

2. Configuração de hosts simples no SSH config

A sintaxe básica de um bloco Host segue este padrão:

Host dev-server
    HostName 192.168.1.100
    User devops
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_dev

Você pode definir quantos hosts quiser. Para servidores de produção, por exemplo:

Host prod-api
    HostName api.exemplo.com
    User admin
    Port 22
    IdentityFile ~/.ssh/id_rsa_prod

Curingas (*) são úteis para agrupar hosts com configurações comuns. Por exemplo, todos os servidores de um domínio podem compartilhar o mesmo usuário e chave:

Host *.exemplo.com
    User deploy
    IdentityFile ~/.ssh/id_ed25519_exemplo
    ServerAliveInterval 60

3. Configuração de múltiplos hosts com parâmetros avançados

Para ambientes mais complexos, você pode refinar cada host com parâmetros avançados. O IdentityFile permite especificar chaves diferentes por servidor, enquanto IdentitiesOnly yes força o uso apenas das chaves explicitamente listadas, ignorando o agente SSH:

Host db-interno
    HostName 10.0.1.50
    User dba
    Port 5432
    IdentityFile ~/.ssh/id_ed25519_db
    IdentitiesOnly yes

Para manter conexões ativas em redes instáveis, use ServerAliveInterval e ServerAliveCountMax:

Host servidor-lento
    HostName 203.0.113.10
    User user
    ServerAliveInterval 30
    ServerAliveCountMax 3

O encaminhamento de portas também pode ser configurado diretamente:

Host servidor-tunel
    HostName 192.168.1.200
    User admin
    LocalForward 8080 localhost:80
    LocalForward 3306 localhost:3306

4. Introdução a bastion hosts (jump hosts)

Um bastion host (ou jump host) é um servidor intermediário que serve como ponto único de entrada para uma rede privada. Em arquiteturas seguras, os servidores internos não têm IP público; apenas o bastion é exposto. Para acessar um servidor interno, você primeiro se conecta ao bastion e, a partir dele, ao destino final.

A diferença entre bastion e proxy SSH é sutil: o bastion é um servidor completo que pode auditar e registrar acessos, enquanto um proxy SSH (como ssh -L) apenas encaminha tráfego. Na prática, o bastion é mais comum em ambientes corporativos.

5. Configuração de bastions com ProxyJump

O parâmetro ProxyJump (disponível desde o OpenSSH 7.3) simplifica drasticamente a configuração de bastions. A sintaxe é direta:

Host servidor-interno
    HostName 10.0.0.100
    User interno
    ProxyJump bastion.exemplo.com

Para usar um bastion com usuário e porta específicos:

Host servidor-interno
    HostName 10.0.0.100
    User interno
    ProxyJump usuario@bastion.exemplo.com:2222

Cadeias de múltiplos bastions são possíveis separando-os por vírgula:

Host servidor-protegido
    HostName 172.16.0.50
    User admin
    ProxyJump bastion1.exemplo.com, bastion2.interno

Como alternativa, o ProxyCommand ainda funciona para versões antigas do OpenSSH:

Host servidor-antigo
    HostName 10.0.0.100
    User user
    ProxyCommand ssh -W %h:%p bastion.exemplo.com

A diferença é que ProxyJump gerencia automaticamente a autenticação e o encaminhamento, enquanto ProxyCommand exige mais configuração manual.

6. Estratégias avançadas para múltiplos bastions

Quando vários hosts compartilham o mesmo bastion, você pode agrupar as configurações:

Host *.rede-interna
    ProxyJump bastion.exemplo.com

Host db-1.rede-interna
    HostName 10.0.0.10
    User dba

Host app-1.rede-interna
    HostName 10.0.0.20
    User deploy

Para cenários de fallback, use o bloco Match com condições:

Match host servidor-critico exec "ping -c1 10.0.0.1"
    ProxyJump bastion-principal

Match host servidor-critico
    ProxyJump bastion-reserva

O ForwardAgent é útil quando o bastion precisa acessar um repositório Git ou outro serviço que exija sua chave SSH:

Host bastion.exemplo.com
    ForwardAgent yes

Cuidado: o agent forwarding deve ser usado com moderação, pois qualquer um com acesso root ao bastion pode usar sua chave.

7. Otimização e troubleshooting no SSH config

Para organizar configurações muito grandes, use a diretiva Include:

Include ~/.ssh/config.d/*.conf

Isso permite separar configurações por projeto ou ambiente, mantendo o arquivo principal limpo.

Para testar conexões, use ssh -v para modo verboso ou ssh -G para ver qual configuração será aplicada:

ssh -G servidor-interno

Problemas comuns incluem:
- Conflitos de Host: o SSH usa o primeiro bloco que corresponde. Coloque curingas no final do arquivo.
- Permissões incorretas: o arquivo ~/.ssh/config deve ter permissão 600 (chmod 600 ~/.ssh/config).
- Chaves erradas: verifique com ssh -i /caminho/da/chave usuario@host.

8. Exemplo completo e boas práticas

Abaixo, um arquivo SSH config realista com múltiplos hosts e bastions:

# Configurações globais
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    Compression yes

# Bastion principal
Host bastion
    HostName bastion.exemplo.com
    User jumpuser
    IdentityFile ~/.ssh/id_ed25519_bastion
    ForwardAgent yes

# Servidores internos via bastion
Host dev-*.interno
    ProxyJump bastion
    User devops
    IdentityFile ~/.ssh/id_ed25519_dev

Host dev-web.interno
    HostName 10.0.1.10

Host dev-db.interno
    HostName 10.0.1.20
    LocalForward 5432 localhost:5432

# Servidor de produção com bastion duplo
Host prod-api
    HostName 10.0.2.100
    User admin
    ProxyJump bastion, proxy-interno.infra
    IdentityFile ~/.ssh/id_rsa_prod
    IdentitiesOnly yes

# Servidor externo direto
Host servidor-externo
    HostName 203.0.113.50
    User meuuser
    Port 2222

Checklist de segurança:
- chmod 600 ~/.ssh/config
- Chaves específicas por host (nunca use a mesma chave para tudo)
- IdentitiesOnly yes para evitar vazamento de chaves do agente
- Versionamento do arquivo (ex.: em um repositório Git privado)

Para manter o arquivo organizado, revise periodicamente os hosts obsoletos e documente cada bloco com comentários.

Referências