公司linux服务200多台,日常运维需要每季度修改密码,非常麻烦,而且由于做了安全加固,禁止root用户远程登录,更增加了复杂度。现采用如下方法可以解决:
1、管理机commuser生成的公钥文件.ssh/id_rsa.pub,放到远程机root的.ssh/authorized_keys中,管理机commuser用户登录ssh root@远程机无需密码;管理机root用户登录远程机需要密码。
2、自动修改密码脚本:
1)管理机生成公钥文件,copy到远程机,有多少远程机,就需要copy台;同时远程机必须安装好expect。
2)远程机/root/pwd目录下建立如下脚本chg_pwd.sh,附上755执行权限。
chg_pwd.sh脚本如下:

#!/usr/expect/bin/expect

set oldrootpwd [lindex $argv 0]
set oldoperpwd [lindex $argv 1]
set newrootpwd [lindex $argv 2]
set newoperpwd [lindex $argv 3]

#-----login timed out or refused -----
expect {
"timed out" exit
"refused" exit
Connect
}

#expect "$"

#-----first login-----
expect {
"(yes/no)?" {
send "yes\n"
}
}
#expect "#"

#-----login root-----
spawn su - root
expect "password:"
send "$oldrootpwd\r"
expect "#"

#-----set root password -----
send "passwd root\r"
expect "password:"
send "$newrootpwd\r"
expect "password:"
send "$newrootpwd\r"
expect "#"

#-----set commuser password -----
send "passwd commuser\r"
expect "password:"
send "$newoperpwd\r"
expect "password:"
send "$newoperpwd\r"
expect "#"
send "exit\r"

interact

3)管理机在/home/commuser/.ssh/目录下建立auto_pwd.sh,list.demo,log.txt 3个文件。
auto_pwd.sh
ssh 10.60.160.254 /usr/expect/bin/chg_pwd.sh testpasswd testpasswd testpasswd testpasswd
ssh 10.60.10.10 /usr/expect/bin/chg_pwd.sh testpasswd testpasswd testpasswd testpasswd
ssh 10.60.160.156 /usr/expect/bin/chg_pwd.sh testpasswd testpasswd testpasswd testpasswd
ssh [email protected] /usr/expect/bin/chg_pwd.sh testpasswd ------------- testpasswd -------------
ssh 10.60.160.252 -------------------------- testpasswd testpasswd testpasswd testpasswd

list.demo
shell ip address shell remotee path oldrootpwd oldoperpwd newrootpwd newoperpwd note
ssh 10.60.160.254 /usr/expect/bin/chg_pwd.sh testpasswd testpasswd testpasswd testpasswd ip esxit no ssh
ssh 10.60.10.10 /usr/expect/bin/chg_pwd.sh testpasswd testpasswd testpasswd testpasswd no ip
ssh 10.60.160.156 /usr/expect/bin/chg_pwd.sh testpasswd testpasswd testpasswd testpasswd ok
ssh [email protected] /usr/expect/bin/chg_pwd.sh testpasswd ------------- testpasswd ------------- no testoper
ssh 10.60.160.252 -------------------------- testpasswd testpasswd testpasswd testpasswd no expect

auto_pwd.sh附上755执行权限,修改密码时候commuser登录管理机执行./auto_pwd.sh > log.txt便可。执行无权限是给/usr/tcl usr/expect 755权限

补充:1)对远程机不能进行安全加固只有root用户的,复制管理机commuser的公钥文件过去也是可以ssh登录,只需优化的是对chg_pwd.sh判断入参是否有old commuser用户。
2)expect安装参考:
Expect是在Tcl基础上创建起来的,它还提供了一些Tcl所没有的命令,它可以用来做一些linux下无法做到交互的一些命令操作,在远程管 理方面发挥很大的作用。
spawn命令激活一个Unix程序来进行交互式的运行。 
send命令向进程发送字符串。
expect 命令等待进程的某些字符串。 
expect支持正规表达式并能同时等待多个字符串,并对每一个字符串执行不同的操作.

A. Tcl 安装
主页: http://www.tcl.tk
下载地址: http://www.tcl.tk/software/tcltk/downloadnow84.tml
1.下载源码包
wget https://nchc.dl.sourceforge.net/project/tcl/Tcl/8.6.8/tcl8.6.8-src.tar.gz
2.解压缩源码包
tar xfvz tcl8.6.8-src.tar.gz
3.安装配置
cd tcl8.6.8/unix
./configure --prefix=/usr/tcl --enable-shared
make && make install
安装完毕以后,进入tcl源代码的根目录,把子目录unix下面的tclUnixPort.h copy到子目录generic中。cp tclUnixPort.h ../generic
暂时不要删除tcl源代码,因为expect的安装过程还需要用。

B. expect 安装 (需Tcl的库)
主页: https://sourceforge.net/projects/expect/
1.下载源码包
wget https://nchc.dl.sourceforge.net/project/expect/Expect/5.45.3/expect5.45.3.tar.gz
2.解压缩源码包
tar xzvf expect5.45.3.tar.gz
3.安装配置
cd expect5.45.3
./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.6.8/generic
make && make install
ln -s /usr/tcl/bin/expect /usr/expect/bin/expect 此步骤可不需执行

自动修改密码方式:
采用此方式无需建立ssh互信,但还是需要安装expect,安装后把autochg_pwd.sh放置在/root/pwd下,并chmod 755 赋权,计划任务crontab -e 建立一个每季度第一天凌晨3点的定时任务:00 3 1 1,4,7,10 * /bin/sh /root/pwd/autochg_pwd.sh

autochg_pwd.sh脚本如下:

#!/bin/bash
ystr=date +%Y
mstr=date +%m
dstr=date +%d

if [ "$mstr" == "01" ];then
mstr="!"
fi
if [ "$mstr" == "02" ];then
mstr="!"
fi
if [ "$mstr" == "03" ];then
mstr="!"
fi
if [ "$mstr" == "04" ];thenbr/>mstr="@"
fi
if [ "$mstr" == "05" ];thenbr/>mstr="@"
fi
if [ "$mstr" == "06" ];thenbr/>mstr="@"
fi
if [ "$mstr" == "07" ];then
mstr="#"
fi
if [ "$mstr" == "08" ];then
mstr="#"
fi
if [ "$mstr" == "09" ];then
mstr="#"
fi
if [ "$mstr" == "10" ];then
mstr="$"
fi
if [ "$mstr" == "11" ];then
mstr="$"
fi
if [ "$mstr" == "12" ];then
mstr="$"
fi

if [ "$mstr" == "!" ];then
oldmstr="$"
fi
if [ "$mstr" == "@" ];then
mstr="!"
fi
if [ "$mstr" == "#" ];thenbr/>mstr="@"
fi
if [ "$mstr" == "$" ];then
mstr="#"
fi

oldrootpwd="testpwd"$ystr$oldmstr
oldoperpwd="testpwd"$ystr$oldmstr
newrootpwd="testpwd"$ystr$mstr
newoperpwd="testpwd"$ystr$mstr

/usr/expect/bin/expect <<-EOF
#-----login root-----
spawn su - root
#expect "password:"
#send "$oldrootpwd\r"
expect "#"

#-----set root password -----
send "passwd root\r"
expect "password:"
send "$newrootpwd\r"
expect "password:"
send "$newrootpwd\r"
expect "#"

#-----set testoper password -----
send "passwd testoper\r"
expect "password:"
send "$newoperpwd\r"
expect "password:"
send "$newoperpwd\r"
expect "#"
send "exit\r"

interact

expect eof
EOF