パスワードを何度も入力することなく、SSH pubキーをサーバーのリストに伝達するにはどうすればよいですか?


26

最近、サーバーのリストへのユーザー名/パスワードアクセスが許可されたので、SSH公開キーをこれらのサーバーに伝達して、より簡単にログインできるようにします。

明確になるように:

  • これを自動化するために利用できる既存の公開キーはリモートサーバー上にありません。
  • これは、これらのサーバーに初めてログインするときになります。サーバーにアクセスするために資格情報を常に入力する必要はありません。
  • またssh-copy-id、forループで繰り返しパスワードを入力する必要もありません。

1
すべてのサーバーで同じユーザー名とパスワードですか?
ロアイマ

@roaima-うん!その詳細も私を驚かせましたが、それがこの特定のデータセンターのセットアップの仕方であり、それが彼らのやり方です。
slm

@ ott---Qを再確認します。forループスルーを行いたくないことを明示的に述べ、何度もssh-copy-idパスワードを送ります。
slm


2
これは、構成管理の完璧なユースケースです。人形、シェフ、アンシブルまたは塩を見てください。
スパーダー

回答:


31

パスワードを複数回入力する代わりにpssh、その-Aスイッチを使用してパスワードを1回要求し、リスト内のすべてのサーバーにパスワードを入力できます。

注:ssh-copy-idただし、この方法を使用してもを使用することはできないため、リモートアカウントの~/.ssh/authorized_keysファイルにSSH pubキーファイルを追加する独自の方法をロールする必要があります。

これが仕事をする例です:

$ cat ~/.ssh/my_id_rsa.pub                    \
    | pssh -h ips.txt -l remoteuser -A -I -i  \
    '                                         \
      umask 077;                              \
      mkdir -p ~/.ssh;                        \
      afile=~/.ssh/authorized_keys;           \
      cat - >> $afile;                        \
      sort -u $afile -o $afile                \
    '
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 23:03:58 [SUCCESS] 10.252.1.1
[2] 23:03:58 [SUCCESS] 10.252.1.2
[3] 23:03:58 [SUCCESS] 10.252.1.3
[4] 23:03:58 [SUCCESS] 10.252.1.10
[5] 23:03:58 [SUCCESS] 10.252.1.5
[6] 23:03:58 [SUCCESS] 10.252.1.6
[7] 23:03:58 [SUCCESS] 10.252.1.9
[8] 23:03:59 [SUCCESS] 10.252.1.8
[9] 23:03:59 [SUCCESS] 10.252.1.7

上記のスクリプトは一般的に次のように構成されています。

$ cat <pubkey> | pssh -h <ip file> -l <remote user> -A -I -i '...cmds to add pubkey...'

高レベルのpssh詳細

  • cat <pubkey> 公開鍵ファイルを出力します pssh
  • pssh-Iスイッチを使用してSTDIN経由でデータを取り込む
  • -l <remote user> リモートサーバーのアカウントです(IPファイル内のサーバー間で同じユーザー名を持っていると仮定しています)
  • -Apsshパスワードを要求し、接続するすべてのサーバーで再利用するように指示します
  • -ipssh出力をファイルに保存するのではなく、STDOUTに送信するように指示します(デフォルトの動作)
  • '...cmds to add pubkey...'-これは私が自分自身でこのダウンを破るますので、何が起こっているのトリッキーな部分である(下記参照します)

リモートサーバーで実行されているコマンド

これらは、pssh各サーバーで実行されるコマンドです。

'                                         \
  umask 077;                              \
  mkdir -p ~/.ssh;                        \
  afile=~/.ssh/authorized_keys;           \
  cat - >> $afile;                        \
  sort -u $afile -o $afile                \
'
順番に:
  • リモートユーザーのumaskを077に設定します。これにより、作成するディレクトリまたはファイルのパーミッションが次のように設定されます。

    $ ls -ld ~/.ssh ~/.ssh/authorized_keys
    drwx------ 2 remoteuser remoteuser 4096 May 21 22:58 /home/remoteuser/.ssh
    -rw------- 1 remoteuser remoteuser  771 May 21 23:03 /home/remoteuser/.ssh/authorized_keys
  • ディレクトリ~/.sshを作成し、既に存在する場合は警告を無視します

  • $afileauthorized_keysファイルへのパスで変数を設定します
  • cat - >> $afile -STDINから入力を取得し、authorized_keysファイルに追加します
  • sort -u $afile -o $afile -authorized_keysファイルを一意にソートして保存します

注:その最後のビットは、同じサーバーに対して上記を複数回実行する場合を処理することです。これにより、パブキーが複数回追加されることがなくなります。

シングルティックに注意してください!

また、これらのコマンドはすべて単一引用符で囲まれているという事実にも特に注意してください。$afileリモートサーバーで実行されるまで評価されたくないため、これは重要です。

'               \
   ..cmds...    \
'

ここを読みやすくするために上記を拡張しましたが、通常は次のようにすべてを1行で実行します。

