SSH-Key (PublicKey) auf mehrere Linux/Unix-Server verteilen mit Python

SSH-Key (PublicKey) auf mehrere Linux/Unix-Server verteilen mit Python

Wer mit vielen Servern arbeitet muss häufiger auf diese zugreifen. Ein Login mit Username und Passwort ist da in der Regel immer ziemlich anstrengend und zeitraubend. Häufig müssen auch nur einzelne Kommandos abgesetzt werden. Beispielsweise die cpuload von allen Servern eines Clusters.

putty_keygenSinnvoll ist es dann, wenn man diesen Befehl einfach und unkompliziert auf möglichst vielen Servern gleichzeitig ausführen kann. In der bash bietet sich dafür eine For-Schleife an. Wenn man nun allerdings die For-Schleife ausführt, dann müsste man bei jedem einzelnen Server sein Kennwort eingeben. Das ist nicht komfortabel. SSH bietet die Möglichkeit sich ohne Kennwort einzuloggen. Dazu wird ein Schlüssel-Paar erstellt. Der Private Schlüssel wird auf dem putty_keygen2Client hinterlegt, beispielsweise euer SSH Client Putty. Der öffentliche Schlüssel (Public Key) wird auf den entfernten Servern hinterlegt. Unter Windows und Putty kann der Schlüssel mit dem kleinen Zusatzprogramm PuTTYgen erstellt werden (siehe Screenshots, klickt zum vergrößern). Alternativ zu PuTTYgen kann das Schlüsselpaar auch mit dem Linuxtool ssh-keygen erstellt werden.

ssh-keygen -t rsa -C "your_email@example.com"

putty key saveDer private Schlüssel muss lokal gespeichert werden und anschließend bei der Putty-Session hinterlegt werden (Auch hier siehe Screenshot, markierter Bereich). Wenn das alles gemacht ist, dann muss der Schlüssel auf alle relevanten Server verteilt werden. Dies ist je nach Anzahl der Server allerdings mehr oder weniger anstrengend bzw. aufwendig. Ich habe mir dazu vor einiger Zeit ein kleines Python-Skript geschrieben. Dieses Skript verteilt meinen Public-Key auf mehrere Server. Vorrausetzung für dieses Skript ist das Python-Paket Paramiko. Wie man Paramiko installiert, habe ich kürzlich in einem anderen Artikel erklärt.

import paramiko
 
serverlist = server.txt
username = 'nico'
pw = 'password'
pub_key = 'ssh-rsa KEY-HASH nico@example.com'
 
def main():
    f = open(serverlist,'r')
    for host in f:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host, username=username, password=pw)
        cmd = 'mkdir .ssh; echo '+pub_key+' > .ssh/authorized_keys'
        ssh.exec_command(cmd)
        ssh.close()
    print 'Public-Keys wurde auf allen Systemen hinterlegt.'
    pass
 
if __name__ == '__main__':
    main()

Zur Erklärung:

serverlist: Hier müsst ihr eine Datei angeben in der alle Server zeilenweise enthalten sind. Die Datei muss entweder im gleichen Verzeichnis- wie euer Skript liegen oder es muss ein relativer bzw. absoluter Pfad angegeben werden. Beispiel:

server1
server2
server3
usw.

username und pw: Diese beiden Variablen sollten selbsterklärend sein. Benutzername  (Der Benutzername sollte auf jedem System identisch sein) und das entsprechende Kennwort an eurem Zielsystem.

pub_key: Hier müsst ihr euren Key kopieren. Dieser ist gewöhnlich etwas länger.

Je nachdem ob das Verzeichnis “.ssh” auf den Zielsystemen bereits existiert solltet ihr die Variable “cmd” auch noch entsprechend abändern.

Wenn ihr das alles beachtet habt, könnt ihr das Skript ausführen. Euer Public-Key sollte nun überall ausgerollt sein. Ein Login via SSH sollte überall möglich sein. Wenn ihr neue Server bekommt, dann solltet ihr die Server-Liste “server.txt” einfach aktualisieren. Ihr könnt das Skript dann ein weiteres mal ausführen. Die Keys werden erneut verteilt.