Der beste Weg, um ein Root-Passwort auf über 3000 Solaris-, AIX- und Linux-Servern zu ändern?

12

Kurz gesagt: Große alte Firma, viele UNIX / Linux-Server.

Ich übernahm die Verantwortung für eine Reihe von Skripten, die vor einigen Jahren noch verfügbar waren. Eines davon war ein Skript, das alle zehn Monate ausgeführt wurde, um das root-Passwort global auf allen unseren Servern zu aktualisieren.

Das Skript ist eine Mischung aus Shell-Skript und Expect und funktioniert mit der SSH-Vertrauensstellung, die zwischen all unseren Servern und einem zentralen Befehls- und Steuerungsserver eingerichtet wurde.

Das Problem ist, dass das Drehbuch ein riesiges Durcheinander ist. Die Expect-Befehle versuchen, jede mögliche Version von "passwd" zu berücksichtigen, die auf einer UNIX / Linux-Box vorhanden ist - und sie variieren erheblich.

Da wir einen Großteil unserer Infrastruktur erweitern und aufrüsten, wird das Skript wirklich unhandlich.

Meine Frage ist: Gibt es einen besseren Weg, dies zu tun? Angenommen, es gibt bereits eine etablierte SSH-Vertrauensstellung. Wie lässt sich das Root-Passwort auf über 3000 Servern gleichzeitig am besten ändern?

Ricapar
quelle
2
Das Verwenden sudound Eliminieren von root-Passwörtern ist keine Option, oder?
Dmitri Chubarov
5
Einen Praktikanten einstellen? :)
EEAA
1
@DmitriChubarov mit "sudo" würde bedeuten, ein anderes Konto zu haben, um ein Passwort zu verwalten (und zu ändern) - also wo ist der Punkt?
the-wabbit
1
@ syneticon-dj Die anderen Konten können neu erstellt und in einer zentral verwalteten Datenbank gespeichert werden, z. B. LDAP oder NIS, was auch immer besser unterstützt wird. Es ist nicht dasselbe, als die lokale Wurzel abzureißen und durch die von ldap zu ersetzen.
Dmitri Chubarov
2
Wenn Sie über 3.000 Maschinen verfügen, benötigen Sie Verwaltungstools ... gestern!
Warren

Antworten:

17

Verwenden Sie Marionette .

Puppet ist sehr flexibel, pflegeleicht und nutzt SSL. Könnte ein bisschen übertrieben klingen und Sie müssen sich zusätzliche Mühe geben, um das Puppet-System aufzubauen.

Aber. Höchstwahrscheinlich ist dies nicht das letzte Massenupdate, das Sie für diese Maschinen durchführen werden. Puppet wird und spart Ihnen viel Zeit, wenn die eigentliche Massenaktualisierung beginnt und Skripte sehr gut lesbar / wiederverwendbar sind.

Zumindest hat das vor ein paar Jahren für mich geklappt und trotzdem kann ich einige dieser Puppet-Rezepte (auch als Skripte bekannt) wiederverwenden. Ich habe es auch in etwas kleineren Umgebungen verwendet, stelle nur sicher, dass jede Maschine tatsächlich einen bekannten Zustand hat .

Ich habe es viele Male (in vielen Unternehmen) bewiesen, dass alle benutzerdefinierten Bereitstellungsskripte nach einer Weile oder wenn der nächste Typ hereinkommt, unangenehm werden. Und solange Sie ein Mobiltelefon bei sich haben, werden Sie alte Skripte verfolgen.

Wenn Sie der Meinung sind, dass dies tatsächlich gut klingt, finden Sie hier ein großartiges Puppet-Tutorial mit einer virtuellen Umgebung , um Ihnen den Einstieg zu erleichtern.

