GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Einfache einseitige Synchronisierung der Benutzerkennwortliste zwischen Servern

Lösung 1:

Sie können awk verwenden, um Benutzer/Gruppen mit IDs von 500 oder höher zu extrahieren. Ich habe mir auch die Freiheit genommen, die Benutzer-ID 65534 auszuschließen, die oft für den "niemand"-Benutzer reserviert ist (je nach Distribution; keine Ahnung, ob CentOS dies tut):

awk -F: '($3>=500) && ($3!=65534)' /etc/passwd > passwd.new
awk -F: '($3>=500) && ($3!=65534)' /etc/group > group.new
awk -F: '($3>=500) && ($3!=65534) {print $1}' /etc/passwd | grep -f - /etc/shadow > shadow.new

Verwenden Sie dann rsync, scp oder die Dateiübertragungsmethode Ihrer Wahl, um die Dateien auf Ihr Sicherungssystem zu kopieren. Diese Dateien können dann an das Ende einer „sauberen“ Passwd-, Gruppen- oder Schattendatei angehängt werden, wenn Sie sie wiederherstellen müssen (dh:nur Standardsystembenutzer/-gruppen, um unbeabsichtigte Duplizierungen von ID/Benutzername zu verhindern).

cat passwd.new >> /etc/passwd
cat group.new >> /etc/group
cat shadow.new >> /etc/shadow

Lösung 2:

NIS/NIS+ wurden genau aus diesem Grund erfunden.

Aber sie sind irgendwie hässlich und zentralisierte (LDAP/Kerberos/SMB/etc.) Authentifizierung ist eine viel viel bessere Idee, wenn Sie es tun können. Um NIS/NIS+ einzurichten, benötigen Sie:

Pakete:

yp-tools ypbind ypserv portmap

und eine /etc/yp.conf mit etwas wie:

domain example.org server nis.example.org
ypserver nis.example.org

und dann in /etc/sysconfig/network:

NISDOMAIN=example.org

Und ich wurde faul, hier ist eine gute Anleitung:http://www.wains.be/index.php/2007/02/28/setting-up-nis-under-centos-4/, die Sie durch die Anleitung führt.

Persönlich würde ich für Backups einfach das gesamte /etc/-Verzeichnis sichern und damit fertig sein. Es sind höchstens ein paar MB.

Lösung 3:

Verwenden Sie cppw und cpgr:

CPPW(8)                                                                                                                                                      

NAME
       cppw, cpgr - copy with locking the given file to the 
       password or group file

SYNOPSIS<br>
       cppw [-h] [-s] password_file
       cpgr [-h] [-s] group_file

DESCRIPTION
       cppw  and  cpgr will copy, with locking, the given file to
       /etc/passwd and /etc/group, respectively.  With the -s flag, 
       they will copy the shadow versions of those files, 
       /etc/shadow and /etc/gshadow, respectively.

       With the -h flag, the commands display a short help message
       and exit silently.

SEE ALSO
       vipw(8), vigr(8), group(5), passwd(5), shadow(5), gshadow(5)

AUTHOR
       cppw and cpgr were written by Stephen Frost, based on vipw 
       and vigr written by Guy Maor.

Lösung 4:

Hier gibt es viele Wege und Lösungen, aber um die ursprüngliche Frage zu beantworten, gibt es drei Schritte:

  1. Erstellen Sie einen passwortlosen SSH-Schlüssel auf dem Server:

    ssh-keygen -b 4096

  2. Kopieren Sie .ssh/id_rsa.pub nach .ssh/authorized__keys2 auf dem Client:

    scp ~/.ssh/id_rsa.pub client:.ssh/authorized_keys2

  3. Fügen Sie so etwas zu Ihrer /etc/crontab hinzu (oder bearbeiten Sie es mit crontab -e):

    0 0 * * * scp /etc/{passwd,shadow,group} [email protected]:/var/mybackupdir

