Skript zum Hinzufügen von Servern aus Google Cloud zur Konfiguration von ssh

Anmerkung. Ein Artikel über ein sehr einfaches Skript, das aus einer Liste von Servern eine Konfiguration für ssh Linux erstellt. Getestet auf Ubuntu 18, verwendet Goodle Cloud SDK, Python 2.7, Bash.


Nach einem starken Anstieg der Anzahl der Server, mit denen ich arbeiten muss, wurde mir klar, dass der Kennwortspeicher und die CMDB keinen solchen operativen Zugriff mehr bieten, wie damals, als ich mir alle IP-Adressen und Details auswendig erinnerte. Vielleicht weil wir CMDB noch nicht gemeistert haben. Trotzdem ist es irgendwie notwendig, das Problem des schnellen SSH-Zugriffs auf eine große Anzahl von Servern zu lösen.


Weiter - aus der Sicht des Linux-Terminals (unter Ubuntu 18 ausgeführt). Vielleicht funktioniert es in anderen Distributionen und wahrscheinlich gibt es sogar ein Analogon unter Windows - ich habe nicht gesucht.


Die Hauptanforderungen:


  • Einfach zu wiederholen. Mehrere Administratoren
    und Sie müssen die Möglichkeit haben, dasselbe für alle zu konfigurieren. Darüber hinaus ermöglichen wir Remote-Arbeit - zumindest hat jeder Laptop eine Situation, aber es kommt vor, dass Sie nicht an Ihrem gewohnten „lang getunten und debuggten“ Computer arbeiten.
  • Server werden hinzugefügt, gelöscht, Adressen geändert. Dies sollte berücksichtigt werden.

Zu diesem Zweck entschied ich mich, Alias-Hosts in den SSH-Einstellungen zu verwenden, die Liste der Server über den GCP-Client von gcloud cli abzurufen und dies alles mit Python 2.7 zu automatisieren (da dies in Ubuntu standardmäßig der Fall war und ich mich entschied, es zu studieren, um mit Daten zu arbeiten). Das Skript selbst mit einer Beschreibung unter dem Schnitt.


Erklärung des Problems


Die Idee war, eine Liste der Kommunikations-Alias-Server und ihrer aktuellen Adressen so zu führen, dass nur ein Name für den Verbindungsaufbau verwendet werden kann. Gleichzeitig wird die Liste selbst regelmäßig von GCP per API aktualisiert.