tomi
quelle
4
Agred, aber verwenden Sie nicht a user{"root":}, um das Passwort festzulegen . Verwenden Sie stattdessen eine exec{"chpasswd -e ..."}, die viel sicherer ist.
Dennis Kaarsemaker
7
Bitte korrigieren Sie Ihre Antwort, Puppet verwendet SSL, nicht SSH. Stimmen Sie mit dem Rest überein , obwohl Ansible wie eine leichte Alternative erscheint, die für diesen Anwendungsfall viel besser geeignet ist. pip install ansibleErstellen Sie einfach in einer GNU / Linux-Box eine Liste von Hosts und ansible -m user -a "password=$crpyt". Keine Agenten benötigt. Verwaltet GNU / Linux, AIX und Solaris sofort.
Dawud
Richtig, es wird SSL verwendet, nicht SSH. Früher war ich Maintainer in einem System, in dem Puppet über SSH verwendet wurde, indem ich einen Client ausführte - eine kurze Geschichte. Antwort korrigiert. Vielen Dank , dass Dawud darauf hinweist!
Tomi
Ich habe meine eigene Antwort unten angegeben , aber ich akzeptiere Ihre, da es wahrscheinlich die "korrekteste" und am besten handhabbare langfristige Lösung für das Problem ist. Es sind jedoch erhebliche Investitionen in Bezug auf Infrastruktur, Planung, Lizenzierung und Zeit erforderlich, um Puppet in einer Umgebung unserer Größe einzuführen.
Eines
1
@DennisKaarsemaker: Das solltest du Puppet Labs als Fehler melden. Sie wären sehr daran interessiert, es zu hören.
Bill Weiss
3

Ich habe das Perl-Modul Authen :: PAM unter Solaris mit großem Erfolg verwendet. Hier ist ein Beispielskript:

#!/usr/bin/perl

use Authen::PAM;

my $username = 'root';
my $password = '1234567';

die qq{Error: Unknown user\n} unless getpwnam($username);

die qq{Error: You must run this as root.\n} unless ($> == 0);

my $pamh;

sub my_conv_func
{
    my @res;
    while ( @_ )
    {
        my $code = shift;
        my $msg = shift;
        my $ans = "";

        if ($code == PAM_PROMPT_ECHO_OFF() )
        {
            if (($msg =~ /^New Password:/i) or ($msg =~ /^Re-enter new Password:/i))
            {
                $ans = $password;
            }
            else
            {
                die qq{Unknown message: $msg\n};
            }
        }
        else
        {
            print qq{$msg\n};
        }

        push @res, (PAM_SUCCESS(), $ans);
    }
    push @res, PAM_SUCCESS();

    return @res;
}

ref($pamh = new Authen::PAM("passwd", $username, \&my_conv_func)) || die "Error code $pamh during PAM init!";

my $res = $pamh->pam_chauthtok;

print $pamh->pam_strerror($res),"\n" unless $res == PAM_SUCCESS();

exit 0;
fortezza
quelle
2

Wenn Sie Perl schreiben können, können Sie mit dem Modul Net :: OpenSSH :: Parallel ganz einfach Skripte schreiben, die auf entfernten Hosts über SSH parallele Aktionen ausführen.

Es enthält ein Beispielskript zum Ändern von Kennwörtern, das Sie als Basis verwenden können. Da es sich anscheinend um eine heterogene Umgebung handelt, möchten Sie die Hosts nach Typ gruppieren und für jeden einen anderen Sub für die Dialogbehandlung verwenden.

salva
quelle
1

Ich weiß nicht, was "am besten" ist und ob es für alle Nicht-Linux * nix-Maschinen in Ihrem Mix möglich ist, aber haben Sie sich für diese Art von Aktivität Marionette oder Cfengine angesehen?

Es gibt auch kommerzielle (sehr teure) Tools für das Identitätsmanagement. Zwei, die ich in der Vergangenheit gesehen / verwendet habe, sind Oracle Identity Manager und das Novel-Äquivalent.

basteln
quelle
1

Nachdem ich weiter nachgeforscht habe, habe ich ein paar Dinge gelernt ...

In erster Linie ist dies eine wirklich lästige Aufgabe, die automatisiert werden muss, insbesondere in vielen verschiedenen Umgebungen. Die richtigste Antwort auf diese Frage lautet wahrscheinlich @ tomi's: use Puppet.

Irgendwann hoffe ich, Puppet zum Verwalten der Infrastruktur zu bewegen, aber die Bereitstellung auf den UNIX-Servern des gesamten Unternehmens für eine Änderung des Root-Kennworts ist derzeit noch nicht möglich.