Lösung 5:

Nun, ich dachte, es gäbe etwas, das ich verwenden könnte, ohne meine eigene Lösung entwickeln zu müssen, aber ich musste schnell etwas tun.

Unten ist ein Skript, das genau das tut, was ich brauchte.

Anleitung

Damit es funktioniert, ändern Sie einfach die wenigen Konfigurationsvariablen für die minimale und maximale UID, damit sie als normal betrachtet werden Benutzer und den entfernten Hostnamen oder die IP-Adresse.

Sie müssen den Remote-Server so eingerichtet haben, dass er eingehende SSH-Sitzungen von root des lokalen Servers akzeptiert Benutzer, ohne ein Passwort eingeben zu müssen.
Commander Keen hat in seiner Antwort auf dieser Seite angedeutet, wie es gemacht wird, aber Sie können sich auch auf die passwortlose SSH-Anmeldung beziehen für detaillierte Anweisungen.

Wie es funktioniert

Was das Skript tut, ist, jedes entfernte passwd zu kopieren , Gruppe , Schatten , gshadow Dateien vom Remote-Server an einen temporären Speicherort auf dem lcoal-Server.
Dann werden diese temporären Dateien von allen "normalen" Benutzern entfernt, wobei nur die Verweise auf die Systembenutzer beibehalten werden.

Der nächste Schritt besteht darin, jede der lokalen Versionen von passwd durchzugehen , Gruppe , Schatten , gshadow und nur die "normalen" Benutzer an ihre entsprechenden temporären Dateien anhängen und dann jeden von ihnen zurück auf den Remote-Server hochladen, um den alten zu ersetzen.

Warnung

Bevor Sie irgendetwas versuchen, vergewissern Sie sich, dass Sie eine Kopie Ihres Passworts anfertigen , Gruppe , Schatten , gshadow sowohl auf dem lokalen als auch auf dem entfernten Server.

Sicherheit

Dateieigentümer und -attribute bleiben erhalten.
Temporäre Dateien werden in /tmp gespeichert und gelöscht, unabhängig davon, ob die Synchronisierung erfolgreich war oder nicht.
Der lokale Server muss passwortlos root haben Zugriff auf das Backup (aber nicht umgekehrt). Dies ist notwendig, damit wir die Konfigurationsdateien der Benutzerkonten erhalten können (die ansonsten eingeschränkt sind).

Der Kodex

Dies ist ein erster Versuch und ein bisschen chaotisch (kein schöner Code), aber es macht seine Arbeit ziemlich gut und jemand anderes könnte es nützlich finden.

Es ist ein Perl-Skript, das nur eine Abhängigkeit von Net::SCP hat Modul zum sicheren Kopieren von Dateien zwischen Servern.

#!/usr/bin/perl -w
use Net::SCP qw(scp);
use strict;

use constant TRUE  => (1==1);
use constant FALSE => (1==0);

#--------------------------------------------------------
# Configuration
# Modify as needed
#--------------------------------------------------------
my $remoteHost = '10.13.113.2';  # email backup server
my $minUID     = 500;
my $maxUID     = 30000;
my $minGID     = 500;
my $maxGID     = 30000;

#--------------------------------------------------------
# Internal variables, normally not to be modified.
#--------------------------------------------------------
my $systemConfigDir = '/etc';
my $tmpDir = $ENV{TMPDIR} || $ENV{TMP} || $ENV{TEMP} || '/tmp';

#--------------------------------------------------------
#  Main
#--------------------------------------------------------
# STEP 1
# Get the remote files to /tmp and
# clean them of their normal users
ProcessFiles('remote');

# STEP 2
# Append the local normal users to the temp files
# and then send them back to the remote
ProcessFiles('local');

