虚拟化容器,大数据,DBA,中间件,监控。

Shell 脚本实现ansible免密认证 expect批量导入ssh公钥

20 12月
作者:admin|分类:系统运维

作为一个运维工程师,不是每个人工作的环境都想阿里、腾讯那样,动不动就上亿的PV量,上万台服务器。我们通常还是工作在,几十台上百台服务器这样的环境,而使用ansible或者puppet这样的自动化运维工具则显得大材小用,并且最终的效果可能还不如几个小工具达到的效果好。像ssh免密登录在配合pssh这样的推送工具,在配合自动化配置脚本,可以说是即方便也使用。本文章将详细带大家以shell脚本的形式实现ssh免密登录进行百台机器的配置和管理。

 

ssh服务


随着明文通信协议telnet渐渐退出历史舞台,ssh这个作为安全的远程登录工具,更加受广大用户的青睐。SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。SSH最初是UNIX系统上的一个程序,后来又迅速扩展到其他操作平台。SSH在正确使用时可弥补网络中的漏洞。SSH客户端适用于多种平台。几乎所有UNIX平台—包括HP-UX、Linux、AIX、Solaris、Digital UNIX、Irix,以及其他平台,都可运行SSH。

ssh服务有两种验证用户登录的方式,一种是基于密码口令的认证,一种是基于密钥的认证。

 

 基于expect批量导入ssh公钥实现ansible免密认证


(1)这里for循环不适合取出IP,所以我的脚本使用while语句来实现 

[root@localhost ~]# cat host_ip.txt 
192.168.179.103 root 123456
192.168.179.104 root 123456

[root@localhost ~]# for i in `cat host_ip.txt`;do echo $i;done
192.168.179.103
root
123456
192.168.179.104
root
123456

[root@localhost ~]# while read line ;do echo $line ;done<host_ip.txt 
192.168.179.103 root 123456
192.168.179.104 root 123456

(2)使用while cut命令取出每个客户端IP 用户名 密码信息 

[root@localhost ~]# cat test.sh 
#/binn/bash
while read line;do
      	ip=`echo $line | cut -d " " -f1`
        user_name=`echo $line | cut -d " " -f2`
        pass_word=`echo $line | cut -d " " -f3`
        echo -e "\033[32m ip:$ip usename:$user_name password:$pass_word \033[0m"
done<host_ip.txt 


[root@localhost ~]# ./test.sh 
 ip:192.168.179.103 usename:root password:123456 
 ip:192.168.179.104 usename:root password:123456 


[root@localhost ~]# rpm -q expect
expect-5.45-14.el7_1.x86_64
[root@localhost ~]# echo $?
0
[root@localhost ~]# rpm -q expec
package expec is not installed
[root@localhost ~]# echo $?
1

(3)expect批量导入ssh公钥完整脚本如下

[root@localhost ~]# cat auto.sh 
#/binn/bash
status=`rpm -q expect`

if [ `whoami` != "root" ];then
	echo "only root can run it! exit"
	exit 1
fi

if [ $status -ne 0   ];then
	yum  install expect -y
fi


while read line;do
      	ip=`echo $line | cut -d " " -f1`
        user_name=`echo $line | cut -d " " -f2`
        pass_word=`echo $line | cut -d " " -f3`
        echo -e "\033[32m ip:$ip usename:$user_name password:$pass_word \033[0m"

/usr/bin/expect << EOF
        spawn ssh-copy-id $user_name@$ip   
        expect {
                "yes/no" { send "yes\n";exp_continue}     
                "password" { send "$pass_word\n"}
        }
expect eof
EOF

done<host_ip.txt 

脚本测试结果如下

[root@localhost ~]# ./auto.sh 
./auto.sh: line 9: [: expect-5.45-14.el7_1.x86_64: integer expression expected
 ip:192.168.179.103 usename:root password:123456 
spawn ssh-copy-id root@192.168.179.103
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.179.103's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.179.103'"
and check to make sure that only the key(s) you wanted were added.

 ip:192.168.179.104 usename:root password:123456 
spawn ssh-copy-id root@192.168.179.104
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
		(if you think this is a mistake, you may want to use -f option)

expect: spawn id exp6 not open
    while executing
"expect eof"
[root@localhost ~]# ssh -l root 192.168.179.103
Last login: Sat Jul 25 17:05:26 2020 from 192.168.179.4

 

浏览488 评论0
返回
目录
返回
首页
Ansible 变量的使用详解 Shell for语句实战案例