Nachdem ich viele Hilfeseiten und viele Google-Fu-Seiten gelesen hatte, gelang es mir, ein Skript zu erstellen, das eine Liste von Zielservern durchläuft, eine SSH-Verbindung herstellt und eine der folgenden Aktionen ausführt:

# Solaris
# Generate new pass via crypt(newpass,salt) and insert it into /etc/shadow

# AIX
$ echo "root:newpass" | chpasswd -f NOCHECK

# Linux
$ echo "newpass" | passwd root --stdin

# IBM VIO (Virtual I/O)
$ echo "echo \"padmin:newpass\" | chpasswd -f NOCHECK" | oem_setup_env

# IBM HMCs (Hardware Management Consoles)
$ chhmcusr -u hscroot -t passwd -v "newpass"

Es geht um einiges mehr als nur um das Ausführen dieser Befehle, aber die oben genannten Befehle wirken wie die Magie.

Ich konnte keine einfache Möglichkeit finden, das Kennwort unter Solaris nicht iterativ zu ändern. Daher haben wir spontan Änderungen vorgenommen /etc/shadow.

Ricapar
quelle
2
Bitte geben Sie keine Klartext-Passwörter in die Befehlszeile ein, da diese im Shell-Verlauf protokolliert werden. Oder stellen Sie den Shell-Verlauf auf ein, /dev/nullbevor Sie dies tun.
Marcin
1
ja, auch kein Passwort in das Skript einfügen, mein Skript überprüfen, um verschlüsseltes Passwort hinzuzufügen
Rahul Patil
1

Kürzlich habe ich dies mit Bash Script gemacht.

#!/usr/bin/env bash

# Change Password of Remote Server Using SSH

#--------------------------------------------
# Define User which you want to
# Change Password in remote server
#--------------------------------------------
Uname="root"
# Create Password in Encrpyted Form Using below command,
# and store in this script
# perl -e'print crypt("YourPassword", "salt")' ; echo -e
# then copy and past in following varible,
# password should be single qouted*

Password='safv8d8ESMmWk'

Update_Pass() {
  ssh $ruser@$Server_ip  -p $port "echo ${Uname}:${Password} | chpasswd -e"
}

Show_Help(){
cat <<_EOF
Usage $0        [OPTION]..
Mandatory arguments to long options are mandatory for short options too.
  -i, --ip     <IP_ADDR_OF_SREVER> IP Address Of Remote Server
  -u, --user   <Username>          Username Of Remote Server    <Default User is root>
  -p, --port   <port>              Port Of Remote Server        <Default is 22>

Note:- For Security Reason Do Not Provide Password to the script, because
       it will get save in history, so do not provide it,
       script will prompt for password

Report $0 bugs to [email protected]
_EOF
}



Main() {

        case $1 in
           -i|--ip) Server_ip=$2;
                    ruser="$4"; [[ -z $ruser ]] && ruser=root
                    port="$6";  [[ -z $port  ]]  && port=22
                    Update_Pass ;;
                *)  Show_Help ;;
        esac
}

Main $*
Rahul Patil
quelle
1

Dies ist meine bisherige Lösung. müssen noch sehen, ob es auf mehreren Systemen funktioniert

#!/usr/bin/env bash

ChangePassword()
{
    echo "changing password for server $ServerIp"
    ssh root@$ServerIp "echo root:${NewPassword} | chpasswd" < /dev/null
}

CreatePassword()
{
    while true;
    do
        echo "Please enter the new password :"
        read -s NewPassword <&0
        echo "Confirm the password :"
        read -s ConfirmPassword <&0 
        # /proc/${PPID}/fd/0

        if [ "$NewPassword" == "$ConfirmPassword" ]
        then
            break
        else
            echo "Passwords do not match"
            echo "Try again..."
        fi
    done
    ChangePassword
    echo "end of createpassword"
}

