3000+ Solaris、AIX、およびLinuxサーバーでrootパスワードを変更する最善の方法は?


12

簡単に言えば、大企業、多くのUNIX / Linuxサーバー。

数年前に残った一連のスクリプトの責任を引き継ぎました。それらの1つは、Xか月ごとに実行され、すべてのサーバーのルートパスワードをグローバルに更新するスクリプトでした。

スクリプトはシェルスクリプトとExpectの混乱であり、すべてのサーバーと中央のコマンドアンドコントロールサーバーの間にセットアップされたSSH信頼で動作します。

問題は、スクリプトが巨大な混乱だということです。Expectコマンドは、そこにあるUNIX / Linuxボックスに存在する「passwd」のすべての可能なバージョンを考慮しようとしています-それらはかなり異なります。

多くのインフラストラクチャを拡張およびアップグレードしているため、スクリプトは非常に管理しにくくなっています。

私の質問は、これを行うより良い方法はありますか?既に確立されたSSH信頼があると仮定すると、3000 +サーバーのルートパスワードを同時に変更する最良の方法は何ですか?


2
sudoルートパスワードを完全に使用および削除することはオプションではありませんか?
ドミトリチュバロフ

5
インターンを雇う?:)
EEAA

1
「sudo」を使用する@DmitriChubarovは、パスワードを維持(および変更)するための別のアカウントを持っていることを意味します。
the-wabbit

1
@ syneticon-dj他のアカウントを新たに作成し、LDAPやNISなど、より適切にサポートされている集中管理されたデータベースに保存することができます。これは、ローカルルートをリッピングしてldapからのルートに置き換えることとは異なります。
ドミトリチュバロフ

2
3k台を超えるマシンがある場合は、管理ツールが必要です...昨日!
ウォーレン

回答:


17

Puppetを使用します。

Puppetは非常に柔軟で、保守が簡単で、SSLを使用します。少しやり過ぎのように聞こえるかもしれませんが、Puppetシステムを構築するには余分な努力が必要です。

だが。ほとんどの場合、これはこれらのマシンに対して行う最後の一括更新ではありません。Puppetは、大量更新手順が実際に開始され、スクリプトが非常に読みやすい/再利用可能な場合、多くの時間を節約します。

少なくともこれは数年前に私のために働いたが、それでもそれらのPuppetレシピ(別名スクリプト)のいくつかを再利用することができます。また、少し小さい環境でも使用しました。すべてのマシンが実際に既知の状態になっていることを確認してください。

私は何度も(多くの企業で)カスタマイズされたすべての展開スクリプトがしばらくすると、またはその次の人が介入すると苦痛になることを何度も証明しました。

これが実際に良さそうだと思う場合は、仮想環境が含まれすばらしいPuppetチュートリアルを使用して開始してください。


4
同意したが、パスワードの設定にa を使用しないでくださいuser{"root":}。代わりに、exec{"chpasswd -e ..."}より安全なを使用してください。
デニスカースメーカー

7
回答を修正してください。puppetはSSHではなくSSLを使用します。ansibleは、このユースケースにはるかに適した軽量の代替手段のように見えますが、残りの部分には同意します。ただ、pip install ansibleGNU / Linuxマシンでは、ホストのリストを構築しansible -m user -a "password=$crpyt"。エージェントは必要ありません。GNU / Linux、AIX、およびSolarisをすぐに管理します。
ダウド

確かに、SSHではなくSSLを使用します。私は、クライアントを実行することによってSSH経由でPuppetが使用されたシステムのメンテナーになるために使用します-長い話です。回答が修正されました。それを指摘してくれたdawudに感謝します!
トミ

以下に独自の回答を示しましたが、おそらく最も「正しく」管理しやすい長期的な解決策であるため、あなたの回答を受け入れています。ただし、当社の規模の環境でPuppetを展開するには、インフラストラクチャ、計画、ライセンス、および時間の面で多大な投資が必要です。いつかそこに
着き

1
@DennisKaarsemaker:それをバグとしてPuppet Labsに報告してください。彼らはそれを聞くことにとても興味があるでしょう。
ビル・ワイス

3

Solarisで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

「ベスト」については知りませんし、ミックス内のすべての非Linux * nixマシンで可能かどうかはわかりませんが、この種のアクティビティについてはpuppetまたはcfengineを検討しましたか?

ID管理用の市販の(非常に高価な)ツールもあります。過去に私が見た/使用した2つのツールは、Oracle Identity Managerとそれに相当するNovelです。


1

これを研究し続けた後、私はいくつかのことを学びました...

何よりもまず、これは特に多くの異なる環境で自動化するのは本当に面倒な作業です。この質問に対する最も正しい答えは、おそらく@tomiのものです: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"

これらのコマンドを実行するだけではありませんが、上記のコマンドが魔法のように機能します。

Solarisでパスワードを非反復的に変更する簡単な方法を見つけることができなかったので/etc/shadow、その場で変更することに頼りました。


2
コマンドラインにクリアテキストのパスワードを入れないでください。シェル履歴に記録されるためです。または、シェルの履歴を設定して/dev/nullから実行します。
マルシン

1
はい、またスクリプトでパスワードを入れないで、暗号化されたpasswdを追加するために私のスクリプトをチェック
ラーフルパティル

1

最近、Bashスクリプトを使用してこれを実行しました。

#!/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常に利用可能ではない....
クリス・S

すべてのボックスでコマンドを実行する部分がかなりうまくあります。問題は、パスワードの実際の変更です。私の知る限り、passwd常にユーザーと対話的です。
リカパー

passwdRHEL Linux上で少なくとも持っている--stdinパラメータ
AngerClown


0

2つのオプション:

パペットを使用する

実行デッキを使用します。Run deckは、数百台のマシンで同時にコマンドを実行できるサーバーです。マシンのサブセットのみでコマンドを実行するために、マシンをグループにグループ化できます。

http://rundeck.org


-2

/etc/shadowファイルのフォーマットは、Linuxディストリビューション全体でかなり標準的なものだと思います。パスワードを更新するための簡単な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
シャドウの形式はそうかもしれませんが、ハッシュはどこでも同じアルゴリズムによって解釈されることを保証されません。さらに、小さなスクリプトはシャドウからすべてのエントリを完全に削除しました。:}
ティンク

おっと、修正する必要があります。私はあなたがそのことをsudo実行しなかったことを願っています;)
HaxElit
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.