同じユーザーとパスの組み合わせを持つ任意の数のサーバーがあります。スクリプト(私が1回呼び出す)を書きたいので、
ssh-copy-id user@myserver
サーバーごとに呼び出されます。それらはすべて同じユーザー/パスを持っているため、これは簡単なはずですが、ssh-copy-id
は毎回別々にパスワードを入力することを望んでおり、スクリプトの目的に反しています。パスワード、つまりssh-copy-id -p mypassword user@myserver
を入力するオプションはありません。
ssh-copy-id
から要求されたときにパスワードフィールドに自動的に入力するスクリプトを作成するにはどうすればよいですか?
sshpass を見てください。パスワードをテキストファイルに入れて、次のようにします。
$ sshpass -f password.txt ssh-copy-id user@yourserver
Expectを使用して、パスワードプロンプトをリッスンし、パスワードを送信できます。
#!/usr/bin/expect -f
spawn ssh-copy-id $argv
expect "password:"
send "YOUR_PASSWORD\n"
expect eof
スクリプトを保存し、実行可能にして、次のように呼び出します:./login.expect user@myserver
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
これは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'
並列SSHツールの1つ(clusterssh、mssh、pssh)が適している場合があります。
たとえば、csshを使用してすべてのマシンにログインし、自分でキーを追加します。
私はそれがどれほどひどい考えであるかを強調したい:
これはもう少し安全な実装です...
#!/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
法案に合うかもしれないいくつかのこと:
他の回答で述べたように、sshpassがおそらく最も簡単なソリューションです。