expect实现一台服务器修改多台服务器密码

19 篇文章 0 订阅
1 篇文章 0 订阅

一、背景

修改Linux系统密码,执行passwd即可更改密码。可如果有成千上百台服务器呢,通过ssh的方式逐一进行修改,对我们来说,工作量是非常大,且效率非常低下。因此准备采用批量修改密码的方式来处理。

二、环境准备

需求:在Linux环境下运行,需要tcl和expect支持

检查系统是否有expect和tcl:
在这里插入图片描述
可以看到系统已经安装有这两个软件,如果没有,yum -y install expect tcl进行安装即可。
「说明:本文利用expect的自动化人机交互功能,登录到远端服务器批量修改密码」

三、具体步骤

1、编写脚本文件
实现批量修改密码,需要创建三个文件:

1.touch /root/pwdmodify/ip.ini

该文件用于存放目标服务器的IP地址和root密码,及新密码;新密码也可以通过mkpasswd生成

这里以1台设备为例,如果你需要修改更多服务器密码,只需要编写服务器IP及对应的root密码即可。如图所示:(IP地址 现在的密码 修改的密码)
在这里插入图片描述
2.touch /root/pwdmodify/passwd.sh

利用for循环实现批量执行,如下:

#!/bin/bash
for ip in `awk '{print $1}' /root/pwdmodify/ip.ini`
do 
  passwd=`grep $ip /root/pwdmodify/ip.ini |awk '{print $2}'`
  #此处用到了 随机生成密码,工作中肯定会记录密码所以,不建议使用
  #new_passwd=`mkpasswd -l 16 -d 4 -c 6 -C 5`
  new_passwd="caishun123"
  expect /root/pwdmodify/action.exp $ip $passwd $new_passwd
done

3.touch /root/pwdmodify/action.exp
注意:set timeout 超市设置要写在spawn之前
利用expect自动人机交互功能,设置特定的匹配形式,便于匹配相应的动作

注意:第一行#! /bin/expect,表示使用expect解释器执行;第11行表示将密码统一修改为传递过来的密码

#! /bin/expect
set ipaddr [lindex $argv 0]
set passwd [lindex $argv 1]
set new_passwd [lindex $argv 2]
set timeout 30
spawn ssh root@$ipaddr
expect {
"yes/no" {send "yes\r";exp_continue}
"password" {send "$passwd\r"}
}
expect "#"
send "echo $new_passwd |passwd --stdin root\r"
send "exit\r"
expect eof

2、为脚本添加可执行权限

chmod 755 /root/pwdmodify/action.exp
chmod 755 /root/pwdmodify/passwd.sh

3、至此,可以实现批量修改密码

**

脚本解释

**
1)第一个脚本passwd.sh,应该好理解。就是利用awk命令把我们编写的ip.ini文本中的服务器IP及root密码分别提取出来;通过for循环,批量交给expect解释器执行。

2)我们重点解释下action.exp脚本;

  1. 第1行告诉操作系统,以下脚本代码使用expect解释器来执行。
  2. 第2行及第3行,第4行使用[lindex $argv n],表示变量ipaddr及passwd接受从bash传递过来的参数,从0开始,分别表示第一个,第二个参数,第三个参数。这里表示从passwd.sh脚本中提取出来的ip 旧密码及新密码
  3. 第5行设定了本脚本所有的超时时间,单位是秒(s)
  4. 第6行利用spawn命令启动ssh会话连接
  5. 第7-9行expect {}代表多行期望;当匹配到yes/no时,自动输入yes并执行回车动作;匹配到password时,自动输入密码并回车。
  6. 第12行不用多解释了吧,登录上远程服务器后,将密码修改为$new_passwd
  7. 第13及14行表示退出expect;其中expect eof与spawn对应,表示捕获终端输出信息的终止。
    mkpasswd命令生成随机密码,如果没有则安装

参数:

-l # (密码的长度定义, 默认是 9)

-d # (数字个数, 默认是 2)

-c # (小写字符个数, 默认是 2)

-C # (大写字符个数, 默认是 2)

-s # (特殊字符个数, 默认是 1)

-v (详细。。。)

-p prog (程序设置密码, 默认是 passwd)

#1.生成密码长度10,数字2个,小写3个,大写3个,特殊2个
mkpasswd  -l 10 -d 2 -c 3 -C 3 -s 2  
W'.Ix5Kvd1    

#2生成随机密码同时制定长度为20
[root@service-01 ~]# mkpasswd -l 20    
mMgfg7bfH~5irgacvqna

#3生成默认长度随机密码
[root@service-01 ~]# mkpasswd          
4kaxd2$WV

 #4生成指定数字位数的密码
[root@service-01 ~]# mkpasswd -d 3    
ob4e}1NL2

#5为用户更改随机密码,当然如果想知道生成的密码需要配合shell来操作,这种方法适用于为很多用户修改随机密码。
[root@service-01 ~]# echo `mkpasswd -l 10` | passwd --stdin root

案例

案例1:通过expect远程执行多条命令

#!/bin/bash 
ip=$1  
user=$2 
password=$3 

expect <<EOF  
    set timeout 10 
    spawn ssh $user@$ip 
    expect { 
        "yes/no" { send "yes\n";exp_continue } 
        "password" { send "$password\n" }
    } 
    expect "]#" { send "useradd hehe\n" } 
    expect "]#" { send "touch /tmp/test.txt\n" } 
    expect "]#" { send "exit\n" } expect eof 
 EOF  
 #./ssh5.sh 192.168.1.10 root 123456 

案例2:使用普通用户登录远程主机,并通过sudo到root权限,通过for循环批量在远程主机执行命令.

$ cat timeout_login.txt 
10.0.1.8
10.0.1.34
10.0.1.88
10.0.1.76
10.0.1.2
10.0.1.3
#!/bin/bash

for i in `cat /home/admin/timeout_login.txt`
do

    /usr/bin/expect << EOF
    spawn /usr/bin/ssh -t -p 22022 admin@$i "sudo su -"

    expect {
        "yes/no" { send "yes\r" }
    }   

    expect {
        "password:" { send "xxo1#qaz\r" }
    }
    
    expect {
        "*password*:" { send "xx1#qaz\r" }
    }

    expect "*]#"
    send "df -Th\r"
    expect "*]#"
    send "exit\r"
    expect eof

EOF
done

案例3:密码过期需要批量修改密码

#!/bin/bash

for i in `cat /root/soft/ip.txt`
do

    /usr/bin/expect << EOF
    spawn /usr/bin/ssh root@$i

    expect {
        "UNIX password" { send "Huawei@123\r" }
    }
    
    expect {
        "New password:" { send "xxHuzzawexxi@1234#\r" }
    }

   expect {
        "Retype new password:" { send "xxHuzzawexxi@1234#\r" }
    }

    expect "*]#"
    send "echo Huawei@123|passwd --stdin root\r"
    expect "*]#"
    send "exit\r"
    expect eof
EOF
done

案例5: 通过expect使用ssh连过去之后对远端机器使用df -lh、date、ls命令
注意:set timeout要写在spawn之前;expect eof要被包含在expect{}的大括号里面

#!/usr/bin/expect
set timeout 30
spawn ssh root@192.168.1.1

expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "hbzq0123\r" }
"~]#" { send "df -lh\r" }

}
expect {
"~]#" { send "free\r" }
}
expect {
"~]#" { send "ls\r" }
}
expect {
"~]#" { send "exit\r"}
expect eof
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sh13661847134

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值