$ cat ~/.ssh/my_id_rsa.pub | pssh -h ips.txt -l remoteuser -A -I -i 'umask 077; mkdir -p ~/.ssh; afile=~/.ssh/authorized_keys; cat - >> $afile; sort -u $afile -o $afile'

ボーナス素材

を使用psshすることにより、ファイルを-h <(...some command...)作成して動的コンテンツを提供する必要がなくなるか、別psshののスイッチを使用してIPのリストを作成できます-H "ip1 ip2 ip3"

例えば:

$ cat .... | pssh -h <(grep -A1 dp15 ~/.ssh/config | grep -vE -- '#|--') ...

上記を使用して、~/.ssh/configファイルからIPのリストを抽出できます。もちろん、printf動的コンテンツの生成にも使用できます。

$ cat .... | pssh -h <(printf "%s\n" srv0{0..9}) ....

例えば:

$ printf "%s\n" srv0{0..9}
srv00
srv01
srv02
srv03
srv04
srv05
srv06
srv07
srv08
srv09

また、seqフォーマットされた数字シーケンスを生成するために使用することもできます!

参照と同様のツール pssh

pssh上記のように使用したくない場合は、他のオプションも利用できます。


2
3つの小さな追加:(1)psshはPythonスクリプトであり、でインストールできますpip install pssh。(2)sshを実行しssh-keygenて、すべてのサーバーで同時にキーを生成することもできますpssh。(3)キーを生成した後、ループ内のすべての公開キーをローカルマシンにauthorized_keysコピーし、それらを共通マシンでアセンブルし、それを各マシンにコピーすることにより、キーを「すべて」に配布できます。 ssh_agent/ ssh_addパスワードを手伝うことができます。
lcd047

@ lcd047-ありがとう、今日は後でAに組み込みます!
slm

1
このスクリプトは、cat(古い)賞の無駄な使用に適していると思います。ファイルのコンテンツでパイプラインを開始するには、そのファイルから入力をリダイレクトするだけです。
マークヴァンレーウェン

1
@MarcvanLeeuwen-私は同意する傾向がありますが、今後の検索でこれに遭遇する可能性のある人が、パブキーがどのように渡されるかを明確に理解するのが簡単になるようにしたかったpsshです。
slm

1
@MarcvanLeeuwen:次のようにすればもはや無駄ではありません:cat ~/.ssh/*.pub | ...。ただし、この状況では、必要な場合とそうでない場合があります。
lcd047

7

を使用する代替方法xargssshpassおよびssh-copy-id

認証情報が次の形式でcredentials.txtにある と仮定しますuser:password@server

$ cat credentials.txt
root:insecure@192.168.0.1
foo:insecure@192.168.0.2
bar:realsecure@192.168.0.3

できること:

tr ':@' '\n' < credentials.txt \
| xargs -L3 sh -c 'sshpass -p $1 ssh-copy-id $0@$2'

注:使用後は、credentials.txtを必ず削除してください!


2
また、すべてのサーバーで同じユーザー名とパスワードを使用している場合は、直接ハードコーディングしてIPアドレスのリストのみを読み取ることができます:
Falco

6

ClusterSSHは、各マシンにウィンドウを提供し、すべてのウィンドウを制御する共通ウィンドウを備えています。

10台のマシンについて話している場合、これは機能します。100台のマシンを話している場合、多くのウィンドウがあります。

ClusterSSHの利点は、1台のマシンが他のマシンと100%異なる場合、ウィンドウをクリックするだけで、そのマシンにのみキーストロークを送信してから、すべてのマシンへのキーストロークの送信に戻ることができることです。


6

Ansibleの使用は非常に簡単です。<USER>実際のログイン名に置き換えるだけです

$ cd /path/to/public/key

$ cat<<END > hosts
  host1.example.com
  10.10.10.10
  END

$ ansible -i hosts all --ask-pass -u <USER> -m authorized_key \
      -a "user=<USER> key='$(cat id_rsa.pub)'"        

0

法案に適合する可能性のあるいくつかのこと:

他の回答で述べたように、sshpassおそらく最も簡単な解決策です。


-1

ここには2つのオプションがあります。

  • すべてのサーバーのIPアドレスを含むファイルを作成してから、以下を実行できます。

    while read -r ip;do
      ssh-copy-id -i .ssh/id_rsa.pub $ip
    done < servers.txt

servers.txtIP /ホスト名を持つファイルを想定しています。

  • すべてのIP /ホスト名をループに入れて、ssh-copy-id次のように実行できます。

    for i in hostname1 hostname2
      do ssh-copy-id -i .ssh/id_rsa.pub $i
    done

これはOPの要件に完全に反しssh-copy-idます。「forループで何度も繰り返しパスワードを入力する必要はありません。」
オールドタイマー

OPがすべてのサーバーに物理的にコピーしない限り、別の方法はないと思います。
トルガオズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.