3000+ Solaris, AIX 및 Linux 서버에서 루트 비밀번호를 변경하는 가장 좋은 방법은 무엇입니까?


12

짧은 이야기 : 큰 오래된 회사, 많은 UNIX / Linux 서버.

몇 년 전에 남은 스크립트에 대한 책임을 물려 받았습니다. 그중 하나는 모든 서버에서 루트 암호를 전체적으로 업데이트하기 위해 $ X 개월마다 실행되는 스크립트였습니다.

이 스크립트는 Shell Script and Expect의 혼란이며 모든 서버와 중앙 명령 및 제어 서버 사이에 설정된 SSH 트러스트에서 작동합니다.

문제는 스크립트가 큰 혼란입니다. Expect 명령은 UNIX / Linux 상자에 존재하는 가능한 모든 "passwd"버전을 설명하려고합니다.

많은 인프라를 확장하고 업그레이드함에 따라 스크립트는 실제로 관리하기가 어렵습니다.

내 질문은 : 더 좋은 방법이 있습니까? 이미 설정된 SSH 신뢰가 있다고 가정하면 3000 개 이상의 서버에서 동시에 루트 암호를 변경하는 가장 좋은 방법은 무엇입니까?


2
sudo루트 암호를 사용 하거나 제거하는 것은 옵션이 아닙니다. 그렇지 않습니까?
Dmitri Chubarov

5
인턴 고용? :)
EEAA

1
"sudo"를 사용하는 @DmitriChubarov 는 암호를 유지하고 변경하기 위해 다른 계정을 가지고 있음을 의미 합니다. 요점은 어디입니까?
the-wabbit

1
@ syneticon-dj 다른 계정은 새로 생성되어 중앙에서 유지 관리되는 일부 데이터베이스 (예 : LDAP 또는 NIS)에 더 잘 지원되는 모든 데이터베이스에 저장 될 수 있습니다. 로컬 루트를 리핑하고 ldap에서 온 루트로 바꾸는 것과는 다릅니다.
Dmitri Chubarov

2
3k 대가 넘는 머신을 보유하고 있다면 어제 관리 도구가 필요합니다!
warren

답변:


17

꼭두각시를 사용하십시오 .

Puppet은 매우 유연하고 유지 관리가 쉽고 SSL을 사용합니다. 약간 과잉 소리를 낼 수 있으므로 꼭두각시 시스템을 구축하기 위해 약간의 노력을 기울여야합니다.

그러나. 아마도 이것은 당신이이 머신들에 대해 수행 할 마지막 대량 업데이트가 아닐 것입니다. 꼭두각시는 실제 대량 업데이트 절차가 시작되고 스크립트가 매우 읽기 쉽고 재사용 가능한 많은 시간을 절약 해줍니다.

적어도 이것은 몇 년 전에 저에게 효과가 있었지만 여전히 Puppet 레시피 (일명 스크립트)를 재사용 할 수 있습니다. 또한 좀 더 작은 규모의 환경에서도 사용했는데 모든 컴퓨터가 실제로 알려진 상태 인지 확인하십시오 .

나는 모든 사용자 정의 된 배포 스크립트가 잠시 후 또는 다음 사람이 들어올 때 엉덩이에 통증이되는 것으로 여러 번 입증했습니다.

이것이 실제로 좋은 것으로 생각되면 시작하기 위해 가상 환경이 포함 된 훌륭한 Puppet 자습서가 있습니다.


4
승인되었지만 a 를 사용하여 비밀번호를 설정 하지 마십시오user{"root":} . 대신 exec{"chpasswd -e ..."}훨씬 안전한을 사용하십시오.
Dennis Kaarsemaker

