Script para adicionar servidores do Google Cloud ao config ssh

Anotação. Um artigo sobre um script muito simples que forma uma configuração para o ssh Linux a partir de uma lista de servidores. Testado no Ubuntu 18, usa o Goodle Cloud SDK, Python 2.7, Bash.


Após um aumento acentuado no número de servidores com os quais tenho que trabalhar, percebi que o armazenamento de senhas e o CMDB não fornecem mais esse acesso operacional, como naqueles dias em que lembrei todos os detalhes de ip e de cor. Talvez porque o CMDB ainda não tenhamos dominado. No entanto, é de alguma forma necessário resolver o problema do acesso rápido via SSH a um grande número de servidores.


Próximo - do ponto de vista do terminal Linux (realizado no Ubuntu 18). Talvez ele funcione em outras distribuições e, provavelmente, há até um análogo no Windows - eu não parecia.


Os principais requisitos:


  • Fácil de repetir. Vários administradores
    e você precisa configurar o mesmo para todos. Além disso, permitimos trabalho remoto - pelo menos todo laptop tem uma situação, mas acontece que você não trabalha no seu computador “afinado e depurado” de sempre.
  • Servidores são adicionados, excluídos, endereços alterados. Isso deve ser considerado.

Para fazer isso, decidi usar hosts alias nas configurações ssh, obter a lista de servidores através do cliente Gcloud cli GCP e automatizar tudo isso usando o Python 2.7 (porque era por padrão no Ubuntu e decidi estudá-lo para trabalhar com dados). O script em si com uma descrição sob o corte.


Declaração do problema


A idéia era a seguinte: manter uma lista de servidores de alias de comunicação e seus endereços atuais de forma que apenas um nome pudesse ser usado para estabelecer uma conexão. Ao mesmo tempo, a lista em si é atualizada periodicamente do GCP pela API.