SetUpPasswordlessSSH()
{   
    echo "enter the old password from server $ServerIp when asked"
    ssh root@$ServerIp mkdir -p .ssh
    cat .ssh/id_rsa.pub | ssh root@$ServerIp 'cat >> .ssh/authorized_keys'

    echo "Passwordless SSH is now available"
    echo "Now you can change the password"
    CreatePassword
}

NoSSH()
{
    echo "Passwordless SSH for this server with ip $ServerIp is not yet set up."
    read -p "Do you want to set it up now? " -n 1 -r <&0
    echo "" 
    if [[ ! $REPLY =~ ^[Yy]$ ]]
    then
        break
    else
        SetUpPasswordlessSSH
    fi
}

AcceptHostKey()
{
    read -p "Do you trust the server? " -n 1 -r <&1 
    echo ""
    if [[ ! $REPLY =~ ^[Yy]$ ]]
    then
        break
    else
        SetUpPasswordlessSSH
    fi
}

Main()
{
    while read -r ServerIp <&9
    do
        echo  "Server $ServerIp ..."
        status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 $ServerIp echo ok 2>&1)
        if [[ $status == ok ]]
        then
            echo "creating password"
            CreatePassword
            echo "password changed"
        elif [[ $status == "Permission denied"* ]]
        then
            NoSSH
        elif [[ $status == "Host key verification failed"* ]]
        then
            echo "Error: $status"
            AcceptHostKey
        else
            echo "ERROR OCCURED FOR SERVER WITH IP: $ServerIp"
            echo "Error: $status"
        fi
    done 9< servers.txt
    history -cw
    clear
}

Main $*
duez
quelle
0

Sie können pdsh verwenden , um Ihren Befehl gleichzeitig auf mehreren Hosts auszuführen.

Jack
quelle
Und welchen Befehl wirst du ausführen? passwdist bei den verschiedenen genannten versionen unterschiedlich. pwnicht immer verfügbar ....
Chris S
Wir haben den Teil der Ausführung von Befehlen auf allen Boxen ziemlich gut. Das Problem ist die tatsächliche Änderung des Passworts. Soweit ich weiß, passwdist es immer benutzerinteraktiv.
Ricapar
passwdAuf RHEL Linux hat zumindest ein --stdinParameter
AngerClown
0

Neben Puppet: SaltStack Ein weiterer Ansatz: Automatisieren Sie die Ausführung mithilfe von SSH-Bibliotheken entweder nacheinander oder parallel mithilfe von Fabric http://docs.fabfile.org/en/1.6/ , Capistrano oder ähnlichem, dessen Bereitstellung nicht viel Zeit und Mühe erfordert.

Eugene
quelle
0

Zwei Optionen:

Puppe benutzen

Run Deck verwenden. Run Deck ist ein Server, mit dem Sie Befehle auf Hunderten von Computern gleichzeitig ausführen können. Sie können Maschinen in Gruppen gruppieren, um Befehle nur für eine Teilmenge von Maschinen auszuführen.

http://rundeck.org

Spuder
quelle
-2

Ich denke, das Format der /etc/shadowDatei ist ziemlich Standard in Linux-Distributionen. Können Sie einfach ein einfaches awk-Skript schreiben, um das Passwort zu aktualisieren?

cat /etc/shadow| awk -v pass='NEWPASSHASH' -v now=`date '+%s'` 'BEGIN{ OFS=FS=":"} /^root/ {$2=pass; $3=now} {print}' > /tmp/shadow && mv /tmp/shadow /etc/shadow

Ich würde es auf jeden Fall testen, damit du dich nicht selbst aussperrst;)

HaxElit
quelle
Ich glaube, die Bearbeitung von / etc / shadow ist der richtige Weg. Wischt die Umleitung / etc / shadow jedoch nicht vor der Bearbeitung aus? Dies sieht aus wie ein Fall für Ed oder Ex.
mpez0
3
Das Format des Schattens kann sein, aber es ist nicht garantiert, dass die Hashes überall vom gleichen Algorithmus interpretiert werden. Außerdem hat Ihr kleines Skript gerade alle Einträge aus dem Schatten entfernt. :}
Tink
lol oops, sollte behoben werden. Ich hoffe du hast das nicht getan;)
HaxElit