Script pour ajouter des serveurs à partir de Google Cloud pour configurer ssh

Annotation. Un article sur un script très simple qui forme une configuration pour ssh Linux à partir d'une liste de serveurs. Testé sur Ubuntu 18, utilise le SDK Goodle Cloud, Python 2.7, Bash.


Après une forte augmentation du nombre de serveurs avec lesquels je dois travailler, j'ai réalisé que le stockage des mots de passe et la CMDB ne fournissaient plus un accès opérationnel comme à l'époque où je me souvenais par cœur de toutes les adresses IP et détails. Peut-être parce que CMDB nous ne l'avons pas encore maîtrisé. Néanmoins, il est en quelque sorte nécessaire de résoudre le problème de l'accès rapide via SSH à un grand nombre de serveurs.


Suivant - du point de vue du terminal Linux (effectué sur Ubuntu 18). Peut-être que cela fonctionne dans d'autres distributions et, probablement, il y a même un analogue sur Windows - je n'ai pas regardé.


Les principales exigences:


  • Facile à répéter. Plusieurs administrateurs
    et vous devez pouvoir configurer la même chose pour tout le monde. De plus, nous autorisons le travail à distance - au moins chaque ordinateur portable a une situation, mais il arrive que vous ne travailliez pas sur votre ordinateur habituel «réglé et débogué».
  • Les serveurs sont ajoutés, supprimés et modifiés. Cela devrait être pris en considération.

Pour ce faire, j'ai décidé d'utiliser des hôtes d'alias dans les paramètres ssh, d'obtenir la liste des serveurs via le client gcloud cli GCP et d'automatiser tout cela à l'aide de Python 2.7 (car c'était par défaut dans Ubuntu et j'ai décidé de l'étudier pour travailler avec des données). Le script lui-même avec une description sous la coupe.


Énoncé du problème


L'idée était la suivante: conserver une liste de la connexion des serveurs d'alias et de leurs adresses actuelles de telle sorte que seul un nom puisse être utilisé pour établir une connexion. Dans le même temps, la liste elle-même est périodiquement mise à jour à partir de GCP par API.


En conséquence, il y avait plusieurs tâches:


  1. Se connecter à l'hôte en tapant uniquement un nom mémorable (nous formons généralement les noms selon des règles strictes, il suffit donc de connaître le client et le système pour deviner presque certainement le nom du serveur). Les noms peuvent être réels (si le serveur est entièrement créé par nous) ou alias à l'intérieur de notre cmdb (si le serveur est créé par le client et que le nom est attribué selon les règles du client). Dans tous les cas, se souvenir d'un nom est plus facile qu'une adresse. L'adresse change également.
  2. Obtenir une liste des hôtes actuels avec des adresses valides. Parce que la plate-forme principale est GCP et 90% des serveurs là-bas, alors ce problème sera résolu via leur API, et non par des outils de surveillance.
  3. Recherche par nom d'hôte. Bien qu'ils soient plus faciles à retenir, le nombre augmente et la mémoire n'est pas illimitée :) Oui, et les nouveaux administrateurs sont plus faciles.
  4. Mettre à jour le groupe d'alias - adresse uniquement lorsque l'adresse change. Cela est nécessaire pour abandonner la réécriture complète de tous les bundles. Cela permettra le stockage des bundles non seulement pour les serveurs GCP. Jusqu'à présent, ce problème n'a pas été résolu :(

Description de la solution


Alias ​​pour se connecter


Tout ici est assez simple et n'a pas été décidé par moi. L'utilitaire Linux ssh prend en charge la configuration d'alias dans le fichier de configuration.


Emplacement du fichier: ~ / .ssh / config


Le format de fichier que nous avons utilisé est très banal, mais en fait les possibilités sont beaucoup plus larges:


HOST alias_ HostName ip__- 

Vous pouvez en savoir plus sur les options de configuration ici , ici ou dans la documentation officielle .


Etapes supplémentaires


  1. Utilisez différentes clés pour vous connecter à différents groupes d'hôtes. Une petite paranoïa en termes de sécurité ne fera pas de mal.
  2. Fournissez une sauvegarde de ce fichier pour vous protéger contre les modifications accidentelles et mettre à jour les erreurs de script.

Rechercher des noms d'hôtes


Ici, la décision ne m'appartient pas du tout, mais à Ben Lobaugh et est décrite dans son article .
En bref, j'ai utilisé sed, qui, pour faciliter le démarrage (une règle très longue dans les paramètres) était abrégé via alias:


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

Si vous avez besoin de trouver l'hôte par la partie nom, alors ce script est parfaitement complété par l'utilitaire grep et en conséquence il se présente comme ceci:


 sshhost | grep '---' 

Il existe d'autres options, par exemple, comme décrit ici .


Saisie semi-automatique du nom d'hôte


Merci pour la solution onix74 !
Ajoutez la ligne à ~ / .bash_completion:


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

Pour la commande ssh, la saisie semi-automatique fonctionnera selon la liste des serveurs d'alias. C'est-à-dire Vous pouvez utiliser ssh pour remplacer le nom du serveur ssh. Cela fonctionne en bash.

Etapes supplémentaires


J'ai l'intention de diviser les hôtes en groupes afin que vous puissiez sélectionner tous les serveurs d'un client particulier ou avec une application spécifique. Il semble que cette fonctionnalité sera intéressante pour l'exécution de scripts de masse et la connexion Ansible; ainsi que pour créer différents détails de connexion pour différents groupes. Mais combien il a vraiment de sens reste à voir.


Obtenir une liste d'hôtes de GCP


Dans cette étape, tout est assez simple, à l'exception des réglages des paramètres (bien qu'ici c'est une question d'expérience). J'ai décidé d'utiliser le SDK GCloud pour obtenir des données, car alors que je l'utilise rarement, mais je suppose que cela me permettra parfois d'utiliser de moins en moins l'interface graphique et de simplifier considérablement la routine d'administration. Par conséquent, l'argument principal est d'acquérir de l'expérience.
Probablement, la même chose pourrait être faite en utilisant curl et l'API GCP REST, puis la solution serait plus universelle (car les SDK GCloud nécessitent une installation et une initialisation distinctes, ce qui n'est pas si compliqué, mais est toujours requis).