7
꼭두각시가 SSH가 아닌 SSL을 사용한다는 답변을 수정하십시오. 하지만, 나머지 동의 ansible이 훨씬 더이 사용 사례에 적합한 경량의 대안처럼 보인다. 그냥 pip install ansibleGNU / 리눅스 상자에 호스트 목록을 구축하고 ansible -m user -a "password=$crpyt". 에이전트가 필요하지 않습니다. 기본적으로 GNU / Linux, AIX 및 Solaris를 관리합니다.
dawud

사실 SSH가 아닌 SSL을 사용합니다. 나는 클라이언트를 실행하여 SSH를 통해 Puppet을 사용하는 시스템에서 관리자로 일합니다. 답변이 수정되었습니다. 그것을 지적하는 감사 dawud !
tomi

나는 아래 에 나 자신의 답변을 제공 했지만 문제에 대한 가장 "올 바르고"관리 가능한 장기적인 해결책 일 것이므로 귀하의 의견을 받아들입니다. 그러나 Puppet을 대규모 환경에 배포하려면 인프라, 계획, 라이센스 및 시간 측면에서 상당한 투자가 필요합니다. 언젠가 우리는 거기에 도착할 것이다 ...
Ricapar

1
@DennisKaarmaker : Puppet Labs에 버그로보고해야합니다. 그들은 그것을 듣는 데 매우 관심이 있습니다.
Bill Weiss

3

솔라리스에서 Perl 모듈 Authen :: PAM을 성공적으로 사용했습니다. 샘플 스크립트는 다음과 같습니다.

#!/usr/bin/perl

use Authen::PAM;

my $username = 'root';
my $password = '1234567';

die qq{Error: Unknown user\n} unless getpwnam($username);

die qq{Error: You must run this as root.\n} unless ($> == 0);

my $pamh;

sub my_conv_func
{
    my @res;
    while ( @_ )
    {
        my $code = shift;
        my $msg = shift;
        my $ans = "";

        if ($code == PAM_PROMPT_ECHO_OFF() )
        {
            if (($msg =~ /^New Password:/i) or ($msg =~ /^Re-enter new Password:/i))
            {
                $ans = $password;
            }
            else
            {
                die qq{Unknown message: $msg\n};
            }
        }
        else
        {
            print qq{$msg\n};
        }

        push @res, (PAM_SUCCESS(), $ans);
    }
    push @res, PAM_SUCCESS();

    return @res;
}

ref($pamh = new Authen::PAM("passwd", $username, \&my_conv_func)) || die "Error code $pamh during PAM init!";

my $res = $pamh->pam_chauthtok;

print $pamh->pam_strerror($res),"\n" unless $res == PAM_SUCCESS();

exit 0;

2

Perl을 작성할 수 있으면 Net :: OpenSSH :: Parallel 모듈을 사용하면 SSH를 통해 원격 호스트에서 병렬로 작업을 수행하는 스크립트를 매우 쉽게 작성할 수 있습니다.

기본으로 사용할 수있는 비밀번호 변경을위한 샘플 스크립트 가 포함되어 있습니다 . 이기종 환경이있는 것처럼 호스트를 유형별로 그룹화하고 모든 대화 처리 하위를 사용하려고합니다.


1

나는 "최상의"에 대해 모른다. 그리고 당신의 믹스에있는 모든 비 리눅스 * nix 머신이 가능한지 아닌지, 이런 종류의 활동을 위해 꼭두각시 나 cfengine을 보았는가?

아이덴티티 관리를위한 상용 (고가의) 툴도 있습니다. 과거에 보았거나 사용했던 두 가지는 Oracle Identity Manager와 Novel에 해당합니다.


1

이것을 계속 연구 한 후에, 나는 몇 가지를 배웠습니다 ...

무엇보다도, 이것은 특히 여러 환경에서 자동화하는 정말 성가신 작업입니다. 이 질문에 대한 가장 정확한 답변은 @ tomi 's : use Puppet입니다.

결국 Puppet이 인프라를 관리하게하려고했지만 루트 암호 변경을 위해 전체 엔터프라이즈의 UNIX 서버에 배포하는 것은 현재로서는 불가능합니다.

