Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1285175
  • 博文数量: 161
  • 博客积分: 10192
  • 博客等级: 上将
  • 技术积分: 2165
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-27 17:09
文章分类

全部博文(161)

文章存档

2012年(2)

2011年(13)

2010年(137)

2009年(5)

2008年(4)

我的朋友

分类: LINUX

2011-05-13 16:04:09

原因:
    
100多台服务器的用户密码修改,要求速度快。(几百台还可以,上千台的话expect速度慢。它本来就不快)
说明:
     共三个文件,如下:
     ip.txt   文本文件,所有待修改密码的服务器ip放这里,一行一个,无空行。
     expect.exp   expect程序,单纯修改密码,被循环调用,需有执行权限x。
     change-passwd.sh   主程序,直接执行它即可,需有执行权限x。
如何运行:
     三个文件放在同一目录下,根据具体情况设置你的ip和其他参数,赋予执行权限,直接执行
change-passwd.sh即可。
程序流程分析:
     直接执行change-passwd.sh,按要求输入所有ip的文件名,如ip.txt
     程序会先用nmap分析ip.txt里所有主机及其22端口是否正常(也可以是其他SSHD端口,根据你的具体情况设置),正常的ip则导入到goodip.txt文件供expect.exp使用;无响应的则导入到badid.txt,供你以后分析原因。这样会迅速淘汰那些网络不通的超时的或SSHD服务异常的主机。
     接下来会清空$HOME/.ssh/known_hosts文件,避免旧KEY影响SSH连接。
     下面就是循环调用expect.exp子程序修改密码;成功的不管,由于其他原因修改不成功的会把其IP导入到fail_ip.txt文件,供你以后查找分析解决,如某些服务器的旧密码可能和你这里设定的不符之类的原因。
     最后完成后会生成$LOG文件,可以分析它,然后删除之。安全原因。

文件详情:    
--------------------------------------------------------------------
cat ip.txt

192.168.0.5
192.168.0.6
192.168.0.x
......
---------------------------------------------------------------------
cat expect.exp

#!/usr/bin/expect -f
#
set force_conservative 0  ;# set to 1 to force conservative mode even if
                          ;# script wasn't run conservatively originally
if {$force_conservative} {
        set send_slow {1 .1}
        proc send {ignore arg} {
                sleep .1
                exp_send -s -- $arg
        }
}


set timeout 5  #5秒超时。若你网络差就改大。嗯,是的,越大就越慢。
spawn ssh [lindex $argv 0]@[lindex $argv 1] -p22
match_max 100000
expect -exact "(yes/no)?"
send -- "yes\r"
expect -exact "assword:"
send -- "[lindex $argv 2]\r"
expect -exact "$"
send -- "passwd\r"
expect -exact "assword:"
send -- "[lindex $argv 2]\r"
expect -exact "New password:"
send -- "[lindex $argv 3]\r"
expect -exact "Retype new password:"
send -- "[lindex $argv 3]\r"
expect -exact "$"
send -- "exit\r"

-----------------------------------------------------------------------
cat change-passwd.sh

#!/bin/bash
#201105 version 0.0.2
#This shell will change user password,use expect.

DATE=`date +%Y%m%d" "%H:%M:%S`
LOG=/tmp/expectlog.$$.$RANDOM.log
TMPFILE=$RANDOM.log

GOODIPFILE=goodip.txt
BADIPFILE=badip.txt
FAILIP=fail_ip.txt

USERNAME=yourname
OLDPASSWD=xxxxxx  #注意特殊字符要加转义\,如“$”,需要写成“\$”. 可事先用autoexpect -p ssh x.x.x.x -p 22 命令记录一个你的修改密码过程,然后查看生成的script.exp,看你的特殊字符到底该如何转义。方便不是。不用死记expect的字符哪些需要转义。
NEWPASSWD=yyyyyy  #同上
SSHKEYFILE=$HOME/.ssh/known_hosts

#if host and 22 port is good,check out to goodip.txt
echo -e "Please input the all ip file name:"
read ALLIPFILE
echo -e "Begin check host and port..."
nmap -sT -p22 -v -i $ALLIPFILE|awk -F'[)(]'  '/^Host.*good.$/{print $2 >"'"$GOODIPFILE"'"}/^Host.*skipping it.$/{print $2 >"'"$BADIPFILE"'"}'
echo -e "Total number ip is `wc -l $ALLIPFILE`"
echo -e "Good ip number ip is `wc -l $GOODIPFILE`"
echo -e "Bad ip number ip is `wc -l $BADIPFILE`"

#change the username passwd with expect.exp
echo -e "Continue? Please input (y/n)"
read CONTINUE
if [ $CONTINUE = "y" ]
    then
    echo -e "BEGIN--->"
    echo -e "We will clean the $HOME/.ssh/known_hosts,please input (y/n)"
    read INPUT
    if [ $INPUT = "y" ]
    then
        echo >$SSHKEYFILE
        if [ $? -eq 0 ]
        then
              echo "Ok,$SSHKEYFILE has been cleand.We will go..."
              echo $DATE>>$LOG
              for i in `cat $GOODIPFILE`
              do
                ./expect.exp $USERNAME $i $OLDPASSWD $NEWPASSWD >>$LOG
              done
              echo -e "<---END"
              echo -e "Failed ip is(are):($FAILIP)"
              #this awk shell will select these ip of change passwd failed.
              awk -v var="" '/^'"$USERNAME"'@[0-9]/{gsub(/('"$USERNAME"'@)||([^0-9]s password:.*$)/,"");var=$0};/current/{print var > "'"$TMPFILE"'"}' $LOG
              grep -vFf $TMPFILE $GOODIPFILE > $FAILIP
              cat $FAILIP
              rm -f $TMPFILE
              #$LOG must been deleted.Because username and passwd had included by $LOG.
              #If you check the error in $LOG,can delete it after check it.
              #rm -f $LOG
        else
              echo "Sorry,$SSHKEYFILE has not been cleand,please check it."
              exit
        fi
    else
        echo "Sorry,$SSHKEYFILE must been cleand.Otherwise the ssh connect server will faild and expect will faild also."
        exit
    fi
else
    echo -e "Ok,bye."
    exit
fi
--------------------------------------------------------------------



---end---
阅读(2095) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~