Pour obtenir les informations nécessaires, j'ai dû utiliser le format json. Bien que cela ait grandement simplifié le traitement ultérieur de la réponse reçue, cela a fait réfléchir un peu à la définition des paramètres de formatage dans le SDK.
En conséquence, j'ai reçu la commande suivante:


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

Il ne renvoie que les serveurs actuellement actifs (cela n'a aucun sens de se connecter aux autres) avec des informations sur leur nom et leur interface réseau. Jusqu'à présent, une seule interface externe est utilisée pour chaque serveur.


Le résultat final arrive en json:


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

Etapes supplémentaires


Trouvez un format dont la sortie réduira ou même éliminera le traitement ultérieur.


Script pour créer une liste d'alias basée sur les données de GCP


Le script a été écrit en python 2.7 pour deux raisons:


  1. J'ai décidé de l'étudier pour travailler avec des données;
  2. python 2.7 est par défaut sur la plupart des systèmes exécutant linux - il n'y aura aucun problème à l'utiliser ailleurs. Étant donné que même gagner maintenant vous permet de mettre un deuxième système et d'utiliser Ubuntu comme terminal.

L'algorithme est le suivant:


  1. Nous obtenons la liste des serveurs du Google Cloud à l'aide du SDK, initiant l'exécution de la commande dans la console à partir de python.
  2. Nous analysons le JSON résultant en types compatibles avec Python.
  3. Nous donnons la sortie au format nécessaire à la configuration ssh (si nécessaire, la sortie du script est redirigée vers ~ / .ssh / config ou vers un fichier intermédiaire).

Afficher le 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'] 

Mise à jour uniquement des données modifiées


Cette tâche est toujours en cours. J'ai l'intention de lire le fichier ssh / config dans le même script, de le comparer avec les valeurs reçues, puis de réécrire l'ensemble du résultat. Ou générez un nouveau fichier séparément et effectuez une comparaison en utilisant une sorte de diff - cela vous permettra de confirmer manuellement toutes les modifications.

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


All Articles