많은 맨 페이지와 많은 Google-fu를 읽은 후 대상 서버 목록을 반복하고 SSH 연결을 열고 다음 중 하나를 실행하는 스크립트를 만들었습니다.

# Solaris
# Generate new pass via crypt(newpass,salt) and insert it into /etc/shadow

# AIX
$ echo "root:newpass" | chpasswd -f NOCHECK

# Linux
$ echo "newpass" | passwd root --stdin

# IBM VIO (Virtual I/O)
$ echo "echo \"padmin:newpass\" | chpasswd -f NOCHECK" | oem_setup_env

# IBM HMCs (Hardware Management Consoles)
$ chhmcusr -u hscroot -t passwd -v "newpass"

그것은 단지 그 명령을 실행하는 것보다 훨씬 더 많은 일을하지만, 위의 것들은 마술을 작동시키는 것입니다.

솔라리스에서 비밀번호를 반복적으로 변경하는 간단한 방법을 찾을 수 없었기 때문에 /etc/shadow즉시 수정 했습니다.


2
쉘 히스토리에 로그인되므로 명령 행에 일반 텍스트 비밀번호를 입력하지 마십시오. 또는 쉘 히스토리를 수행 /dev/null하기 전에로 설정하십시오 .
Marcin

1
예, 스크립트도 넣지 마십시오 비밀번호, 암호화 된 passwd 파일을 추가 내 스크립트를 확인
라훌 파틸에게

1

최근에 Bash Script를 사용 하여이 작업을 수행했습니다.

#!/usr/bin/env bash

# Change Password of Remote Server Using SSH

#--------------------------------------------
# Define User which you want to
# Change Password in remote server
#--------------------------------------------
Uname="root"
# Create Password in Encrpyted Form Using below command,
# and store in this script
# perl -e'print crypt("YourPassword", "salt")' ; echo -e
# then copy and past in following varible,
# password should be single qouted*

Password='safv8d8ESMmWk'

Update_Pass() {
  ssh $ruser@$Server_ip  -p $port "echo ${Uname}:${Password} | chpasswd -e"
}

Show_Help(){
cat <<_EOF
Usage $0        [OPTION]..
Mandatory arguments to long options are mandatory for short options too.
  -i, --ip     <IP_ADDR_OF_SREVER> IP Address Of Remote Server
  -u, --user   <Username>          Username Of Remote Server    <Default User is root>
  -p, --port   <port>              Port Of Remote Server        <Default is 22>

Note:- For Security Reason Do Not Provide Password to the script, because
       it will get save in history, so do not provide it,
       script will prompt for password

Report $0 bugs to loginrahul90@gmail.com
_EOF
}



Main() {

        case $1 in
           -i|--ip) Server_ip=$2;
                    ruser="$4"; [[ -z $ruser ]] && ruser=root
                    port="$6";  [[ -z $port  ]]  && port=22
                    Update_Pass ;;
                *)  Show_Help ;;
        esac
}

Main $*

1

이것은 지금까지 내 솔루션입니다. 여전히 여러 시스템에서 작동하는지 확인해야합니다.

#!/usr/bin/env bash

ChangePassword()
{
    echo "changing password for server $ServerIp"
    ssh root@$ServerIp "echo root:${NewPassword} | chpasswd" < /dev/null
}

CreatePassword()
{
    while true;
    do
        echo "Please enter the new password :"
        read -s NewPassword <&0
        echo "Confirm the password :"
        read -s ConfirmPassword <&0 
        # /proc/${PPID}/fd/0

        if [ "$NewPassword" == "$ConfirmPassword" ]
        then
            break
        else
            echo "Passwords do not match"
            echo "Try again..."
        fi
    done
    ChangePassword
    echo "end of createpassword"
}

