Solution 1 :
Vous pouvez utiliser awk pour extraire les utilisateurs/groupes avec des ID de 500 ou plus. J'ai également pris la liberté d'exclure l'identifiant d'utilisateur 65534, qui est souvent réservé à l'utilisateur "personne" (selon la distribution ; aucune idée si CentOS le fait) :
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
Utilisez ensuite rsync, scp ou la méthode de transmission de fichiers de votre choix pour copier les fichiers sur votre système de sauvegarde. Ces fichiers peuvent ensuite être ajoutés à la fin d'un mot de passe, d'un groupe ou d'un fichier fantôme "propre" lorsque vous avez besoin de les restaurer (c'est-à-dire :utilisateurs/groupes système par défaut uniquement, pour éviter les duplications involontaires d'ID/nom d'utilisateur).
cat passwd.new >> /etc/passwd
cat group.new >> /etc/group
cat shadow.new >> /etc/shadow
Solution 2 :
NIS/NIS+ ont été inventés pour cette raison précise.
Mais ils sont un peu laids et l'authentification centralisée (LDAP/Kerberos/SMB/etc.) est une bien meilleure idée si vous pouvez le faire. Pour configurer NIS/NIS+, vous aurez besoin de :
Forfaits :
yp-tools ypbind ypserv portmap
et un /etc/yp.conf avec quelque chose comme :
domain example.org server nis.example.org
ypserver nis.example.org
puis dans /etc/sysconfig/network :
NISDOMAIN=example.org
Et je suis devenu paresseux, voici un bon guide :http://www.wains.be/index.php/2007/02/28/setting-up-nis-under-centos-4/ qui vous guidera à travers.
Personnellement, pour la sauvegarde, je sauvegarderais simplement l'intégralité du répertoire /etc/ et j'en aurais terminé. Ce n'est que quelques Mo tout au plus.
Solution 3 :
utilisez cppw et 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.
Solution 4 :
Il existe de nombreuses façons et solutions ici, mais pour répondre à la question initiale, il y a trois étapes :
-
Créez une clé SSH sans mot de passe sur le serveur :
ssh-keygen -b 4096
-
Copiez .ssh/id_rsa.pub vers .ssh/authorized__keys2 sur le client :
scp ~/.ssh/id_rsa.pub client:.ssh/authorized_keys2
-
Ajoutez quelque chose comme ceci à votre /etc/crontab (ou modifiez avec crontab -e) :
0 0 * * * scp /etc/{passwd,shadow,group} [email protected]:/var/mybackupdir
Solution 5 :
Eh bien, je pensais qu'il y avait quelque chose d'existant que je pouvais utiliser sans avoir à lancer ma propre solution, mais je devais faire quelque chose rapidement.
Vous trouverez ci-dessous un script qui fera exactement ce dont j'avais besoin.
Instructions
Pour que cela fonctionne, il suffit de changer les quelques variables de configuration pour que l'UID minimum et maximum soit considéré comme un normal utilisateur et le nom d'hôte distant ou l'adresse IP.
Vous devez avoir configuré le serveur distant pour accepter les sessions SSH entrantes depuis le root
du serveur local utilisateur sans avoir à saisir de mot de passe.
Le commandant Keen a expliqué comment cela se faisait dans sa réponse sur cette page, mais vous pouvez également vous référer à la connexion SSH sans mot de passe pour des instructions détaillées.
Comment ça marche
Ce que fait le script est de copier chacun des passwd distants , groupe , ombre , gombre fichiers du serveur distant vers un emplacement temporaire sur le serveur local.
Ensuite, il supprime ces fichiers temporaires de tous les utilisateurs "normaux", en ne conservant que les références aux utilisateurs du système.
L'étape suivante consiste à parcourir chacune des versions locales de passwd , groupe , ombre , gombre et en ajoutant uniquement les utilisateurs "normaux" à leurs fichiers temporaires correspondants, puis en téléchargeant chacun d'eux sur le serveur distant pour remplacer l'ancien.
Avertissement
Avant de tenter quoi que ce soit, assurez-vous de faire une copie de votre passwd , groupe , ombre , gombre sur les serveurs locaux et distants.
Sécurité
La propriété et les attributs des fichiers sont préservés.
Les fichiers temporaires sont enregistrés dans /tmp
et supprimé, que la synchronisation ait réussi ou non.
Le serveur local doit avoir root
sans mot de passe accès à la sauvegarde (mais pas l'inverse). Ceci est nécessaire pour que nous puissions obtenir les fichiers de configuration des comptes d'utilisateurs (qui sont autrement restreints).
Le code
C'est une première tentative et c'est un peu brouillon (pas beau code) mais ça fait plutôt bien le travail et quelqu'un d'autre pourrait le trouver utile.
C'est un script Perl qui ne dépend que du Net::SCP
module pour copier des fichiers en toute sécurité entre les serveurs.
#!/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;
}
}
Mise à jour 21MAY2010 :code mis à jour pour améliorer la synchronisation de l'ID de groupe