
RedHat 파생 배포판(CentOS)을 사용하여 일반 사용자(UID가 500개 이상) 목록과 그룹(및 섀도우 파일)을 백업 서버에 푸시하고 싶습니다.
동기화는 주 서버에서 백업 서버로 단방향으로만 이루어집니다.
나는 LDAP나 NIS를 다루고 싶지 않습니다.
나에게 필요한 것은 백업 서버를 최신 상태로 유지하기 위해 매일 밤 실행할 수 있는 간단한 스크립트뿐입니다.
메인 서버는 SSH를 통해 백업 시스템에 접속할 수 있습니다.
어떠한 제안?
편집하다:
지금까지 제안해 주셔서 감사합니다. 하지만 제가 충분히 명확하게 설명하지 못한 것 같습니다.
저는 다음을 수행하는 일반 사용자의 동기화만 보고 있습니다.UID가 500 이상입니다..
시스템/서비스 사용자(UID가 500 미만)는 두 시스템에서 다를 수 있습니다.
따라서 전체 파일을 동기화할 수는 없습니다.
답변1
awk를 사용하여 ID가 500 이상인 사용자/그룹을 추출할 수 있습니다. 또한 "nobody" 사용자를 위해 종종 예약되는 사용자 ID 65534를 자유롭게 제외했습니다(distro에 따라 다르며 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
그런 다음 rsync, scp 또는 선택한 파일 전송 방법을 사용하여 파일을 백업 시스템에 복사합니다. 그런 다음 이러한 파일을 복원해야 할 때 '깨끗한' 비밀번호, 그룹 또는 섀도우 파일 끝에 추가할 수 있습니다(예: ID/사용자 이름의 의도하지 않은 중복을 방지하기 위해 기본 시스템 사용자/그룹만 해당).
cat passwd.new >> /etc/passwd
cat group.new >> /etc/group
cat shadow.new >> /etc/shadow
답변2
NIS/NIS+는 바로 이러한 이유로 발명되었습니다.
하지만 좀 추악하고 중앙 집중식(LDAP/Kerberos/SMB/등) 인증이 가능하다면 훨씬 더 나은 아이디어입니다. NIS/NIS+를 설정하려면 다음이 필요합니다.
패키지:
yp-tools ypbind ypserv portmap
그리고 다음과 같은 /etc/yp.conf가 있습니다:
domain example.org server nis.example.org
ypserver nis.example.org
그런 다음 /etc/sysconfig/network에서:
NISDOMAIN=example.org
그리고 나는 게을러졌습니다. 여기에 좋은 하우투가 있습니다:http://www.wains.be/index.php/2007/02/28/setting-up-nis-under-centos-4/그 내용을 안내해 드리겠습니다.
개인적으로 백업을 위해 전체 /etc/ 디렉토리를 백업하고 완료했습니다. 기껏해야 몇 메가에 불과합니다.
답변3
cppw 및 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.
답변4
글쎄요, 자체 솔루션을 출시하지 않고도 사용할 수 있는 것이 존재한다고 생각했지만 빠르게 조치를 취해야 했습니다.
아래는 내가 필요한 작업을 수행하는 스크립트입니다.
지침
작동하려면 최소 및 최대 UID에 대한 몇 가지 구성 변수를 변경하면 됩니다.정상사용자 및 원격 호스트 이름 또는 IP 주소.
root
비밀번호를 입력하지 않고도 로컬 서버 사용자로부터 들어오는 SSH 세션을 수락하도록 원격 서버를 설정해야 합니다 .
킨 사령관이 페이지의 답변에서 이것이 어떻게 수행되었는지 암시했지만 다음을 참조할 수도 있습니다.비밀번호 없는 SSH 로그인자세한 지침을 보려면.
작동 원리
스크립트가 하는 일은 각 원격 장치를 복사하는 것입니다.비밀번호,그룹,그림자,그림자원격 서버의 파일을 lcoal 서버의 임시 위치로 복사합니다.
그런 다음 모든 "일반" 사용자로부터 이러한 임시 파일을 제거하고 시스템 사용자에 대한 참조만 유지합니다.
다음 단계는 각 로컬 버전을 살펴보는 것입니다.비밀번호,그룹,그림자,그림자"일반" 사용자만 해당 임시 파일에 추가한 다음 각 사용자를 다시 원격 서버에 업로드하여 이전 사용자를 대체합니다.
경고
무엇이든 시도하기 전에 사본을 만들어 두십시오. 비밀번호,그룹,그림자,그림자로컬 및 원격 서버 모두에서.
보안
파일 소유권과 속성은 유지됩니다. 동기화 성공 여부에 관계없이
임시 파일이 저장되고 삭제됩니다 . 로컬 서버는 비밀번호 없이 백업에 액세스할 수 있어야 합니다(그 반대의 경우는 불가능). 이는 사용자 계정 구성 파일(다른 방법으로는 제한됨)을 가져오기 위해 필요합니다./tmp
root
코드
이것은 첫 번째 시도이고 약간 지저분하지만(아름다운 코드는 아님) 작업을 꽤 잘 수행하고 다른 사람이 유용하다고 생각할 수도 있습니다.
이것은 오직 Perl 스크립트에만 의존하는 Perl 스크립트입니다.Net::SCP
서버 간에 파일을 안전하게 복사하는 모듈입니다.
#!/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;
}
}
2010년 5월 21일 업데이트: 그룹 ID 동기화를 개선하기 위해 코드를 업데이트했습니다.