GNU/Linux >> Tutoriels Linux >  >> Linux

Synchronisation unidirectionnelle simple de la liste des mots de passe utilisateur entre les serveurs

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 :

  1. Créez une clé SSH sans mot de passe sur le serveur :

    ssh-keygen -b 4096

  2. Copiez .ssh/id_rsa.pub vers .ssh/authorized__keys2 sur le client :

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

  3. 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


Linux
  1. La fonction de la racine du groupe d'utilisateurs ? ?

  2. Création d'utilisateur avec plusieurs options de commande ?

  3. Lister les membres d'un groupe sous Linux

  4. Gérer les groupes d'utilisateurs Linux

  5. Mot de passe panique sous Linux

Comment changer le mot de passe utilisateur sous Linux

Comment ajouter un utilisateur à un groupe sous Linux

Comment lister les groupes sous Linux

Désactiver l'authentification par mot de passe SSH pour un utilisateur ou un groupe spécifique

Comment ajouter un utilisateur à un groupe sous Linux

Comment ajouter un utilisateur à un groupe Linux