问题
要通过一个跳板机ssh 登录其他主机,每次使用ssh hostIp -l username 再输入密码的方式太耗时,想要进行密码自动填充
解决
使用expect +bash shell 在ssshHost.sh 脚本中封装expect 的ssh登录自动填充密码功能
- 使用
expect 的自动填充密码功能+interact 交互功能
- 将
(hostIp,connectionStr) 写入配置文本或者直接在shell脚本作为字典
- shell读取用户输入hostIp,匹配出connectionStr,调用expect进行ssh登录,相关操作完成后
ctrl +d 退出
主要代码: expect部分:
function auto_login_ssh(){
expect -c "
set timeout 3600;
spawn ssh -o StrictHostKeyChecking=no $2;
expect {
*assword:* {
send $1r;
}
}
interact
"
return $?
}
bash shell部分:
declare -a hostInfoDict
hostInfoDict=(
["127"]="127.0.0.1 username passwd"
)
echo $#
if [ $# -ne 1 ]; then
echo "The args are problematic need hostIPNickName"
exit 1
fi
sshHostIp=$1
echo $sshHostIp
# echo ${hostInfoDict[$sshHostIp]}
OLD_IFS="$IFS"
IFS=" "
path_info_arr=(${hostInfoDict[$sshHostIp]})
IFS="$OLD_IFS"
hostIP=${path_info_arr[0]}
hostUser=${path_info_arr[1]}
hostPassWD=${path_info_arr[2]}
auto_login_ssh $hostPassWD $hostUser"@"$hostIP
其中:
- expect部分设置
timeout 为3600s强制退出
-
interact 开启交互模式
-
return $? 返回上一个命令执行结果,0:正常执行,正值:异常
-
declare -a hostInfoDict 声明shell字典
-
["127"]="127.0.0.1 username passwd" [hostIpNickName]="hostIp userName passWD"
-
$# 获取输入参数个数
-
[ $# -ne 1 ] 对于数值比较,要用文本类型描述,如:ne 、eq 、gt 等,对于字符串比较,用符号描述,如:== 、!= 、> 等
-
sshHostIp=$1 获取第一个参数,即hostIpNickName
-
IFS=" " 设置分隔符,注意保护现场与恢复现场
-
(${hostInfoDict[$sshHostIp]}) shell字典取值使用${}
执行脚本: ssshHost.sh 127
存在的安全性等问题
1、 ssh 的用户名、密码为明文,很容易泄露 2、只要通过前台登录上堡垒机,都能执行该脚本登录相关主机 3、如果设置timeout = -1 永不过期,若ssh连接界面没有使用ctrl +d ,而是直接关闭界面的话,该脚本不会退出,一直停留在后台 4、ssh 登录到别的主机之后,存在中文乱码现象。
相关解决方案思考: 1、 将shell脚本加密,或者使用编译后的C 来调用该脚本 2、没有好方法,如果要进行密码校验的话,失去了脚本的基本功能-_-! 3、根据场景设置了3600s强制下线,这个可以新增一个脚本对当前类似于僵死进程kill 掉 4、在跳板机增加LANG=zh_CN.GBK ,默认以GBK 登录 容我再想想……
参考文章
shell expect的简单用法 shell数组和字典 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|