傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波
写在前面
今天和小伙伴们分享批量配置SSH免密的一些笔记
传统的运维场景可以通过Ansible 等运维工具处理
在安装使用一些运维工具,比如Ansible,或则一些pass组件,需要配置ssh免密,sudo免密的操作
今天和小伙伴分享如何批量操作
博文内容比较简单,涉及 + expect
内网外网安装 + 通过expect
来批量配置免密
食用方式: + 需要Linux 基础知识
理解不足小伙伴帮忙指正
傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波
expect 安装 expect 是由Don Libes基于Tcl(Tool Command Language )语言
开发的,主要应用于自动化交互式操作的场景,借助Expect处理交互的命令,可以将交互过程如:ssh登录,ftp登录等写在一个脚本上
,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率
在内网环境下,无法连接yum源,我们可以找一台有网的机器,把rpm包下载下来,然后上传到内网环境
1 2 3 4 [root@vms152 ~] ... [root@vms152 ~] expect-5.45-14.el7_1.x86_64.rpm tcl-8.5.13-8.el7.x86_64.rpm
通过rpm -ivh
的方式来安装
1 2 3 4 5 6 7 8 [root@vms152 soft] 准备中... 正在升级/安装... 1:tcl-1:8.5.13-8.el7 2:expect-5.45-14.el7_1 [root@vms152 soft] [root@vms152 soft] /usr/bin/expect
在可以连接yum源的情况下,我们直接通过包管理器yum来下载
expect 基础用法 这里以root用户为例配置免密
Expect作为一种重要的TCL扩展包,主要有以下几个命令:
spawn:spawn用于启动一个进程,之后所有expect操作都在这个进程中进行,类似于我们直接在命令行敲bash
expect:获取匹配信息匹配成功则执行expect后面的程序动作(检测由壳内进程发出的特定交互指令反馈字符串后向下执行)
send:用于向进程发送字符串(从壳外向壳内进程发送一条字符串,换行符为确认结束)
interact:允许用户交互
exp_continue:在expect中多次匹配就需要用到
send_user:用来打印输出 相当于shell中的echo
exit:退出expect脚本
eof:expect执行结束 退出
set:定义变量
puts:输出变量
set timeout:设置超时时间
我们来看一个简单的Demo,命令行的方式来运行,通过SSH登录一台机器,并退出。这个交互式到的命令通过expect如何处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@vms152 soft] > spawn ssh root@127.0.0.1 > expect "*pass*" { send "redhat\r" } > expect "*connecting*" { send "yes\r" } > expect "#" > send "exit \r" > expect eof > EOF spawn ssh root@127.0.0.1 root@127.0.0.1's password: Last login: Sat Aug 20 15:22:06 2022 from 127.0.0.1 [root@vms152 ~]# exit 登出 Connection to 127.0.0.1 closed. [root@vms152 soft]#
如果是第一次登录,或者没有保存公钥,那么会有一个保存公钥的提示,我们可以这样处理,这次我们通过ctl脚本的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@vms153 ~] spawn ssh root@127.0.0.1 expect { "*connecting*" { send "yes\r" } "*pass*" { send "redhat\r" } } expect { "#" {send "\r" } "*pass*" { send "redhat\r" } } expect { "#" {send "exit \r" } } expect eof
清空SHSH存放公钥的文件,给脚本授权,执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@vms153 ~] [root@vms154 ~] [root@vms153 ~] spawn ssh root@127.0.0.1 The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. ECDSA key fingerprint is SHA256:rQokINjVDeZOfyKKcLlhIe92bgkN8xZ13QiPwr/0cxo. ECDSA key fingerprint is MD5:35:83:98:1d:76:b8:33:b0:b6:ba:d5:0f:34:2f:ba:b9. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added ' 127.0.0.1' (ECDSA) to the list of known hosts. root@127.0.0.1' s password:Last login: Sat Aug 20 17:25:03 2022 from 127.0.0.1 [root@vms153 ~] 登出 Connection to 127.0.0.1 closed. [root@vms153 ~]
当然,也可以交互式的使用,下面的脚本实现通过SHH远程到一台机器,并查看主机名,然后把终端交给标准输入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@vms153 ~] spawn ssh root@192.168.26.152 expect { "*connecting*" { send "yes\r" } "*pass*" { send "redhat\r" } } expect { "#" {send "\r" } "*pass*" { send "redhat\r" } } expect "#" send "hostname \r" expect "#" interact
运行脚本,我们可以直接操作SSH机器
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@vms153 ~] spawn ssh root@192.168.26.152 root@192.168.26.152 s password: Last login: Sat Aug 20 17:31:07 2022 from 192.168.26.153 [root@vms152 ~] [root@vms152 ~] vms152.rhce.cc [root@vms152 ~] anaconda-ks.cfg calico_3_14.tar calico.yaml one-client-install.sh set.sh soft [root@vms152 ~] 登出 Connection to 192.168.26.152 closed. [root@vms153 ~]
expect 配置root免密 1 2 3 [root@vms152 soft] 192.168.26.153 192.168.26.154
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 [root@vms152 soft] /usr/bin/expect <<-EOF spawn ssh-keygen expect "(/root/.ssh/id_rsa)" {send "\r"} expect { "(empty for no passphrase)" {send "\r"} "already" {send "y\r"} } expect { "again" {send "\r"} "(empty for no passphrase)" {send "\r"} } expect { "again" {send "\r"} "#" {send "\r"} } expect "#" expect eof EOF for IP in $( cat host_list )do if [ -n IP ];then /usr/bin/expect <<-EOF spawn ssh-copy-id root@$IP expect { "*yes/no*" { send "yes\r"} "*password*" { send "redhat\r" } } expect { "*password" { send "redhat\r"} "#" { send "\r"} } expect "#" expect eof EOF fi done
这里需要说明的是 expect
中有些特殊关键字用于匹配过程,代表某些特殊的含义或状态,可能会和shell 脚本中的冲突,所以一般只用于expect命令中而不能在expect命令单独使用,比如 eof,timeout等,如果密码中存在特殊字符,且在脚本里冲突,那么可以使用一些python模块来处理,比如Paramiko
,fabric
等。
博文参考 linux expect 详解:https://blog.csdn.net/zxycyj1989/article/details/125837697