Infolgedessen gab es mehrere Aufgaben:


  1. Stellen Sie eine Verbindung zum Host her, indem Sie nur einen einprägsamen Namen eingeben (normalerweise werden die Namen nach strengen Regeln gebildet, sodass es ausreicht, den Client und das System zu kennen, um den Servernamen mit ziemlicher Sicherheit zu erraten). Namen können real (wenn der Server vollständig von uns erstellt wurde) oder alias in unserer Cmdb sein (wenn der Server vom Client erstellt wurde und der Name gemäß den Clientregeln zugewiesen wurde). In jedem Fall ist es einfacher, sich einen Namen als eine Adresse zu merken. Die Adresse ändert sich ebenfalls.
  2. Eine Liste der aktuellen Hosts mit gültigen Adressen abrufen. Weil Die Hauptplattform ist GCP, und 90% der Server sind dort. Dieses Problem wird dann durch die API und nicht durch Überwachungstools gelöst.
  3. Suche nach Hostnamen. Obwohl sie leichter zu merken sind, wächst die Anzahl und der Speicher ist nicht unbegrenzt :) Ja, und neue Administratoren sind einfacher.
  4. Aktualisieren Sie die Alias-Paketadresse nur, wenn sich die Adresse ändert. Dies ist erforderlich, um das vollständige Umschreiben aller Bundles aufzugeben. Dies ermöglicht die Speicherung von Bundles nicht nur für GCP-Server. Bisher wurde dieses Problem nicht gelöst :(

Lösungsbeschreibung


Alias ​​zum Verbinden


Alles hier ist ganz einfach und nicht von mir entschieden. Das Linux-Dienstprogramm ssh unterstützt die Alias-Konfiguration in der Konfigurationsdatei.


Dateispeicherort: ~ / .ssh / config


Das von uns verwendete Dateiformat ist sehr banal, aber tatsächlich sind die Möglichkeiten dort viel breiter:


HOST alias_ HostName ip__- 

Weitere Informationen zu den Konfigurationsoptionen finden Sie hier , hier oder in der offiziellen Dokumentation .


Weitere Schritte


  1. Verwenden Sie verschiedene Schlüssel, um eine Verbindung zu verschiedenen Hostgruppen herzustellen. Eine kleine Paranoia in Sachen Sicherheit wird nicht schaden.
  2. Erstellen Sie eine Sicherungskopie dieser Datei, um sich vor versehentlichen Änderungen zu schützen und Skriptfehler zu aktualisieren.

Suchen Sie nach Hostnamen


Hier liegt die Entscheidung gar nicht bei mir, sondern bei Ben Lobaugh und ist in seinem Artikel beschrieben .
Kurz gesagt, ich habe sed verwendet, das zum leichteren Starten (eine sehr lange Regel in den Parametern) mit alias abgekürzt wurde:


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

Wenn Sie den Host nach dem Namensteil suchen müssen, wird dieses Skript durch das Dienstprogramm grep perfekt ergänzt, und als Ergebnis sieht es folgendermaßen aus:


 sshhost | grep '---' 

Es gibt zum Beispiel andere Möglichkeiten, wie hier beschrieben.


Hostname wird automatisch vervollständigt


Danke für die Lösung onix74 !
Fügen Sie die Zeile zu ~ / .bash_completion hinzu:


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

Für den Befehl ssh funktioniert die automatische Vervollständigung gemäß der Liste der Alias-Server. Das heißt Sie können ssh verwenden, um den Namen des ssh-Servers zu ersetzen. Es funktioniert in Bash.

Weitere Schritte


Ich plane, die Hosts in Gruppen zu unterteilen, damit Sie alle Server eines bestimmten Clients oder einer bestimmten Anwendung auswählen können. Es scheint, dass diese Funktion für die Ausführung von Massenskripten und Ansible-Verbindungen interessant sein wird. sowie verschiedene Verbindungsdetails für verschiedene Gruppen zu erstellen. Aber wie viel Sinn es wirklich macht, bleibt abzuwarten.


Eine Liste der Hosts erhalten Sie von GCP


In diesem Schritt ist bis auf die Parametereinstellungen alles ganz einfach (obwohl es hier um Erfahrung geht). Ich habe mich für das GCloud SDK entschieden, um Daten abzurufen, weil Ich benutze es zwar selten, aber ich nehme an, dass dies mir irgendwann erlauben wird, die grafische Oberfläche immer weniger zu nutzen und die Administrationsroutine erheblich zu vereinfachen. Das Hauptargument ist daher, Erfahrung zu sammeln.
Dies könnte wahrscheinlich auch mit curl und der GCP-REST-API geschehen, und dann wäre die Lösung universeller (da die GCloud-SDKs eine separate Installation und Initialisierung erfordern, die nicht so kompliziert sind, aber dennoch erforderlich sind).


Um die notwendigen Informationen zu erhalten, musste ich das json-Format verwenden. Obwohl dies die weitere Verarbeitung der empfangenen Antwort stark vereinfacht hat, wurde ein wenig über das Festlegen von Formatierungsparametern im SDK nachgedacht.
Als Ergebnis erhielt ich den folgenden Befehl:


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

Es werden nur derzeit aktive Server mit Informationen zu ihrem Namen und ihrer Netzwerkschnittstelle zurückgegeben (es macht keinen Sinn, eine Verbindung zu den anderen Servern herzustellen). Bisher wird für jeden Server nur eine externe Schnittstelle verwendet.


Das Endergebnis kommt in json an:


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

Weitere Schritte


Suchen Sie ein Format, dessen Ausgabe die nachfolgende Verarbeitung minimiert oder sogar eliminiert.


Skript zum Erstellen einer Aliasliste basierend auf Daten von GCP


Das Skript wurde aus zwei Gründen in Python 2.7 geschrieben:


  1. Ich beschloss, es zu studieren, um mit Daten zu arbeiten.
  2. Python 2.7 ist standardmäßig auf den meisten Linux-Systemen installiert - es wird keine Probleme geben, es an anderer Stelle zu verwenden. Angesichts dessen, dass Sie jetzt sogar gewinnen können, können Sie ein zweites System einsetzen und Ubuntu als Terminal verwenden.

Der Algorithmus lautet wie folgt:


  1. Die Liste der Server wird mithilfe des SDK aus der Google Cloud abgerufen, wodurch die Ausführung des Befehls in der Konsole von Python aus initiiert wird.
  2. Wir analysieren den resultierenden JSON in pythonfreundliche Typen.
  3. Wir geben die Ausgabe in dem Format an, das für die Einstellung von ssh erforderlich ist (bei Bedarf wird die Skriptausgabe an ~ / .ssh / config oder eine Zwischendatei umgeleitet).

Skript anzeigen
 #!/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'] 

Aktualisieren nur geänderter Daten


Diese Aufgabe ist noch in Bearbeitung. Ich plane, die ssh / config-Datei im selben Skript zu lesen, sie mit den empfangenen Werten zu vergleichen und dann das gesamte Ergebnis zurückzuschreiben. Oder generieren Sie eine neue Datei separat und führen Sie einen Vergleich mit einer Art Diff durch. Auf diese Weise können Sie alle Änderungen manuell bestätigen.

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


All Articles