web-dev-qa-db-ja.com

ssh-copy-idの自動化

同じユーザーとパスの組み合わせを持つ任意の数のサーバーがあります。スクリプト(私が1回呼び出す)を書きたいので、

ssh-copy-id user@myserver

サーバーごとに呼び出されます。それらはすべて同じユーザー/パスを持っているため、これは簡単なはずですが、ssh-copy-idは毎回別々にパスワードを入力することを望んでおり、スクリプトの目的に反しています。パスワード、つまりssh-copy-id -p mypassword user@myserverを入力するオプションはありません。

ssh-copy-idから要求されたときにパスワードフィールドに自動的に入力するスクリプトを作成するにはどうすればよいですか?

32
devin

sshpass を見てください。パスワードをテキストファイルに入れて、次のようにします。

$ sshpass -f password.txt ssh-copy-id user@yourserver
28
quanta

Expectを使用して、パスワードプロンプトをリッスンし、パスワードを送信できます。

#!/usr/bin/expect -f
spawn ssh-copy-id $argv
expect "password:"
send "YOUR_PASSWORD\n"
expect eof

スクリプトを保存し、実行可能にして、次のように呼び出します:./login.expect user@myserver

20
MonkeeSage

quantaの答えはかなり良いですが、テキストファイルにパスワードを入力する必要があります。

「sshpass」のマンページから:

オプションを指定しない場合、sshpassは標準入力からパスワードを読み取ります。

したがって、できることは、スクリプトの実行中にパスワードを1回キャプチャし、それを変数に格納し、パスワードをエコーし​​、それを入力としてsshpassにパイプすることです。

私はいつもこれをやっていて、それはうまくいきます。例:echo "Please insert the password used for ssh login on remote machine:" read -r USERPASS for TARGETIP in $@; do echo "$USERPASS" | sshpass ssh-copy-id -f -i $KEYLOCATION "$USER"@"$TARGETIP" done

4
Esoteric Eric

これはssh-copy-idの問題です。また、実行するたびにキーが追加されます。プロセスを自動化している場合、authorized_keysファイルは重複したキーですぐに乱雑になります。これは、両方の問題を回避するPythonプログラムです。これは、コントロールサーバーから実行され、あるリモートサーバーから別のリモートサーバーにキーを配置します。

import subprocess
def Remote(cmd,IP):
    cmd = '''ssh root@%s '''%(IP)+cmd
    lines = subprocess.check_output(cmd.split())
    return '\n'.join(lines)
source = '123.456.78.90'
target = '239.234.654.123'
getkey = 'cat /root/.ssh/id_rsa.pub'
getauth = 'cat /root/.ssh/authorized_keys'
sourcekey = Remote(getkey, source).replace('\n','').strip()
authkeys = Remote(getauth, target).replace('\n','').strip()
if sourcekey not in authkeys: 
    keycmd=''' echo "%s" >>/root/.ssh/authorized_keys; 
    chmod 600 /root/.ssh/authorized_keys '''%(sourcekey) # A compound Shell statement
    print 'Installed key', Remote(keycmd,target)
else: print 'Does not need key'
2
mfs

並列SSHツールの1つ(clusterssh、mssh、pssh)が適している場合があります。

たとえば、csshを使用してすべてのマシンにログインし、自分でキーを追加します。

1
MikeyB

私はそれがどれほどひどい考えであるかを強調したい:

  1. スクリプトでハードコードされたパスワードを使用する
  2. すべてのサーバーで同じパスワードを使用してください。
  3. これを主張する場合は、SSH public_key + password認証を使用しないでください
  4. パスワードをテキストファイルに保存する

これはもう少し安全な実装です...

#!/usr/bin/python3
import os
import getpass
import argparse

parser = argparse.argument_parser()
parser.add_argument('-l','--login', action='store', help='username')
parser.add_argument('-p','--port', action='store', default='22', help='port')
parser.add_argument('-L','--list', action='store', help='file list of IPs')
parser.add_argument('-i','--ip-address', action='store', nargs='+', metavar='Host' help='ip or list of ips')

args = parser.parse_args()
if not args.login:
    print("You need a login, broski!")
    return 0

if args.list:
    ips = [i for i in open(args.list, 'r').readlines()]
    passwd = getpass.getpass('Password: ')

    for ip in ips:
        cmd = 'ssh-id-copy {0}@{1} -p {2}'.format(ip,args.port,passwd)            
        os.system('sshpass -p ' + passwd + ' ' + cmd)
        print("Key added: ", ip)   # prints if successful
        # ex: sshpass -p passwd ssh-id-copy [email protected]

Elif args.Host:
    ip = args.Host
    cmd = 'ssh-id-copy {0}@{1} -p {2}'.format(ip,args.port,passwd)
    os.system('sshpass -p ' + passwd + ' ' + cmd)
    print("Key added: ", ip)   # prints if successful
else:
    print("No IP addresses were given to run script...")
    return 0 
0
True Demon

法案に合うかもしれないいくつかのこと:

他の回答で述べたように、sshpassがおそらく最も簡単なソリューションです。

0
Richlv