GNU/Linux >> Tutoriales Linux >  >> Linux

Sencilla sincronización unidireccional de la lista de contraseñas de usuario entre servidores

Solución 1:

Puede usar awk para extraer usuarios/grupos con ID de 500 o más. También me he tomado la libertad de excluir el ID de usuario 65534, que a menudo está reservado para el usuario "nadie" (dependiendo de la distribución; no tengo idea si CentOS lo hace):

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

A continuación, utilice rsync, scp o el método de transmisión de archivos que prefiera para copiar los archivos en su sistema de copia de seguridad. Estos archivos se pueden agregar al final de un archivo de contraseña, grupo o sombra 'limpio' cuando necesite restaurarlos (es decir, solo usuarios/grupos predeterminados del sistema, para evitar duplicaciones no intencionales de ID/nombre de usuario).

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

Solución 2:

NIS/NIS+ se inventaron exactamente por esta razón.

Pero son un poco feos y centralizados (LDAP/Kerberos/SMB/etc.) la autenticación es una idea mucho mejor si puede hacerlo. Para configurar NIS/NIS+ necesitará:

Paquetes:

yp-tools ypbind ypserv portmap

y un /etc/yp.conf con algo como:

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

y luego en /etc/sysconfig/network:

NISDOMAIN=example.org

Y me dio pereza, aquí hay un buen tutorial:http://www.wains.be/index.php/2007/02/28/setting-up-nis-under-centos-4/ que lo guiará.

Personalmente, para la copia de seguridad, simplemente haría una copia de seguridad de todo el directorio /etc/ y terminaría con eso. Son solo unos pocos megas como máximo.

Solución 3:

usa cppw y 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.

Solución 4:

Aquí hay muchas formas y soluciones, pero para responder a la pregunta original hay tres pasos:

  1. Cree una clave SSH sin contraseña en el servidor:

    ssh-keygen -b 4096

  2. Copie .ssh/id_rsa.pub a .ssh/authorized__keys2 en el cliente:

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

  3. Agregue algo como esto a su /etc/crontab (o edite con crontab -e):

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

Solución 5:

Bueno, pensé que había algo existente que podría usar sin tener que implementar mi propia solución, pero tenía que hacer algo rápido.

A continuación se muestra un script que hará justo lo que necesitaba.

Instrucciones

Para que funcione, simplemente cambie las pocas variables de configuración para que el UID mínimo y máximo se considere como normal usuario y el nombre del host remoto o la dirección IP.

Debe haber configurado el servidor remoto para aceptar sesiones SSH entrantes desde el root del servidor local usuario sin tener que introducir una contraseña.
El comandante Keen insinuó cómo se hace en su respuesta en esta página, pero también puede consultar inicio de sesión SSH sin contraseña para obtener instrucciones detalladas.

Cómo funciona

Lo que hace el script es copiar cada una de las contraseñas remotas , grupo , sombra , gsombra archivos del servidor remoto a una ubicación temporal en el servidor local.
Luego, elimina estos archivos temporales de todos los usuarios "normales", conservando solo las referencias a los usuarios del sistema.

El siguiente paso es revisar cada una de las versiones locales de passwd , grupo , sombra , gsombra y agregando solo los usuarios "normales" a sus archivos temporales correspondientes, luego subiendo cada uno de ellos al servidor remoto para reemplazar el anterior.

Advertencia

Antes de intentar cualquier cosa, asegúrese de hacer una copia de su contraseña , grupo , sombra , gsombra tanto en el servidor local como en el remoto.

Seguridad

Se conservan la propiedad y los atributos de los archivos.
Los archivos temporales se guardan en /tmp y eliminado, ya sea que la sincronización haya sido exitosa o no.
El servidor local debe tener root sin contraseña acceso a la copia de seguridad (pero no al revés). Esto es necesario para que podamos obtener los archivos de configuración de las cuentas de usuario (que de lo contrario están restringidos).

El Código

Este es un primer intento y es un poco complicado (no es un código hermoso), pero hace el trabajo bastante bien y alguien más puede encontrarlo útil.

Es un script de Perl que solo tiene una dependencia en el Net::SCP módulo para copiar archivos de forma segura entre servidores.

#!/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;
        }
}

Actualización del 21 de mayo de 2010:código actualizado para mejorar la sincronización del ID de grupo


Linux
  1. Listar miembros de un grupo en Linux

  2. Administrar grupos de usuarios de Linux

  3. Contraseña de pánico en Linux

  4. ¿Cuál es la diferencia entre agregar un usuario a sudoers vs grupo raíz?

  5. ¿Los servidores Linux simples realmente necesitan un usuario no root por razones de seguridad?

Cómo cambiar la contraseña de usuario en Linux

Cómo agregar un usuario a un grupo en Linux

Cómo enumerar grupos en Linux

Deshabilitar la autenticación de contraseña SSH para un usuario o grupo específico

Cómo agregar un usuario a un grupo en Linux

Cómo agregar un usuario a un grupo de Linux