Como resultado, houve várias tarefas:


  1. Conectando-se ao host digitando apenas um nome memorável (geralmente formamos os nomes de acordo com regras estritas, portanto é suficiente conhecer o cliente e o sistema para quase certamente adivinhar o nome do servidor). Os nomes podem ser reais (se o servidor for completamente criado por nós) ou alias dentro de nosso cmdb (se o servidor for criado pelo cliente e o nome for atribuído de acordo com as regras do cliente). De qualquer forma, lembrar um nome é mais fácil do que um endereço. O endereço também muda.
  2. Obtendo uma lista dos hosts atuais com endereços válidos. Porque como a plataforma principal é o GCP e 90% dos servidores estão lá, esse problema será resolvido por meio da API e não pelas ferramentas de monitoramento.
  3. Pesquise pelo nome do host. Embora sejam mais fáceis de lembrar, o número está aumentando e a memória não é ilimitada :) Sim, e novos administradores são mais fáceis.
  4. Atualizar alias bundle - endereço somente quando o endereço for alterado. Isso é necessário para abandonar a reescrita completa de todos os pacotes configuráveis. Isso permitirá o armazenamento de pacotes não apenas para servidores GCP. Até agora, este problema não foi resolvido :(

Descrição da solução


Alias ​​para conectar


Tudo aqui é bastante simples e não foi decidido por mim. O utilitário Linux ssh suporta a configuração de alias no arquivo de configuração.


Local do arquivo: ~ / .ssh / config


O formato de arquivo que usamos é muito banal, mas na verdade as possibilidades são muito maiores:


HOST alias_ HostName ip__- 

Você pode ler mais sobre as opções de configuração aqui , aqui ou na documentação oficial .


Passos adicionais


  1. Use chaves diferentes para conectar-se a diferentes grupos de hosts. Um pouco de paranóia em termos de segurança não fará mal.
  2. Forneça backup deste arquivo para proteger contra alterações acidentais e atualizar erros de script.

Pesquisar nomes de host


Aqui a decisão não pertence a mim, mas a Ben Lobaugh e é descrita em seu artigo .
Resumidamente, usei o sed, que, para facilitar a partida (uma regra muito longa nos parâmetros), foi abreviado por meio de alias:


 alias sshhosts="sed -rn 's/^\s*HOST\s+(.*)\s*/\1/ip' ~/.ssh/config" 

Se você precisar encontrar o host pela parte do nome, esse script será perfeitamente complementado pelo utilitário grep e, como resultado, ficará assim:


 sshhost | grep '---' 

Existem outras opções, por exemplo, conforme descrito aqui .


Preenchimento automático do nome do host


Obrigado pela solução onix74 !
Adicione a linha a ~ / .bash_completion:


 complete -W "$(grep "^HOST " ~/.ssh/config | grep -v "\*" | sed 's/[^ ]* *\(.*\)/\1/')" ssh 

Para o comando ssh, o preenchimento automático funcionará de acordo com a lista de servidores de alias. I.e. Você pode usar ssh para substituir o nome do servidor ssh. Funciona no bash.

Passos adicionais


Eu planejo dividir os hosts em grupos para que você possa selecionar todos os servidores de um cliente específico ou com um aplicativo específico. Parece que esse recurso será interessante para execução de scripts em massa e conexão Ansible; bem como criar diferentes detalhes de conexão para diferentes grupos. Mas o quanto realmente faz sentido continua a ser visto.


Obtenha uma lista de hosts do GCP


Nesta etapa, tudo é bem simples, exceto pelas configurações dos parâmetros (embora aqui seja uma questão de experiência). Eu decidi usar o SDK do GCloud para obter dados, porque embora raramente o use, mas suponho que em algum momento isso me permita usar a interface gráfica cada vez menos e simplifique significativamente a rotina de administração. Portanto, o argumento principal é ganhar experiência.
Provavelmente, o mesmo poderia ser feito usando curl e a API RCP do GCP e a solução seria mais universal (já que os SDKs do GCloud exigem instalação e inicialização separadas, o que não é tão complicado, mas ainda é necessário).


Para obter as informações necessárias, tive que usar o formato json. Embora isso tenha simplificado bastante o processamento adicional da resposta recebida, ele fez pensar um pouco sobre a configuração de parâmetros de formatação no SDK.
Como resultado, recebi o seguinte comando:


 gcloud compute instances list --filter="status:running" --format="json(name, status, networkInterfaces[].accessConfigs[])" 

Ele retorna apenas servidores atualmente ativos (não faz sentido se conectar aos outros) com informações sobre o nome e a interface de rede. Até o momento, apenas uma interface externa é usada para cada servidor.


O resultado final chega em json:


 [ ---...---- { "name": "-", "networkInterfaces": [ { "accessConfigs": [ { "kind": "compute#accessConfig", "name": "External NAT", "natIP": "ip-", "networkTier": "PREMIUM", "type": "ONE_TO_ONE_NAT" } ] } ], "status": "RUNNING" }, ----...--- ] 

Passos adicionais


Encontre um formato cuja saída minimize ou mesmo elimine o processamento subsequente.


Script para criar uma lista de alias com base nos dados do GCP


O script foi escrito em python 2.7 por dois motivos:


  1. Eu decidi estudá-lo para trabalhar com dados;
  2. O python 2.7 é por padrão na maioria dos sistemas executando o linux - não haverá problemas em usá-lo em outro lugar. Dado que mesmo o win agora permite que você coloque um segundo sistema e use o Ubuntu como terminal.

O algoritmo é o seguinte:


  1. Obtemos a lista de servidores do Google Cloud usando o SDK, iniciando a execução do comando no console a partir do python.
  2. Analisamos o JSON resultante em tipos compatíveis com python.
  3. Fornecemos a saída no formato necessário para configurar o ssh (se necessário, a saída do script é redirecionada para ~ / .ssh / config ou para algum arquivo intermediário).

Ver script
 #!/usr/bin/python import commands import json sComputeListOutput = commands.getoutput('gcloud compute instances list --filter="status:running" --format="json(name, status, networkInterfaces[].accessConfigs[])" ') s = json.loads(sComputeListOutput) for server in s: print 'HOST ',server['name'] print ' HostName ',server['networkInterfaces'][0]['accessConfigs'][0]['natIP'] 

Atualizando apenas dados modificados


Esta tarefa ainda está em andamento. Eu pretendo ler o arquivo ssh / config no mesmo script, compará-lo com os valores recebidos e, em seguida, escrever o resultado inteiro. Ou gere um novo arquivo separadamente e faça uma comparação usando algum tipo de diff - isso permitirá que você confirme manualmente todas as alterações.

Source: https://habr.com/ru/post/pt484500/


All Articles