如何通过 bash 脚本将 ssh 密钥添加到主机
Posted
技术标签:
【中文标题】如何通过 bash 脚本将 ssh 密钥添加到主机【英文标题】:how to add ssh key to host via bash script 【发布时间】:2017-02-01 20:33:14 【问题描述】:我一直在尝试自动创建用户和配置 ssh 访问。
到目前为止,我创建了一个访问主机并通过expect创建新用户的脚本,如下:
expect -c '
spawn ssh '$user'@'$ip';
expect "assword: ";
send "'$passwd'\r";
expect "prompt\n";
send "adduser '$new_user'\r";
...
send "mkdir /home/'$new_user'/.ssh\r";
expect "prompt\n";
send "exit\r";
'
这很好,之后我需要将 .pub 密钥文件添加到主机中的授权密钥文件中,这是地狱开始的地方。
我试过了:
ssh_key='/home/.../key.pub'
content=$(cat $ssh_key)
expect -c '
spawn ssh '$user'@'$ip' "echo '$content' >> /home/'$new_user'/.ssh/authorized_keys;
expect "password:";
...
'
得到:
missing "
while executing
"spawn ssh root@000.00.00.00 ""
couldn't read file "<ssh .pub key content> ...
我也试过了:
cat $ssh_key | ssh $user@$ip "cat >> /home/$new_user/.ssh/authorized_keys"
没有成功,我只得到密码查询闪烁,我无法用最后一种方法连接期望。
【问题讨论】:
您可能会养成使用shellcheck.net 的习惯——它会发现您的错误。 【参考方案1】:我将在这里忽略较大的问题,并专门关注您的问题。 (还有更大的问题:不要在这里使用expect
——如果你依赖sshpass
,你可以极大地简化这个脚本。
现在,当您关闭单引号时,您不会启动任何其他类型的引号。这意味着当您用空格替换变量时,您结束了传递给expect
的-c
参数。
不要这样做:
'foo'$bar'baz'
这样做:
'foo'"$bar"'baz'
...所以你的脚本看起来更像:
ssh_key='/home/.../key.pub'
content=$(<"$ssh_key")
expect -c '
spawn ssh '"$user"'@'"$ip"' "echo '"$content"' >> /home/'"$new_user"'/.ssh/authorized_keys;
expect "password:";
...
'
不过,要完全避免这种情况,请考虑以下类似的方法:
#!/bin/bash
# ^^^^- NOT /bin/sh
content=$(<"$ssh_key") # more efficient alternative to $(cat ...)
# generate shell-quoted versions of your variables
# these are safe to substitute into a script
# ...even if the original content contains evil things like $(rm -rf /*)
printf -v content_q '%q' "$content"
printf -v new_user_q '%q' "$new_user"
# use those shell-quoted versions remotely
sshpass -f"$password_file" ssh "$host" bash -s <<EOF
adduser $new_user_q
printf '%s\n' $content_q >>/home/$new_user_q/.ssh/authorized_keys
EOF
【讨论】:
以上是关于如何通过 bash 脚本将 ssh 密钥添加到主机的主要内容,如果未能解决你的问题,请参考以下文章
无法将 IP 地址“xxx”的 RSA 主机密钥添加到已知主机列表 (/home/webapp/.ssh/known_hosts)