SetUpPasswordlessSSH()
{   
    echo "enter the old password from server $ServerIp when asked"
    ssh root@$ServerIp mkdir -p .ssh
    cat .ssh/id_rsa.pub | ssh root@$ServerIp 'cat >> .ssh/authorized_keys'

    echo "Passwordless SSH is now available"
    echo "Now you can change the password"
    CreatePassword
}

NoSSH()
{
    echo "Passwordless SSH for this server with ip $ServerIp is not yet set up."
    read -p "Do you want to set it up now? " -n 1 -r <&0
    echo "" 
    if [[ ! $REPLY =~ ^[Yy]$ ]]
    then
        break
    else
        SetUpPasswordlessSSH
    fi
}

AcceptHostKey()
{
    read -p "Do you trust the server? " -n 1 -r <&1 
    echo ""
    if [[ ! $REPLY =~ ^[Yy]$ ]]
    then
        break
    else
        SetUpPasswordlessSSH
    fi
}

Main()
{
    while read -r ServerIp <&9
    do
        echo  "Server $ServerIp ..."
        status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 $ServerIp echo ok 2>&1)
        if [[ $status == ok ]]
        then
            echo "creating password"
            CreatePassword
            echo "password changed"
        elif [[ $status == "Permission denied"* ]]
        then
            NoSSH
        elif [[ $status == "Host key verification failed"* ]]
        then
            echo "Error: $status"
            AcceptHostKey
        else
            echo "ERROR OCCURED FOR SERVER WITH IP: $ServerIp"
            echo "Error: $status"
        fi
    done 9< servers.txt
    history -cw
    clear
}

Main $*

0

pdsh 를 사용 하여 동시에 여러 호스트에서 명령을 실행할 수 있습니다 .


그리고 어떤 명령을 실행 하시겠습니까? passwd언급 된 버전마다 다릅니다. pw항상 가능하지는 않습니다 ....
Chris S

우리는 모든 박스에서 명령을 실행하는 부분이 꽤 있습니다. 문제는 실제 암호 변경입니다. 내가 아는 한 passwd항상 사용자 대화식입니다.
Ricapar

passwdRHEL 리눅스에 적어도 가지고 --stdin매개 변수
AngerClown

0

꼭두각시 이외에도 : SaltStack 또 다른 접근법- 배치에 많은 시간 / 노력이 필요하지 않은 Fabric http://docs.fabfile.org/en/1.6/ , Capistrano 등을 사용하여 순차적으로 또는 병렬로 SSH 라이브러리를 사용하여 실행을 자동화 하십시오 .


0

두 가지 옵션 :

꼭두각시 사용

런 데크를 사용하십시오. Run deck은 수백 대의 컴퓨터에서 동시에 명령을 실행할 수있는 서버입니다. 기계의 서브 세트에서만 명령을 실행하기 위해 기계를 그룹으로 그룹화 할 수 있습니다.

http://rundeck.org


-2

/etc/shadow파일 형식은 리눅스 배포판에서 꽤 표준 적이 라고 생각합니다 . 간단한 awk 스크립트를 작성하여 비밀번호를 업데이트 할 수 있습니까?

cat /etc/shadow| awk -v pass='NEWPASSHASH' -v now=`date '+%s'` 'BEGIN{ OFS=FS=":"} /^root/ {$2=pass; $3=now} {print}' > /tmp/shadow && mv /tmp/shadow /etc/shadow

나는 당신이 당신 자신을 잠그지 않도록 테스트해야합니다.)


/ etc / shadow를 편집하는 것이 좋습니다. 그러나 리디렉션 전에 리디렉션이 / etc / shadow를 지우지 않습니까? 이것은 ed 또는 ex의 경우처럼 보입니다.
mpez0

3
그림자의 형식은 가능하지만 해시가 모든 곳에서 동일한 알고리즘으로 해석되는 것은 아닙니다. 또한 작은 스크립트는 그림자에서 모든 항목을 완전히 제거했습니다. :}
Tink

LOP 죄송합니다. 수정해야합니다. 나는 당신이 그
주석을
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.