#--------------------------------------------------------
# ProcessFiles sub does one of two things:
# - if the passed argument is 'remote', then fetch each
#   user account file from the remote server, then remove
#   all normal users from each file, only keeping the
#   system users.
# - if the passed argument is 'local', then appends all
#   normal local users to the previously fetched and
#   cleaned-up files, then copies them back to the remote.
#--------------------------------------------------------
sub ProcessFiles {
        my $which = shift;
        my $tmpfile;
        my %username = ();
        my %usergroup = ();
        my %userUID = ();
        my %userGID = ();
        my @info;
        foreach my $f ('passwd','group','shadow','gshadow') {
                my $tmpfile = "$tmpDir/$f.REMOTE";
                if ($which eq 'remote') {
                        # Fetch the remote file
                        unlink $tmpfile if -e $tmpfile;
                        scp("$remoteHost:$systemConfigDir/$f", $tmpfile)
                                or die ("Could not get '$f' from '$remoteHost'");
                }
                # Glob the file content
                open CONFIGFILE, (($which eq 'remote') ? $tmpfile : "$systemConfigDir/$f");
                my @lines = <CONFIGFILE>;
                close CONFIGFILE;
                # Open the temp file, either truncating it or in append mode
                open TMPFILE,  (($which eq 'remote') ? ">$tmpfile" : ">>$tmpfile" )
                        or die "Could not open '$tmpfile' for processing";
                foreach my $line (@lines) {
                         # Skip comments, although they should be illegal in these files
                        next if $f =~ /^\s*#/;
                        @info = (split ':', $line);
                        if ($f eq 'passwd') {
                                my $uid = $info[2];
                                my $isnormaluser = ($uid > $minUID) && ($uid < $maxUID);
                                next if (($which eq 'remote') ? $isnormaluser : !$isnormaluser);
                                $username{$info[0]} = TRUE;
                                $userUID{$uid} = TRUE;
                                $userGID{$info[3]} = TRUE;
                        } elsif ($f eq 'group') {
                                my $gid = $info[2];
                                my $isnormalgroup = ($gid > $minGID) && ($gid < $maxGID);
                                next if (($which eq 'remote') ? $isnormalgroup : !$isnormalgroup);
                                $usergroup{$info[0]} = TRUE;
                        } elsif ($f eq 'shadow') {
                                next if !exists $username{$info[0]};
                        } else {
                                next if !exists $usergroup{$info[0]};
                        }
                        # Any line that reaches this point is valid
                        print TMPFILE $line;
                }
                close TMPFILE;
                if ($which eq 'local') {
                        # send the file back
                        scp($tmpfile, "$remoteHost:$systemConfigDir/$f") or
                                die ("Could not send '$f' to '$remoteHost'");
                        unlink $tmpfile;
                }
        }
}

#--------------------------------------------------------
# Make sure we cleanup the temp files when we exit
#--------------------------------------------------------
END {
        my $tmpfile;
        foreach my $f ('passwd','group','shadow','gshadow') {
                $tmpfile = "$tmpDir/$f.REMOTE";
                unlink $tmpfile if -e $tmpfile;
        }
}

Update 21. MAI 2010:Code aktualisiert, um die Synchronisierung der Gruppen-ID zu verbessern


Linux
  1. So fügen Sie Benutzer zu einer Gruppe in Linux hinzu

  2. Mitglieder einer Gruppe in Linux auflisten

  3. Linux-Benutzergruppen verwalten

  4. Setzen oder ändern Sie ein Benutzerkennwort in Linux

  5. Panikpasswort unter Linux

So ändern Sie das Benutzerkennwort in Linux

So fügen Sie einen Benutzer zu einer Gruppe in Linux hinzu

Wie man Gruppen in Linux auflistet

Deaktivieren Sie die SSH-Passwortauthentifizierung für bestimmte Benutzer oder Gruppen

So fügen Sie einen Benutzer zu einer Gruppe unter Linux hinzu

So fügen Sie einen Benutzer zu einer Linux-Gruppe hinzu