GNU/Linux >> Znalost Linux >  >> Linux

Jednoduchá jednosměrná synchronizace seznamu uživatelských hesel mezi servery

Řešení 1:

Pomocí awk můžete extrahovat uživatele/skupiny s ID 500 nebo vyšším. Také jsem si dovolil vyloučit ID uživatele 65534, které je často vyhrazeno pro uživatele „nikdo“ (v závislosti na distribuci; nemám ponětí, zda tak činí CentOS):

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

Poté pomocí rsync, scp nebo zvolené metody přenosu souborů zkopírujte soubory do zálohovacího systému. Tyto soubory lze poté připojit na konec „čistého“ souboru passwd, skupiny nebo stínového souboru, když je potřebujete obnovit (tj.:pouze výchozí uživatelé/skupiny systému, aby se zabránilo neúmyslné duplikaci ID/uživatelského jména).

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

Řešení 2:

NIS/NIS+ byly vynalezeny přesně z tohoto důvodu.

Ale jsou trochu ošklivé a centralizované (LDAP/Kerberos/SMB/atd.) autentizace je mnohem lepší nápad, pokud to umíte. K nastavení NIS/NIS+ budete potřebovat:

Balíčky:

yp-tools ypbind ypserv portmap

a /etc/yp.conf s něčím jako:

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

a poté v /etc/sysconfig/network:

NISDOMAIN=example.org

A já jsem zlenivěl, tady je dobrý návod:http://www.wains.be/index.php/2007/02/28/setting-up-nis-under-centos-4/, který vás tím provede.

Osobně bych pro zálohování zálohoval celý adresář /etc/ a skončil. Je to maximálně jen pár megů.

Řešení 3:

použijte cppw a 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.

Řešení 4:

Existuje mnoho způsobů a řešení, ale k zodpovězení původní otázky existují tři kroky:

  1. Vytvořte na serveru klíč SSH bez hesla:

    ssh-keygen -b 4096

  2. Zkopírujte .ssh/id_rsa.pub do .ssh/authorized__keys2 na klientovi:

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

  3. Přidejte něco takového do svého /etc/crontab (nebo upravte pomocí crontab -e):

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

Řešení 5:

Myslel jsem, že existuje něco, co bych mohl použít, aniž bych musel vytvářet vlastní řešení, ale musel jsem rychle něco udělat.

Níže je skript, který udělá přesně to, co jsem potřeboval.

Pokyny

Aby to fungovalo, stačí změnit několik konfiguračních proměnných pro minimální a maximální UID, aby byly považovány za normální uživatele a název vzdáleného hostitele nebo IP adresu.

Vzdálený server musíte nastavit tak, aby přijímal příchozí relace SSH z root místního serveru uživatele bez nutnosti zadávat heslo.
Velitel Keen naznačil, jak se to dělá, ve své odpovědi na této stránce, ale můžete se také podívat na přihlášení SSH bez hesla pro podrobné pokyny.

Jak to funguje

Skript dělá zkopírování každého vzdáleného passwd , skupina , stín , gshadow soubory ze vzdáleného serveru do dočasného umístění na serveru lcoal.
Poté odebere tyto dočasné soubory všem "normálním" uživatelům a ponechá pouze odkazy na systémové uživatele.

Dalším krokem je projít každou z místních verzí passwd , skupina , stín , gshadow a připojení pouze "normálních" uživatelů k jejich odpovídajícím dočasným souborům a následné nahrání každého z nich zpět na vzdálený server, aby nahradil ten starý.

Upozornění

Než se o něco pokusíte, ujistěte se, že jste si vytvořili kopii svého hesla , skupina , stín , gshadow na místním i vzdáleném serveru.

Zabezpečení

Vlastnictví souboru a atributy jsou zachovány.
Dočasné soubory jsou uloženy ve formátu /tmp a smazáno, ať už byla synchronizace úspěšná nebo ne.
Místní server musí mít root bez hesla přístup k záloze (ale ne naopak). To je nezbytné, abychom mohli získat konfigurační soubory uživatelských účtů (které jsou jinak omezeny).

Kodex

Toto je první pokus a je to trochu chaotický (není krásný kód), ale funguje to docela dobře a někdo jiný to může považovat za užitečné.

Je to skript v Perlu, který je závislý pouze na Net::SCP modul pro bezpečné kopírování souborů mezi servery.

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

Aktualizace 21. května 2010:aktualizovaný kód pro zlepšení synchronizace ID skupiny


Linux
  1. Jak přidat uživatele do skupiny v Linuxu

  2. Vytváření uživatelů s více možnostmi příkazů?

  3. Seznam členů skupiny v Linuxu

  1. Spravujte skupiny uživatelů Linuxu

  2. Jaký je rozdíl mezi přidáním uživatele do sudoers a kořenové skupiny?

  3. Potřebují jednoduché servery Linux z bezpečnostních důvodů skutečně uživatele bez oprávnění root?

  1. Funkce kořene uživatelské skupiny??

  2. Rozdíl mezi ! vs!! vs * v /etc/shadow

  3. BASH:Zkontrolujte v /etc/shadow, pokud je heslo uživatele uzamčeno