作为运维经常操作Linux服务器是不可避免的事情的,那么你们都是怎么管理的呢?
我们管理的方式较为复杂了,我说一下:
有一套服务器资产管理系统,所有服务器都记录在上面,包括用户名密码,内外网地址都会有记录。服务器做了禁止ROOT登录,我们用公钥登录,在服务器上配公钥和私钥,然后配置SecureCRT以SSH以公钥方式登录服务器。
配置操作方法在我以前文章有发过。
有的企业使用自动化工具将公钥分发到所有服务器上,实现免密码登录,这样也是较为方便的。下面开始进入正题。
使用今天的自动化运维脚本也可以实现,但它的功能可不单单是这一个。
expect:是一种自动交互式的语言脚本,可以实现自动交互而无需手动敲yes or no。CentOS 的机器,可以使用 yum install expect 的方式安装。
expect 脚本实现 SSH 自动登陆服务器
vim test.exp
#告诉操作系统脚本里的代码使用那一个shell来执行,使用which expect 即可找到命令所在路径。
#!/usr/bin/expect
# 设置超时时间为 0 秒
set timeout 0
#spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。所以不要用 “which spawn“之类的命令去找spawn命令。好比windows里的dir就是一个内部命令,这个命令由shell自带,你无法找到一个dir.exe 的可执行文件。
spawn ssh root@192.168.0.163
#这里的expect也是expect的一个内部命令,有点晕吧,expect的shell命令和内部命令是一样的,但不是一个功能,习惯就好了。这个命令的意思是判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间后返回,这里等待时长就是前面设置的30秒
expect "password:"
#这里就是执行交互动作,send表示发送什么命令,后面的一定要加表示回车。
send "A0000223456700"
#执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。如果你只是登录过去执行则使用expect eof
interact
这样一来,把 ali.exp 文件设为可执行的之后,就可以 ./test.exp 运行脚本,自动就连上服务器了。
下面分享一个要传送脚本参数的例子:
#!/usr/bin/expect
# 设置超时时间为 0 秒
set timeout 0
# 设置要登录的主机 IP 地址,$argv 参数数组,expect脚本可以接受从bash传递过来的参数.可以使用[lindex $argv n]获得,n从0开始,分别表示第一个,第二个,第三个....参数
set host "[lindex $argv 0]"
#spawn 一个 ssh 登录进程
spawn ssh $host
# 等待响应,如果做了免密码登录会立即登录
expect {
"yes/no"
{ send "yes" } ##这里如果要匹配多个字符串需要自动写入请继续往下写{}的内容
}
interact
# expect eof
使用效果如图:
其实做服务器管理上面这些功能就够了,功能还有很多,有兴趣的小伙伴可去探索一起交流撒。
如果有兴趣可以做个集中批量分发ssh秘钥机子写个脚本批量分发下去,然后在使用expect脚本更方便管理了。
下面附上SSH无密码登录的原理及配置
配置主机A免密登录到主机B
1.在主机A生产密钥对: ssh-keygen -t rsa, 会在.ssh目录下产生密钥文件
2.拷贝主机A的公钥到主机B: scp id_rsa.pub
3.将主机A的公钥加到主机B的授权列表.ssh/authorized_keys(若不存在,手动创建): cat id_rsa.pub >> authorized_keys
4.授权列表authorized_keys的权限必须是600,chmod 600 authorized_keys
编写Expect脚本,实现key的上传
#!/bin/expect
#
if { $argc != 2 } {
send_user "usage: send-rsa-id file host \n"
exit
}
#define var
set password wbxue.blog
set file [lindex $argv 0 ]
set ip [lindex $argv 1 ]
#start exec command
spawn ssh-copy-id -i $file root@$ip
expect {
"yes/on" {send "yes\r";exp_continue}
"*password*" {send "$password\r"}
}
expect eof
利用bash脚本调用Expect脚本批量给服务器上传(此时已实现免密码登录)
- #!/bin/bash
- file=/root/.ssh/id_rsa.pub
- net=192.168.100
- ip=$net.$n
- for n in {1..255};do
- expect send-rsa-pub.exp $file $ip
- done
Expect指令说明:
set:可以设置超时,也可以设置变量。
timeout:expect超时等待时间,默认10S。
spawn:执行一个命令。
expect"":匹配输出的内容。
exp_continue:继续执行下面匹配。
\r:可以理解为回车。
$argc:统计位置参数数量。
[lindex$argv 0]:脚本后第一个参数,类似于shell中$1,以此类推。
puts:打印字符串,类似于Shell的echo。
awk-v I="$ip":赋值变量。
expect{...}:输入多行记录。
其他指定说明:
timeout-1:永不超时退出。
log_file/var/log/expect.log:记录交互信息。
interact:交互后不退出远程终端,如果加要把expect "root@*" {send "exit\r"}注释掉,如果不加,就直接退出。