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:
-
Erstellen Sie einen passwortlosen SSH-Schlüssel auf dem Server:
ssh-keygen -b 4096
-
Kopieren Sie .ssh/id_rsa.pub nach .ssh/authorized__keys2 auf dem Client:
scp ~/.ssh/id_rsa.pub client:.ssh/authorized_keys2
-
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